Index: trunk/phase3/maintenance/postgres/compare_schemas.pl |
— | — | @@ -7,8 +7,9 @@ |
8 | 8 | use warnings; |
9 | 9 | use Data::Dumper; |
10 | 10 | |
11 | | -my @old = ("../tables.sql"); |
| 11 | +my @old = ("../tables.sql", "../mysql5/tables.sql"); |
12 | 12 | my $new = "tables.sql"; |
| 13 | +my @xfile; |
13 | 14 | |
14 | 15 | ## Read in exceptions and other metadata |
15 | 16 | my %ok; |
— | — | @@ -23,7 +24,7 @@ |
24 | 25 | next; |
25 | 26 | } |
26 | 27 | if ($name eq 'XFILE') { |
27 | | - push @old, $val; |
| 28 | + push @xfile, $val; |
28 | 29 | next; |
29 | 30 | } |
30 | 31 | for (split(/\s+/ => $val)) { |
— | — | @@ -31,12 +32,10 @@ |
32 | 33 | } |
33 | 34 | } |
34 | 35 | |
35 | | -open my $newfh, "<", $new or die qq{Could not open $new: $!\n}; |
36 | | - |
37 | 36 | my $datatype = join '|' => qw( |
38 | 37 | bool |
39 | 38 | tinyint int bigint real float |
40 | | -tinytext mediumtext text char varchar |
| 39 | +tinytext mediumtext text char varchar varbinary |
41 | 40 | timestamp datetime |
42 | 41 | tinyblob mediumblob blob |
43 | 42 | ); |
— | — | @@ -50,12 +49,44 @@ |
51 | 50 | my $indextype = join '|' => qw(INDEX KEY FULLTEXT), "PRIMARY KEY", "UNIQUE INDEX", "UNIQUE KEY"; |
52 | 51 | $indextype = qr{$indextype}; |
53 | 52 | |
| 53 | +my $engine = qr{TYPE|ENGINE}; |
| 54 | + |
54 | 55 | my $tabletype = qr{InnoDB|MyISAM|HEAP|HEAP MAX_ROWS=\d+}; |
55 | 56 | |
| 57 | +my $charset = qr{utf8}; |
| 58 | + |
| 59 | + |
| 60 | +open my $newfh, "<", $new or die qq{Could not open $new: $!\n}; |
| 61 | + |
| 62 | + |
56 | 63 | my ($table,%old); |
57 | | -for my $old (@old) { |
58 | | - open my $oldfh, "<", $old or die qq{Could not open $old: $!\n}; |
59 | 64 | |
| 65 | +## Read in the xfiles |
| 66 | +my %xinfo; |
| 67 | +for my $xfile (@xfile) { |
| 68 | + print "Loading $xfile\n"; |
| 69 | + my $info = &parse_sql($xfile); |
| 70 | + for (keys %$info) { |
| 71 | + $xinfo{$_} = $info->{$_}; |
| 72 | + } |
| 73 | +} |
| 74 | + |
| 75 | +for my $oldfile (@old) { |
| 76 | + print "Loading $oldfile\n"; |
| 77 | + my $info = &parse_sql($oldfile); |
| 78 | + for (keys %xinfo) { |
| 79 | + $info->{$_} = $xinfo{$_}; |
| 80 | + } |
| 81 | + $old{$oldfile} = $info; |
| 82 | +} |
| 83 | + |
| 84 | +sub parse_sql { |
| 85 | + |
| 86 | + my $oldfile = shift; |
| 87 | + |
| 88 | + open my $oldfh, "<", $oldfile or die qq{Could not open $oldfile: $!\n}; |
| 89 | + |
| 90 | + my %info; |
60 | 91 | while (<$oldfh>) { |
61 | 92 | next if /^\s*\-\-/ or /^\s+$/; |
62 | 93 | s/\s*\-\- [\w ]+$//; |
— | — | @@ -63,37 +94,62 @@ |
64 | 95 | |
65 | 96 | if (/CREATE\s*TABLE/i) { |
66 | 97 | m{^CREATE TABLE /\*\$wgDBprefix\*/(\w+) \($} |
67 | | - or die qq{Invalid CREATE TABLE at line $. of $old\n}; |
| 98 | + or die qq{Invalid CREATE TABLE at line $. of $oldfile\n}; |
68 | 99 | $table = $1; |
69 | | - $old{$table}{name}=$table; |
| 100 | + $info{$table}{name}=$table; |
70 | 101 | } |
71 | | - elsif (/^\) TYPE=($tabletype);$/) { |
72 | | - $old{$table}{type}=$1; |
| 102 | + elsif (/^\) ($engine)=($tabletype);$/) { |
| 103 | + $info{$table}{engine}=$1; |
| 104 | + $info{$table}{type}=$2; |
73 | 105 | } |
| 106 | + elsif (/^\) ($engine)=($tabletype), DEFAULT CHARSET=($charset);$/) { |
| 107 | + $info{$table}{engine}=$1; |
| 108 | + $info{$table}{type}=$2; |
| 109 | + $info{$table}{charset}=$3; |
| 110 | + } |
74 | 111 | elsif (/^ (\w+) $datatype$typeval$typeval2{0,3},?$/) { |
75 | | - $old{$table}{column}{$1} = $2; |
| 112 | + $info{$table}{column}{$1} = $2; |
76 | 113 | } |
77 | 114 | elsif (/^ ($indextype)(?: (\w+))? \(([\w, \(\)]+)\),?$/) { |
78 | | - $old{$table}{lc $1."_name"} = $2 ? $2 : ""; |
79 | | - $old{$table}{lc $1."pk_target"} = $3; |
| 115 | + $info{$table}{lc $1."_name"} = $2 ? $2 : ""; |
| 116 | + $info{$table}{lc $1."pk_target"} = $3; |
80 | 117 | } |
81 | 118 | else { |
82 | | - die "Cannot parse line $. of $old:\n$_\n"; |
| 119 | + die "Cannot parse line $. of $oldfile:\n$_\n"; |
83 | 120 | } |
| 121 | + |
84 | 122 | } |
85 | 123 | close $oldfh; |
| 124 | + |
| 125 | + return \%info; |
| 126 | + |
| 127 | +} ## end of parse_sql |
| 128 | + |
| 129 | +for my $oldfile (@old) { |
| 130 | + |
| 131 | +## Begin non-standard indent |
| 132 | + |
| 133 | +## MySQL sanity checks |
| 134 | +for my $table (sort keys %{$old{$oldfile}}) { |
| 135 | + my $t = $old{$oldfile}{$table}; |
| 136 | + if (($oldfile =~ /5/ and $t->{engine} ne 'ENGINE') |
| 137 | + or |
| 138 | + ($oldfile !~ /5/ and $t->{engine} ne 'TYPE')) { |
| 139 | + die "Invalid engine for $oldfile: $t->{engine}\n" unless $t->{name} eq 'profiling'; |
| 140 | + } |
86 | 141 | } |
87 | 142 | |
88 | | -$datatype = join '|' => qw( |
| 143 | +my $dtype = join '|' => qw( |
89 | 144 | SMALLINT INTEGER BIGINT NUMERIC SERIAL |
90 | 145 | TEXT CHAR VARCHAR |
91 | 146 | BYTEA |
92 | 147 | TIMESTAMPTZ |
93 | 148 | CIDR |
94 | 149 | ); |
95 | | -$datatype = qr{($datatype)}; |
| 150 | +$dtype = qr{($dtype)}; |
96 | 151 | my %new; |
97 | 152 | my ($infunction,$inview,$inrule) = (0,0,0); |
| 153 | +seek $newfh, 0, 0; |
98 | 154 | while (<$newfh>) { |
99 | 155 | next if /^\s*\-\-/ or /^\s*$/; |
100 | 156 | s/\s*\-\- [\w ']+$//; |
— | — | @@ -130,24 +186,23 @@ |
131 | 187 | } |
132 | 188 | elsif (/^\);$/) { |
133 | 189 | } |
134 | | - elsif (/^ (\w+) +$datatype/) { |
| 190 | + elsif (/^ (\w+) +$dtype/) { |
135 | 191 | $new{$table}{column}{$1} = $2; |
136 | 192 | } |
137 | 193 | else { |
138 | 194 | die "Cannot parse line $. of $new:\n$_\n"; |
139 | 195 | } |
140 | 196 | } |
141 | | -close $newfh; |
142 | 197 | |
143 | 198 | ## Old but not new |
144 | | -for my $t (sort keys %old) { |
| 199 | +for my $t (sort keys %{$old{$oldfile}}) { |
145 | 200 | if (!exists $new{$t} and !exists $ok{OLD}{$t}) { |
146 | 201 | print "Table not in $new: $t\n"; |
147 | 202 | next; |
148 | 203 | } |
149 | 204 | next if exists $ok{OLD}{$t} and !$ok{OLD}{$t}; |
150 | 205 | my $newt = exists $ok{OLD}{$t} ? $ok{OLD}{$t} : $t; |
151 | | - my $oldcol = $old{$t}{column}; |
| 206 | + my $oldcol = $old{$oldfile}{$t}{column}; |
152 | 207 | my $newcol = $new{$newt}{column}; |
153 | 208 | for my $c (keys %$oldcol) { |
154 | 209 | if (!exists $newcol->{$c}) { |
— | — | @@ -164,12 +219,16 @@ |
165 | 220 | } |
166 | 221 | ## New but not old: |
167 | 222 | for (sort keys %new) { |
168 | | - if (!exists $old{$_} and !exists $ok{NEW}{$_}) { |
| 223 | + if (!exists $old{$oldfile}{$_} and !exists $ok{NEW}{$_}) { |
169 | 224 | print "Not in old: $_\n"; |
170 | 225 | next; |
171 | 226 | } |
172 | 227 | } |
173 | 228 | |
| 229 | + |
| 230 | +} ## end each file to be parsed |
| 231 | + |
| 232 | + |
174 | 233 | __DATA__ |
175 | 234 | ## Known exceptions |
176 | 235 | OLD: searchindex ## We use tsearch2 directly on the page table instead |