341
359
maybe_exit(error_num);
364
Prints out an error message and maybe kills the process.
368
error_num - process return value
369
fmt_reason - a format string for use by vsnprintf.
370
... - variable arguments for above fmt_reason string
373
This call prints out the formatted error message to stderr and then
374
terminates the process, unless the --force command line option is used.
376
This call should be used for non-fatal errors (such as database
377
errors) that the code may still be able to continue to the next unit
381
static void maybe_die(int error_num, const char* fmt_reason, ...)
385
va_start(args,fmt_reason);
386
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
389
fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
392
maybe_exit(error_num);
398
Sends a query to server, optionally reads result, prints error message if
402
drizzleclient_query_with_error_report()
403
drizzle_con connection to use
404
res if non zero, result will be put there with
405
drizzleclient_store_result()
406
query query to send to server
409
0 query sending and (if res!=0) result reading went ok
413
static int drizzleclient_query_with_error_report(drizzle_con_st *con,
414
drizzle_result_st *result,
415
const char *query_str,
418
drizzle_return_t ret;
420
if (drizzle_query_str(con, result, query_str, &ret) == NULL ||
421
ret != DRIZZLE_RETURN_OK)
423
if (ret == DRIZZLE_RETURN_ERROR_CODE)
425
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
426
query_str, drizzle_result_error(result),
427
drizzle_result_error_code(result));
428
drizzle_result_free(result);
432
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
433
query_str, drizzle_con_error(con), ret);
439
ret= drizzle_column_buffer(result);
441
ret= drizzle_result_buffer(result);
442
if (ret != DRIZZLE_RETURN_OK)
444
drizzle_result_free(result);
445
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
446
query_str, drizzle_con_error(con), ret);
454
Open a new .sql file to dump the table or view into
457
open_sql_file_for_table
458
name name of the table or view
461
0 Failed to open file
462
> 0 Handle of the open file
464
static FILE* open_sql_file_for_table(const char* table)
467
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
468
internal::convert_dirname(tmp_path,(char *)path.c_str(),NULL);
469
res= fopen(internal::fn_format(filename, table, tmp_path, ".sql", 4), "w");
344
475
static void free_resources(void)
346
477
if (md_result_file && md_result_file != stdout)
347
478
fclose(md_result_file);
348
479
opt_password.erase();
352
void maybe_exit(int error)
484
static void maybe_exit(int error)
354
486
if (!first_error)
355
487
first_error= error;
356
488
if (ignore_errors)
358
delete db_connection;
359
delete destination_connection;
490
drizzle_con_free(&dcon);
491
drizzle_free(&drizzle);
360
492
free_resources();
498
db_connect -- connects to the host and selects DB.
501
static int connect_to_db(string host, string user,string passwd)
503
drizzle_return_t ret;
505
verbose_msg(_("-- Connecting to %s, using protocol %s...\n"), ! host.empty() ? (char *)host.c_str() : "localhost", opt_protocol.c_str());
506
drizzle_create(&drizzle);
507
drizzle_con_create(&drizzle, &dcon);
508
drizzle_con_set_tcp(&dcon, (char *)host.c_str(), opt_drizzle_port);
509
drizzle_con_set_auth(&dcon, (char *)user.c_str(), (char *)passwd.c_str());
510
drizzle_con_add_options(&dcon, use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
511
ret= drizzle_con_connect(&dcon);
512
if (ret != DRIZZLE_RETURN_OK)
514
DB_error(NULL, ret, "when trying to connect");
519
} /* connect_to_db */
523
** dbDisconnect -- disconnects from the host.
525
static void dbDisconnect(string &host)
527
verbose_msg(_("-- Disconnecting from %s...\n"), ! host.empty() ? host.c_str() : "localhost");
528
drizzle_con_free(&dcon);
529
drizzle_free(&drizzle);
533
static void unescape(FILE *file,char *pos,uint32_t length)
537
if (!(tmp=(char*) malloc(length*2+1)))
538
die(EX_DRIZZLEERR, _("Couldn't allocate memory"));
540
drizzle_escape_string(tmp, pos, length);
550
static bool test_if_special_chars(const char *str)
552
for ( ; *str ; str++)
553
if (!my_isvar(charset_info,*str) && *str != '$')
556
} /* test_if_special_chars */
561
quote_name(name, buff, force)
563
Quotes char string, taking into account compatible mode
567
name Unquoted string containing that which will be quoted
568
buff The buffer that contains the quoted value, also returned
569
force Flag to make it ignore 'test_if_special_chars'
576
static char *quote_name(const char *name, char *buff, bool force)
581
if (!force && !opt_quoted && !test_if_special_chars(name))
597
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
601
name name of the table
602
buff quoted name of the table
605
Quote \, _, ' and % characters
607
Note: Because DRIZZLE uses the C escape syntax in strings
608
(for example, '\n' to represent newline), you must double
609
any '\' that you use in your LIKE strings. For example, to
610
search for '\n', specify it as '\\n'. To search for '\', specify
611
it as '\\\\' (the backslashes are stripped once by the parser
612
and another time when the pattern match is done, leaving a
613
single backslash to be matched).
615
Example: "t\1" => "t\\\\1"
618
static char *quote_for_like(const char *name, char *buff)
630
else if (*name == '\'' || *name == '_' || *name == '%')
641
Quote and print a string.
645
xml_file - output file
646
str - string to print
650
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
653
static void print_quoted_xml(FILE *xml_file, const char *str, uint32_t len)
657
for (end= str + len; str != end; str++)
661
fputs("<", xml_file);
664
fputs(">", xml_file);
667
fputs("&", xml_file);
670
fputs(""", xml_file);
673
fputc(*str, xml_file);
682
Print xml tag. Optionally add attribute(s).
685
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
686
..., attribute_name_n, attribute_value_n, NULL)
687
xml_file - output file
688
sbeg - line beginning
689
line_end - line ending
690
tag_name - XML tag name.
691
first_attribute_name - tag and first attribute
692
first_attribute_value - (Implied) value of first attribute
693
attribute_name_n - attribute n
694
attribute_value_n - value of attribute n
697
Print XML tag with any number of attribute="value" pairs to the xml_file.
700
sbeg<tag_name first_attribute_name="first_attribute_value" ...
701
attribute_name_n="attribute_value_n">send
703
Additional arguments must be present in attribute/value pairs.
704
The last argument should be the null character pointer.
705
All attribute_value arguments MUST be NULL terminated strings.
706
All attribute_value arguments will be quoted before output.
709
static void print_xml_tag(FILE * xml_file, const char* sbeg,
710
const char* line_end,
711
const char* tag_name,
712
const char* first_attribute_name, ...)
715
const char *attribute_name, *attribute_value;
717
fputs(sbeg, xml_file);
718
fputc('<', xml_file);
719
fputs(tag_name, xml_file);
721
va_start(arg_list, first_attribute_name);
722
attribute_name= first_attribute_name;
723
while (attribute_name != NULL)
725
attribute_value= va_arg(arg_list, char *);
726
assert(attribute_value != NULL);
728
fputc(' ', xml_file);
729
fputs(attribute_name, xml_file);
730
fputc('\"', xml_file);
732
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
733
fputc('\"', xml_file);
735
attribute_name= va_arg(arg_list, char *);
739
fputc('>', xml_file);
740
fputs(line_end, xml_file);
746
Print xml tag with for a field that is null
750
xml_file - output file
751
sbeg - line beginning
752
stag_atr - tag and attribute
753
sval - value of attribute
754
line_end - line ending
757
Print tag with one attribute to the xml_file. Format is:
758
<stag_atr="sval" xsi:nil="true"/>
760
sval MUST be a NULL terminated string.
761
sval string will be qouted before output.
764
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
765
const char* stag_atr, const char* sval,
766
const char* line_end)
768
fputs(sbeg, xml_file);
769
fputs("<", xml_file);
770
fputs(stag_atr, xml_file);
771
fputs("\"", xml_file);
772
print_quoted_xml(xml_file, sval, strlen(sval));
773
fputs("\" xsi:nil=\"true\" />", xml_file);
774
fputs(line_end, xml_file);
780
Print xml tag with many attributes.
784
xml_file - output file
785
row_name - xml tag name
786
tableRes - query result
790
Print tag with many attribute to the xml_file. Format is:
791
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
793
All atributes and values will be quoted before output.
796
static void print_xml_row(FILE *xml_file, const char *row_name,
797
drizzle_result_st *tableRes, drizzle_row_t *row)
800
drizzle_column_st *column;
801
size_t *lengths= drizzle_row_field_sizes(tableRes);
803
fprintf(xml_file, "\t\t<%s", row_name);
805
drizzle_column_seek(tableRes, 0);
806
for (i= 0; (column= drizzle_column_next(tableRes)); i++)
810
fputc(' ', xml_file);
811
print_quoted_xml(xml_file, drizzle_column_name(column),
812
strlen(drizzle_column_name(column)));
813
fputs("=\"", xml_file);
814
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
815
fputc('"', xml_file);
819
fputs(" />\n", xml_file);
825
Print hex value for blob data.
829
output_file - output file
830
str - string to print
834
Print hex value for blob data.
837
static void print_blob_as_hex(FILE *output_file, const char *str, uint32_t len)
839
/* sakaik got the idea to to provide blob's in hex notation. */
840
const char *ptr= str, *end= ptr + len;
841
for (; ptr < end ; ptr++)
842
fprintf(output_file, "%02X", *((unsigned char *)ptr));
843
check_io(output_file);
847
get_table_structure -- retrievs database structure, prints out corresponding
848
CREATE statement and fills out insert_pat if the table is the type we will
854
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
855
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
856
num_fields - number of fields in the table
859
true if success, false if error
862
static bool get_table_structure(char *table, char *db, char *table_type,
863
char *ignore_flag, uint64_t *num_fields)
865
bool init=0, delayed, write_data, complete_insert;
866
char *result_table, *opt_quoted_table;
867
const char *insert_option;
868
char name_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE+3];
869
char table_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+3];
870
char table_buff2[DRIZZLE_MAX_TABLE_SIZE*2+3];
871
char query_buff[QUERY_LENGTH];
872
FILE *sql_file= md_result_file;
873
drizzle_result_st result;
876
*ignore_flag= check_if_ignore_table(table, table_type);
878
delayed= opt_delayed;
879
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
882
verbose_msg(_("-- Warning: Unable to use delayed inserts for table '%s' "
883
"because it's of type %s\n"), table, table_type);
887
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
889
complete_insert= opt_complete_insert;
893
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
894
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
896
verbose_msg(_("-- Retrieving table structure for table %s...\n"), table);
898
result_table= quote_name(table, table_buff, 1);
899
opt_quoted_table= quote_name(table, table_buff2, 0);
901
if (opt_order_by_primary)
904
order_by= primary_key_fields(result_table);
909
/* using SHOW CREATE statement */
910
if (! opt_no_create_info)
912
/* Make an sql-file, if path was given iow. option -T was given */
913
char buff[20+FN_REFLEN];
914
const drizzle_column_st *column;
916
snprintf(buff, sizeof(buff), "show create table %s", result_table);
918
if (drizzleclient_query_with_error_report(&dcon, &result, buff, false))
923
if (!(sql_file= open_sql_file_for_table(table)))
925
drizzle_result_free(&result);
929
write_header(sql_file, db);
931
if (!opt_xml && opt_comments)
933
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
940
Even if the "table" is a view, we do a DROP TABLE here.
942
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
946
column= drizzle_column_index(&result, 0);
948
row= drizzle_row_next(&result);
950
fprintf(sql_file, "%s;\n", row[1]);
953
drizzle_result_free(&result);
956
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
959
if (drizzleclient_query_with_error_report(&dcon, &result, query_buff, false))
967
If write_data is true, then we build up insert statements for
968
the table's data. Note: in subsequent lines of code, this test
969
will have to be performed each time we are appending to
974
if (opt_replace_into)
975
insert_pat.append("REPLACE ");
977
insert_pat.append("INSERT ");
978
insert_pat.append(insert_option);
979
insert_pat.append("INTO ");
980
insert_pat.append(opt_quoted_table);
983
insert_pat.append(" (");
987
insert_pat.append(" VALUES ");
988
if (!extended_insert)
989
insert_pat.append("(");
993
while ((row= drizzle_row_next(&result)))
999
insert_pat.append(", ");
1002
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1005
*num_fields= drizzle_result_row_count(&result);
1006
drizzle_result_free(&result);
1010
verbose_msg(_("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n"),
1011
progname.c_str(), drizzle_con_error(&dcon));
1013
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1015
if (drizzleclient_query_with_error_report(&dcon, &result, query_buff, false))
1018
/* Make an sql-file, if path was given iow. option -T was given */
1019
if (! opt_no_create_info)
1023
if (!(sql_file= open_sql_file_for_table(table)))
1025
drizzle_result_free(&result);
1028
write_header(sql_file, db);
1030
if (!opt_xml && opt_comments)
1031
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1034
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
1036
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1038
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1045
if (opt_replace_into)
1046
insert_pat.append("REPLACE ");
1048
insert_pat.append("INSERT ");
1049
insert_pat.append(insert_option);
1050
insert_pat.append("INTO ");
1051
insert_pat.append(result_table);
1052
if (complete_insert)
1053
insert_pat.append(" (");
1056
insert_pat.append(" VALUES ");
1057
if (!extended_insert)
1058
insert_pat.append("(");
1062
while ((row= drizzle_row_next(&result)))
1064
size_t *lengths= drizzle_row_field_sizes(&result);
1067
if (!opt_xml && !opt_no_create_info)
1069
fputs(",\n",sql_file);
1072
if (complete_insert)
1073
insert_pat.append(", ");
1076
if (complete_insert)
1077
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1078
if (!opt_no_create_info)
1082
print_xml_row(sql_file, "field", &result, &row);
1087
fprintf(sql_file, " %s.%s %s", result_table,
1088
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
1091
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
1094
if (row[SHOW_DEFAULT])
1096
fputs(" DEFAULT ", sql_file);
1097
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
1099
if (!row[SHOW_NULL][0])
1100
fputs(" NOT NULL", sql_file);
1101
if (row[SHOW_EXTRA][0])
1102
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
1106
*num_fields= drizzle_result_row_count(&result);
1107
drizzle_result_free(&result);
1109
if (!opt_no_create_info)
1111
/* Make an sql-file, if path was given iow. option -T was given */
1112
char buff[20+FN_REFLEN];
1113
uint32_t keynr,primary_key;
1114
snprintf(buff, sizeof(buff), "show keys from %s", result_table);
1115
if (drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1117
fprintf(stderr, _("%s: Can't get keys for table %s\n"),
1118
progname.c_str(), result_table);
1124
/* Find first which key is primary key */
1126
primary_key=INT_MAX;
1127
while ((row= drizzle_row_next(&result)))
1129
if (atoi(row[3]) == 1)
1132
#ifdef FORCE_PRIMARY_KEY
1133
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
1136
if (!strcmp(row[2],"PRIMARY"))
1143
drizzle_row_seek(&result,0);
1145
while ((row= drizzle_row_next(&result)))
1149
print_xml_row(sql_file, "key", &result, &row);
1153
if (atoi(row[3]) == 1)
1156
putc(')', sql_file);
1157
if (atoi(row[1])) /* Test if duplicate key */
1158
/* Duplicate allowed */
1159
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
1160
else if (keynr == primary_key)
1161
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
1163
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
1167
putc(',', sql_file);
1168
fputs(quote_name(row[4], name_buff, 0), sql_file);
1170
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
1173
drizzle_result_free(&result);
1177
putc(')', sql_file);
1178
fputs("\n)",sql_file);
1181
/* Get DRIZZLE specific create options */
1184
char show_name_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+2+24];
1186
/* Check memory for quote_for_like() */
1187
snprintf(buff, sizeof(buff), "show table status like %s",
1188
quote_for_like(table, show_name_buff));
1190
if (!drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1192
if (!(row= drizzle_row_next(&result)))
1195
_("Error: Couldn't read status information for table %s\n"),
1201
print_xml_row(sql_file, "options", &result, &row);
1204
fputs("/*!",sql_file);
1205
print_value(sql_file,&result,row,"engine=","Engine",0);
1206
print_value(sql_file,&result,row,"","Create_options",0);
1207
print_value(sql_file,&result,row,"comment=","Comment",1);
1209
fputs(" */",sql_file);
1213
drizzle_result_free(&result);
1217
fputs(";\n", sql_file);
1219
fputs("\t</table_structure>\n", sql_file);
1223
if (complete_insert) {
1224
insert_pat.append(") VALUES ");
1225
if (!extended_insert)
1226
insert_pat.append("(");
1228
if (sql_file != md_result_file)
1230
fputs("\n", sql_file);
1231
write_footer(sql_file);
1235
} /* get_table_structure */
1237
static void add_load_option(string &str, const char *option,
1238
const string &option_value)
1240
if (option_value.empty())
1242
/* Null value means we don't add this option. */
1248
if (option_value.compare(0, 2, "0x") == 0)
1250
/* It's a hex constant, don't escape */
1251
str.append(option_value);
1255
/* char constant; escape */
1256
field_escape(str, option_value);
1262
Allow the user to specify field terminator strings like:
1263
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
1264
This is done by doubling ' and add a end -\ if needed to avoid
1265
syntax errors from the SQL parser.
1268
static void field_escape(string &in, const string &from)
1270
uint32_t end_backslashes= 0;
1274
string::const_iterator it= from.begin();
1275
while (it != from.end())
1280
end_backslashes^= 1; /* find odd number of backslashes */
1283
if (*it == '\'' && !end_backslashes)
1285
/* We want a duplicate of "'" for DRIZZLE */
1292
/* Add missing backslashes if user has specified odd number of backs.*/
1293
if (end_backslashes)
1306
dump_table saves database contents as a series of INSERT statements.
1317
static void dump_table(char *table, char *db)
1320
char table_buff[DRIZZLE_MAX_TABLE_SIZE+3];
1321
string query_string;
1322
char table_type[DRIZZLE_MAX_TABLE_SIZE];
1323
char *result_table, table_buff2[DRIZZLE_MAX_TABLE_SIZE*2+3], *opt_quoted_table;
1325
uint32_t rownr, row_break, total_length, init_length;
1326
uint64_t num_fields= 0;
1327
drizzle_return_t ret;
1328
drizzle_result_st result;
1329
drizzle_column_st *column;
1334
Make sure you get the create table info before the following check for
1335
--no-data flag below. Otherwise, the create table info won't be printed.
1337
if (!get_table_structure(table, db, table_type, &ignore_flag, &num_fields))
1339
maybe_die(EX_TABLE_STATUS, _("Error retrieving table structure for table: \"%s\""), table);
1343
/* Check --no-data flag */
1346
verbose_msg(_("-- Skipping dump data for table '%s', --no-data was used\n"),
1352
If the table type is a merge table or any type that has to be
1353
_completely_ ignored and no data dumped
1355
if (ignore_flag & IGNORE_DATA)
1357
verbose_msg(_("-- Warning: Skipping data for table '%s' because " \
1358
"it's of type %s\n"), table, table_type);
1361
/* Check that there are any fields in the table */
1362
if (num_fields == 0)
1364
verbose_msg(_("-- Skipping dump data for table '%s', it has no fields\n"),
1369
result_table= quote_name(table,table_buff, 1);
1370
opt_quoted_table= quote_name(table, table_buff2, 0);
1372
verbose_msg(_("-- Sending SELECT query...\n"));
1374
query_string.clear();
1375
query_string.reserve(1024);
1379
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1382
Convert the path to native os format
1383
and resolve to the full filepath.
1385
internal::convert_dirname(tmp_path,(char *)path.c_str(),NULL);
1386
internal::my_load_path(tmp_path, tmp_path, NULL);
1387
internal::fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
1389
/* Must delete the file that 'INTO OUTFILE' will write to */
1390
internal::my_delete(filename, MYF(0));
1392
/* now build the query string */
1394
query_string.append( "SELECT * INTO OUTFILE '");
1395
query_string.append( filename);
1396
query_string.append( "'");
1398
if (! fields_terminated.empty() || ! enclosed.empty() || ! opt_enclosed.empty() || ! escaped.empty())
1399
query_string.append( " FIELDS");
1401
add_load_option(query_string, " TERMINATED BY ", fields_terminated);
1402
add_load_option(query_string, " ENCLOSED BY ", enclosed);
1403
add_load_option(query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
1404
add_load_option(query_string, " ESCAPED BY ", escaped);
1405
add_load_option(query_string, " LINES TERMINATED BY ", lines_terminated);
1407
query_string.append(" FROM ");
1408
query_string.append(result_table);
1410
if (! where.empty())
1412
query_string.append(" WHERE ");
1413
query_string.append(where);
1418
query_string.append(" ORDER BY ");
1419
query_string.append(order_by);
1422
if (drizzle_query(&dcon, &result, query_string.c_str(),
1423
query_string.length(), &ret) == NULL ||
1424
ret != DRIZZLE_RETURN_OK)
1426
DB_error(&result, ret, _("when executing 'SELECT INTO OUTFILE'"));
1430
drizzle_result_free(&result);
1435
if (!opt_xml && opt_comments)
1437
fprintf(md_result_file,_("\n--\n-- Dumping data for table %s\n--\n"),
1439
check_io(md_result_file);
1442
query_string.append( "SELECT * FROM ");
1443
query_string.append( result_table);
1445
if (! where.empty())
1447
if (!opt_xml && opt_comments)
1449
fprintf(md_result_file, "-- WHERE: %s\n", where.c_str());
1450
check_io(md_result_file);
1453
query_string.append( " WHERE ");
1454
query_string.append( (char *)where.c_str());
1458
if (!opt_xml && opt_comments)
1460
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
1461
check_io(md_result_file);
1463
query_string.append( " ORDER BY ");
1464
query_string.append( order_by);
1467
if (!opt_xml && !opt_compact)
1469
fputs("\n", md_result_file);
1470
check_io(md_result_file);
1472
if (drizzleclient_query_with_error_report(&dcon, &result,
1473
query_string.c_str(), quick))
1478
verbose_msg(_("-- Retrieving rows...\n"));
1479
if (drizzle_result_column_count(&result) != num_fields)
1481
fprintf(stderr,_("%s: Error in field count for table: %s ! Aborting.\n"),
1482
progname.c_str(), result_table);
1483
error= EX_CONSCHECK;
1484
drizzle_result_free(&result);
1488
/* Moved disable keys to after lock per bug 15977 */
1489
if (opt_disable_keys)
1491
fprintf(md_result_file, "ALTER TABLE %s DISABLE KEYS;\n",
1493
check_io(md_result_file);
1496
total_length= DRIZZLE_MAX_LINE_LENGTH; /* Force row break */
1499
init_length=(uint32_t) insert_pat.length()+4;
1501
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
1505
fprintf(md_result_file, "set autocommit=0;\n");
1506
check_io(md_result_file);
1519
drizzle_row_free(&result, row);
1521
row= drizzle_row_buffer(&result, &ret);
1522
if (ret != DRIZZLE_RETURN_OK)
1525
_("%s: Error reading rows for table: %s (%d:%s) ! Aborting.\n"),
1526
progname.c_str(), result_table, ret, drizzle_con_error(&dcon));
1527
drizzle_result_free(&result);
1532
row= drizzle_row_next(&result);
1537
lengths= drizzle_row_field_sizes(&result);
1540
if ((rownr % show_progress_size) == 0)
1542
verbose_msg(_("-- %"PRIu32" of ~%"PRIu64" rows dumped for table %s\n"), rownr, total_rows, opt_quoted_table);
1544
if (!extended_insert && !opt_xml)
1546
fputs(insert_pat.c_str(),md_result_file);
1547
check_io(md_result_file);
1549
drizzle_column_seek(&result,0);
1553
fputs("\t<row>\n", md_result_file);
1554
check_io(md_result_file);
1557
for (i= 0; i < drizzle_result_column_count(&result); i++)
1560
uint32_t length= lengths[i];
1562
if (!(column= drizzle_column_next(&result)))
1564
_("Not enough fields from table %s! Aborting.\n"),
1568
63 is my_charset_bin. If charsetnr is not 63,
1569
we have not a BLOB but a TEXT column.
1570
we'll dump in hex only BLOB columns.
1572
is_blob= (opt_hex_blob && drizzle_column_charset(column) == 63 &&
1573
(drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_VARCHAR ||
1574
drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_BLOB)) ? 1 : 0;
1575
if (extended_insert && !opt_xml)
1579
extended_row.clear();
1580
extended_row.append("(");
1583
extended_row.append(",");
1589
if (!(drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NUM))
1592
"length * 2 + 2" is OK for both HEX and non-HEX modes:
1593
- In HEX mode we need exactly 2 bytes per character
1594
plus 2 bytes for '0x' prefix.
1595
- In non-HEX mode we need up to 2 bytes per character,
1596
plus 2 bytes for leading and trailing '\'' characters.
1597
Also we need to reserve 1 byte for terminating '\0'.
1599
char * tmp_str= (char *)malloc(length * 2 + 2 + 1);
1600
memset(tmp_str, '\0', length * 2 + 2 + 1);
1601
if (opt_hex_blob && is_blob)
1603
extended_row.append("0x");
1604
drizzle_hex_string(tmp_str, row[i], length);
1605
extended_row.append(tmp_str);
1609
extended_row.append("'");
1610
drizzle_escape_string(tmp_str, row[i],length);
1611
extended_row.append(tmp_str);
1612
extended_row.append("'");
1618
/* change any strings ("inf", "-inf", "nan") into NULL */
1620
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
1621
my_isalpha(charset_info, ptr[1])))
1622
extended_row.append( "NULL");
1625
extended_row.append( ptr);
1630
extended_row.append("''");
1633
extended_row.append("NULL");
1639
fputc(',', md_result_file);
1640
check_io(md_result_file);
1644
if (!(drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NUM))
1648
if (opt_hex_blob && is_blob && length)
1650
/* Define xsi:type="xs:hexBinary" for hex encoded data */
1651
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
1652
drizzle_column_name(column), "xsi:type=", "xs:hexBinary", NULL);
1653
print_blob_as_hex(md_result_file, row[i], length);
1657
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
1658
drizzle_column_name(column), NULL);
1659
print_quoted_xml(md_result_file, row[i], length);
1661
fputs("</field>\n", md_result_file);
1663
else if (opt_hex_blob && is_blob && length)
1665
fputs("0x", md_result_file);
1666
print_blob_as_hex(md_result_file, row[i], length);
1669
unescape(md_result_file, row[i], length);
1673
/* change any strings ("inf", "-inf", "nan") into NULL */
1677
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
1678
drizzle_column_name(column), NULL);
1679
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
1681
fputs("</field>\n", md_result_file);
1683
else if (my_isalpha(charset_info, *ptr) ||
1684
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
1685
fputs("NULL", md_result_file);
1687
fputs(ptr, md_result_file);
1692
/* The field value is NULL */
1694
fputs("NULL", md_result_file);
1696
print_xml_null_tag(md_result_file, "\t\t", "field name=",
1697
drizzle_column_name(column), "\n");
1699
check_io(md_result_file);
1705
fputs("\t</row>\n", md_result_file);
1706
check_io(md_result_file);
1709
if (extended_insert)
1711
uint32_t row_length;
1712
extended_row.append(")");
1713
row_length= 2 + extended_row.length();
1714
if (total_length + row_length < DRIZZLE_MAX_LINE_LENGTH)
1716
total_length+= row_length;
1717
fputc(',',md_result_file); /* Always row break */
1718
fputs(extended_row.c_str(),md_result_file);
1723
fputs(";\n", md_result_file);
1724
row_break=1; /* This is first row */
1726
fputs(insert_pat.c_str(),md_result_file);
1727
fputs(extended_row.c_str(),md_result_file);
1728
total_length= row_length+init_length;
1730
check_io(md_result_file);
1734
fputs(");\n", md_result_file);
1735
check_io(md_result_file);
1739
/* XML - close table tag and supress regular output */
1741
fputs("\t</table_data>\n", md_result_file);
1742
else if (extended_insert && row_break)
1743
fputs(";\n", md_result_file); /* If not empty table */
1744
fflush(md_result_file);
1745
check_io(md_result_file);
1747
/* Moved enable keys to before unlock per bug 15977 */
1748
if (opt_disable_keys)
1750
fprintf(md_result_file,"ALTER TABLE %s ENABLE KEYS;\n",
1752
check_io(md_result_file);
1756
fprintf(md_result_file, "commit;\n");
1757
check_io(md_result_file);
1759
drizzle_result_free(&result);
1769
static char *getTableName(int reset)
1771
static drizzle_result_st result;
1772
static bool have_result= false;
1777
if (drizzleclient_query_with_error_report(&dcon, &result, "SHOW TABLES", false))
1782
if ((row= drizzle_row_next(&result)))
1786
drizzle_row_seek(&result, 0);
1789
drizzle_result_free(&result);
1793
} /* getTableName */
364
1796
static int dump_all_databases()
366
1798
drizzle_row_t row;
367
drizzle_result_st *tableres;
1799
drizzle_result_st tableres;
370
DrizzleDumpDatabase *database;
373
std::cerr << _("-- Retrieving database structures...") << std::endl;
375
/* Blocking the MySQL privilege tables too because we can't import them due to bug#646187 */
376
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
377
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql')";
379
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM DATA_DICTIONARY.SCHEMAS WHERE SCHEMA_NAME NOT IN ('information_schema','data_dictionary')";
381
tableres= db_connection->query(query);
382
while ((row= drizzle_row_next(tableres)))
1802
if (drizzleclient_query_with_error_report(&dcon, &tableres, "SHOW DATABASES", false))
1804
while ((row= drizzle_row_next(&tableres)))
384
std::string database_name(row[0]);
385
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
386
database= new DrizzleDumpDatabaseMySQL(database_name, db_connection);
388
database= new DrizzleDumpDatabaseDrizzle(database_name, db_connection);
390
database->setCollate(row[1]);
391
database_store.push_back(database);
1806
if (dump_all_tables_in_db(row[0]))
393
db_connection->freeResult(tableres);
1809
drizzle_result_free(&tableres);
396
1812
/* dump_all_databases */
403
DrizzleDumpDatabase *database;
405
1819
for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
408
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
409
database= new DrizzleDumpDatabaseMySQL(temp, db_connection);
411
database= new DrizzleDumpDatabaseDrizzle(temp, db_connection);
412
database_store.push_back(database);
1822
if (dump_all_tables_in_db((char *)temp.c_str()))
415
1826
} /* dump_databases */
1830
Table Specific database initalization.
1834
qdatabase quoted name of the database
1841
int init_dumping_tables(char *qdatabase)
1847
drizzle_result_st result;
1848
drizzle_return_t ret;
1850
snprintf(qbuf, sizeof(qbuf),
1851
"SHOW CREATE DATABASE IF NOT EXISTS %s",
1854
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
1855
ret != DRIZZLE_RETURN_OK)
1857
if (ret == DRIZZLE_RETURN_ERROR_CODE)
1858
drizzle_result_free(&result);
1860
/* Old server version, dump generic CREATE DATABASE */
1861
if (opt_drop_database)
1862
fprintf(md_result_file,
1863
"\nDROP DATABASE IF EXISTS %s;\n",
1865
fprintf(md_result_file,
1866
"\nCREATE DATABASE IF NOT EXISTS %s;\n",
1871
if (drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
1873
if (opt_drop_database)
1874
fprintf(md_result_file,
1875
"\nDROP DATABASE IF EXISTS %s;\n",
1877
row = drizzle_row_next(&result);
1878
if (row != NULL && row[1])
1880
fprintf(md_result_file,"\n%s;\n",row[1]);
1883
drizzle_result_free(&result);
1887
} /* init_dumping_tables */
1890
static int init_dumping(char *database, int init_func(char*))
1892
drizzle_result_st result;
1893
drizzle_return_t ret;
1896
/* If this DB contains non-standard tables we don't want it */
1898
snprintf(qbuf, sizeof(qbuf), "SELECT TABLE_NAME FROM DATA_DICTIONARY.TABLES WHERE TABLE_SCHEMA='%s' AND TABLE_TYPE != 'STANDARD'", database);
1900
if (drizzle_query_str(&dcon, &result, qbuf, &ret) != NULL)
1902
drizzle_result_buffer(&result);
1903
if (drizzle_result_row_count(&result) > 0)
1905
drizzle_result_free(&result);
1910
drizzle_result_free(&result);
1912
if (drizzle_select_db(&dcon, &result, database, &ret) == NULL ||
1913
ret != DRIZZLE_RETURN_OK)
1915
DB_error(&result, ret, _("when executing 'SELECT INTO OUTFILE'"));
1916
return 1; /* If --force */
1918
drizzle_result_free(&result);
1920
if (path.empty() && !opt_xml)
1922
if (opt_databases || opt_alldbs)
1925
length of table name * 2 (if name contains quotes), 2 quotes and 0
1927
char quoted_database_buf[DRIZZLE_MAX_DB_SIZE*2+3];
1928
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
1931
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
1932
check_io(md_result_file);
1935
/* Call the view or table specific function */
1936
init_func(qdatabase);
1938
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
1939
check_io(md_result_file);
1942
if (extended_insert)
1943
extended_row.clear();
1945
} /* init_dumping */
1948
/* Return 1 if we should copy the table */
1950
static bool include_table(const char *hash_key, size_t key_size)
1952
string match(hash_key, key_size);
1953
boost::unordered_set<string>::iterator iter= ignore_table.find(match);
1954
return (iter == ignore_table.end());
1958
static int dump_all_tables_in_db(char *database)
1961
char hash_key[DRIZZLE_MAX_DB_SIZE+DRIZZLE_MAX_TABLE_SIZE+2]; /* "db.tablename" */
1963
drizzle_result_st result;
1964
drizzle_return_t ret;
1966
memset(hash_key, 0, DRIZZLE_MAX_DB_SIZE+DRIZZLE_MAX_TABLE_SIZE+2);
1967
afterdot= strcpy(hash_key, database) + strlen(database);
1970
if (init_dumping(database, init_dumping_tables))
1973
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NULL);
1976
if (drizzle_query_str(&dcon, &result, "FLUSH LOGS", &ret) == NULL ||
1977
ret != DRIZZLE_RETURN_OK)
1979
DB_error(&result, ret, _("when doing refresh"));
1980
/* We shall continue here, if --force was given */
1983
drizzle_result_free(&result);
1985
while ((table= getTableName(0)))
1987
char *end= strcpy(afterdot, table) + strlen(table);
1988
if (include_table(hash_key, end - hash_key))
1990
dump_table(table,database);
1997
fputs("</database>\n", md_result_file);
1998
check_io(md_result_file);
2002
} /* dump_all_tables_in_db */
2006
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
2007
table name from the server for the table name given on the command line.
2008
we do this because the table name given on the command line may be a
2009
different case (e.g. T1 vs t1)
2012
pointer to the table name
2016
static char *get_actual_table_name(const char *old_table_name,
2017
drizzled::memory::Root *root)
2020
drizzle_result_st result;
2022
char query[50 + 2*DRIZZLE_MAX_TABLE_SIZE];
2023
char show_name_buff[FN_REFLEN];
2027
/* Check memory for quote_for_like() */
2028
assert(2*sizeof(old_table_name) < sizeof(show_name_buff));
2029
snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
2030
quote_for_like(old_table_name, show_name_buff));
2032
if (drizzleclient_query_with_error_report(&dcon, &result, query, false))
2035
num_rows= drizzle_result_row_count(&result);
2041
TODO-> Return all matching rows
2043
row= drizzle_row_next(&result);
2044
lengths= drizzle_row_field_sizes(&result);
2045
name= root->strmake_root(row[0], lengths[0]);
2047
drizzle_result_free(&result);
417
2053
static int dump_selected_tables(const string &db, const vector<string> &table_names)
419
DrizzleDumpDatabase *database;
421
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
422
database= new DrizzleDumpDatabaseMySQL(db, db_connection);
424
database= new DrizzleDumpDatabaseDrizzle(db, db_connection);
426
if (not database->populateTables(table_names))
429
if (not ignore_errors)
430
maybe_exit(EX_DRIZZLEERR);
433
database_store.push_back(database);
2055
drizzled::memory::Root root;
2056
char **dump_tables, **pos, **end;
2057
drizzle_result_st result;
2058
drizzle_return_t ret;
2061
if (init_dumping((char *)db.c_str(), init_dumping_tables))
2064
root.init_alloc_root(8192);
2065
if (!(dump_tables= pos= (char**) root.alloc_root(table_names.size() * sizeof(char *))))
2066
die(EX_EOM, _("alloc_root failure."));
2068
for (vector<string>::const_iterator it= table_names.begin(); it != table_names.end(); ++it)
2071
/* the table name passed on commandline may be wrong case */
2072
if ((*pos= get_actual_table_name(temp.c_str(), &root)))
2080
root.free_root(MYF(0));
2082
maybe_die(EX_ILLEGAL_TABLE, _("Couldn't find table: \"%s\""),(char *) temp.c_str());
2083
/* We shall countinue here, if --force was given */
2090
if (drizzle_query_str(&dcon, &result, "FLUSH LOGS", &ret) == NULL ||
2091
ret != DRIZZLE_RETURN_OK)
2094
root.free_root(MYF(0));
2095
DB_error(&result, ret, _("when doing refresh"));
2096
/* We shall countinue here, if --force was given */
2099
drizzle_result_free(&result);
2102
print_xml_tag(md_result_file, "", "\n", "database", "name=", (char *)db.c_str(), NULL);
2104
/* Dump each selected table */
2105
for (pos= dump_tables; pos < end; pos++)
2106
dump_table(*pos, (char *)db.c_str());
2108
root.free_root(MYF(0));
2113
fputs("</database>\n", md_result_file);
2114
check_io(md_result_file);
436
2117
} /* dump_selected_tables */
438
static int do_flush_tables_read_lock()
2119
static int do_flush_tables_read_lock(drizzle_con_st *drizzle_con)
441
2122
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
445
2126
and most client connections are stalled. Of course, if a second long
446
2127
update starts between the two FLUSHes, we have that bad stall.
449
db_connection->queryNoResult("FLUSH TABLES");
450
db_connection->queryNoResult("FLUSH TABLES WITH READ LOCK");
455
static int do_unlock_tables()
457
db_connection->queryNoResult("UNLOCK TABLES");
461
static int start_transaction()
463
db_connection->queryNoResult("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
464
db_connection->queryNoResult("START TRANSACTION WITH CONSISTENT SNAPSHOT");
2130
( drizzleclient_query_with_error_report(drizzle_con, 0, "FLUSH TABLES", false) ||
2131
drizzleclient_query_with_error_report(drizzle_con, 0,
2132
"FLUSH TABLES WITH READ LOCK", false) );
2135
static int do_unlock_tables(drizzle_con_st *drizzle_con)
2137
return drizzleclient_query_with_error_report(drizzle_con, 0, "UNLOCK TABLES", false);
2140
static int start_transaction(drizzle_con_st *drizzle_con)
2142
return (drizzleclient_query_with_error_report(drizzle_con, 0,
2143
"SET SESSION TRANSACTION ISOLATION "
2144
"LEVEL REPEATABLE READ", false) ||
2145
drizzleclient_query_with_error_report(drizzle_con, 0,
2146
"START TRANSACTION "
2147
"WITH CONSISTENT SNAPSHOT", false));
2151
/* Print a value with a prefix on file */
2152
static void print_value(FILE *file, drizzle_result_st *result, drizzle_row_t row,
2153
const char *prefix, const char *name,
2156
drizzle_column_st *column;
2157
drizzle_column_seek(result, 0);
2159
for ( ; (column= drizzle_column_next(result)) ; row++)
2161
if (!strcmp(drizzle_column_name(column),name))
2163
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
2166
fputs(prefix, file);
2168
unescape(file,row[0],(uint32_t) strlen(row[0]));
2170
fputs(row[0], file);
2176
return; /* This shouldn't happen */
2180
* Fetches a row from a result based on a field name
2181
* Returns const char* of the data in that row or NULL if not found
2184
static const char* fetch_named_row(drizzle_result_st *result, drizzle_row_t row, const char *name)
2186
drizzle_column_st *column;
2187
drizzle_column_seek(result, 0);
2189
for ( ; (column= drizzle_column_next(result)) ; row++)
2191
if (!strcmp(drizzle_column_name(column),name))
2193
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
2195
drizzle_column_seek(result, 0);
2200
drizzle_column_seek(result, 0);
2208
Check if we the table is one of the table types that should be ignored:
2209
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
2210
If the table should be altogether ignored, it returns a true, false if it
2211
should not be ignored. If the user has selected to use INSERT DELAYED, it
2212
sets the value of the bool pointer supports_delayed_inserts to 0 if not
2213
supported, 1 if it is supported.
2217
check_if_ignore_table()
2218
table_name Table name to check
2219
table_type Type of table
2222
drizzle Drizzle connection
2223
verbose Write warning messages
2226
char (bit value) See IGNORE_ values at top
2229
char check_if_ignore_table(const char *table_name, char *table_type)
2231
char result= IGNORE_NONE;
2232
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
2233
const char *number_of_rows= NULL;
2234
drizzle_result_st res;
2237
/* Check memory for quote_for_like() */
2238
assert(2*sizeof(table_name) < sizeof(show_name_buff));
2239
snprintf(buff, sizeof(buff), "show table status like %s",
2240
quote_for_like(table_name, show_name_buff));
2241
if (drizzleclient_query_with_error_report(&dcon, &res, buff, false))
2245
if (!(row= drizzle_row_next(&res)))
2248
_("Error: Couldn't read status information for table %s\n"),
2250
drizzle_result_free(&res);
2251
return(result); /* assume table is ok */
2255
if ((number_of_rows= fetch_named_row(&res, row, "Rows")) != NULL)
2257
total_rows= strtoul(number_of_rows, NULL, 10);
2261
If the table type matches any of these, we do support delayed inserts.
2262
Note-> we do not want to skip dumping this table if if is not one of
2263
these types, but we do want to use delayed inserts in the dump if
2264
the table type is _NOT_ one of these types
2267
strncpy(table_type, row[1], DRIZZLE_MAX_TABLE_SIZE-1);
2270
if (strcmp(table_type,"MyISAM") &&
2271
strcmp(table_type,"ARCHIVE") &&
2272
strcmp(table_type,"HEAP") &&
2273
strcmp(table_type,"MEMORY"))
2274
result= IGNORE_INSERT_DELAYED;
2277
drizzle_result_free(&res);
2283
Get string of comma-separated primary key field names
2286
char *primary_key_fields(const char *table_name)
2287
RETURNS pointer to allocated buffer (must be freed by caller)
2288
table_name quoted table name
2291
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
2292
field names, and then build that string and return the pointer
2295
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
2296
or if there is some failure. It is better to continue to dump
2297
the table unsorted, rather than exit without dumping the data.
2300
static char *primary_key_fields(const char *table_name)
2302
drizzle_result_st res;
2303
drizzle_return_t ret;
2305
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
2306
char show_keys_buff[15 + DRIZZLE_MAX_TABLE_SIZE * 2 + 3];
2307
uint32_t result_length= 0;
2309
char buff[DRIZZLE_MAX_TABLE_SIZE * 2 + 3];
2312
snprintf(show_keys_buff, sizeof(show_keys_buff),
2313
"SHOW KEYS FROM %s", table_name);
2314
if (drizzle_query_str(&dcon, &res, show_keys_buff, &ret) == NULL ||
2315
ret != DRIZZLE_RETURN_OK)
2317
if (ret == DRIZZLE_RETURN_ERROR_CODE)
2319
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2320
" records are NOT sorted (%s)\n"),
2321
table_name, drizzle_result_error(&res));
2322
drizzle_result_free(&res);
2326
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2327
" records are NOT sorted (%s)\n"),
2328
table_name, drizzle_con_error(&dcon));
2334
if (drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
2336
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2337
" records are NOT sorted (%s)\n"),
2338
table_name, drizzle_con_error(&dcon));
2343
* Figure out the length of the ORDER BY clause result.
2344
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
2345
* row, and UNIQUE keys come before others. So we only need to check
2346
* the first key, not all keys.
2348
if ((row= drizzle_row_next(&res)) && atoi(row[1]) == 0)
2353
quoted_field= quote_name(row[4], buff, 0);
2354
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
2355
} while ((row= drizzle_row_next(&res)) && atoi(row[3]) > 1);
2358
/* Build the ORDER BY clause result */
2362
/* result (terminating \0 is already in result_length) */
2364
size_t result_length_alloc= result_length + 10;
2365
result= (char *)malloc(result_length_alloc);
2368
fprintf(stderr, _("Error: Not enough memory to store ORDER BY clause\n"));
2369
drizzle_result_free(&res);
2372
drizzle_row_seek(&res, 0);
2373
row= drizzle_row_next(&res);
2374
quoted_field= quote_name(row[4], buff, 0);
2375
end= strcpy(result, quoted_field) + strlen(quoted_field);
2376
result_length_alloc -= strlen(quoted_field);
2377
while ((row= drizzle_row_next(&res)) && atoi(row[3]) > 1)
2379
quoted_field= quote_name(row[4], buff, 0);
2380
end+= snprintf(end, result_length_alloc, ",%s",quoted_field);
2381
result_length_alloc -= strlen(quoted_field);
2385
drizzle_result_free(&res);
468
2389
int main(int argc, char **argv)
474
#if defined(ENABLE_NLS)
475
# if defined(HAVE_LOCALE_H)
476
setlocale(LC_ALL, "");
478
bindtextdomain("drizzle7", LOCALEDIR);
479
textdomain("drizzle7");
482
po::options_description commandline_options(_("Options used only in command line"));
2394
drizzle_result_st result;
2396
po::options_description commandline_options(N_("Options used only in command line"));
483
2397
commandline_options.add_options()
484
2398
("all-databases,A", po::value<bool>(&opt_alldbs)->default_value(false)->zero_tokens(),
485
_("Dump all the databases. This will be same as --databases with all databases selected."))
2399
N_("Dump all the databases. This will be same as --databases with all databases selected."))
486
2400
("all-tablespaces,Y", po::value<bool>(&opt_alltspcs)->default_value(false)->zero_tokens(),
487
_("Dump all the tablespaces."))
2401
N_("Dump all the tablespaces."))
488
2402
("complete-insert,c", po::value<bool>(&opt_complete_insert)->default_value(false)->zero_tokens(),
489
_("Use complete insert statements."))
2403
N_("Use complete insert statements."))
2404
("compress,C", po::value<bool>(&opt_compress)->default_value(false)->zero_tokens(),
2405
N_("Use compression in server/client protocol."))
490
2406
("flush-logs,F", po::value<bool>(&flush_logs)->default_value(false)->zero_tokens(),
491
_("Flush logs file in server before starting dump. Note that if you dump many databases at once (using the option --databases= or --all-databases), the logs will be flushed for each database dumped. The exception is when using --lock-all-tables in this case the logs will be flushed only once, corresponding to the moment all tables are locked. So if you want your dump and the log flush to happen at the same exact moment you should use --lock-all-tables or --flush-logs"))
2407
N_("Flush logs file in server before starting dump. Note that if you dump many databases at once (using the option --databases= or --all-databases), the logs will be flushed for each database dumped. The exception is when using --lock-all-tables in this case the logs will be flushed only once, corresponding to the moment all tables are locked. So if you want your dump and the log flush to happen at the same exact moment you should use --lock-all-tables or --flush-logs"))
492
2408
("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
493
_("Continue even if we get an sql-error."))
494
("help,?", _("Display this help message and exit."))
2409
N_("Continue even if we get an sql-error."))
2410
("help,?", N_("Display this help message and exit."))
495
2411
("lock-all-tables,x", po::value<bool>(&opt_lock_all_tables)->default_value(false)->zero_tokens(),
496
_("Locks all tables across all databases. This is achieved by taking a global read lock for the duration of the whole dump. Automatically turns --single-transaction off."))
2412
N_("Locks all tables across all databases. This is achieved by taking a global read lock for the duration of the whole dump. Automatically turns --single-transaction and --lock-tables off."))
2413
("order-by-primary", po::value<bool>(&opt_order_by_primary)->default_value(false)->zero_tokens(),
2414
N_("Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer."))
497
2415
("single-transaction", po::value<bool>(&opt_single_transaction)->default_value(false)->zero_tokens(),
498
_("Creates a consistent snapshot by dumping all tables in a single transaction. Works ONLY for tables stored in storage engines which support multiversioning (currently only InnoDB does); the dump is NOT guaranteed to be consistent for other storage engines. While a --single-transaction dump is in process, to ensure a valid dump file (correct table contents), no other connection should use the following statements: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not isolated from them."))
2416
N_("Creates a consistent snapshot by dumping all tables in a single transaction. Works ONLY for tables stored in storage engines which support multiversioning (currently only InnoDB does); the dump is NOT guaranteed to be consistent for other storage engines. While a --single-transaction dump is in process, to ensure a valid dump file (correct table contents), no other connection should use the following statements: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not isolated from them. Option automatically turns off --lock-tables."))
2417
("opt", N_("Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt."))
500
_("Disable --opt. Disables --add-drop-table, --add-locks, --create-options, ---extended-insert and --disable-keys."))
501
("tables", _("Overrides option --databases (-B)."))
2419
N_("Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys."))
2420
("tables", N_("Overrides option --databases (-B)."))
502
2421
("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(10000),
503
_("Number of rows before each output progress report (requires --verbose)."))
2422
N_("Number of rows before each output progress report (requires --verbose)."))
504
2423
("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
505
_("Print info about the various stages."))
506
("version,V", _("Output version information and exit."))
507
("skip-comments", _("Turn off Comments"))
508
("skip-create", _("Turn off create-options"))
509
("skip-extended-insert", _("Turn off extended-insert"))
510
("skip-dump-date", _( "Turn off dump date at the end of the output"))
511
("no-defaults", _("Do not read from the configuration files"))
2424
N_("Print info about the various stages."))
2425
("version,V", N_("Output version information and exit."))
2426
("xml,X", N_("Dump a database as well formed XML."))
2427
("skip-comments", N_("Turn off Comments"))
2428
("skip-create", N_("Turn off create-options"))
2429
("skip-extended-insert", N_("Turn off extended-insert"))
2430
("skip-dump-date",N_( "Turn off dump-date"))
2431
("no-defaults", N_("Do not read from the configuration files"))
514
po::options_description dump_options(_("Options specific to the drizzle client"));
2434
po::options_description dump_options(N_("Options specific to the drizzle client"));
515
2435
dump_options.add_options()
516
2436
("add-drop-database", po::value<bool>(&opt_drop_database)->default_value(false)->zero_tokens(),
517
_("Add a 'DROP DATABASE' before each create."))
518
("skip-drop-table", _("Do not add a 'drop table' before each create."))
2437
N_("Add a 'DROP DATABASE' before each create."))
2438
("add-drop-table", po::value<bool>(&opt_drop)->default_value(true)->zero_tokens(),
2439
N_("Add a 'drop table' before each create."))
2440
("allow-keywords", po::value<bool>(&opt_keywords)->default_value(false)->zero_tokens(),
2441
N_("Allow creation of column names that are keywords."))
2442
("comments,i", po::value<bool>(&opt_comments)->default_value(true)->zero_tokens(),
2443
N_("Write additional information."))
519
2444
("compact", po::value<bool>(&opt_compact)->default_value(false)->zero_tokens(),
520
_("Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys"))
2445
N_("Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys --skip-add-locks"))
2446
("create-options", po::value<bool>(&create_options)->default_value(true)->zero_tokens(),
2447
N_("Include all DRIZZLE specific create options."))
2448
("dump-date", po::value<bool>(&opt_dump_date)->default_value(true)->zero_tokens(),
2449
N_("Put a dump date to the end of the output."))
521
2450
("databases,B", po::value<bool>(&opt_databases)->default_value(false)->zero_tokens(),
522
_("To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output."))
523
("skip-disable-keys,K",
524
_("'ALTER TABLE tb_name DISABLE KEYS;' and 'ALTER TABLE tb_name ENABLE KEYS;' will not be put in the output."))
2451
N_("To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output."))
2452
("delayed-insert", po::value<bool>(&opt_delayed)->default_value(false)->zero_tokens(),
2453
N_("Insert rows with INSERT DELAYED;"))
2454
("disable-keys,K", po::value<bool>(&opt_disable_keys)->default_value(true)->zero_tokens(),
2455
N_("'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will be put in the output."))
2456
("extended-insert,e", po::value<bool>(&extended_insert)->default_value(true)->zero_tokens(),
2457
N_("Allows utilization of the new, much faster INSERT syntax."))
2458
("fields-terminated-by", po::value<string>(&fields_terminated)->default_value(""),
2459
N_("Fields in the textfile are terminated by ..."))
2460
("fields-enclosed-by", po::value<string>(&enclosed)->default_value(""),
2461
N_("Fields in the importfile are enclosed by ..."))
2462
("fields-optionally-enclosed-by", po::value<string>(&opt_enclosed)->default_value(""),
2463
N_("Fields in the i.file are opt. enclosed by ..."))
2464
("fields-escaped-by", po::value<string>(&escaped)->default_value(""),
2465
N_("Fields in the i.file are escaped by ..."))
2466
("hex-blob", po::value<bool>(&opt_hex_blob)->default_value(false)->zero_tokens(),
2467
"Dump binary strings (BINARY, VARBINARY, BLOB) in hexadecimal format.")
525
2468
("ignore-table", po::value<string>(),
526
_("Do not dump the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. Each table must be specified with both database and table names, e.g. --ignore-table=database.table"))
2469
N_("Do not dump the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. Each table must be specified with both database and table names, e.g. --ignore-table=database.table"))
527
2470
("insert-ignore", po::value<bool>(&opt_ignore)->default_value(false)->zero_tokens(),
528
_("Insert rows with INSERT IGNORE."))
2471
N_("Insert rows with INSERT IGNORE."))
2472
("lines-terminated-by", po::value<string>(&lines_terminated)->default_value(""),
2473
N_("Lines in the i.file are terminated by ..."))
529
2474
("no-autocommit", po::value<bool>(&opt_autocommit)->default_value(false)->zero_tokens(),
530
_("Wrap a table's data in START TRANSACTION/COMMIT statements."))
2475
N_("Wrap tables with autocommit/commit statements."))
531
2476
("no-create-db,n", po::value<bool>(&opt_create_db)->default_value(false)->zero_tokens(),
532
_("'CREATE DATABASE IF NOT EXISTS db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given."))
2477
N_("'CREATE DATABASE IF NOT EXISTS db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given."))
2478
("no-create-info,t", po::value<bool>(&opt_no_create_info)->default_value(false)->zero_tokens(),
2479
N_("Don't write table creation info."))
533
2480
("no-data,d", po::value<bool>(&opt_no_data)->default_value(false)->zero_tokens(),
534
_("No row information."))
2481
N_("No row information."))
2482
("no-set-names,N", N_("Deprecated. Use --skip-set-charset instead."))
2483
("set-charset", po::value<bool>(&opt_set_charset)->default_value(false)->zero_tokens(),
2484
N_("Enable set-name"))
2485
("quick,q", po::value<bool>(&quick)->default_value(true)->zero_tokens(),
2486
N_("Don't buffer query, dump directly to stdout."))
2487
("quote-names,Q", po::value<bool>(&opt_quoted)->default_value(true)->zero_tokens(),
2488
N_("Quote table and column names with backticks (`)."))
535
2489
("replace", po::value<bool>(&opt_replace_into)->default_value(false)->zero_tokens(),
536
_("Use REPLACE INTO instead of INSERT INTO."))
537
("destination-type", po::value<string>()->default_value("stdout"),
538
_("Where to send output to (stdout|database"))
539
("destination-host", po::value<string>(&opt_destination_host)->default_value("localhost"),
540
_("Hostname for destination db server (requires --destination-type=database)"))
541
("destination-port", po::value<uint16_t>(&opt_destination_port)->default_value(4427),
542
_("Port number for destination db server (requires --destination-type=database)"))
543
("destination-user", po::value<string>(&opt_destination_user),
544
_("User name for destination db server (resquires --destination-type=database)"))
545
("destination-password", po::value<string>(&opt_destination_password),
546
_("Password for destination db server (requires --destination-type=database)"))
547
("destination-database", po::value<string>(&opt_destination_database),
548
_("The database in the destination db server (requires --destination-type=database, not for use with --all-databases)"))
549
("my-data-is-mangled", po::value<bool>(&opt_data_is_mangled)->default_value(false)->zero_tokens(),
550
_("Do not make a UTF8 connection to MySQL, use if you have UTF8 data in a non-UTF8 table"))
2490
N_("Use REPLACE INTO instead of INSERT INTO."))
2491
("result-file,r", po::value<string>(),
2492
N_("Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed)."))
2493
("tab,T", po::value<string>(&path)->default_value(""),
2494
N_("Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if drizzledump is run on the same machine as the drizzled daemon."))
2495
("where,w", po::value<string>(&where)->default_value(""),
2496
N_("Dump only selected records; QUOTES mandatory!"))
553
po::options_description client_options(_("Options specific to the client"));
2499
po::options_description client_options(N_("Options specific to the client"));
554
2500
client_options.add_options()
555
2501
("host,h", po::value<string>(¤t_host)->default_value("localhost"),
556
_("Connect to host."))
2502
N_("Connect to host."))
557
2503
("password,P", po::value<string>(&password)->default_value(PASSWORD_SENTINEL),
558
_("Password to use when connecting to server. If password is not given it's solicited on the tty."))
2504
N_("Password to use when connecting to server. If password is not given it's solicited on the tty."))
559
2505
("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
560
_("Port number to use for connection."))
2506
N_("Port number to use for connection."))
561
2507
("user,u", po::value<string>(¤t_user)->default_value(""),
562
_("User for login if not current user."))
2508
N_("User for login if not current user."))
563
2509
("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
564
_("The protocol of connection (mysql or drizzle)."))
2510
N_("The protocol of connection (mysql or drizzle)."))
567
po::options_description hidden_options(_("Hidden Options"));
2513
po::options_description hidden_options(N_("Hidden Options"));
568
2514
hidden_options.add_options()
569
("database-used", po::value<vector<string> >(), _("Used to select the database"))
570
("Table-used", po::value<vector<string> >(), _("Used to select the tables"))
2515
("database-used", po::value<vector<string> >(), N_("Used to select the database"))
2516
("Table-used", po::value<vector<string> >(), N_("Used to select the tables"))
573
po::options_description all_options(_("Allowed Options + Hidden Options"));
2519
po::options_description all_options(N_("Allowed Options + Hidden Options"));
574
2520
all_options.add(commandline_options).add(dump_options).add(client_options).add(hidden_options);
576
po::options_description long_options(_("Allowed Options"));
2522
po::options_description long_options(N_("Allowed Options"));
577
2523
long_options.add(commandline_options).add(dump_options).add(client_options);
579
2525
std::string system_config_dir_dump(SYSCONFDIR);