From 9ee4995747e6705fd4e72ba6edd1b26ad286bd47 Mon Sep 17 00:00:00 2001 From: Greg Sabino Mullane Date: Wed, 8 Nov 2006 22:54:58 +0000 Subject: [PATCH] Compare both schemas, be a little more verbose, add some other checks. --- maintenance/postgres/compare_schemas.pl | 103 +++++++++++++++++++----- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/maintenance/postgres/compare_schemas.pl b/maintenance/postgres/compare_schemas.pl index 4a76b27018..f8305a00d4 100644 --- a/maintenance/postgres/compare_schemas.pl +++ b/maintenance/postgres/compare_schemas.pl @@ -7,8 +7,9 @@ use strict; use warnings; use Data::Dumper; -my @old = ("../tables.sql"); +my @old = ("../tables.sql", "../mysql5/tables.sql"); my $new = "tables.sql"; +my @xfile; ## Read in exceptions and other metadata my %ok; @@ -23,7 +24,7 @@ while () { next; } if ($name eq 'XFILE') { - push @old, $val; + push @xfile, $val; next; } for (split(/\s+/ => $val)) { @@ -31,12 +32,10 @@ while () { } } -open my $newfh, "<", $new or die qq{Could not open $new: $!\n}; - my $datatype = join '|' => qw( bool tinyint int bigint real float -tinytext mediumtext text char varchar +tinytext mediumtext text char varchar varbinary timestamp datetime tinyblob mediumblob blob ); @@ -50,12 +49,44 @@ my $typeval2 = qr{ unsigned| binary| NOT NULL| NULL| auto_increment| default ['\ my $indextype = join '|' => qw(INDEX KEY FULLTEXT), "PRIMARY KEY", "UNIQUE INDEX", "UNIQUE KEY"; $indextype = qr{$indextype}; +my $engine = qr{TYPE|ENGINE}; + my $tabletype = qr{InnoDB|MyISAM|HEAP|HEAP MAX_ROWS=\d+}; +my $charset = qr{utf8}; + + +open my $newfh, "<", $new or die qq{Could not open $new: $!\n}; + + my ($table,%old); -for my $old (@old) { - open my $oldfh, "<", $old or die qq{Could not open $old: $!\n}; +## Read in the xfiles +my %xinfo; +for my $xfile (@xfile) { + print "Loading $xfile\n"; + my $info = &parse_sql($xfile); + for (keys %$info) { + $xinfo{$_} = $info->{$_}; + } +} + +for my $oldfile (@old) { + print "Loading $oldfile\n"; + my $info = &parse_sql($oldfile); + for (keys %xinfo) { + $info->{$_} = $xinfo{$_}; + } + $old{$oldfile} = $info; +} + +sub parse_sql { + + my $oldfile = shift; + + open my $oldfh, "<", $oldfile or die qq{Could not open $oldfile: $!\n}; + + my %info; while (<$oldfh>) { next if /^\s*\-\-/ or /^\s+$/; s/\s*\-\- [\w ]+$//; @@ -63,37 +94,62 @@ for my $old (@old) { if (/CREATE\s*TABLE/i) { m{^CREATE TABLE /\*\$wgDBprefix\*/(\w+) \($} - or die qq{Invalid CREATE TABLE at line $. of $old\n}; + or die qq{Invalid CREATE TABLE at line $. of $oldfile\n}; $table = $1; - $old{$table}{name}=$table; + $info{$table}{name}=$table; } - elsif (/^\) TYPE=($tabletype);$/) { - $old{$table}{type}=$1; + elsif (/^\) ($engine)=($tabletype);$/) { + $info{$table}{engine}=$1; + $info{$table}{type}=$2; + } + elsif (/^\) ($engine)=($tabletype), DEFAULT CHARSET=($charset);$/) { + $info{$table}{engine}=$1; + $info{$table}{type}=$2; + $info{$table}{charset}=$3; } elsif (/^ (\w+) $datatype$typeval$typeval2{0,3},?$/) { - $old{$table}{column}{$1} = $2; + $info{$table}{column}{$1} = $2; } elsif (/^ ($indextype)(?: (\w+))? \(([\w, \(\)]+)\),?$/) { - $old{$table}{lc $1."_name"} = $2 ? $2 : ""; - $old{$table}{lc $1."pk_target"} = $3; + $info{$table}{lc $1."_name"} = $2 ? $2 : ""; + $info{$table}{lc $1."pk_target"} = $3; } else { - die "Cannot parse line $. of $old:\n$_\n"; + die "Cannot parse line $. of $oldfile:\n$_\n"; } + } close $oldfh; + + return \%info; + +} ## end of parse_sql + +for my $oldfile (@old) { + +## Begin non-standard indent + +## MySQL sanity checks +for my $table (sort keys %{$old{$oldfile}}) { + my $t = $old{$oldfile}{$table}; + if (($oldfile =~ /5/ and $t->{engine} ne 'ENGINE') + or + ($oldfile !~ /5/ and $t->{engine} ne 'TYPE')) { + die "Invalid engine for $oldfile: $t->{engine}\n" unless $t->{name} eq 'profiling'; + } } -$datatype = join '|' => qw( +my $dtype = join '|' => qw( SMALLINT INTEGER BIGINT NUMERIC SERIAL TEXT CHAR VARCHAR BYTEA TIMESTAMPTZ CIDR ); -$datatype = qr{($datatype)}; +$dtype = qr{($dtype)}; my %new; my ($infunction,$inview,$inrule) = (0,0,0); +seek $newfh, 0, 0; while (<$newfh>) { next if /^\s*\-\-/ or /^\s*$/; s/\s*\-\- [\w ']+$//; @@ -130,24 +186,23 @@ while (<$newfh>) { } elsif (/^\);$/) { } - elsif (/^ (\w+) +$datatype/) { + elsif (/^ (\w+) +$dtype/) { $new{$table}{column}{$1} = $2; } else { die "Cannot parse line $. of $new:\n$_\n"; } } -close $newfh; ## Old but not new -for my $t (sort keys %old) { +for my $t (sort keys %{$old{$oldfile}}) { if (!exists $new{$t} and !exists $ok{OLD}{$t}) { print "Table not in $new: $t\n"; next; } next if exists $ok{OLD}{$t} and !$ok{OLD}{$t}; my $newt = exists $ok{OLD}{$t} ? $ok{OLD}{$t} : $t; - my $oldcol = $old{$t}{column}; + my $oldcol = $old{$oldfile}{$t}{column}; my $newcol = $new{$newt}{column}; for my $c (keys %$oldcol) { if (!exists $newcol->{$c}) { @@ -164,12 +219,16 @@ for my $t (sort keys %old) { } ## New but not old: for (sort keys %new) { - if (!exists $old{$_} and !exists $ok{NEW}{$_}) { + if (!exists $old{$oldfile}{$_} and !exists $ok{NEW}{$_}) { print "Not in old: $_\n"; next; } } + +} ## end each file to be parsed + + __DATA__ ## Known exceptions OLD: searchindex ## We use tsearch2 directly on the page table instead -- 2.20.1