482
static void maybe_exit(int error)
361
void maybe_exit(int error)
484
363
if (!first_error)
485
364
first_error= error;
486
365
if (ignore_errors)
488
drizzle_con_free(&dcon);
489
drizzle_free(&drizzle);
367
delete db_connection;
368
if (destination_connection)
369
delete destination_connection;
490
370
free_resources();
496
db_connect -- connects to the host and selects DB.
499
static int connect_to_db(string host, string user,string passwd)
501
drizzle_return_t ret;
503
verbose_msg(_("-- Connecting to %s, using protocol %s...\n"), ! host.empty() ? (char *)host.c_str() : "localhost", opt_protocol.c_str());
504
drizzle_create(&drizzle);
505
drizzle_con_create(&drizzle, &dcon);
506
drizzle_con_set_tcp(&dcon, (char *)host.c_str(), opt_drizzle_port);
507
drizzle_con_set_auth(&dcon, (char *)user.c_str(), (char *)passwd.c_str());
508
drizzle_con_add_options(&dcon, use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
509
ret= drizzle_con_connect(&dcon);
510
if (ret != DRIZZLE_RETURN_OK)
512
DB_error(NULL, ret, "when trying to connect");
517
} /* connect_to_db */
521
** dbDisconnect -- disconnects from the host.
523
static void dbDisconnect(string &host)
525
verbose_msg(_("-- Disconnecting from %s...\n"), ! host.empty() ? host.c_str() : "localhost");
526
drizzle_con_free(&dcon);
527
drizzle_free(&drizzle);
531
static void unescape(FILE *file,char *pos,uint32_t length)
535
if (!(tmp=(char*) malloc(length*2+1)))
536
die(EX_DRIZZLEERR, _("Couldn't allocate memory"));
538
drizzle_escape_string(tmp, pos, length);
548
static bool test_if_special_chars(const char *str)
550
for ( ; *str ; str++)
551
if (!my_isvar(charset_info,*str) && *str != '$')
554
} /* test_if_special_chars */
559
quote_name(name, buff, force)
561
Quotes char string, taking into account compatible mode
565
name Unquoted string containing that which will be quoted
566
buff The buffer that contains the quoted value, also returned
567
force Flag to make it ignore 'test_if_special_chars'
574
static char *quote_name(const char *name, char *buff, bool force)
579
if (!force && !opt_quoted && !test_if_special_chars(name))
595
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
599
name name of the table
600
buff quoted name of the table
603
Quote \, _, ' and % characters
605
Note: Because DRIZZLE uses the C escape syntax in strings
606
(for example, '\n' to represent newline), you must double
607
any '\' that you use in your LIKE strings. For example, to
608
search for '\n', specify it as '\\n'. To search for '\', specify
609
it as '\\\\' (the backslashes are stripped once by the parser
610
and another time when the pattern match is done, leaving a
611
single backslash to be matched).
613
Example: "t\1" => "t\\\\1"
616
static char *quote_for_like(const char *name, char *buff)
628
else if (*name == '\'' || *name == '_' || *name == '%')
639
Quote and print a string.
643
xml_file - output file
644
str - string to print
648
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
651
static void print_quoted_xml(FILE *xml_file, const char *str, uint32_t len)
655
for (end= str + len; str != end; str++)
659
fputs("<", xml_file);
662
fputs(">", xml_file);
665
fputs("&", xml_file);
668
fputs(""", xml_file);
671
fputc(*str, xml_file);
680
Print xml tag. Optionally add attribute(s).
683
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
684
..., attribute_name_n, attribute_value_n, NULL)
685
xml_file - output file
686
sbeg - line beginning
687
line_end - line ending
688
tag_name - XML tag name.
689
first_attribute_name - tag and first attribute
690
first_attribute_value - (Implied) value of first attribute
691
attribute_name_n - attribute n
692
attribute_value_n - value of attribute n
695
Print XML tag with any number of attribute="value" pairs to the xml_file.
698
sbeg<tag_name first_attribute_name="first_attribute_value" ...
699
attribute_name_n="attribute_value_n">send
701
Additional arguments must be present in attribute/value pairs.
702
The last argument should be the null character pointer.
703
All attribute_value arguments MUST be NULL terminated strings.
704
All attribute_value arguments will be quoted before output.
707
static void print_xml_tag(FILE * xml_file, const char* sbeg,
708
const char* line_end,
709
const char* tag_name,
710
const char* first_attribute_name, ...)
713
const char *attribute_name, *attribute_value;
715
fputs(sbeg, xml_file);
716
fputc('<', xml_file);
717
fputs(tag_name, xml_file);
719
va_start(arg_list, first_attribute_name);
720
attribute_name= first_attribute_name;
721
while (attribute_name != NULL)
723
attribute_value= va_arg(arg_list, char *);
724
assert(attribute_value != NULL);
726
fputc(' ', xml_file);
727
fputs(attribute_name, xml_file);
728
fputc('\"', xml_file);
730
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
731
fputc('\"', xml_file);
733
attribute_name= va_arg(arg_list, char *);
737
fputc('>', xml_file);
738
fputs(line_end, xml_file);
744
Print xml tag with for a field that is null
748
xml_file - output file
749
sbeg - line beginning
750
stag_atr - tag and attribute
751
sval - value of attribute
752
line_end - line ending
755
Print tag with one attribute to the xml_file. Format is:
756
<stag_atr="sval" xsi:nil="true"/>
758
sval MUST be a NULL terminated string.
759
sval string will be qouted before output.
762
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
763
const char* stag_atr, const char* sval,
764
const char* line_end)
766
fputs(sbeg, xml_file);
767
fputs("<", xml_file);
768
fputs(stag_atr, xml_file);
769
fputs("\"", xml_file);
770
print_quoted_xml(xml_file, sval, strlen(sval));
771
fputs("\" xsi:nil=\"true\" />", xml_file);
772
fputs(line_end, xml_file);
778
Print xml tag with many attributes.
782
xml_file - output file
783
row_name - xml tag name
784
tableRes - query result
788
Print tag with many attribute to the xml_file. Format is:
789
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
791
All atributes and values will be quoted before output.
794
static void print_xml_row(FILE *xml_file, const char *row_name,
795
drizzle_result_st *tableRes, drizzle_row_t *row)
798
drizzle_column_st *column;
799
size_t *lengths= drizzle_row_field_sizes(tableRes);
801
fprintf(xml_file, "\t\t<%s", row_name);
803
drizzle_column_seek(tableRes, 0);
804
for (i= 0; (column= drizzle_column_next(tableRes)); i++)
808
fputc(' ', xml_file);
809
print_quoted_xml(xml_file, drizzle_column_name(column),
810
strlen(drizzle_column_name(column)));
811
fputs("=\"", xml_file);
812
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
813
fputc('"', xml_file);
817
fputs(" />\n", xml_file);
823
Print hex value for blob data.
827
output_file - output file
828
str - string to print
832
Print hex value for blob data.
835
static void print_blob_as_hex(FILE *output_file, const char *str, uint32_t len)
837
/* sakaik got the idea to to provide blob's in hex notation. */
838
const char *ptr= str, *end= ptr + len;
839
for (; ptr < end ; ptr++)
840
fprintf(output_file, "%02X", *((unsigned char *)ptr));
841
check_io(output_file);
845
get_table_structure -- retrievs database structure, prints out corresponding
846
CREATE statement and fills out insert_pat if the table is the type we will
852
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
853
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
854
num_fields - number of fields in the table
857
true if success, false if error
860
static bool get_table_structure(char *table, char *db, char *table_type,
861
char *ignore_flag, uint64_t *num_fields)
863
bool init=0, delayed, write_data, complete_insert;
864
char *result_table, *opt_quoted_table;
865
const char *insert_option;
866
char name_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE+3];
867
char table_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+3];
868
char table_buff2[DRIZZLE_MAX_TABLE_SIZE*2+3];
869
char query_buff[QUERY_LENGTH];
870
FILE *sql_file= md_result_file;
871
drizzle_result_st result;
874
*ignore_flag= check_if_ignore_table(table, table_type);
876
delayed= opt_delayed;
877
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
880
verbose_msg(_("-- Warning: Unable to use delayed inserts for table '%s' "
881
"because it's of type %s\n"), table, table_type);
885
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
887
complete_insert= opt_complete_insert;
891
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
892
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
894
verbose_msg(_("-- Retrieving table structure for table %s...\n"), table);
896
result_table= quote_name(table, table_buff, 1);
897
opt_quoted_table= quote_name(table, table_buff2, 0);
899
if (opt_order_by_primary)
902
order_by= primary_key_fields(result_table);
907
/* using SHOW CREATE statement */
908
if (! opt_no_create_info)
910
/* Make an sql-file, if path was given iow. option -T was given */
911
char buff[20+FN_REFLEN];
912
const drizzle_column_st *column;
914
snprintf(buff, sizeof(buff), "show create table %s", result_table);
916
if (drizzleclient_query_with_error_report(&dcon, &result, buff, false))
921
if (!(sql_file= open_sql_file_for_table(table)))
923
drizzle_result_free(&result);
927
write_header(sql_file, db);
929
if (!opt_xml && opt_comments)
931
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
938
Even if the "table" is a view, we do a DROP TABLE here.
940
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
944
column= drizzle_column_index(&result, 0);
946
row= drizzle_row_next(&result);
948
fprintf(sql_file, "%s;\n", row[1]);
951
drizzle_result_free(&result);
954
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
957
if (drizzleclient_query_with_error_report(&dcon, &result, query_buff, false))
965
If write_data is true, then we build up insert statements for
966
the table's data. Note: in subsequent lines of code, this test
967
will have to be performed each time we are appending to
972
if (opt_replace_into)
973
insert_pat.append("REPLACE ");
975
insert_pat.append("INSERT ");
976
insert_pat.append(insert_option);
977
insert_pat.append("INTO ");
978
insert_pat.append(opt_quoted_table);
981
insert_pat.append(" (");
985
insert_pat.append(" VALUES ");
986
if (!extended_insert)
987
insert_pat.append("(");
991
while ((row= drizzle_row_next(&result)))
997
insert_pat.append(", ");
1000
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1003
*num_fields= drizzle_result_row_count(&result);
1004
drizzle_result_free(&result);
1008
verbose_msg(_("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n"),
1009
progname.c_str(), drizzle_con_error(&dcon));
1011
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1013
if (drizzleclient_query_with_error_report(&dcon, &result, query_buff, false))
1016
/* Make an sql-file, if path was given iow. option -T was given */
1017
if (! opt_no_create_info)
1021
if (!(sql_file= open_sql_file_for_table(table)))
1023
drizzle_result_free(&result);
1026
write_header(sql_file, db);
1028
if (!opt_xml && opt_comments)
1029
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1032
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
1034
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1036
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1043
if (opt_replace_into)
1044
insert_pat.append("REPLACE ");
1046
insert_pat.append("INSERT ");
1047
insert_pat.append(insert_option);
1048
insert_pat.append("INTO ");
1049
insert_pat.append(result_table);
1050
if (complete_insert)
1051
insert_pat.append(" (");
1054
insert_pat.append(" VALUES ");
1055
if (!extended_insert)
1056
insert_pat.append("(");
1060
while ((row= drizzle_row_next(&result)))
1062
size_t *lengths= drizzle_row_field_sizes(&result);
1065
if (!opt_xml && !opt_no_create_info)
1067
fputs(",\n",sql_file);
1070
if (complete_insert)
1071
insert_pat.append(", ");
1074
if (complete_insert)
1075
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1076
if (!opt_no_create_info)
1080
print_xml_row(sql_file, "field", &result, &row);
1085
fprintf(sql_file, " %s.%s %s", result_table,
1086
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
1089
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
1092
if (row[SHOW_DEFAULT])
1094
fputs(" DEFAULT ", sql_file);
1095
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
1097
if (!row[SHOW_NULL][0])
1098
fputs(" NOT NULL", sql_file);
1099
if (row[SHOW_EXTRA][0])
1100
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
1104
*num_fields= drizzle_result_row_count(&result);
1105
drizzle_result_free(&result);
1107
if (!opt_no_create_info)
1109
/* Make an sql-file, if path was given iow. option -T was given */
1110
char buff[20+FN_REFLEN];
1111
uint32_t keynr,primary_key;
1112
snprintf(buff, sizeof(buff), "show keys from %s", result_table);
1113
if (drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1115
fprintf(stderr, _("%s: Can't get keys for table %s\n"),
1116
progname.c_str(), result_table);
1122
/* Find first which key is primary key */
1124
primary_key=INT_MAX;
1125
while ((row= drizzle_row_next(&result)))
1127
if (atoi(row[3]) == 1)
1130
#ifdef FORCE_PRIMARY_KEY
1131
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
1134
if (!strcmp(row[2],"PRIMARY"))
1141
drizzle_row_seek(&result,0);
1143
while ((row= drizzle_row_next(&result)))
1147
print_xml_row(sql_file, "key", &result, &row);
1151
if (atoi(row[3]) == 1)
1154
putc(')', sql_file);
1155
if (atoi(row[1])) /* Test if duplicate key */
1156
/* Duplicate allowed */
1157
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
1158
else if (keynr == primary_key)
1159
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
1161
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
1165
putc(',', sql_file);
1166
fputs(quote_name(row[4], name_buff, 0), sql_file);
1168
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
1171
drizzle_result_free(&result);
1175
putc(')', sql_file);
1176
fputs("\n)",sql_file);
1179
/* Get DRIZZLE specific create options */
1182
char show_name_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+2+24];
1184
/* Check memory for quote_for_like() */
1185
snprintf(buff, sizeof(buff), "show table status like %s",
1186
quote_for_like(table, show_name_buff));
1188
if (!drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1190
if (!(row= drizzle_row_next(&result)))
1193
_("Error: Couldn't read status information for table %s\n"),
1199
print_xml_row(sql_file, "options", &result, &row);
1202
fputs("/*!",sql_file);
1203
print_value(sql_file,&result,row,"engine=","Engine",0);
1204
print_value(sql_file,&result,row,"","Create_options",0);
1205
print_value(sql_file,&result,row,"comment=","Comment",1);
1207
fputs(" */",sql_file);
1211
drizzle_result_free(&result);
1215
fputs(";\n", sql_file);
1217
fputs("\t</table_structure>\n", sql_file);
1221
if (complete_insert) {
1222
insert_pat.append(") VALUES ");
1223
if (!extended_insert)
1224
insert_pat.append("(");
1226
if (sql_file != md_result_file)
1228
fputs("\n", sql_file);
1229
write_footer(sql_file);
1233
} /* get_table_structure */
1235
static void add_load_option(string &str, const char *option,
1236
const string &option_value)
1238
if (option_value.empty())
1240
/* Null value means we don't add this option. */
1246
if (option_value.compare(0, 2, "0x") == 0)
1248
/* It's a hex constant, don't escape */
1249
str.append(option_value);
1253
/* char constant; escape */
1254
field_escape(str, option_value);
1260
Allow the user to specify field terminator strings like:
1261
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
1262
This is done by doubling ' and add a end -\ if needed to avoid
1263
syntax errors from the SQL parser.
1266
static void field_escape(string &in, const string &from)
1268
uint32_t end_backslashes= 0;
1272
string::const_iterator it= from.begin();
1273
while (it != from.end())
1278
end_backslashes^= 1; /* find odd number of backslashes */
1281
if (*it == '\'' && !end_backslashes)
1283
/* We want a duplicate of "'" for DRIZZLE */
1290
/* Add missing backslashes if user has specified odd number of backs.*/
1291
if (end_backslashes)
1304
dump_table saves database contents as a series of INSERT statements.
1315
static void dump_table(char *table, char *db)
1318
char table_buff[DRIZZLE_MAX_TABLE_SIZE+3];
1319
string query_string;
1320
char table_type[DRIZZLE_MAX_TABLE_SIZE];
1321
char *result_table, table_buff2[DRIZZLE_MAX_TABLE_SIZE*2+3], *opt_quoted_table;
1323
uint32_t rownr, row_break, total_length, init_length;
1324
uint64_t num_fields= 0;
1325
drizzle_return_t ret;
1326
drizzle_result_st result;
1327
drizzle_column_st *column;
1332
Make sure you get the create table info before the following check for
1333
--no-data flag below. Otherwise, the create table info won't be printed.
1335
if (!get_table_structure(table, db, table_type, &ignore_flag, &num_fields))
1337
maybe_die(EX_TABLE_STATUS, _("Error retrieving table structure for table: \"%s\""), table);
1341
/* Check --no-data flag */
1344
verbose_msg(_("-- Skipping dump data for table '%s', --no-data was used\n"),
1350
If the table type is a merge table or any type that has to be
1351
_completely_ ignored and no data dumped
1353
if (ignore_flag & IGNORE_DATA)
1355
verbose_msg(_("-- Warning: Skipping data for table '%s' because " \
1356
"it's of type %s\n"), table, table_type);
1359
/* Check that there are any fields in the table */
1360
if (num_fields == 0)
1362
verbose_msg(_("-- Skipping dump data for table '%s', it has no fields\n"),
1367
result_table= quote_name(table,table_buff, 1);
1368
opt_quoted_table= quote_name(table, table_buff2, 0);
1370
verbose_msg(_("-- Sending SELECT query...\n"));
1372
query_string.clear();
1373
query_string.reserve(1024);
1377
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1380
Convert the path to native os format
1381
and resolve to the full filepath.
1383
internal::convert_dirname(tmp_path,(char *)path.c_str(),NULL);
1384
internal::my_load_path(tmp_path, tmp_path, NULL);
1385
internal::fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
1387
/* Must delete the file that 'INTO OUTFILE' will write to */
1388
internal::my_delete(filename, MYF(0));
1390
/* now build the query string */
1392
query_string.append( "SELECT * INTO OUTFILE '");
1393
query_string.append( filename);
1394
query_string.append( "'");
1396
if (! fields_terminated.empty() || ! enclosed.empty() || ! opt_enclosed.empty() || ! escaped.empty())
1397
query_string.append( " FIELDS");
1399
add_load_option(query_string, " TERMINATED BY ", fields_terminated);
1400
add_load_option(query_string, " ENCLOSED BY ", enclosed);
1401
add_load_option(query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
1402
add_load_option(query_string, " ESCAPED BY ", escaped);
1403
add_load_option(query_string, " LINES TERMINATED BY ", lines_terminated);
1405
query_string.append(" FROM ");
1406
query_string.append(result_table);
1408
if (! where.empty())
1410
query_string.append(" WHERE ");
1411
query_string.append(where);
1416
query_string.append(" ORDER BY ");
1417
query_string.append(order_by);
1420
if (drizzle_query(&dcon, &result, query_string.c_str(),
1421
query_string.length(), &ret) == NULL ||
1422
ret != DRIZZLE_RETURN_OK)
1424
DB_error(&result, ret, _("when executing 'SELECT INTO OUTFILE'"));
1428
drizzle_result_free(&result);
1433
if (!opt_xml && opt_comments)
1435
fprintf(md_result_file,_("\n--\n-- Dumping data for table %s\n--\n"),
1437
check_io(md_result_file);
1440
query_string.append( "SELECT * FROM ");
1441
query_string.append( result_table);
1443
if (! where.empty())
1445
if (!opt_xml && opt_comments)
1447
fprintf(md_result_file, "-- WHERE: %s\n", where.c_str());
1448
check_io(md_result_file);
1451
query_string.append( " WHERE ");
1452
query_string.append( (char *)where.c_str());
1456
if (!opt_xml && opt_comments)
1458
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
1459
check_io(md_result_file);
1461
query_string.append( " ORDER BY ");
1462
query_string.append( order_by);
1465
if (!opt_xml && !opt_compact)
1467
fputs("\n", md_result_file);
1468
check_io(md_result_file);
1470
if (drizzleclient_query_with_error_report(&dcon, &result,
1471
query_string.c_str(), quick))
1476
verbose_msg(_("-- Retrieving rows...\n"));
1477
if (drizzle_result_column_count(&result) != num_fields)
1479
fprintf(stderr,_("%s: Error in field count for table: %s ! Aborting.\n"),
1480
progname.c_str(), result_table);
1481
error= EX_CONSCHECK;
1482
drizzle_result_free(&result);
1486
/* Moved disable keys to after lock per bug 15977 */
1487
if (opt_disable_keys)
1489
fprintf(md_result_file, "ALTER TABLE %s DISABLE KEYS;\n",
1491
check_io(md_result_file);
1494
total_length= DRIZZLE_MAX_LINE_LENGTH; /* Force row break */
1497
init_length=(uint32_t) insert_pat.length()+4;
1499
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
1503
fprintf(md_result_file, "set autocommit=0;\n");
1504
check_io(md_result_file);
1517
drizzle_row_free(&result, row);
1519
row= drizzle_row_buffer(&result, &ret);
1520
if (ret != DRIZZLE_RETURN_OK)
1523
_("%s: Error reading rows for table: %s (%d:%s) ! Aborting.\n"),
1524
progname.c_str(), result_table, ret, drizzle_con_error(&dcon));
1525
drizzle_result_free(&result);
1530
row= drizzle_row_next(&result);
1535
lengths= drizzle_row_field_sizes(&result);
1538
if ((rownr % show_progress_size) == 0)
1540
verbose_msg(_("-- %"PRIu32" of ~%"PRIu64" rows dumped for table %s\n"), rownr, total_rows, opt_quoted_table);
1542
if (!extended_insert && !opt_xml)
1544
fputs(insert_pat.c_str(),md_result_file);
1545
check_io(md_result_file);
1547
drizzle_column_seek(&result,0);
1551
fputs("\t<row>\n", md_result_file);
1552
check_io(md_result_file);
1555
for (i= 0; i < drizzle_result_column_count(&result); i++)
1558
uint32_t length= lengths[i];
1560
if (!(column= drizzle_column_next(&result)))
1562
_("Not enough fields from table %s! Aborting.\n"),
1566
63 is my_charset_bin. If charsetnr is not 63,
1567
we have not a BLOB but a TEXT column.
1568
we'll dump in hex only BLOB columns.
1570
is_blob= (drizzle_column_charset(column) == 63 &&
1571
(drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_VARCHAR ||
1572
drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_BLOB)) ? 1 : 0;
1573
if (extended_insert && !opt_xml)
1577
extended_row.clear();
1578
extended_row.append("(");
1581
extended_row.append(",");
1587
if (!(drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NUM))
1590
"length * 2 + 2" is OK for both HEX and non-HEX modes:
1591
- In HEX mode we need exactly 2 bytes per character
1592
plus 2 bytes for '0x' prefix.
1593
- In non-HEX mode we need up to 2 bytes per character,
1594
plus 2 bytes for leading and trailing '\'' characters.
1595
Also we need to reserve 1 byte for terminating '\0'.
1597
char * tmp_str= (char *)malloc(length * 2 + 2 + 1);
1598
memset(tmp_str, '\0', length * 2 + 2 + 1);
1601
extended_row.append("0x");
1602
drizzle_hex_string(tmp_str, row[i], length);
1603
extended_row.append(tmp_str);
1607
extended_row.append("'");
1608
drizzle_escape_string(tmp_str, row[i],length);
1609
extended_row.append(tmp_str);
1610
extended_row.append("'");
1616
/* change any strings ("inf", "-inf", "nan") into NULL */
1618
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
1619
my_isalpha(charset_info, ptr[1])))
1620
extended_row.append( "NULL");
1623
extended_row.append( ptr);
1628
extended_row.append("''");
1631
extended_row.append("NULL");
1637
fputc(',', md_result_file);
1638
check_io(md_result_file);
1642
if (!(drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NUM))
1646
if (is_blob && length)
1648
/* Define xsi:type="xs:hexBinary" for hex encoded data */
1649
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
1650
drizzle_column_name(column), "xsi:type=", "xs:hexBinary", NULL);
1651
print_blob_as_hex(md_result_file, row[i], length);
1655
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
1656
drizzle_column_name(column), NULL);
1657
print_quoted_xml(md_result_file, row[i], length);
1659
fputs("</field>\n", md_result_file);
1661
else if (is_blob && length)
1663
fputs("0x", md_result_file);
1664
print_blob_as_hex(md_result_file, row[i], length);
1667
unescape(md_result_file, row[i], length);
1671
/* change any strings ("inf", "-inf", "nan") into NULL */
1675
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
1676
drizzle_column_name(column), NULL);
1677
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
1679
fputs("</field>\n", md_result_file);
1681
else if (my_isalpha(charset_info, *ptr) ||
1682
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
1683
fputs("NULL", md_result_file);
1685
fputs(ptr, md_result_file);
1690
/* The field value is NULL */
1692
fputs("NULL", md_result_file);
1694
print_xml_null_tag(md_result_file, "\t\t", "field name=",
1695
drizzle_column_name(column), "\n");
1697
check_io(md_result_file);
1703
fputs("\t</row>\n", md_result_file);
1704
check_io(md_result_file);
1707
if (extended_insert)
1709
uint32_t row_length;
1710
extended_row.append(")");
1711
row_length= 2 + extended_row.length();
1712
if (total_length + row_length < DRIZZLE_MAX_LINE_LENGTH)
1714
total_length+= row_length;
1715
fputc(',',md_result_file); /* Always row break */
1716
fputs(extended_row.c_str(),md_result_file);
1721
fputs(";\n", md_result_file);
1722
row_break=1; /* This is first row */
1724
fputs(insert_pat.c_str(),md_result_file);
1725
fputs(extended_row.c_str(),md_result_file);
1726
total_length= row_length+init_length;
1728
check_io(md_result_file);
1732
fputs(");\n", md_result_file);
1733
check_io(md_result_file);
1737
/* XML - close table tag and supress regular output */
1739
fputs("\t</table_data>\n", md_result_file);
1740
else if (extended_insert && row_break)
1741
fputs(";\n", md_result_file); /* If not empty table */
1742
fflush(md_result_file);
1743
check_io(md_result_file);
1745
/* Moved enable keys to before unlock per bug 15977 */
1746
if (opt_disable_keys)
1748
fprintf(md_result_file,"ALTER TABLE %s ENABLE KEYS;\n",
1750
check_io(md_result_file);
1754
fprintf(md_result_file, "commit;\n");
1755
check_io(md_result_file);
1757
drizzle_result_free(&result);
1767
static char *getTableName(int reset)
1769
static drizzle_result_st result;
1770
static bool have_result= false;
1775
if (drizzleclient_query_with_error_report(&dcon, &result, "SHOW TABLES", false))
1780
if ((row= drizzle_row_next(&result)))
1784
drizzle_row_seek(&result, 0);
1787
drizzle_result_free(&result);
1791
} /* getTableName */
1794
374
static int dump_all_databases()
1796
376
drizzle_row_t row;
1797
drizzle_result_st tableres;
377
drizzle_result_st *tableres;
1800
if (drizzleclient_query_with_error_report(&dcon, &tableres, "SHOW DATABASES", false))
1802
while ((row= drizzle_row_next(&tableres)))
380
DrizzleDumpDatabase *database;
383
std::cerr << _("-- Retrieving database structures...") << std::endl;
385
/* Blocking the MySQL privilege tables too because we can't import them due to bug#646187 */
386
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
387
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql')";
389
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM DATA_DICTIONARY.SCHEMAS WHERE SCHEMA_NAME NOT IN ('information_schema','data_dictionary')";
391
tableres= db_connection->query(query);
392
while ((row= drizzle_row_next(tableres)))
1804
if (dump_all_tables_in_db(row[0]))
394
std::string database_name(row[0]);
395
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
396
database= new DrizzleDumpDatabaseMySQL(database_name, db_connection);
398
database= new DrizzleDumpDatabaseDrizzle(database_name, db_connection);
400
database->setCollate(row[1]);
401
database_store.push_back(database);
1807
drizzle_result_free(&tableres);
403
db_connection->freeResult(tableres);
1810
406
/* dump_all_databases */
413
DrizzleDumpDatabase *database;
1817
415
for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
1820
if (dump_all_tables_in_db((char *)temp.c_str()))
418
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
419
database= new DrizzleDumpDatabaseMySQL(temp, db_connection);
421
database= new DrizzleDumpDatabaseDrizzle(temp, db_connection);
422
database_store.push_back(database);
1824
425
} /* dump_databases */
1828
Table Specific database initalization.
1832
qdatabase quoted name of the database
1839
int init_dumping_tables(char *qdatabase)
1845
drizzle_result_st result;
1846
drizzle_return_t ret;
1848
snprintf(qbuf, sizeof(qbuf),
1849
"SHOW CREATE DATABASE IF NOT EXISTS %s",
1852
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
1853
ret != DRIZZLE_RETURN_OK)
1855
if (ret == DRIZZLE_RETURN_ERROR_CODE)
1856
drizzle_result_free(&result);
1858
/* Old server version, dump generic CREATE DATABASE */
1859
if (opt_drop_database)
1860
fprintf(md_result_file,
1861
"\nDROP DATABASE IF EXISTS %s;\n",
1863
fprintf(md_result_file,
1864
"\nCREATE DATABASE IF NOT EXISTS %s;\n",
1869
if (drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
1871
if (opt_drop_database)
1872
fprintf(md_result_file,
1873
"\nDROP DATABASE IF EXISTS %s;\n",
1875
row = drizzle_row_next(&result);
1876
if (row != NULL && row[1])
1878
fprintf(md_result_file,"\n%s;\n",row[1]);
1881
drizzle_result_free(&result);
1885
} /* init_dumping_tables */
1888
static int init_dumping(char *database, int init_func(char*))
1890
drizzle_result_st result;
1891
drizzle_return_t ret;
1894
/* If this DB contains non-standard tables we don't want it */
1896
snprintf(qbuf, sizeof(qbuf), "SELECT TABLE_NAME FROM DATA_DICTIONARY.TABLES WHERE TABLE_SCHEMA='%s' AND TABLE_TYPE != 'STANDARD'", database);
1898
if (drizzle_query_str(&dcon, &result, qbuf, &ret) != NULL)
1900
drizzle_result_buffer(&result);
1901
if (drizzle_result_row_count(&result) > 0)
1903
drizzle_result_free(&result);
1908
drizzle_result_free(&result);
1910
if (drizzle_select_db(&dcon, &result, database, &ret) == NULL ||
1911
ret != DRIZZLE_RETURN_OK)
1913
DB_error(&result, ret, _("when executing 'SELECT INTO OUTFILE'"));
1914
return 1; /* If --force */
1916
drizzle_result_free(&result);
1918
if (path.empty() && !opt_xml)
1920
if (opt_databases || opt_alldbs)
1923
length of table name * 2 (if name contains quotes), 2 quotes and 0
1925
char quoted_database_buf[DRIZZLE_MAX_DB_SIZE*2+3];
1926
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
1929
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
1930
check_io(md_result_file);
1933
/* Call the view or table specific function */
1934
init_func(qdatabase);
1936
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
1937
check_io(md_result_file);
1940
if (extended_insert)
1941
extended_row.clear();
1943
} /* init_dumping */
1946
/* Return 1 if we should copy the table */
1948
static bool include_table(const char *hash_key, size_t key_size)
1950
string match(hash_key, key_size);
1951
boost::unordered_set<string>::iterator iter= ignore_table.find(match);
1952
return (iter == ignore_table.end());
1956
static int dump_all_tables_in_db(char *database)
1959
char hash_key[DRIZZLE_MAX_DB_SIZE+DRIZZLE_MAX_TABLE_SIZE+2]; /* "db.tablename" */
1961
drizzle_result_st result;
1962
drizzle_return_t ret;
1964
memset(hash_key, 0, DRIZZLE_MAX_DB_SIZE+DRIZZLE_MAX_TABLE_SIZE+2);
1965
afterdot= strcpy(hash_key, database) + strlen(database);
1968
if (init_dumping(database, init_dumping_tables))
1971
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NULL);
1974
if (drizzle_query_str(&dcon, &result, "FLUSH LOGS", &ret) == NULL ||
1975
ret != DRIZZLE_RETURN_OK)
1977
DB_error(&result, ret, _("when doing refresh"));
1978
/* We shall continue here, if --force was given */
1981
drizzle_result_free(&result);
1983
while ((table= getTableName(0)))
1985
char *end= strcpy(afterdot, table) + strlen(table);
1986
if (include_table(hash_key, end - hash_key))
1988
dump_table(table,database);
1995
fputs("</database>\n", md_result_file);
1996
check_io(md_result_file);
2000
} /* dump_all_tables_in_db */
2004
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
2005
table name from the server for the table name given on the command line.
2006
we do this because the table name given on the command line may be a
2007
different case (e.g. T1 vs t1)
2010
pointer to the table name
2014
static char *get_actual_table_name(const char *old_table_name,
2015
drizzled::memory::Root *root)
2018
drizzle_result_st result;
2020
char query[50 + 2*DRIZZLE_MAX_TABLE_SIZE];
2021
char show_name_buff[FN_REFLEN];
2025
/* Check memory for quote_for_like() */
2026
assert(2*sizeof(old_table_name) < sizeof(show_name_buff));
2027
snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
2028
quote_for_like(old_table_name, show_name_buff));
2030
if (drizzleclient_query_with_error_report(&dcon, &result, query, false))
2033
num_rows= drizzle_result_row_count(&result);
2039
TODO-> Return all matching rows
2041
row= drizzle_row_next(&result);
2042
lengths= drizzle_row_field_sizes(&result);
2043
name= root->strmake_root(row[0], lengths[0]);
2045
drizzle_result_free(&result);
2051
427
static int dump_selected_tables(const string &db, const vector<string> &table_names)
2053
drizzled::memory::Root root;
2054
char **dump_tables, **pos, **end;
2055
drizzle_result_st result;
2056
drizzle_return_t ret;
2059
if (init_dumping((char *)db.c_str(), init_dumping_tables))
2062
root.init_alloc_root(8192);
2063
if (!(dump_tables= pos= (char**) root.alloc_root(table_names.size() * sizeof(char *))))
2064
die(EX_EOM, _("alloc_root failure."));
2066
for (vector<string>::const_iterator it= table_names.begin(); it != table_names.end(); ++it)
2069
/* the table name passed on commandline may be wrong case */
2070
if ((*pos= get_actual_table_name(temp.c_str(), &root)))
2078
root.free_root(MYF(0));
2080
maybe_die(EX_ILLEGAL_TABLE, _("Couldn't find table: \"%s\""),(char *) temp.c_str());
2081
/* We shall countinue here, if --force was given */
2088
if (drizzle_query_str(&dcon, &result, "FLUSH LOGS", &ret) == NULL ||
2089
ret != DRIZZLE_RETURN_OK)
2092
root.free_root(MYF(0));
2093
DB_error(&result, ret, _("when doing refresh"));
2094
/* We shall countinue here, if --force was given */
2097
drizzle_result_free(&result);
2100
print_xml_tag(md_result_file, "", "\n", "database", "name=", (char *)db.c_str(), NULL);
2102
/* Dump each selected table */
2103
for (pos= dump_tables; pos < end; pos++)
2104
dump_table(*pos, (char *)db.c_str());
2106
root.free_root(MYF(0));
2111
fputs("</database>\n", md_result_file);
2112
check_io(md_result_file);
429
DrizzleDumpDatabase *database;
431
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
432
database= new DrizzleDumpDatabaseMySQL(db, db_connection);
434
database= new DrizzleDumpDatabaseDrizzle(db, db_connection);
436
if (not database->populateTables(table_names))
439
maybe_exit(EX_DRIZZLEERR);
442
database_store.push_back(database);
2115
445
} /* dump_selected_tables */
2117
static int do_flush_tables_read_lock(drizzle_con_st *drizzle_con)
447
static int do_flush_tables_read_lock()
2120
450
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
2124
454
and most client connections are stalled. Of course, if a second long
2125
455
update starts between the two FLUSHes, we have that bad stall.
2128
( drizzleclient_query_with_error_report(drizzle_con, 0, "FLUSH TABLES", false) ||
2129
drizzleclient_query_with_error_report(drizzle_con, 0,
2130
"FLUSH TABLES WITH READ LOCK", false) );
2133
static int do_unlock_tables(drizzle_con_st *drizzle_con)
2135
return drizzleclient_query_with_error_report(drizzle_con, 0, "UNLOCK TABLES", false);
2138
static int start_transaction(drizzle_con_st *drizzle_con)
2140
return (drizzleclient_query_with_error_report(drizzle_con, 0,
2141
"SET SESSION TRANSACTION ISOLATION "
2142
"LEVEL REPEATABLE READ", false) ||
2143
drizzleclient_query_with_error_report(drizzle_con, 0,
2144
"START TRANSACTION "
2145
"WITH CONSISTENT SNAPSHOT", false));
2149
/* Print a value with a prefix on file */
2150
static void print_value(FILE *file, drizzle_result_st *result, drizzle_row_t row,
2151
const char *prefix, const char *name,
2154
drizzle_column_st *column;
2155
drizzle_column_seek(result, 0);
2157
for ( ; (column= drizzle_column_next(result)) ; row++)
2159
if (!strcmp(drizzle_column_name(column),name))
2161
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
2164
fputs(prefix, file);
2166
unescape(file,row[0],(uint32_t) strlen(row[0]));
2168
fputs(row[0], file);
2174
return; /* This shouldn't happen */
2178
* Fetches a row from a result based on a field name
2179
* Returns const char* of the data in that row or NULL if not found
2182
static const char* fetch_named_row(drizzle_result_st *result, drizzle_row_t row, const char *name)
2184
drizzle_column_st *column;
2185
drizzle_column_seek(result, 0);
2187
for ( ; (column= drizzle_column_next(result)) ; row++)
2189
if (!strcmp(drizzle_column_name(column),name))
2191
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
2193
drizzle_column_seek(result, 0);
2198
drizzle_column_seek(result, 0);
2206
Check if we the table is one of the table types that should be ignored:
2207
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
2208
If the table should be altogether ignored, it returns a true, false if it
2209
should not be ignored. If the user has selected to use INSERT DELAYED, it
2210
sets the value of the bool pointer supports_delayed_inserts to 0 if not
2211
supported, 1 if it is supported.
2215
check_if_ignore_table()
2216
table_name Table name to check
2217
table_type Type of table
2220
drizzle Drizzle connection
2221
verbose Write warning messages
2224
char (bit value) See IGNORE_ values at top
2227
char check_if_ignore_table(const char *table_name, char *table_type)
2229
char result= IGNORE_NONE;
2230
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
2231
const char *number_of_rows= NULL;
2232
drizzle_result_st res;
2235
/* Check memory for quote_for_like() */
2236
assert(2*sizeof(table_name) < sizeof(show_name_buff));
2237
snprintf(buff, sizeof(buff), "show table status like %s",
2238
quote_for_like(table_name, show_name_buff));
2239
if (drizzleclient_query_with_error_report(&dcon, &res, buff, false))
2243
if (!(row= drizzle_row_next(&res)))
2246
_("Error: Couldn't read status information for table %s\n"),
2248
drizzle_result_free(&res);
2249
return(result); /* assume table is ok */
2253
if ((number_of_rows= fetch_named_row(&res, row, "Rows")) != NULL)
2255
total_rows= strtoul(number_of_rows, NULL, 10);
2259
If the table type matches any of these, we do support delayed inserts.
2260
Note-> we do not want to skip dumping this table if if is not one of
2261
these types, but we do want to use delayed inserts in the dump if
2262
the table type is _NOT_ one of these types
2265
strncpy(table_type, row[1], DRIZZLE_MAX_TABLE_SIZE-1);
2268
if (strcmp(table_type,"MyISAM") &&
2269
strcmp(table_type,"ARCHIVE") &&
2270
strcmp(table_type,"HEAP") &&
2271
strcmp(table_type,"MEMORY"))
2272
result= IGNORE_INSERT_DELAYED;
2275
drizzle_result_free(&res);
2281
Get string of comma-separated primary key field names
2284
char *primary_key_fields(const char *table_name)
2285
RETURNS pointer to allocated buffer (must be freed by caller)
2286
table_name quoted table name
2289
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
2290
field names, and then build that string and return the pointer
2293
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
2294
or if there is some failure. It is better to continue to dump
2295
the table unsorted, rather than exit without dumping the data.
2298
static char *primary_key_fields(const char *table_name)
2300
drizzle_result_st res;
2301
drizzle_return_t ret;
2303
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
2304
char show_keys_buff[15 + DRIZZLE_MAX_TABLE_SIZE * 2 + 3];
2305
uint32_t result_length= 0;
2307
char buff[DRIZZLE_MAX_TABLE_SIZE * 2 + 3];
2310
snprintf(show_keys_buff, sizeof(show_keys_buff),
2311
"SHOW KEYS FROM %s", table_name);
2312
if (drizzle_query_str(&dcon, &res, show_keys_buff, &ret) == NULL ||
2313
ret != DRIZZLE_RETURN_OK)
2315
if (ret == DRIZZLE_RETURN_ERROR_CODE)
2317
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2318
" records are NOT sorted (%s)\n"),
2319
table_name, drizzle_result_error(&res));
2320
drizzle_result_free(&res);
2324
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2325
" records are NOT sorted (%s)\n"),
2326
table_name, drizzle_con_error(&dcon));
2332
if (drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
2334
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2335
" records are NOT sorted (%s)\n"),
2336
table_name, drizzle_con_error(&dcon));
2341
* Figure out the length of the ORDER BY clause result.
2342
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
2343
* row, and UNIQUE keys come before others. So we only need to check
2344
* the first key, not all keys.
2346
if ((row= drizzle_row_next(&res)) && atoi(row[1]) == 0)
2351
quoted_field= quote_name(row[4], buff, 0);
2352
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
2353
} while ((row= drizzle_row_next(&res)) && atoi(row[3]) > 1);
2356
/* Build the ORDER BY clause result */
2360
/* result (terminating \0 is already in result_length) */
2362
size_t result_length_alloc= result_length + 10;
2363
result= (char *)malloc(result_length_alloc);
2366
fprintf(stderr, _("Error: Not enough memory to store ORDER BY clause\n"));
2367
drizzle_result_free(&res);
2370
drizzle_row_seek(&res, 0);
2371
row= drizzle_row_next(&res);
2372
quoted_field= quote_name(row[4], buff, 0);
2373
end= strcpy(result, quoted_field) + strlen(quoted_field);
2374
result_length_alloc -= strlen(quoted_field);
2375
while ((row= drizzle_row_next(&res)) && atoi(row[3]) > 1)
2377
quoted_field= quote_name(row[4], buff, 0);
2378
end+= snprintf(end, result_length_alloc, ",%s",quoted_field);
2379
result_length_alloc -= strlen(quoted_field);
2383
drizzle_result_free(&res);
458
db_connection->queryNoResult("FLUSH TABLES");
459
db_connection->queryNoResult("FLUSH TABLES WITH READ LOCK");
464
static int do_unlock_tables()
466
db_connection->queryNoResult("UNLOCK TABLES");
470
static int start_transaction()
472
db_connection->queryNoResult("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
473
db_connection->queryNoResult("START TRANSACTION WITH CONSISTENT SNAPSHOT");
2387
477
int main(int argc, char **argv)