mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql-bench / copy-db.sh
blob082db2203aad8366ab99949842dfeaa7d1662211
1 #!/usr/bin/perl
2 # Copyright (c) 2000, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
3 # Use is subject to license terms.
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Library General Public
7 # License as published by the Free Software Foundation; version 2
8 # of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Library General Public License for more details.
15 # You should have received a copy of the GNU Library General Public
16 # License along with this library; if not, write to the Free
17 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
18 # MA 02110-1301, USA
20 # start initialition
23 $VER = "1.0";
25 use Getopt::Long;
26 use Cwd;
27 use DBI;
29 $max_row_length=500000; # Don't create bigger SQL rows that this
30 $opt_lock=1; # lock tables
32 $pwd = cwd(); $pwd = "." if ($pwd eq '');
34 require "$pwd/server-cfg" || die "Can't read Configuration file: $!\n";
36 $|=1;
38 $opt_from_server= $opt_to_server= "mysql";
39 $opt_from_host= $opt_to_host= "localhost";
40 $opt_from_db= $opt_to_db= "test";
41 $opt_from_user=$opt_from_password=$opt_to_user=$opt_to_password="";
42 $opt_help=$opt_verbose=$opt_debug=0;
45 GetOptions("from-server=s","to-server=s","from-host=s","to-host=s","from-db=s",
46 "to-db=s", "help", "verbose","debug") || usage();
48 usage() if ($opt_help ||
49 ($opt_from_server eq $opt_to_server &&
50 $opt_from_db eq $opt_to_db &&
51 $opt_from_host eq $opt_to_host));
53 ####
54 #### Usage
55 ####
58 sub usage
60 print <<EOF;
62 $0 version $VER by Monty
64 Copies tables between two database servers. If the destination table doesn\'t
65 exist it\'s autoamticly created. If the destination table exists, it
66 should be compatible with the source table.
68 Because DBI doesn\'t provide full information about the columns in a table,
69 some columns may not have optimal types in a create tables. Any created
70 tables will also not have any keys!
72 Usage: $0 [options] tables...
74 Options:
75 --help Show this help and exit
76 --from-server Source server (Default: $opt_from_server)
77 --from-host Source hostname (Default: $opt_from_host)
78 --from-db Source database name (Default: $opt_from_db)
79 --from-user Source user (Default: $opt_from_password)
80 --from-password Source password (Default: $opt_from_password)
81 --to-server Destination server (Default: $opt_to_server)
82 --to-host Destination hostname (Default: $opt_to_host)
83 --to-db Destination database name (Default: $opt_to_db)
84 --to-user Destination user (Default: $opt_to_user)
85 --to-password Destination password (Default: $opt_to_password)
86 --verbose Be more verbose
88 If you the server names ends with _ODBC, then this program will connect
89 through ODBC instead of using a native driver.
90 EOF
91 exit(0);
94 ####
95 #### Connect
96 ####
98 $from_server=get_server($opt_from_server,$opt_from_host,$opt_from_db);
99 $to_server=get_server($opt_to_server,$opt_to_host,$opt_to_db);
101 $opt_user=$opt_from_user; $opt_password=$opt_from_password;
102 print "- connecting to SQL servers\n" if ($opt_verbose);
103 $from_dbh=$from_server->connect() || die "Can't connect to source server $opt_from_server on host $opt_from_host using db $opt_from_db";
104 $opt_user=$opt_to_user; $opt_password=$opt_to_password;
105 $to_dbh=$to_server->connect() || die "Can't connect to source server $opt_to_server on host $opt_to_host using db $opt_to_db";
107 ####
108 #### Copy data
109 ####
111 foreach $table (@ARGV)
114 print "- querying $table\n" if ($opt_verbose);
115 $sth=$from_dbh->prepare("select * from $table") || die "Can't prepare query to get $table; $DBI::errstr";
116 $sth->execute || die "Can't execute query to get data from $table; $DBI::errstr";
118 if (!table_exists($to_server,$to_dbh,$table))
120 print "- creating $table\n" if ($opt_verbose);
121 $table_def=get_table_definition($from_server,$from_dbh,$sth);
122 do_many($to_dbh,$to_server->create($table,$table_def,[]));
124 if ($opt_lock && $to_server->{'lock_tables'})
126 print "- locking $table\n" if ($opt_verbose);
127 $to_dbh->do("lock tables $table WRITE");
130 $columns=$sth->{NUM_OF_FIELDS};
131 $columns_to_quote=get_columns_to_quote($sth);
132 $insert_multi_value=$sth->{'insert_multi_value'};
133 $query="insert into $table values"; $result="";
135 print "- copying $table\n" if ($opt_verbose);
136 while (($row = $sth->fetchrow_arrayref))
138 $tmp="(";
139 for ($i=0 ; $i < $columns ; $i++)
141 if ($columns_to_quote->[$i])
143 $tmp.= $to_dbh->quote($row->[$i]) . ",";
145 else
147 $tmp.= $row->[$i] . ",";
150 substr($tmp,-1)=")"; # Remove last ','
151 if ($insert_multi_value)
153 $to_dbh->do($query . $tmp) || die "Can't insert row: $DBI::errstr";
155 elsif (length($result)+length($tmp) >= $max_row_length && $result)
157 $to_dbh->do($query . $result) || die "Can't insert row: $DBI::errstr";
158 $result="";
160 elsif (length($result))
162 $result.= ",$tmp";
164 else
166 $result=$tmp;
169 if (length($result))
171 $to_dbh->do($query . $result) || die "Can't insert row: $DBI::errstr";
173 if ($opt_lock && $to_server->{'lock_tables'})
175 $to_dbh->do("unlock tables");
180 sub get_table_definition
182 my ($server,$dbh,$sth)=@_;
183 my ($i,$names,$types,$scale,$precision,$nullable,@res);
185 $names=$sth->{NAME};
186 $types=$sth->{TYPE};
187 $nullable=$sth->{NULLABLE};
188 if (0)
190 # The following doesn't yet work
191 $scale=$sth->{SCALE};
192 $precision=$sth->{PRECISION};
194 else
196 my (@tmp);
197 @tmp= (undef()) x $sth->{NUM_OF_FIELDS};
198 $precision= $scale= \@tmp;
200 for ($i = 0; $i < $sth->{NUM_OF_FIELDS} ; $i++)
202 push(@res,$names->[$i] . " " .
203 odbc_to_sql($server,$types->[$i],$precision->[$i],$scale->[$i]) .
204 ($nullable->[$i] ? "" : " NOT NULL"));
206 return \@res;
210 sub odbc_to_sql
212 my ($server,$type,$precision,$scale)=@_;
214 if ($type == DBI::SQL_CHAR())
216 return defined($precision) ? "char($precision)" : "varchar(255)";
219 if ($type == DBI::SQL_NUMERIC())
221 $precision=15 if (!defined($precision));
222 $scale=6 if (!defined($scale));
223 return "numeric($precision,$scale)";
225 if ($type == DBI::SQL_DECIMAL())
227 $precision=15 if (!defined($precision));
228 $scale=6 if (!defined($scale));
229 return "decimal($precision,$scale)";
231 if ($type == DBI::SQL_INTEGER())
233 return "integer" if (!defined($precision));
234 return "integer($precision)";
236 if ($type == DBI::SQL_SMALLINT())
238 return "smallint" if (!defined($precision));
239 return "smallint($precision)";
241 if ($type == DBI::SQL_FLOAT())
243 $precision=12 if (!defined($precision));
244 $scale=2 if (!defined($scale));
245 return "float($precision,$scale)";
247 if ($type == DBI::SQL_REAL())
249 $precision=12 if (!defined($precision));
250 $scale=2 if (!defined($scale));
251 return "float($precision,$scale)";
253 if ($type == DBI::SQL_DOUBLE())
255 $precision=22 if (!defined($precision));
256 $scale=2 if (!defined($scale));
257 return "double($precision,$scale)";
259 if ($type == DBI::SQL_VARCHAR())
261 $precision=255 if (!defined($precision));
262 return "varchar($precision)";
264 return "date" if ($type == DBI::SQL_DATE());
265 return "time" if ($type == DBI::SQL_TIME());
266 return "timestamp" if ($type == DBI::SQL_TIMESTAMP());
267 return $server->{'text'} if ($type == DBI::SQL_LONGVARCHAR());
268 return $server->{'blob'} if ($type == DBI::SQL_LONGVARBINARY());
269 if ($type == DBI::SQL_BIGINT())
271 return "bigint" if (!defined($precision));
272 return "bigint($precision)";
274 if ($type == DBI::SQL_TINYINT())
276 return "tinyint" if (!defined($precision));
277 return "tinyint($precision)";
279 die "Can't covert type '$type' to a ODBC type\n";
283 # return an array with 1 for all coumns that we have to quote
286 sub get_columns_to_quote($sth)
288 my ($sth)=@_;
289 my ($i,@res,$type,$tmp);
291 @res=();
292 for ($i = 0; $i < $sth->{NUM_OF_FIELDS} ; $i++)
294 $type=$sth->{TYPE}->[$i];
295 $tmp=1; # String by default
296 if ($type == DBI::SQL_NUMERIC() || $type == DBI::SQL_DECIMAL() ||
297 $type == DBI::SQL_INTEGER() || $type == DBI::SQL_SMALLINT() ||
298 $type == DBI::SQL_SMALLINT() || $type == DBI::SQL_FLOAT() ||
299 $type == DBI::SQL_REAL() || $type == DBI::SQL_DOUBLE() ||
300 $type == DBI::SQL_BIGINT() || $type == DBI::SQL_TINYINT())
302 $tmp=0;
304 push (@res,$tmp);
306 return \@res;
310 # Check if table exists; Return 1 if table exists
313 sub table_exists
315 my ($server,$dbh,$table)=@_;
316 if ($server->{'limits'}->{'group_functions'})
318 return !safe_query($dbh,"select count(*) from $table");
320 if ($server->{'limits'}->{'limit'})
322 return !safe_query($dbh,"select * from $table limit 1");
324 die "Don't know how to check if table '$table' exists in destination server\n";
329 # execute query; return 0 if query is ok
332 sub safe_query
334 my ($dbh,$query)=@_;
335 my ($sth);
337 print "query: $query\n" if ($opt_debug);
338 if (!($sth= $dbh->prepare($query)))
340 print "error: $DBI::errstr\n" if ($opt_debug);
341 return 1;
343 if (!$sth->execute)
345 print "error: $DBI::errstr\n" if ($opt_debug);
346 return 1
348 while ($sth->fetchrow_arrayref)
351 $sth->finish;
352 undef($sth);
353 return 0;
357 # execute an array of queries
360 sub do_many
362 my ($dbh,@statements)=@_;
363 my ($statement,$sth);
365 foreach $statement (@statements)
367 print "query: $statement\n" if ($opt_debug);
368 if (!($sth=$dbh->do($statement)))
370 die "Can't execute command '$statement'\nError: $DBI::errstr\n";