#!/usr/bin/env perl
our
$VERSION
=
'1.0'
;
our
$db
: Getopt(db=s SQLite);
our
$write_to_dir
: Getopt(
write
=s);
my
$schema
=
shift
;
my
$source
=
shift
;
my
$target
=
shift
;
if
(not
$schema
or not
$source
) {
print
"usage: dbic-diff <class> <treeish1> [<treeish2>]\n"
;
exit
1;
}
$| = 1;
my
$scratch
= new Directory::Scratch;
my
$dirold
= (
$source
and -d
$source
) ?
$source
:
$scratch
->
mkdir
(
'old'
);
my
$dirnew
= (
$target
and -d
$target
) ?
$target
:
$scratch
->
mkdir
(
'new'
);
print
"-- source: $source\n"
;
print
"-- target: "
. (
$target
||
'index'
) .
"\n"
;
print
"-- exporting $source..."
;
system
(
"git archive $source | tar xf - -C $dirold"
);
print
"done\n"
;
if
(
$target
) {
print
"-- exporting $target..."
;
system
(
"git archive $target | tar xf - -C $dirnew"
);
}
else
{
print
"-- copying contents of index..."
;
system
(
"git checkout-index -a --prefix=$dirnew/"
);
}
print
"done\n"
;
my
$collector
=
sub
{
my
$aref
=
shift
;
return
sub
{
my
$path
=
shift
;
if
(
$path
->is_dir) {
my
$dir
=
$path
->subdir(
'lib'
);
push
@$aref
,
$dir
if
$path
->contains(
$dir
);
}
}
};
my
@pathold
;
my
@pathnew
;
$dirold
->recurse(
callback
=>
$collector
->(\
@pathold
));
$dirnew
->recurse(
callback
=>
$collector
->(\
@pathnew
));
my
@argsold
=
(
map
((
'-I'
,
$_
->stringify),
@pathold
),
qq{-MSQL::Translator::Schema::Constraint}
,
qq{-M$schema}
,
qq{-e}
,
qq{$schema->connect('dbd:nullp')->create_ddl_dir('$db', 'OLD', '$scratch')}
);
my
@argsnew
=
(
map
((
'-I'
,
$_
->stringify),
@pathnew
),
qq{-MSQL::Translator::Schema::Constraint}
,
qq{-M$schema}
,
qq{-e}
,
qq{$schema->connect('dbd:nullp')->create_ddl_dir('$db', 'NEW', '$scratch')}
);
print
"-- creating DDLs..."
;
if
(
my
$pid
=
fork
) {
waitpid
$pid
, 0;
}
else
{
close
STDOUT;
close
STDERR;
exec
perl
=>
@argsold
;
}
if
(
my
$pid
=
fork
) {
waitpid
$pid
, 0;
}
else
{
close
STDOUT;
close
STDERR;
exec
perl
=>
@argsnew
;
}
print
"done\n"
;
print
"-- performing diff..."
;
(
my
$file
=
$schema
) =~ s/::/-/g;
my
$old
= new SQL::Translator
parser
=>
$db
;
my
$new
= new SQL::Translator
parser
=>
$db
;
$old
->translate(
"$scratch/$file-OLD-$db.sql"
);
$new
->translate(
"$scratch/$file-NEW-$db.sql"
);
$old
->schema->name(
$source
);
$new
->schema->name(
$target
||
'index'
);
my
$opts
=
{
caseopt
=> 0,
ignore_index_names
=> 0,
ignore_constraint_names
=> 0,
ignore_view_sql
=> 0,
ignore_proc_sql
=> 0,
output_db
=>
$db
,
no_batch_alters
=> 1,
debug
=> 1,
trace
=> 1
};
my
$diff
= SQL::Translator::Diff::schema_diff(
$old
->schema,
$db
,
$new
->schema,
$db
,
$opts
);
print
"done\n\n"
;
write_sql_to_directory(
$write_to_dir
)
if
$write_to_dir
;
print
$diff
;
sub
write_sql_to_directory {
my
$dir
=
shift
;
$target
||=
'index'
;
my
$file
=
"$dir/$source-$target"
;
$file
.=
".sql"
;
print
"Writing SQL to $file...\n"
;
open
my
$fh
,
">"
,
$file
||
die
"Can't open $file: $!"
;
print
$fh
$diff
;
close
$fh
;
print
"Done!\n"
;
}