diff --git a/helper/compare_dbs.pl b/helper/compare_dbs.pl index 225f8b1..3600eed 100755 --- a/helper/compare_dbs.pl +++ b/helper/compare_dbs.pl @@ -6,6 +6,7 @@ use warnings; use DBI; use Getopt::Long; use Carp; +use JSON::XS; # Format: /// # Where: @@ -23,23 +24,16 @@ my @diff_exceptions = qw( views/ldap/ldap_entries/view_definition tables/mysql/.+/create_options ); -my @local_missing_exceptions = qw(); -my @remote_missing_exceptions = qw(); - -my $exception_list = { - default_diff_exceptions => \@diff_exceptions, - default_local_missing_exceptions => \@local_missing_exceptions, - default_remote_missing_exceptions => \@remote_missing_exceptions, -}; my $credentials_file = '/etc/mysql/sipwise_extra.cnf'; my $argv = { - formatter => '', - schemes => '', - host_db1 => '', - pass_db1 => '', - user_db1 => '', - port_db1 => '', + formatter => '', + host_db1 => 'localhost', + pass_db1 => '', + port_db1 => '3306', + schema_file => '', + schema_name => '', + user_db1 => '', }; get_options(); @@ -155,9 +149,7 @@ __SQL__ , }; -my @objs_list = qw( tables columns indexes constraints triggers views routines ); - -my $schema1 = "DBI:mysql:;host=$argv->{host_db1};port=$argv->{port_db1};mysql_read_default_file=$credentials_file"; +my $schema1 = "DBI:mysql:$argv->{schema_name};host=$argv->{host_db1};port=$argv->{port_db1};mysql_read_default_file=$credentials_file"; my $dbh1 = DBI->connect( $schema1, $argv->{user_db1}, @@ -165,23 +157,23 @@ my $dbh1 = DBI->connect( { RaiseError => 1 } ) or croak("Can't connect to local db: $schema1"); -my $masters = $dbh1->selectall_hashref('SHOW ALL SLAVES STATUS', 'Master_Host'); my $res = []; my $exit = 0; -foreach my $master ( keys( %{$masters} ) ) { - $exception_list->{local_missing_exceptions} = $exception_list->{default_local_missing_exceptions}; - $exception_list->{remote_missing_exceptions} = $exception_list->{remote_missing_exceptions}; - - my $master_port = $masters->{$master}->{Master_Port}; - my $schemes = $masters->{$master}->{Replicate_Wild_Do_Table}; - my $ignore_tables = $masters->{$master}->{Replicate_Ignore_Table}; - foreach my $entry ( split(/,/, $ignore_tables) ) { - foreach my $obj (@objs_list) { - push( @{$exception_list->{local_missing_exceptions}}, "$obj/" . $entry =~ s/\./\//r ); - } - } - compare_schemes($master, $master_port, $schemes); +my $json; +{ + #Enable 'slurp' mode + local $/ = ''; + open my $fh, "<", $argv->{schema_file}; + $json = <$fh>; + close $fh; +} +my $json_schema = decode_json($json); + +my @objs_list = qw( tables columns indexes constraints triggers views routines ); +foreach my $obj (@objs_list) { + my $db_schema = $dbh1->selectall_hashref( $queries->{$obj}, 'key_col', undef, $argv->{schema_name} ); + print_diff( $db_schema, $json_schema->{$obj}, $obj, $res, $argv->{schema_name} ); } if ( $argv->{formatter} eq 'tap' ) { @@ -197,7 +189,8 @@ exit $exit; sub get_options { GetOptions( 'formatter=s' => \$argv->{'formatter'}, - 'schemes=s' => \$argv->{'schemes'}, + 'schema-file=s' => \$argv->{'schema_file'}, + 'schema-name=s' => \$argv->{'schema_name'}, 'host-db1=s' => \$argv->{'host_db1'}, 'user-db1=s' => \$argv->{'user_db1'}, 'pass-db1=s' => \$argv->{'pass_db1'}, @@ -206,31 +199,6 @@ sub get_options { ); } -sub compare_schemes { - my ($host, $port, $schemes) = @_; - my $schema2 = "DBI:mysql:;host=$host;port=$port;mysql_read_default_file=$credentials_file"; - my $dbh2 = DBI->connect( - $schema2, - '', - '', - { RaiseError => 1 } ) or - croak("Can't connect to remote db: $schema2"); - - my $connection = "$host:$port"; - my @schemes = map { s/\..*//r } split(/,/, $schemes); - - foreach my $schema (@schemes) { - my ($sth1, $sth2); - my ($struct1, $struct2); - foreach my $obj (@objs_list) { - $struct1 = $dbh1->selectall_hashref( $queries->{$obj}, 'key_col', undef, $schema ); - $struct2 = $dbh2->selectall_hashref( $queries->{$obj}, 'key_col', undef, $schema ); - - print_diff($struct1, $struct2, $obj, $res, $schema, $connection); - } - } -} - sub print_usage { my $usage =<<__USAGE__ Usage: compare_db.pl [] @@ -270,21 +238,18 @@ sub is_exception { } sub print_diff { - my ($obj1, $obj2, $object_name, $result, $schema, $connection) = @_; - - my $schema1_name = "$argv->{host_db1}:$argv->{port_db1}"; - my $schema2_name = $connection; + my ($obj1, $obj2, $object_name, $result, $schema) = @_; foreach my $key ( sort( keys( %{$obj1} ) ) ) { unless ( exists($obj2->{$key}) ) { - next if ( is_exception($exception_list->{remote_missing_exceptions}, $object_name, $schema, $key) ); - push( @{$result}, "Element: " . lc("$object_name/$schema/$key") . " is missing in $schema2_name" ); + next if ( is_exception(\@diff_exceptions, $object_name, $schema, $key) ); + push( @{$result}, "Element: " . lc("$object_name/$schema/$key") . " is missing in json file" ); next; } foreach my $c_name ( sort( keys( %{ $obj1->{$key} } ) ) ) { unless ( exists($obj2->{$key}->{$c_name}) ) { - next if ( is_exception($exception_list->{remote_missing_exceptions}, $object_name, $schema, $key, $c_name) ); - push( @{$result}, "Element: " . lc("$object_name/$schema/$key/$c_name") . " is missing in $schema2_name" ); + next if ( is_exception(\@diff_exceptions, $object_name, $schema, $key, $c_name) ); + push( @{$result}, "Element: " . lc("$object_name/$schema/$key/$c_name") . " is missing in json file" ); next; } @@ -295,24 +260,24 @@ sub print_diff { $obj2->{$key}->{$c_name} = 'NULL' if ( ! defined($obj2->{$key}->{$c_name}) ); if ( $obj1->{$key}->{$c_name} ne $obj2->{$key}->{$c_name} ) { - next if ( is_exception($exception_list->{diff_exceptions}, $object_name, $schema, $key, $c_name) ); + next if ( is_exception(\@diff_exceptions, $object_name, $schema, $key, $c_name) ); push( @{$result}, "Element: " . lc("$object_name/$schema/$key/$c_name") . " are not equal:\n ---\n" - . " $schema1_name: $obj1->{$key}->{$c_name}\n" - . " $schema2_name: $obj2->{$key}->{$c_name}" ); + . " local db: $obj1->{$key}->{$c_name}\n" + . " json file: $obj2->{$key}->{$c_name}" ); } } } foreach my $key ( sort( keys( %{$obj2} ) ) ) { unless ( exists($obj1->{$key}) ) { - next if ( is_exception($exception_list->{local_missing_exceptions}, $object_name, $schema, $key) ); - push( @{$result}, "Element: " . lc("$object_name/$schema/$key") . " is missing in $schema1_name" ); + next if ( is_exception(\@diff_exceptions, $object_name, $schema, $key) ); + push( @{$result}, "Element: " . lc("$object_name/$schema/$key") . " is missing in local db" ); next; } foreach my $c_name ( sort( keys( %{ $obj2->{$key} } ) ) ) { unless ( exists($obj1->{$key}->{$c_name}) ) { - next if ( is_exception($exception_list->{local_missing_exceptions}, $object_name, $schema, $key, $c_name) ); - push( @{$result}, "Element: ". lc("$object_name/$schema/$key/$c_name") ." is missing in $schema1_name" ); + next if ( is_exception(\@diff_exceptions, $object_name, $schema, $key, $c_name) ); + push( @{$result}, "Element: ". lc("$object_name/$schema/$key/$c_name") ." is missing in local db" ); next; } } @@ -333,7 +298,7 @@ sub tap_output { } else { print "1..1\n"; - print "ok 1 All schemes are equal\n"; + print "ok 1 Schema is ok\n"; } } @@ -347,6 +312,6 @@ sub human_output { } } else { - print "All schemes $argv->{schemes} are equal\n"; + print "Schema $argv->{schema_name} is equal to json file\n"; } } diff --git a/sbin/ngcp-mysql-compare-dbs b/sbin/ngcp-mysql-compare-dbs index 52d28ea..ddc1975 100755 --- a/sbin/ngcp-mysql-compare-dbs +++ b/sbin/ngcp-mysql-compare-dbs @@ -68,11 +68,27 @@ if [[ -n "${FORMATTER}" ]]; then opts+=(--formatter="${FORMATTER}") fi +declare -a schemes=() +while IFS= read -r -d $'\0'; do + schemes+=("${REPLY}") +done < <(find '/usr/share/ngcp-db-schema/schema/' -name "*.json" -print0) + declare -a local_instances=() get_local_instances +rc=0 for local_mysql in "${local_instances[@]}"; do - /usr/share/ngcp-system-tests/compare_dbs.pl \ - --host-db1="${local_mysql%:*}" \ - --port-db1="${local_mysql#*:}" \ - "${opts[@]}" + for schema in "${schemes[@]}"; do + schema_name="${schema##*/}" + schema_name="${schema_name%.json}" + if ! /usr/share/ngcp-system-tests/compare_dbs.pl \ + --host-db1="${local_mysql%:*}" \ + --port-db1="${local_mysql#*:}" \ + --schema-file="${schema}" \ + --schema-name="${schema_name}" \ + "${opts[@]}"; then + rc=1 + fi + done done + +exit ${rc}