~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to tests/sql-bench/copy-db

  • Committer: Mark Atwood
  • Date: 2011-06-05 15:07:40 UTC
  • mfrom: (2313.4.2 xtrabackup)
  • Revision ID: me@mark.atwood.name-20110605150740-q3bsq3kt33rwfc9u
Tags: 2011.06.19
mergeĀ lp:~olafvdspek/drizzle/xtrabackup

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/perl
2
 
# Copyright (C) 2000, 2003 MySQL AB
3
 
#
4
 
# This library is free software; you can redistribute it and/or
5
 
# modify it under the terms of the GNU Library General Public
6
 
# License as published by the Free Software Foundation; version 2
7
 
# of the License.
8
 
#
9
 
# This library is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
# Library General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU Library General Public
15
 
# License along with this library; if not, write to the Free
16
 
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
17
 
# MA 02111-1307, USA
18
 
#
19
 
# start initialition
20
 
#
21
 
 
22
 
$VER = "1.0";
23
 
 
24
 
use Getopt::Long;
25
 
use Cwd;
26
 
use DBI;
27
 
 
28
 
$max_row_length=500000;         # Don't create bigger SQL rows that this
29
 
$opt_lock=1;                    # lock tables
30
 
 
31
 
$pwd = cwd(); $pwd = "." if ($pwd eq '');
32
 
 
33
 
require "$pwd/server-cfg" || die "Can't read Configuration file: $!\n";
34
 
 
35
 
$|=1;
36
 
 
37
 
$opt_from_server= $opt_to_server= "mysql";
38
 
$opt_from_host= $opt_to_host=     "localhost";
39
 
$opt_from_db= $opt_to_db=         "test";
40
 
$opt_from_user=$opt_from_password=$opt_to_user=$opt_to_password="";
41
 
$opt_help=$opt_verbose=$opt_debug=0;
42
 
 
43
 
 
44
 
GetOptions("from-server=s","to-server=s","from-host=s","to-host=s","from-db=s",
45
 
           "to-db=s", "help", "verbose","debug") || usage();
46
 
 
47
 
usage() if ($opt_help || 
48
 
            ($opt_from_server eq $opt_to_server && 
49
 
             $opt_from_db eq $opt_to_db &&
50
 
             $opt_from_host eq $opt_to_host));
51
 
 
52
 
####
53
 
#### Usage
54
 
####
55
 
 
56
 
 
57
 
sub usage
58
 
{
59
 
  print <<EOF;
60
 
 
61
 
$0 version $VER by Monty
62
 
 
63
 
 Copies tables between two database servers. If the destination table doesn\'t
64
 
 exist it\'s autoamticly created.  If the destination table exists, it
65
 
 should be compatible with the source table.
66
 
 
67
 
 Because DBI doesn\'t provide full information about the columns in a table,
68
 
 some columns may not have optimal types in a create tables.  Any created
69
 
 tables will also not have any keys!
70
 
 
71
 
  Usage: $0 [options] tables...
72
 
 
73
 
  Options:
74
 
  --help         Show this help and exit
75
 
  --from-server   Source server                 (Default: $opt_from_server)
76
 
  --from-host     Source hostname               (Default: $opt_from_host)
77
 
  --from-db       Source database name          (Default: $opt_from_db)
78
 
  --from-user     Source user                   (Default: $opt_from_password)
79
 
  --from-password Source password               (Default: $opt_from_password)
80
 
  --to-server     Destination server            (Default: $opt_to_server)
81
 
  --to-host       Destination hostname          (Default: $opt_to_host)
82
 
  --to-db         Destination database name     (Default: $opt_to_db)
83
 
  --to-user       Destination user              (Default: $opt_to_user)
84
 
  --to-password   Destination password          (Default: $opt_to_password)
85
 
  --verbose       Be more verbose
86
 
 
87
 
  If you the server names ends with _ODBC, then this program will connect
88
 
  through ODBC instead of using a native driver.
89
 
EOF
90
 
   exit(0);
91
 
}
92
 
 
93
 
####
94
 
#### Connect
95
 
####
96
 
 
97
 
$from_server=get_server($opt_from_server,$opt_from_host,$opt_from_db);
98
 
$to_server=get_server($opt_to_server,$opt_to_host,$opt_to_db);
99
 
 
100
 
$opt_user=$opt_from_user; $opt_password=$opt_from_password;
101
 
print "- connecting to SQL servers\n" if ($opt_verbose);
102
 
$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";
103
 
$opt_user=$opt_to_user; $opt_password=$opt_to_password;
104
 
$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";
105
 
 
106
 
####
107
 
#### Copy data
108
 
####
109
 
 
110
 
foreach $table (@ARGV)
111
 
{
112
 
 
113
 
  print "- querying $table\n" if ($opt_verbose);
114
 
  $sth=$from_dbh->prepare("select * from $table") || die "Can't prepare query to get $table; $DBI::errstr";
115
 
  $sth->execute || die "Can't execute query to get data from $table; $DBI::errstr";
116
 
 
117
 
  if (!table_exists($to_server,$to_dbh,$table))
118
 
  {
119
 
    print "- creating $table\n" if ($opt_verbose);
120
 
    $table_def=get_table_definition($from_server,$from_dbh,$sth);
121
 
    do_many($to_dbh,$to_server->create($table,$table_def,[]));
122
 
  }
123
 
  if ($opt_lock && $to_server->{'lock_tables'})
124
 
  {
125
 
    print "- locking $table\n" if ($opt_verbose);
126
 
    $to_dbh->do("lock tables $table WRITE");
127
 
  }
128
 
 
129
 
  $columns=$sth->{NUM_OF_FIELDS};
130
 
  $columns_to_quote=get_columns_to_quote($sth);
131
 
  $insert_multi_value=$sth->{'insert_multi_value'};
132
 
  $query="insert into $table values"; $result="";
133
 
 
134
 
  print "- copying $table\n" if ($opt_verbose);
135
 
  while (($row = $sth->fetchrow_arrayref))
136
 
  {
137
 
    $tmp="(";
138
 
    for ($i=0 ; $i < $columns ; $i++)
139
 
    {
140
 
      if ($columns_to_quote->[$i])
141
 
      {
142
 
        $tmp.= $to_dbh->quote($row->[$i]) . ",";
143
 
      }
144
 
      else
145
 
      {
146
 
        $tmp.= $row->[$i] . ",";        
147
 
      }
148
 
    }
149
 
    substr($tmp,-1)=")";                # Remove last ','
150
 
    if ($insert_multi_value)
151
 
    {
152
 
      $to_dbh->do($query . $tmp) || die "Can't insert row: $DBI::errstr";
153
 
    }
154
 
    elsif (length($result)+length($tmp) >= $max_row_length && $result)
155
 
    {
156
 
      $to_dbh->do($query . $result) || die "Can't insert row: $DBI::errstr";
157
 
      $result="";
158
 
    }
159
 
    elsif (length($result))
160
 
    {
161
 
      $result.= ",$tmp";
162
 
    }
163
 
    else
164
 
    {
165
 
      $result=$tmp;
166
 
    }
167
 
  }
168
 
  if (length($result))
169
 
  {
170
 
    $to_dbh->do($query . $result) || die "Can't insert row: $DBI::errstr";
171
 
  }
172
 
  if ($opt_lock && $to_server->{'lock_tables'})
173
 
  {
174
 
    $to_dbh->do("unlock tables");
175
 
  }
176
 
}
177
 
 
178
 
 
179
 
sub get_table_definition
180
 
{
181
 
  my ($server,$dbh,$sth)=@_;
182
 
  my ($i,$names,$types,$scale,$precision,$nullable,@res);
183
 
 
184
 
  $names=$sth->{NAME};
185
 
  $types=$sth->{TYPE};
186
 
  $nullable=$sth->{NULLABLE};
187
 
  if (0)
188
 
  {
189
 
    # The following doesn't yet work
190
 
    $scale=$sth->{SCALE};
191
 
    $precision=$sth->{PRECISION};
192
 
  }
193
 
  else
194
 
  {
195
 
    my (@tmp);
196
 
    @tmp= (undef()) x $sth->{NUM_OF_FIELDS};
197
 
    $precision= $scale= \@tmp;
198
 
  }
199
 
  for ($i = 0; $i < $sth->{NUM_OF_FIELDS} ; $i++)
200
 
  {
201
 
    push(@res,$names->[$i] . " " .
202
 
         odbc_to_sql($server,$types->[$i],$precision->[$i],$scale->[$i]) .
203
 
         ($nullable->[$i] ? "" : " NOT NULL"));
204
 
  }
205
 
  return \@res;
206
 
}
207
 
 
208
 
 
209
 
sub odbc_to_sql
210
 
{
211
 
  my ($server,$type,$precision,$scale)=@_;
212
 
 
213
 
  if ($type == DBI::SQL_CHAR())
214
 
  {
215
 
    return defined($precision) ? "char($precision)" : "varchar(255)";
216
 
  }
217
 
 
218
 
  if ($type == DBI::SQL_NUMERIC())
219
 
  {
220
 
    $precision=15 if (!defined($precision));
221
 
    $scale=6 if (!defined($scale));
222
 
    return "numeric($precision,$scale)";
223
 
  }
224
 
  if ($type == DBI::SQL_DECIMAL())
225
 
  {
226
 
    $precision=15 if (!defined($precision));
227
 
    $scale=6 if (!defined($scale));
228
 
    return "decimal($precision,$scale)";
229
 
  }
230
 
  if ($type == DBI::SQL_INTEGER())
231
 
  {
232
 
    return "integer" if (!defined($precision));
233
 
    return "integer($precision)";
234
 
  }
235
 
  if ($type == DBI::SQL_SMALLINT())
236
 
  {
237
 
    return "smallint" if (!defined($precision));
238
 
    return "smallint($precision)";
239
 
  }
240
 
  if ($type == DBI::SQL_FLOAT())
241
 
  {
242
 
    $precision=12 if (!defined($precision));
243
 
    $scale=2 if (!defined($scale));
244
 
    return "float($precision,$scale)";
245
 
  }
246
 
  if ($type == DBI::SQL_REAL())
247
 
  {
248
 
    $precision=12 if (!defined($precision));
249
 
    $scale=2 if (!defined($scale));
250
 
    return "float($precision,$scale)";
251
 
  }
252
 
  if ($type == DBI::SQL_DOUBLE())
253
 
  {
254
 
    $precision=22 if (!defined($precision));
255
 
    $scale=2 if (!defined($scale));
256
 
    return "double($precision,$scale)";
257
 
  }
258
 
  if ($type == DBI::SQL_VARCHAR())
259
 
  {
260
 
    $precision=255 if (!defined($precision));
261
 
    return "varchar($precision)";
262
 
  }
263
 
  return "date"                         if ($type == DBI::SQL_DATE());
264
 
  return "time"                         if ($type == DBI::SQL_TIME());
265
 
  return "timestamp"                    if ($type == DBI::SQL_TIMESTAMP());
266
 
  return $server->{'text'}              if ($type == DBI::SQL_LONGVARCHAR());
267
 
  return $server->{'blob'}              if ($type == DBI::SQL_LONGVARBINARY());
268
 
  if ($type == DBI::SQL_BIGINT())
269
 
  {
270
 
    return "bigint" if (!defined($precision));
271
 
    return "bigint($precision)";
272
 
  }
273
 
  if ($type == DBI::SQL_TINYINT())
274
 
  {
275
 
    return "tinyint" if (!defined($precision));
276
 
    return "tinyint($precision)";
277
 
  }
278
 
  die "Can't covert type '$type' to a ODBC type\n";
279
 
}
280
 
 
281
 
#
282
 
# return an array with 1 for all coumns that we have to quote
283
 
#
284
 
                                              
285
 
sub get_columns_to_quote($sth)
286
 
{
287
 
  my ($sth)=@_;
288
 
  my ($i,@res,$type,$tmp);
289
 
 
290
 
  @res=();
291
 
  for ($i = 0; $i < $sth->{NUM_OF_FIELDS} ; $i++)
292
 
  {
293
 
    $type=$sth->{TYPE}->[$i];
294
 
    $tmp=1;                     # String by default
295
 
    if ($type == DBI::SQL_NUMERIC()     || $type == DBI::SQL_DECIMAL() ||
296
 
        $type == DBI::SQL_INTEGER()     || $type == DBI::SQL_SMALLINT() ||
297
 
        $type == DBI::SQL_SMALLINT()    || $type == DBI::SQL_FLOAT() ||
298
 
        $type == DBI::SQL_REAL()        || $type == DBI::SQL_DOUBLE() ||
299
 
        $type == DBI::SQL_BIGINT()      || $type == DBI::SQL_TINYINT())
300
 
    {
301
 
      $tmp=0;
302
 
    }
303
 
    push (@res,$tmp);
304
 
  }
305
 
  return \@res;
306
 
}
307
 
 
308
 
#
309
 
# Check if table exists;  Return 1 if table exists
310
 
#
311
 
 
312
 
sub table_exists
313
 
{
314
 
  my ($server,$dbh,$table)=@_;
315
 
  if ($server->{'limits'}->{'group_functions'})
316
 
  {
317
 
    return !safe_query($dbh,"select count(*) from $table");
318
 
  }
319
 
  if ($server->{'limits'}->{'limit'})
320
 
  {
321
 
    return !safe_query($dbh,"select * from $table limit 1");
322
 
  }
323
 
  die "Don't know how to check if table '$table' exists in destination server\n";
324
 
}
325
 
 
326
 
 
327
 
#
328
 
# execute query;  return 0 if query is ok
329
 
#
330
 
 
331
 
sub safe_query
332
 
{
333
 
  my ($dbh,$query)=@_;
334
 
  my ($sth);
335
 
 
336
 
  print "query: $query\n" if ($opt_debug);
337
 
  if (!($sth= $dbh->prepare($query)))
338
 
  {
339
 
    print "error: $DBI::errstr\n" if ($opt_debug);
340
 
    return 1;
341
 
  }
342
 
  if (!$sth->execute)
343
 
  {
344
 
    print "error: $DBI::errstr\n" if ($opt_debug);
345
 
    return 1
346
 
  }
347
 
  while ($sth->fetchrow_arrayref)
348
 
  {
349
 
  }
350
 
  $sth->finish;
351
 
  undef($sth);
352
 
  return 0;
353
 
}
354
 
 
355
 
#
356
 
# execute an array of queries
357
 
#
358
 
 
359
 
sub do_many
360
 
{
361
 
  my ($dbh,@statements)=@_;
362
 
  my ($statement,$sth);
363
 
 
364
 
  foreach $statement (@statements)
365
 
  {
366
 
    print "query: $statement\n" if ($opt_debug);
367
 
    if (!($sth=$dbh->do($statement)))
368
 
    {
369
 
      die "Can't execute command '$statement'\nError: $DBI::errstr\n";
370
 
    }
371
 
  }
372
 
}