first cut of kmig-stage, and tweak kmig-link to allow linking to non-existent parent...
[migration-tools.git] / kmig.d / bin / mig-stage
1 #!/usr/bin/perl -w
2 ###############################################################################
3 =pod
4
5 =head1 NAME
6
7 mig-stage 
8
9 Load the SQL-converted version of the specified file into the migration schema.
10
11 Extra arguments are passed to the underlying call to psql
12
13 If the tracked file was previously staged with a different table, drop that
14 table.
15
16
17 =head1 SYNOPSIS
18
19 B<mig-stage> <file> [other arguments...]
20
21 =cut
22
23 ###############################################################################
24
25 use strict;
26 use Switch;
27 use Env qw(
28     HOME MYSQL_HOST MYSQL_TCP_PORT MYSQL_USER MYSQL_DATABASE MYSQL_PW
29     MIGSCHEMA MIGBASEWORKDIR MIGBASEGITDIR MIGGITDIR MIGWORKDIR
30 );
31 use Pod::Usage;
32 use DBI;
33 use Cwd 'abs_path';
34 use FindBin;
35 my $mig_bin = "$FindBin::Bin/";
36 use lib "$FindBin::Bin/";
37 use KMig;
38
39 pod2usage(-verbose => 2) if ! $ARGV[0] || $ARGV[0] eq '--help';
40
41 KMig::die_if_no_env_migschema();
42 KMig::die_if_mig_tracking_table_does_not_exist();
43
44 my $file = abs_path($ARGV[0]);
45 if ($file =~ /^$MIGBASEWORKDIR/) {
46     stage_csv(@ARGV);
47 } else {
48     print "File falls outside of MIGWORKDIR ($MIGWORKDIR): $file\n";
49 }
50
51 exit 0;
52
53 ###############################################################################
54
55 sub stage_csv {
56     my $file = abs_path(shift);
57     my @args = @_;
58
59     my $tracked_file_id = KMig::check_for_tracked_file($file);
60     if ($tracked_file_id) {
61         my $data = KMig::status_this_file($file);
62
63         if (! $data->{'utf8_filename'}) {
64             die "mig-iconv or mig-skip-iconv needed for UTF8 version of file: $file\n";
65         }
66
67         if (! $data->{'clean_filename'}) {
68             die "mig-clean or mig-skip-clean needed for .clean version of file: $file\n";
69         }
70
71         if (! $data->{'stage_sql_filename'}) {
72             die "mig-convert needed for .stage.sql version of file: $file\n";
73         }
74
75         my $stage_sql_filename = $data->{'stage_sql_filename'};
76         if (! -e $stage_sql_filename) {
77             die "missing file: $stage_sql_filename\n";
78         }
79
80         my $table = `grep 'CREATE TABLE' $stage_sql_filename  | cut -f3 -d\\  | head -1`;
81         chomp $table;
82
83         if (defined $data->{'staged_table'} && $data->{'staged_table'} ne $table) {
84             if ($data->{staged_table} !~ '^m_') {
85                 die "Previously staged table $data->{staged_table} does not have a m_ prefix; afraid to drop.";
86             }
87             my $dbh2 = KMig::db_connect();
88             print "dropping previously staged table: $data->{staged_table}\n";
89             my $rv2 = $dbh2->do("
90                 DROP TABLE $data->{staged_table};
91             ") || die "Error dropping table $data->{staged_table}: $!\n";
92             print "changing references to old tables\n";
93             my $rv3 = $dbh2->do("
94                 UPDATE m_tracked_column
95                 SET staged_table = " . $dbh2->quote($table) . "
96                 WHERE staged_table = " . $dbh2->quote($data->{staged_table}) . "
97             ") || die "Error changing references to $data->{staged_table}: $!\n";
98             my $rv4 = $dbh2->do("
99                 UPDATE m_tracked_column
100                 SET target_table = " . $dbh2->quote($table) . "
101                 WHERE target_table = " . $dbh2->quote($data->{staged_table}) . "
102             ") || die "Error changing references to $data->{staged_table}: $!\n";
103             KMig::db_disconnect($dbh2);
104         }
105
106         print "running staging SQL: $stage_sql_filename\n";
107
108         system($mig_bin . 'mig-sql', @args, '-e', ("SOURCE $stage_sql_filename;"));
109
110         if (! KMig::check_db_migschema_for_specific_table($table)) {
111             die "Missing staged table: $table\n";
112         } else {
113             print "table staged: $table\n";
114         }
115
116         my $dbh = KMig::db_connect();
117         my $rv = $dbh->do("
118             UPDATE m_tracked_file
119             SET staged_table = " . $dbh->quote($table) . "
120             WHERE base_filename = " . $dbh->quote($file) . "
121             ;
122         ") || die "Error updating table m_tracked_file: $!\n";
123         KMig::db_disconnect($dbh);
124     } else {
125         print "File not currently tracked: $file\n";
126     }
127 }