Commit 0830fbcc authored by lenz@mysql.com's avatar lenz@mysql.com

Merge build:/home/bk/mysql-4.0

into mysql.com:/Users/mysqldev/my/mysql-4.0
parents 8066830f 7092bbe8
...@@ -10,7 +10,7 @@ mysql_tableinfo - creates and populates information tables with ...@@ -10,7 +10,7 @@ mysql_tableinfo - creates and populates information tables with
the output of SHOW DATABASES, SHOW TABLES (or SHOW TABLE STATUS), the output of SHOW DATABASES, SHOW TABLES (or SHOW TABLE STATUS),
SHOW COLUMNS and SHOW INDEX. SHOW COLUMNS and SHOW INDEX.
This is version 1.0. This is version 1.1.
=head1 SYNOPSIS =head1 SYNOPSIS
...@@ -62,7 +62,7 @@ GetOptions( \%opt, ...@@ -62,7 +62,7 @@ GetOptions( \%opt,
"quiet|q", "quiet|q",
) or usage("Invalid option"); ) or usage("Invalid option");
if ($opt{help}) {usage();} if ($opt{'help'}) {usage();}
my ($db_to_write,$db_like_wild,$tbl_like_wild); my ($db_to_write,$db_like_wild,$tbl_like_wild);
if (@ARGV==0) if (@ARGV==0)
...@@ -74,6 +74,8 @@ $db_like_wild=($ARGV[0])?$ARGV[0]:"%"; shift @ARGV; ...@@ -74,6 +74,8 @@ $db_like_wild=($ARGV[0])?$ARGV[0]:"%"; shift @ARGV;
$tbl_like_wild=($ARGV[0])?$ARGV[0]:"%"; shift @ARGV; $tbl_like_wild=($ARGV[0])?$ARGV[0]:"%"; shift @ARGV;
if (@ARGV>0) { usage("Too many arguments"); } if (@ARGV>0) { usage("Too many arguments"); }
$0 = $1 if $0 =~ m:/([^/]+)$:;
my $info_db="`".$opt{'prefix'}."db`"; my $info_db="`".$opt{'prefix'}."db`";
my $info_tbl="`".$opt{'prefix'}."tbl". my $info_tbl="`".$opt{'prefix'}."tbl".
(($opt{'tbl-status'})?"_status":"")."`"; (($opt{'tbl-status'})?"_status":"")."`";
...@@ -84,11 +86,11 @@ my $info_idx="`".$opt{'prefix'}."idx`"; ...@@ -84,11 +86,11 @@ my $info_idx="`".$opt{'prefix'}."idx`";
# --- connect to the database --- # --- connect to the database ---
my $dsn = ";host=$opt{'host'}"; my $dsn = ";host=$opt{'host'}";
$dsn .= ";port=$opt{port}" if $opt{port}; $dsn .= ";port=$opt{'port'}" if $opt{'port'};
$dsn .= ";mysql_socket=$opt{socket}" if $opt{socket}; $dsn .= ";mysql_socket=$opt{'socket'}" if $opt{'socket'};
my $dbh = DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=perl", my $dbh = DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=perl",
$opt{user}, $opt{password}, $opt{'user'}, $opt{'password'},
{ {
RaiseError => 1, RaiseError => 1,
PrintError => 0, PrintError => 0,
...@@ -104,20 +106,19 @@ if (!$opt{'quiet'}) ...@@ -104,20 +106,19 @@ if (!$opt{'quiet'})
{ {
print "\n!! This program is doing to do:\n\n"; print "\n!! This program is doing to do:\n\n";
print "**DROP** TABLE ...\n" if ($opt{'clear'} or $opt{'clear-only'}); print "**DROP** TABLE ...\n" if ($opt{'clear'} or $opt{'clear-only'});
print "**DELETE** FROM ... WHERE `Database LIKE $db_like_wild AND `Table` LIKE $tbl_like_wild print "**DELETE** FROM ... WHERE `Database` LIKE $db_like_wild AND `Table` LIKE $tbl_like_wild
**INSERT** INTO ... **INSERT** INTO ...
on the following tables :\n"; on the following tables :\n";
my $i;
foreach $i (($info_db, $info_tbl), foreach (($info_db, $info_tbl),
(($opt{'col'})?$info_col:()), (($opt{'col'})?$info_col:()),
(($opt{'idx'})?$info_idx:())) (($opt{'idx'})?$info_idx:()))
{ {
print(" $db_to_write.$i\n"); print(" $db_to_write.$_\n");
} }
print "\nContinue (you can skip this confirmation step with --quiet) ? (y|n) [n]"; print "\nContinue (you can skip this confirmation step with --quiet) ? (y|n) [n]";
my $answer=<STDIN>; if (<STDIN> !~ /^\s*y\s*$/i)
unless ($answer =~ /^\s*y\s*$/i)
{ {
print "Nothing done!\n";exit; print "Nothing done!\n";exit;
} }
...@@ -126,17 +127,16 @@ on the following tables :\n"; ...@@ -126,17 +127,16 @@ on the following tables :\n";
if ($opt{'clear'} or $opt{'clear-only'}) if ($opt{'clear'} or $opt{'clear-only'})
{ {
#do not drop the $db_to_write database ! #do not drop the $db_to_write database !
my $i; foreach (($info_db, $info_tbl),
foreach $i (($info_db, $info_tbl), (($opt{'col'})?$info_col:()),
(($opt{'col'})?$info_col:()), (($opt{'idx'})?$info_idx:()))
(($opt{'idx'})?$info_idx:()))
{ {
$dbh->do("DROP TABLE IF EXISTS $db_to_write.$i"); $dbh->do("DROP TABLE IF EXISTS $db_to_write.$_");
} }
if ($opt{'clear-only'}) if ($opt{'clear-only'})
{ {
print "Wrote to database $db_to_write .\n" unless ($opt{'quiet'}); print "Wrote to database $db_to_write .\n" unless ($opt{'quiet'});
exit(); exit;
} }
} }
...@@ -151,14 +151,14 @@ $dbh->do("CREATE DATABASE IF NOT EXISTS $db_to_write"); ...@@ -151,14 +151,14 @@ $dbh->do("CREATE DATABASE IF NOT EXISTS $db_to_write");
$dbh->do("USE $db_to_write"); $dbh->do("USE $db_to_write");
#get databases #get databases
$sth{db}=$dbh->prepare("SHOW DATABASES LIKE $db_like_wild"); $sth{'db'}=$dbh->prepare("SHOW DATABASES LIKE $db_like_wild");
$sth{db}->execute; $sth{'db'}->execute;
#create $info_db which will receive info about databases. #create $info_db which will receive info about databases.
#Ensure that the first column to be called "Database" (as SHOW DATABASES LIKE #Ensure that the first column to be called "Database" (as SHOW DATABASES LIKE
#returns a varying #returns a varying
#column name (of the form "Database (%...)") which is not suitable) #column name (of the form "Database (%...)") which is not suitable)
$extra_col_desc{db}=do_create_table("db",$info_db,undef,"`Database`"); $extra_col_desc{'db'}=do_create_table("db",$info_db,undef,"`Database`");
#we'll remember the type of the `Database` column (as returned by #we'll remember the type of the `Database` column (as returned by
#SHOW DATABASES), which we will need when creating the next tables. #SHOW DATABASES), which we will need when creating the next tables.
...@@ -166,55 +166,56 @@ $extra_col_desc{db}=do_create_table("db",$info_db,undef,"`Database`"); ...@@ -166,55 +166,56 @@ $extra_col_desc{db}=do_create_table("db",$info_db,undef,"`Database`");
$dbh->do("DELETE FROM $info_db WHERE `Database` LIKE $db_like_wild"); $dbh->do("DELETE FROM $info_db WHERE `Database` LIKE $db_like_wild");
while (@{$row{db}}=$sth{db}->fetchrow_array) #go through all databases while ($row{'db'}=$sth{'db'}->fetchrow_arrayref) #go through all databases
{ {
#insert the database name #insert the database name
$dbh->do("INSERT INTO $info_db VALUES(" $dbh->do("INSERT INTO $info_db VALUES("
.join_quote(@{$row{db}}).")"); .join(',' , ( map $dbh->quote($_), @{$row{'db'}} ) ).")" );
#for each database, get tables #for each database, get tables
$sth{tbl}=$dbh->prepare("SHOW TABLE" $sth{'tbl'}=$dbh->prepare("SHOW TABLE"
.( ($opt{'tbl-status'}) ? .( ($opt{'tbl-status'}) ?
" STATUS" " STATUS"
: "S" ) : "S" )
." from `${$row{db}}[0]` LIKE $tbl_like_wild"); ." from `$row{'db'}->[0]` LIKE $tbl_like_wild");
$sth{tbl}->execute; $sth{'tbl'}->execute;
unless ($done_create_table{$info_tbl}) unless ($done_create_table{$info_tbl})
#tables must be created only once, and out-of-date info must be #tables must be created only once, and out-of-date info must be
#cleared once #cleared once
{ {
$done_create_table{$info_tbl}=1; $done_create_table{$info_tbl}=1;
$extra_col_desc{table}= $extra_col_desc{'tbl'}=
do_create_table("tbl",$info_tbl, do_create_table("tbl",$info_tbl,
#add an extra column (database name) at the left #add an extra column (database name) at the left
#and ensure that the table name will be called "Table" #and ensure that the table name will be called "Table"
#(this is unncessesary with #(this is unncessesary with
#SHOW TABLE STATUS, but necessary with SHOW TABLES (which returns a column #SHOW TABLE STATUS, but necessary with SHOW TABLES (which returns a column
#named "Tables_in_...")) #named "Tables_in_..."))
"`Database` ".$extra_col_desc{db},"`Table`"); "`Database` ".$extra_col_desc{'db'},"`Table`");
$dbh->do("DELETE FROM $info_tbl WHERE `Database` LIKE $db_like_wild AND `Table` LIKE $tbl_like_wild"); $dbh->do("DELETE FROM $info_tbl WHERE `Database` LIKE $db_like_wild AND `Table` LIKE $tbl_like_wild");
} }
while (@{$row{tbl}}=$sth{tbl}->fetchrow_array) while ($row{'tbl'}=$sth{'tbl'}->fetchrow_arrayref)
{ {
$dbh->do("INSERT INTO $info_tbl VALUES(" $dbh->do("INSERT INTO $info_tbl VALUES("
.$dbh->quote(${$row{db}}[0]).",".join_quote(@{$row{tbl}}).")"); .$dbh->quote($row{'db'}->[0]).","
.join(',' , ( map $dbh->quote($_), @{$row{'tbl'}} ) ).")");
#for each table, get columns... #for each table, get columns...
if ($opt{'col'}) if ($opt{'col'})
{ {
$sth{col}=$dbh->prepare("SHOW COLUMNS FROM `${$row{tbl}}[0]` FROM `${$row{db}}[0]`"); $sth{'col'}=$dbh->prepare("SHOW COLUMNS FROM `$row{'tbl'}->[0]` FROM `$row{'db'}->[0]`");
$sth{col}->execute; $sth{'col'}->execute;
unless ($done_create_table{$info_col}) unless ($done_create_table{$info_col})
{ {
$done_create_table{$info_col}=1; $done_create_table{$info_col}=1;
do_create_table("col",$info_col, do_create_table("col",$info_col,
"`Database` ".$extra_col_desc{db}."," "`Database` ".$extra_col_desc{'db'}.","
."`Table` ".$extra_col_desc{table}."," ."`Table` ".$extra_col_desc{'tbl'}.","
."`Seq_in_table` BIGINT(3)"); ."`Seq_in_table` BIGINT(3)");
#We need to add a sequence number (1 for the first column of the table, #We need to add a sequence number (1 for the first column of the table,
#2 for the second etc) so that users are able to retrieve columns in order #2 for the second etc) so that users are able to retrieve columns in order
...@@ -225,13 +226,13 @@ while (@{$row{db}}=$sth{db}->fetchrow_array) #go through all databases ...@@ -225,13 +226,13 @@ while (@{$row{db}}=$sth{db}->fetchrow_array) #go through all databases
AND `Table` LIKE $tbl_like_wild"); AND `Table` LIKE $tbl_like_wild");
} }
my $col_number=0; my $col_number=0;
while (@{$row{col}}=$sth{col}->fetchrow_array) while ($row{'col'}=$sth{'col'}->fetchrow_arrayref)
{ {
$dbh->do("INSERT INTO $info_col VALUES(" $dbh->do("INSERT INTO $info_col VALUES("
.$dbh->quote(${$row{db}}[0])."," .$dbh->quote($row{'db'}->[0]).","
.$dbh->quote(${$row{tbl}}[0])."," .$dbh->quote($row{'tbl'}->[0]).","
.++$col_number."," .++$col_number.","
.join_quote(@{$row{col}}).")"); .join(',' , ( map $dbh->quote($_), @{$row{'col'}} ) ).")");
} }
} }
...@@ -239,22 +240,22 @@ while (@{$row{db}}=$sth{db}->fetchrow_array) #go through all databases ...@@ -239,22 +240,22 @@ while (@{$row{db}}=$sth{db}->fetchrow_array) #go through all databases
if ($opt{'idx'}) if ($opt{'idx'})
{ {
$sth{idx}=$dbh->prepare("SHOW INDEX FROM `${$row{tbl}}[0]` FROM `${$row{db}}[0]`"); $sth{'idx'}=$dbh->prepare("SHOW INDEX FROM `$row{'tbl'}->[0]` FROM `$row{'db'}->[0]`");
$sth{idx}->execute; $sth{'idx'}->execute;
unless ($done_create_table{$info_idx}) unless ($done_create_table{$info_idx})
{ {
$done_create_table{$info_idx}=1; $done_create_table{$info_idx}=1;
do_create_table("idx",$info_idx, do_create_table("idx",$info_idx,
"`Database` ".$extra_col_desc{db}); "`Database` ".$extra_col_desc{'db'});
$dbh->do("DELETE FROM $info_idx WHERE `Database` $dbh->do("DELETE FROM $info_idx WHERE `Database`
LIKE $db_like_wild LIKE $db_like_wild
AND `Table` LIKE $tbl_like_wild"); AND `Table` LIKE $tbl_like_wild");
} }
while (@{$row{idx}}=$sth{idx}->fetchrow_array) while ($row{'idx'}=$sth{'idx'}->fetchrow_arrayref)
{ {
$dbh->do("INSERT INTO $info_idx VALUES(" $dbh->do("INSERT INTO $info_idx VALUES("
.$dbh->quote(${$row{db}}[0])."," .$dbh->quote($row{'db'}->[0]).","
.join_quote(@{$row{idx}}).")"); .join(',' , ( map $dbh->quote($_), @{$row{'idx'}} ) ).")");
} }
} }
} }
...@@ -263,37 +264,30 @@ while (@{$row{db}}=$sth{db}->fetchrow_array) #go through all databases ...@@ -263,37 +264,30 @@ while (@{$row{db}}=$sth{db}->fetchrow_array) #go through all databases
print "Wrote to database $db_to_write .\n" unless ($opt{'quiet'}); print "Wrote to database $db_to_write .\n" unless ($opt{'quiet'});
exit; exit;
sub join_quote
{
my (@list)=@_; my $i;
foreach $i (@list) { $i=$dbh->quote($i); }
return (join ',',@list);
}
sub do_create_table sub do_create_table
{ {
my ($sth_key,$target_tbl,$extra_col_desc,$first_col_name)=@_; my ($sth_key,$target_tbl,$extra_col_desc,$first_col_name)=@_;
my $create_table_query=$extra_col_desc; my $create_table_query=$extra_col_desc;
my ($i,$type,$first_col_desc,$col_desc); my ($i,$first_col_desc,$col_desc);
for ($i=0;$i<$sth{$sth_key}->{NUM_OF_FIELDS};$i++) for ($i=0;$i<$sth{$sth_key}->{NUM_OF_FIELDS};$i++)
{ {
if ($create_table_query) { $create_table_query.=", "; } if ($create_table_query) { $create_table_query.=", "; }
$type=$sth{$sth_key}->{mysql_type_name}->[$i]; $col_desc=$sth{$sth_key}->{mysql_type_name}->[$i];
$col_desc=$type; if ($col_desc =~ /char|int/i)
if ($type =~ /char|int/i)
{ {
$col_desc.="($sth{$sth_key}->{PRECISION}->[$i])"; $col_desc.="($sth{$sth_key}->{PRECISION}->[$i])";
} }
elsif ($type =~ /decimal|numeric/i) #(never seen that) elsif ($col_desc =~ /decimal|numeric/i) #(never seen that)
{ {
$col_desc.= $col_desc.=
"($sth{$sth_key}->{PRECISION}->[$i],$sth{$sth_key}->{SCALE}->[$i])"; "($sth{$sth_key}->{PRECISION}->[$i],$sth{$sth_key}->{SCALE}->[$i])";
} }
elsif ($type !~ /date/i) #date and datetime are OK, elsif ($col_desc !~ /date/i) #date and datetime are OK,
#no precision or scale for them #no precision or scale for them
{ {
warn "unexpected column type '$type' warn "unexpected column type '$col_desc'
(neither 'char','int','decimal|numeric') (neither 'char','int','decimal|numeric')
when creating $target_tbl, hope table creation will go OK\n"; when creating $target_tbl, hope table creation will go OK\n";
} }
...@@ -393,6 +387,10 @@ Caution: info tables contain certain columns (e.g. ...@@ -393,6 +387,10 @@ Caution: info tables contain certain columns (e.g.
Database, Table, Null...) whose names, as they are MySQL reserved words, Database, Table, Null...) whose names, as they are MySQL reserved words,
need to be backquoted (`...`) when used in SQL statements. need to be backquoted (`...`) when used in SQL statements.
Caution: as information fetching and info tables filling happen at the
same time, info tables may contain inaccurate information about
themselves.
=head1 OPTIONS =head1 OPTIONS
=over 4 =over 4
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment