~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzledump.cc

  • Committer: Monty Taylor
  • Date: 2008-10-27 23:19:48 UTC
  • mto: (520.4.12 merge-innodb-plugin)
  • mto: This revision was merged to the branch mainline in revision 563.
  • Revision ID: monty@inaugust.com-20081027231948-3kl6ss04plbakqcr
Split some more things out of common_includes.h.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 
27
27
#define DUMP_VERSION "10.13"
28
28
 
 
29
#include <config.h>
 
30
#include <string>
29
31
#include "client_priv.h"
30
 
#include <string>
31
32
 
32
33
#include <mysys/my_sys.h>
33
34
#include <mystrings/m_string.h>
34
35
#include <mystrings/m_ctype.h>
35
36
#include <mysys/hash.h>
36
37
#include <stdarg.h>
37
 
#include <algorithm>
38
 
 
39
 
#include <drizzled/gettext.h>
40
38
 
41
39
#include <drizzled/error.h>
42
40
 
49
47
#define EX_EOM 4
50
48
#define EX_EOF 5 /* ferror for output file was got */
51
49
#define EX_ILLEGAL_TABLE 6
52
 
#define EX_TABLE_STATUS 7
53
50
 
54
51
/* index into 'show fields from table' */
55
52
 
73
70
                      char **err_pos, uint *err_len);
74
71
 
75
72
static void field_escape(string &in, const char *from);
76
 
static bool  verbose= false, opt_no_create_info= false, opt_no_data= false,
77
 
                quick= true, extended_insert= true,
78
 
                lock_tables= true, ignore_errors= false, flush_logs= false,
79
 
                opt_drop= true, opt_keywords= false,
80
 
                opt_lock= true, opt_compress= false,
81
 
                opt_delayed= false, create_options= true, opt_quoted= false,
82
 
                opt_databases= false, opt_alldbs= false, opt_create_db= false,
83
 
                opt_lock_all_tables= false,
84
 
                opt_set_charset= false, opt_dump_date= true,
85
 
                opt_autocommit= false, opt_disable_keys= true, opt_xml= false,
86
 
                opt_delete_master_logs= false, tty_password= false,
87
 
                opt_single_transaction= false, opt_comments= false,
88
 
                opt_compact= false, opt_hex_blob= false, 
89
 
                opt_order_by_primary=false, opt_ignore= false,
90
 
                opt_complete_insert= false, opt_drop_database= false,
91
 
                opt_replace_into= false,
92
 
                opt_routines= false,
93
 
                opt_slave_apply= false,
94
 
                opt_include_master_host_port= false,
95
 
                opt_alltspcs= false;
96
 
static bool debug_info_flag= false, debug_check_flag= false;
 
73
static bool  verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
 
74
                quick= 1, extended_insert= 1,
 
75
                lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0,
 
76
                opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
 
77
                opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
 
78
                opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,
 
79
                opt_set_charset=0, opt_dump_date=1,
 
80
                opt_autocommit=0,opt_disable_keys=1,opt_xml=0,
 
81
                opt_delete_master_logs=0, tty_password=0,
 
82
                opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
 
83
                opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
 
84
                opt_complete_insert= 0, opt_drop_database= 0,
 
85
                opt_replace_into= 0,
 
86
                opt_routines=0,
 
87
                opt_slave_apply= 0, 
 
88
                opt_include_master_host_port= 0,
 
89
                opt_events= 0,
 
90
                opt_alltspcs=0, opt_notspcs= 0;
 
91
static bool debug_info_flag= 0, debug_check_flag= 0;
97
92
static uint32_t opt_max_allowed_packet, opt_net_buffer_length;
98
 
static DRIZZLE drizzle_connection, *drizzle= 0;
 
93
static DRIZZLE drizzle_connection,*drizzle=0;
99
94
static string insert_pat;
100
 
static char  *opt_password= NULL, *current_user= NULL,
101
 
             *current_host= NULL, *path= NULL, *fields_terminated= NULL,
102
 
             *lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
103
 
             *escaped= NULL,
104
 
             *where= NULL, *order_by= NULL,
105
 
             *opt_compatible_mode_str= NULL,
106
 
             *err_ptr= NULL;
107
 
static char **defaults_argv= NULL;
 
95
static char  *opt_password=0,*current_user=0,
 
96
             *current_host=0,*path=0,*fields_terminated=0,
 
97
             *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
 
98
             *where=0, *order_by=0,
 
99
             *opt_compatible_mode_str= 0,
 
100
             *err_ptr= 0,
 
101
             *log_error_file= NULL;
 
102
static char **defaults_argv= 0;
108
103
static char compatible_mode_normal_str[255];
 
104
/* Server supports character_set_results session variable? */
 
105
static bool server_supports_switching_charsets= true;
109
106
static uint32_t opt_compatible_mode= 0;
110
107
#define DRIZZLE_OPT_MASTER_DATA_EFFECTIVE_SQL 1
111
108
#define DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL 2
112
109
#define DRIZZLE_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
113
110
#define DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL 2
114
 
static uint32_t opt_drizzle_port= 0;
115
 
static uint opt_master_data;
 
111
static uint opt_drizzle_port= 0, opt_master_data;
116
112
static uint opt_slave_data;
117
113
static uint my_end_arg;
118
 
static int first_error= 0;
 
114
static int   first_error=0;
119
115
static string extended_row;
120
116
FILE *md_result_file= 0;
121
 
FILE *stderror_file= 0;
 
117
FILE *stderror_file=0;
122
118
 
123
119
/*
124
120
  Constant for detection of default value of default_charset.
130
126
static char *default_charset;
131
127
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
132
128
const char *default_dbug_option="d:t:o,/tmp/drizzledump.trace";
 
129
/* have we seen any VIEWs during table scanning? */
 
130
bool seen_views= 0;
133
131
const char *compatible_mode_names[]=
134
132
{
135
133
  "MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
164
162
   "Dump all the tablespaces.",
165
163
   (char**) &opt_alltspcs, (char**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
166
164
   0, 0},
 
165
  {"no-tablespaces", 'y',
 
166
   "Do not dump any tablespace information.",
 
167
   (char**) &opt_notspcs, (char**) &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
168
   0, 0},
167
169
  {"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
168
170
   (char**) &opt_drop_database, (char**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
169
171
   0},
240
242
   "Option automatically turns --lock-tables off.",
241
243
   (char**) &opt_slave_data, (char**) &opt_slave_data, 0,
242
244
   GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
 
245
  {"events", 'E', "Dump events.",
 
246
     (char**) &opt_events, (char**) &opt_events, 0, GET_BOOL,
 
247
     NO_ARG, 0, 0, 0, 0, 0, 0},
243
248
  {"extended-insert", 'e',
244
249
   "Allows utilization of the new, much faster INSERT syntax.",
245
250
   (char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
269
274
   "--lock-all-tables or --master-data with --flush-logs",
270
275
   (char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
271
276
   0, 0},
 
277
  {"flush-privileges", OPT_ESC, "Emit a FLUSH PRIVILEGES statement "
 
278
   "after dumping the DRIZZLE database.  This option should be used any "
 
279
   "time the dump contains the DRIZZLE database and any other database "
 
280
   "that depends on the data in the DRIZZLE database for proper restore. ",
 
281
   (char**) &flush_privileges, (char**) &flush_privileges, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
282
   0, 0},
272
283
  {"force", 'f', "Continue even if we get an sql-error.",
273
284
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
274
285
   0, 0, 0, 0, 0, 0},
286
297
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
287
298
  {"include-master-host-port", OPT_DRIZZLEDUMP_INCLUDE_MASTER_HOST_PORT,
288
299
   "Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
289
 
   (char**) &opt_include_master_host_port,
290
 
   (char**) &opt_include_master_host_port,
 
300
   (char**) &opt_include_master_host_port, 
 
301
   (char**) &opt_include_master_host_port, 
291
302
   0, GET_BOOL, NO_ARG,
292
303
   0, 0, 0, 0, 0, 0},
293
304
  {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
303
314
   0, 0, 0, 0, 0, 0},
304
315
  {"lock-tables", 'l', "Lock all tables for read.", (char**) &lock_tables,
305
316
   (char**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
317
  {"log-error", OPT_ERROR_LOG_FILE, "Append warnings and errors to given file.",
 
318
   (char**) &log_error_file, (char**) &log_error_file, 0, GET_STR,
 
319
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
306
320
  {"master-data", OPT_MASTER_DATA,
307
321
   "This causes the binary log position and filename to be appended to the "
308
322
   "output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
345
359
  {"order-by-primary", OPT_ORDER_BY_PRIMARY,
346
360
   "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.",
347
361
   (char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
348
 
  {"password", 'P',
 
362
  {"password", 'p',
349
363
   "Password to use when connecting to server. If password is not given it's solicited on the tty.",
350
364
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
351
 
  {"port", 'p', "Port number to use for connection.", 
352
 
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
365
  {"port", 'P', "Port number to use for connection.", (char**) &opt_drizzle_port,
 
366
   (char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
 
367
   0},
353
368
  {"quick", 'q', "Don't buffer query, dump directly to stdout.",
354
369
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
355
370
  {"quote-names",'Q', "Quote table and column names with backticks (`).",
364
379
  {"routines", 'R', "Dump stored routines (functions and procedures).",
365
380
     (char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
366
381
     NO_ARG, 0, 0, 0, 0, 0, 0},
 
382
  {"set-variable", 'O',
 
383
   "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
 
384
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
367
385
  /*
368
386
    Note that the combination --single-transaction --master-data
369
387
    will give bullet-proof binlog position only if server >=4.1.3. That's the
487
505
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
488
506
  puts("Dumping definition and data DRIZZLE database or table");
489
507
  short_usage_sub();
490
 
  print_defaults("drizzle",load_default_groups);
 
508
  print_defaults("my",load_default_groups);
491
509
  my_print_help(my_long_options);
492
510
  my_print_variables(my_long_options);
493
511
} /* usage */
505
523
  {
506
524
    fputs("<?xml version=\"1.0\"?>\n", sql_file);
507
525
    /*
508
 
      Schema reference.  Allows use of xsi:nil for NULL values and
 
526
      Schema reference.  Allows use of xsi:nil for NULL values and 
509
527
      xsi:type to define an element's data type.
510
528
    */
511
529
    fputs("<drizzledump ", sql_file);
587
605
}
588
606
 
589
607
 
590
 
static unsigned char* get_table_key(const char *entry, size_t *length, bool)
 
608
static unsigned char* get_table_key(const char *entry, size_t *length,
 
609
                            bool not_used __attribute__((unused)))
591
610
{
592
611
  *length= strlen(entry);
593
612
  return (unsigned char*) entry;
594
613
}
595
614
 
596
615
 
597
 
extern "C"
598
 
bool get_one_option(int optid, const struct my_option *, char *argument)
 
616
static bool
 
617
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
 
618
               char *argument)
599
619
{
600
 
  char *endchar= NULL;
601
 
  uint64_t temp_drizzle_port= 0;
602
 
 
603
620
  switch (optid) {
604
621
  case 'p':
605
 
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
606
 
    /* if there is an alpha character this is not a valid port */
607
 
    if (strlen(endchar) != 0)
608
 
    {
609
 
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
610
 
      exit(EX_USAGE);
611
 
    }
612
 
    /* If the port number is > 65535 it is not a valid port
613
 
 *        This also helps with potential data loss casting unsigned long to a
614
 
 *               uint32_t. */
615
 
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
616
 
    {
617
 
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
618
 
      exit(EX_USAGE);
619
 
    }
620
 
    else
621
 
    {
622
 
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
623
 
    }
624
 
    break;
625
 
  case 'P':
626
622
    if (argument)
627
623
    {
628
 
      char *start= argument;
629
 
      if (opt_password)
630
 
        free(opt_password);
631
 
      opt_password= strdup(argument);
632
 
      if (opt_password == NULL)
633
 
      {
634
 
        fprintf(stderr, "Memory allocation error while copying password. "
635
 
                        "Aborting.\n");
636
 
        exit(ENOMEM);
637
 
      }
638
 
      while (*argument)
639
 
      {
640
 
        /* Overwriting password with 'x' */
641
 
        *argument++= 'x';
642
 
      }
 
624
      char *start=argument;
 
625
      free(opt_password);
 
626
      opt_password=my_strdup(argument,MYF(MY_FAE));
 
627
      while (*argument) *argument++= 'x';               /* Destroy argument */
643
628
      if (*start)
644
 
      {
645
 
        /* Cut length of argument */
646
 
        start[1]= 0;
647
 
      }
 
629
        start[1]=0;                             /* Cut length of argument */
648
630
      tty_password= 0;
649
631
    }
650
632
    else
651
 
    {
652
 
      tty_password= 1;
653
 
    }
 
633
      tty_password=1;
654
634
    break;
655
635
  case 'r':
656
636
    if (!(md_result_file= my_fopen(argument, O_WRONLY,
717
697
      fprintf(stderr, "Illegal use of option --ignore-table=<database>.<table>\n");
718
698
      exit(1);
719
699
    }
720
 
    char * tmpptr= strdup(argument);
721
 
    if (!(tmpptr) || my_hash_insert(&ignore_table, (unsigned char*)tmpptr))
 
700
    if (my_hash_insert(&ignore_table, (unsigned char*)my_strdup(argument, MYF(0))))
722
701
      exit(EX_EOM);
723
702
    break;
724
703
  }
738
717
                                    &err_ptr, &error_len);
739
718
      if (error_len)
740
719
      {
741
 
        strncpy(buff, err_ptr, min((uint32_t)sizeof(buff), error_len));
 
720
        strmake(buff, err_ptr, min((uint32_t)sizeof(buff), error_len));
742
721
        fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
743
722
        exit(1);
744
723
      }
747
726
      {
748
727
        if (mode & 1)
749
728
        {
750
 
          uint32_t len = strlen(compatible_mode_names[i]);
751
 
          end= strcpy(end, compatible_mode_names[i]) + len;
752
 
          end= strcpy(end, ",")+1;
 
729
          end= my_stpcpy(end, compatible_mode_names[i]);
 
730
          end= my_stpcpy(end, ",");
753
731
        }
754
732
      }
755
733
      if (end!=compatible_mode_normal_str)
775
753
  opt_net_buffer_length= *drizzle_params->p_net_buffer_length;
776
754
 
777
755
  md_result_file= stdout;
778
 
  load_defaults("drizzle",load_default_groups,argc,argv);
 
756
  load_defaults("my",load_default_groups,argc,argv);
779
757
  defaults_argv= *argv;
780
758
 
781
759
  if (hash_init(&ignore_table, charset_info, 16, 0, 0,
782
760
                (hash_get_key) get_table_key,
783
761
                (hash_free_key) free_table_ent, 0))
784
762
    return(EX_EOM);
 
763
  /* Don't copy internal log tables */
 
764
  if (my_hash_insert(&ignore_table,
 
765
                     (unsigned char*) my_strdup("mysql.apply_status", MYF(MY_WME))) ||
 
766
      my_hash_insert(&ignore_table,
 
767
                     (unsigned char*) my_strdup("mysql.schema", MYF(MY_WME))) ||
 
768
      my_hash_insert(&ignore_table,
 
769
                     (unsigned char*) my_strdup("mysql.general_log", MYF(MY_WME))) ||
 
770
      my_hash_insert(&ignore_table,
 
771
                     (unsigned char*) my_strdup("mysql.slow_log", MYF(MY_WME))) ||
 
772
      my_hash_insert(&ignore_table,
 
773
                     (unsigned char*) my_strdup("mysql.online_backup", MYF(MY_WME))) ||
 
774
      my_hash_insert(&ignore_table,
 
775
                     (unsigned char*) my_strdup("mysql.online_backup_progress", MYF(MY_WME))))
 
776
    return(EX_EOM);
785
777
 
786
778
  if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
787
779
    return(ho_error);
875
867
    error_num   - process return value
876
868
    fmt_reason  - a format string for use by vsnprintf.
877
869
    ...         - variable arguments for above fmt_reason string
878
 
 
 
870
  
879
871
  DESCRIPTION
880
872
    This call prints out the formatted error message to stderr and then
881
873
    terminates the process.
904
896
    error_num   - process return value
905
897
    fmt_reason  - a format string for use by vsnprintf.
906
898
    ...         - variable arguments for above fmt_reason string
907
 
 
 
899
  
908
900
  DESCRIPTION
909
901
    This call prints out the formatted error message to stderr and then
910
902
    terminates the process, unless the --force command line option is used.
911
 
 
 
903
    
912
904
    This call should be used for non-fatal errors (such as database
913
905
    errors) that the code may still be able to continue to the next unit
914
906
    of work.
915
 
 
 
907
    
916
908
*/
917
909
static void maybe_die(int error_num, const char* fmt_reason, ...)
918
910
{
959
951
  return 0;
960
952
}
961
953
 
 
954
 
 
955
/**
 
956
  Switch charset for results to some specified charset.  If the server does not
 
957
  support character_set_results variable, nothing can be done here.  As for
 
958
  whether something should be done here, future new callers of this function
 
959
  should be aware that the server lacking the facility of switching charsets is
 
960
  treated as success.
 
961
 
 
962
  @note  If the server lacks support, then nothing is changed and no error
 
963
         condition is returned.
 
964
 
 
965
  @returns  whether there was an error or not
 
966
*/
 
967
static int switch_character_set_results(DRIZZLE *drizzle, const char *cs_name)
 
968
{
 
969
  char query_buffer[QUERY_LENGTH];
 
970
  size_t query_length;
 
971
 
 
972
  /* Server lacks facility.  This is not an error, by arbitrary decision . */
 
973
  if (!server_supports_switching_charsets)
 
974
    return false;
 
975
 
 
976
  query_length= snprintf(query_buffer,
 
977
                         sizeof (query_buffer),
 
978
                         "SET SESSION character_set_results = '%s'",
 
979
                         (const char *) cs_name);
 
980
 
 
981
  return drizzle_real_query(drizzle, query_buffer, query_length);
 
982
}
 
983
 
962
984
/*
963
985
  Open a new .sql file to dump the table or view into
964
986
 
1043
1065
{
1044
1066
  char *tmp;
1045
1067
 
1046
 
  if (!(tmp=(char*) malloc(length*2+1)))
 
1068
  if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME))))
1047
1069
    die(EX_DRIZZLEERR, "Couldn't allocate memory");
1048
1070
 
1049
1071
  drizzle_escape_string(tmp, pos, length);
1191
1213
  Print xml tag. Optionally add attribute(s).
1192
1214
 
1193
1215
  SYNOPSIS
1194
 
    print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
 
1216
    print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name, 
1195
1217
                    ..., attribute_name_n, attribute_value_n, NULL)
1196
1218
    xml_file              - output file
1197
1219
    sbeg                  - line beginning
1206
1228
    Print XML tag with any number of attribute="value" pairs to the xml_file.
1207
1229
 
1208
1230
    Format is:
1209
 
      sbeg<tag_name first_attribute_name="first_attribute_value" ...
 
1231
      sbeg<tag_name first_attribute_name="first_attribute_value" ... 
1210
1232
      attribute_name_n="attribute_value_n">send
1211
1233
  NOTE
1212
1234
    Additional arguments must be present in attribute/value pairs.
1216
1238
*/
1217
1239
 
1218
1240
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1219
 
                          const char* line_end,
1220
 
                          const char* tag_name,
 
1241
                          const char* line_end, 
 
1242
                          const char* tag_name, 
1221
1243
                          const char* first_attribute_name, ...)
1222
1244
{
1223
1245
  va_list arg_list;
1225
1247
 
1226
1248
  fputs(sbeg, xml_file);
1227
1249
  fputc('<', xml_file);
1228
 
  fputs(tag_name, xml_file);
 
1250
  fputs(tag_name, xml_file);  
1229
1251
 
1230
1252
  va_start(arg_list, first_attribute_name);
1231
1253
  attribute_name= first_attribute_name;
1235
1257
    assert(attribute_value != NULL);
1236
1258
 
1237
1259
    fputc(' ', xml_file);
1238
 
    fputs(attribute_name, xml_file);
 
1260
    fputs(attribute_name, xml_file);    
1239
1261
    fputc('\"', xml_file);
1240
 
 
 
1262
    
1241
1263
    print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
1242
1264
    fputc('\"', xml_file);
1243
1265
 
1361
1383
    db          - db name
1362
1384
    table_type  - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
1363
1385
    ignore_flag - what we must particularly ignore - see IGNORE_ defines above
1364
 
    num_fields  - number of fields in the table
1365
1386
 
1366
1387
  RETURN
1367
 
    true if success, false if error
 
1388
    number of fields in table, 0 if error
1368
1389
*/
1369
1390
 
1370
 
static bool get_table_structure(char *table, char *db, char *table_type,
1371
 
                                char *ignore_flag, uint64_t *num_fields)
 
1391
static uint get_table_structure(char *table, char *db, char *table_type,
 
1392
                                char *ignore_flag)
1372
1393
{
1373
1394
  bool    init=0, delayed, write_data, complete_insert;
 
1395
  uint64_t num_fields;
1374
1396
  char       *result_table, *opt_quoted_table;
1375
1397
  const char *insert_option;
1376
1398
  char       name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
1394
1416
  if ((write_data= !(*ignore_flag & IGNORE_DATA)))
1395
1417
  {
1396
1418
    complete_insert= opt_complete_insert;
1397
 
    insert_pat.clear();
 
1419
    insert_pat= "";
1398
1420
  }
1399
1421
 
1400
1422
  insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
1426
1448
 
1427
1449
      snprintf(buff, sizeof(buff), "show create table %s", result_table);
1428
1450
 
1429
 
      if (drizzle_query_with_error_report(drizzle, &result, buff))
1430
 
        return false;
 
1451
      if (switch_character_set_results(drizzle, "binary") ||
 
1452
          drizzle_query_with_error_report(drizzle, &result, buff) ||
 
1453
          switch_character_set_results(drizzle, default_charset))
 
1454
        return(0);
1431
1455
 
1432
1456
      if (path)
1433
1457
      {
1434
1458
        if (!(sql_file= open_sql_file_for_table(table)))
1435
 
          return false;
 
1459
          return(0);
1436
1460
 
1437
1461
        write_header(sql_file, db);
1438
1462
      }
1439
1463
      if (!opt_xml && opt_comments)
1440
1464
      {
 
1465
      if (strcmp (table_type, "VIEW") == 0)         /* view */
 
1466
        fprintf(sql_file, "\n--\n-- Temporary table structure for view %s\n--\n\n",
 
1467
                result_table);
 
1468
      else
1441
1469
        fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1442
1470
                result_table);
1443
1471
        check_io(sql_file);
1445
1473
      if (opt_drop)
1446
1474
      {
1447
1475
      /*
1448
 
        Even if the "table" is a view, we do a DROP TABLE here.
 
1476
        Even if the "table" is a view, we do a DROP TABLE here.  The
 
1477
        view-specific code below fills in the DROP VIEW.
1449
1478
       */
1450
1479
        fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",
1451
1480
                opt_quoted_table);
1453
1482
      }
1454
1483
 
1455
1484
      field= drizzle_fetch_field_direct(result, 0);
 
1485
      if (strcmp(field->name, "View") == 0)
 
1486
      {
 
1487
        char *scv_buff= NULL;
 
1488
 
 
1489
        verbose_msg("-- It's a view, create dummy table for view\n");
 
1490
 
 
1491
        /* save "show create" statement for later */
 
1492
        if ((row= drizzle_fetch_row(result)) && (scv_buff=row[1]))
 
1493
          scv_buff= my_strdup(scv_buff, MYF(0));
 
1494
 
 
1495
        drizzle_free_result(result);
 
1496
 
 
1497
        /*
 
1498
          Create a table with the same name as the view and with columns of
 
1499
          the same name in order to satisfy views that depend on this view.
 
1500
          The table will be removed when the actual view is created.
 
1501
 
 
1502
          The properties of each column, aside from the data type, are not
 
1503
          preserved in this temporary table, because they are not necessary.
 
1504
 
 
1505
          This will not be necessary once we can determine dependencies
 
1506
          between views and can simply dump them in the appropriate order.
 
1507
        */
 
1508
        snprintf(query_buff, sizeof(query_buff),
 
1509
                 "SHOW FIELDS FROM %s", result_table);
 
1510
        if (switch_character_set_results(drizzle, "binary") ||
 
1511
            drizzle_query_with_error_report(drizzle, &result, query_buff) ||
 
1512
            switch_character_set_results(drizzle, default_charset))
 
1513
        {
 
1514
          /*
 
1515
            View references invalid or privileged table/col/fun (err 1356),
 
1516
            so we cannot create a stand-in table.  Be defensive and dump
 
1517
            a comment with the view's 'show create' statement. (Bug #17371)
 
1518
          */
 
1519
 
 
1520
          if (drizzle_errno(drizzle) == ER_VIEW_INVALID)
 
1521
            fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : "");
 
1522
 
 
1523
          free(scv_buff);
 
1524
 
 
1525
          return(0);
 
1526
        }
 
1527
        else
 
1528
          free(scv_buff);
 
1529
 
 
1530
        if (drizzle_num_rows(result))
 
1531
        {
 
1532
          if (opt_drop)
 
1533
          {
 
1534
            /*
 
1535
              We have already dropped any table of the same name above, so
 
1536
              here we just drop the view.
 
1537
            */
 
1538
 
 
1539
            fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
 
1540
                    opt_quoted_table);
 
1541
            check_io(sql_file);
 
1542
          }
 
1543
 
 
1544
          fprintf(sql_file,
 
1545
                  "/*!50001 CREATE TABLE %s (\n",
 
1546
                  result_table);
 
1547
 
 
1548
          /*
 
1549
            Get first row, following loop will prepend comma - keeps from
 
1550
            having to know if the row being printed is last to determine if
 
1551
            there should be a _trailing_ comma.
 
1552
          */
 
1553
 
 
1554
          row= drizzle_fetch_row(result);
 
1555
 
 
1556
          fprintf(sql_file, "  %s %s", quote_name(row[0], name_buff, 0),
 
1557
                  row[1]);
 
1558
 
 
1559
          while((row= drizzle_fetch_row(result)))
 
1560
          {
 
1561
            /* col name, col type */
 
1562
            fprintf(sql_file, ",\n  %s %s",
 
1563
                    quote_name(row[0], name_buff, 0), row[1]);
 
1564
          }
 
1565
          fprintf(sql_file, "\n) */;\n"); 
 
1566
          check_io(sql_file);
 
1567
        }
 
1568
 
 
1569
        drizzle_free_result(result);
 
1570
 
 
1571
        if (path)
 
1572
          my_fclose(sql_file, MYF(MY_WME));
 
1573
 
 
1574
        seen_views= 1;
 
1575
        return(0);
 
1576
      }
1456
1577
 
1457
1578
      row= drizzle_fetch_row(result);
1458
1579
 
1467
1588
    {
1468
1589
      if (path)
1469
1590
        my_fclose(sql_file, MYF(MY_WME));
1470
 
      return false;
 
1591
      return(0);
1471
1592
    }
1472
1593
 
1473
1594
    /*
1509
1630
        insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1510
1631
      }
1511
1632
    }
1512
 
    *num_fields= drizzle_num_rows(result);
 
1633
    num_fields= drizzle_num_rows(result);
1513
1634
    drizzle_free_result(result);
1514
1635
  }
1515
1636
  else
1520
1641
    snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1521
1642
             result_table);
1522
1643
    if (drizzle_query_with_error_report(drizzle, &result, query_buff))
1523
 
      return false;
 
1644
      return(0);
1524
1645
 
1525
1646
    /* Make an sql-file, if path was given iow. option -T was given */
1526
1647
    if (!opt_no_create_info)
1528
1649
      if (path)
1529
1650
      {
1530
1651
        if (!(sql_file= open_sql_file_for_table(table)))
1531
 
          return false;
 
1652
          return(0);
1532
1653
        write_header(sql_file, db);
1533
1654
      }
1534
1655
      if (!opt_xml && opt_comments)
1539
1660
      if (!opt_xml)
1540
1661
        fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1541
1662
      else
1542
 
        print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
 
1663
        print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table, 
1543
1664
                NULL);
1544
1665
      check_io(sql_file);
1545
1666
    }
1607
1728
        check_io(sql_file);
1608
1729
      }
1609
1730
    }
1610
 
    *num_fields= drizzle_num_rows(result);
 
1731
    num_fields= drizzle_num_rows(result);
1611
1732
    drizzle_free_result(result);
1612
1733
    if (!opt_no_create_info)
1613
1734
    {
1627
1748
                my_progname, result_table, drizzle_error(drizzle));
1628
1749
        if (path)
1629
1750
          my_fclose(sql_file, MYF(MY_WME));
1630
 
        return false;
 
1751
        return(0);
1631
1752
      }
1632
1753
 
1633
1754
      /* Find first which key is primary key */
1747
1868
    write_footer(sql_file);
1748
1869
    my_fclose(sql_file, MYF(MY_WME));
1749
1870
  }
1750
 
  return true;
 
1871
  return((uint) num_fields);
1751
1872
} /* get_table_structure */
1752
1873
 
1753
1874
static void add_load_option(string &str, const char *option,
1760
1881
  }
1761
1882
 
1762
1883
  str.append(option);
1763
 
 
 
1884
  
1764
1885
  if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
1765
1886
  {
1766
1887
    /* It's a hex constant, don't escape */
1783
1904
 
1784
1905
static void field_escape(string &in, const char *from)
1785
1906
{
1786
 
  uint end_backslashes= 0;
 
1907
  uint end_backslashes= 0; 
1787
1908
 
1788
1909
  in.append("'");
1789
1910
 
1837
1958
  char table_type[NAME_LEN];
1838
1959
  char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
1839
1960
  int error= 0;
1840
 
  uint32_t rownr, row_break, total_length, init_length;
1841
 
  uint64_t num_fields= 0;
 
1961
  uint32_t         rownr, row_break, total_length, init_length;
 
1962
  uint num_fields;
1842
1963
  DRIZZLE_RES     *res;
1843
1964
  DRIZZLE_FIELD   *field;
1844
1965
  DRIZZLE_ROW     row;
1848
1969
    Make sure you get the create table info before the following check for
1849
1970
    --no-data flag below. Otherwise, the create table info won't be printed.
1850
1971
  */
1851
 
  if (!get_table_structure(table, db, table_type, &ignore_flag, &num_fields))
1852
 
  {
1853
 
    maybe_die(EX_TABLE_STATUS, "Error retrieving table structure for table: \"%s\"", table);
 
1972
  num_fields= get_table_structure(table, db, table_type, &ignore_flag);
 
1973
 
 
1974
  /*
 
1975
    The "table" could be a view.  If so, we don't do anything here.
 
1976
  */
 
1977
  if (strcmp(table_type, "VIEW") == 0)
1854
1978
    return;
1855
 
  }
1856
1979
 
1857
1980
  /* Check --no-data flag */
1858
1981
  if (opt_no_data)
1880
2003
    return;
1881
2004
  }
1882
2005
 
 
2006
  /*
 
2007
     Check --skip-events flag: it is not enough to skip creation of events
 
2008
     discarding SHOW CREATE EVENT statements generation. The myslq.event
 
2009
     table data should be skipped too.
 
2010
  */
 
2011
  if (!opt_events && !my_strcasecmp(&my_charset_utf8_general_ci, db, "mysql") &&
 
2012
      !my_strcasecmp(&my_charset_utf8_general_ci, table, "event"))
 
2013
  {
 
2014
    verbose_msg("-- Skipping data table mysql.event, --skip-events was used\n");
 
2015
    return;
 
2016
  }
 
2017
 
1883
2018
  result_table= quote_name(table,table_buff, 1);
1884
2019
  opt_quoted_table= quote_name(table, table_buff2, 0);
1885
2020
 
1896
2031
      Convert the path to native os format
1897
2032
      and resolve to the full filepath.
1898
2033
    */
1899
 
    convert_dirname(tmp_path,path,NULL);
 
2034
    convert_dirname(tmp_path,path,NULL);    
1900
2035
    my_load_path(tmp_path, tmp_path, NULL);
1901
2036
    fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
1902
2037
 
1914
2049
 
1915
2050
    if (fields_terminated || enclosed || opt_enclosed || escaped)
1916
2051
      query_string.append( " FIELDS");
1917
 
 
 
2052
    
1918
2053
    add_load_option(query_string, " TERMINATED BY ", fields_terminated);
1919
2054
    add_load_option(query_string, " ENCLOSED BY ", enclosed);
1920
2055
    add_load_option(query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
1950
2085
              result_table);
1951
2086
      check_io(md_result_file);
1952
2087
    }
1953
 
 
 
2088
    
1954
2089
    query_string.append( "SELECT * FROM ");
1955
2090
    query_string.append( result_table);
1956
2091
 
1961
2096
        fprintf(md_result_file, "-- WHERE:  %s\n", where);
1962
2097
        check_io(md_result_file);
1963
2098
      }
1964
 
 
 
2099
      
1965
2100
      query_string.append( " WHERE ");
1966
2101
      query_string.append( where);
1967
2102
    }
2070
2205
        if (extended_insert && !opt_xml)
2071
2206
        {
2072
2207
          if (i == 0)
2073
 
          {
2074
 
            extended_row.clear();
2075
 
            extended_row.append("(");
2076
 
          }
 
2208
            extended_row= "(";
2077
2209
          else
2078
2210
            extended_row.append(",");
2079
2211
 
2096
2228
                if (opt_hex_blob && is_blob)
2097
2229
                {
2098
2230
                  extended_row.append("0x");
2099
 
                  octet2hex(tmp_str, row[i], length);
 
2231
                  drizzle_hex_string(tmp_str, row[i], length);
2100
2232
                  extended_row.append(tmp_str);
2101
2233
                }
2102
2234
                else
2150
2282
                }
2151
2283
                else
2152
2284
                {
2153
 
                  print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
 
2285
                  print_xml_tag(md_result_file, "\t\t", "", "field", "name=", 
2154
2286
                                field->name, NULL);
2155
2287
                  print_quoted_xml(md_result_file, row[i], length);
2156
2288
                }
2446
2578
  char table_buff[NAME_LEN*2+3];
2447
2579
  char hash_key[2*NAME_LEN+2];  /* "db.tablename" */
2448
2580
  char *afterdot;
2449
 
 
2450
 
  afterdot= strcpy(hash_key, database) + strlen(database);
 
2581
  int using_mysql_db= my_strcasecmp(&my_charset_utf8_general_ci, database, "mysql");
 
2582
 
 
2583
 
 
2584
  afterdot= my_stpcpy(hash_key, database);
2451
2585
  *afterdot++= '.';
2452
2586
 
2453
2587
  if (init_dumping(database, init_dumping_tables))
2456
2590
    print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NULL);
2457
2591
  if (lock_tables)
2458
2592
  {
2459
 
    string query("LOCK TABLES ");
 
2593
    string query;
 
2594
    query= "LOCK TABLES ";
2460
2595
    for (numrows= 0 ; (table= getTableName(1)) ; )
2461
2596
    {
2462
 
      char *end= strcpy(afterdot, table) + strlen(table);
 
2597
      char *end= my_stpcpy(afterdot, table);
2463
2598
      if (include_table((unsigned char*) hash_key,end - hash_key))
2464
2599
      {
2465
2600
        numrows++;
2480
2615
  }
2481
2616
  while ((table= getTableName(0)))
2482
2617
  {
2483
 
    char *end= strcpy(afterdot, table) + strlen(table);
 
2618
    char *end= my_stpcpy(afterdot, table);
2484
2619
    if (include_table((unsigned char*) hash_key, end - hash_key))
2485
2620
    {
2486
2621
      dump_table(table,database);
2495
2630
  }
2496
2631
  if (lock_tables)
2497
2632
    drizzle_query_with_error_report(drizzle, 0, "UNLOCK TABLES");
2498
 
 
 
2633
  if (flush_privileges && using_mysql_db == 0)
 
2634
  {
 
2635
    fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
 
2636
    fprintf(md_result_file,"\n/*! FLUSH PRIVILEGES */;\n");
 
2637
  }
2499
2638
  return(0);
2500
2639
} /* dump_all_tables_in_db */
2501
2640
 
2551
2690
static int dump_selected_tables(char *db, char **table_names, int tables)
2552
2691
{
2553
2692
  char table_buff[NAME_LEN*2+3];
2554
 
  string lock_tables_query("LOCK TABLES ");
 
2693
  string lock_tables_query;
2555
2694
  MEM_ROOT root;
2556
2695
  char **dump_tables, **pos, **end;
2557
2696
 
2563
2702
  if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
2564
2703
     die(EX_EOM, "alloc_root failure.");
2565
2704
 
 
2705
  lock_tables_query= "LOCK TABLES ";
2566
2706
  for (; tables > 0 ; tables-- , table_names++)
2567
2707
  {
2568
2708
    /* the table name passed on commandline may be wrong case */
2836
2976
    Only one row is returned, and the first column is the name of the
2837
2977
    active log.
2838
2978
  */
2839
 
  strncpy(buff_log_name, row[0], buff_len - 1);
 
2979
  strmake(buff_log_name, row[0], buff_len - 1);
2840
2980
 
2841
2981
  drizzle_free_result(res);
2842
2982
  return 0;
2908
3048
 
2909
3049
      for (; pos != end && *pos != ','; pos++) ;
2910
3050
      var_len= (uint32_t) (pos - start);
2911
 
      strncpy(buff, start, min((uint32_t)sizeof(buff), var_len));
 
3051
      strmake(buff, start, min((uint32_t)sizeof(buff), var_len));
2912
3052
      find= find_type(buff, lib, var_len);
2913
3053
      if (!find)
2914
3054
      {
2916
3056
        *err_len= var_len;
2917
3057
      }
2918
3058
      else
2919
 
        found|= (uint32_t)((int64_t) 1 << (find - 1));
 
3059
        found|= ((int64_t) 1 << (find - 1));
2920
3060
      if (pos == end)
2921
3061
        break;
2922
3062
      start= pos + 1;
3008
3148
    drizzle_free_result(res);
3009
3149
    return(result);                         /* assume table is ok */
3010
3150
  }
3011
 
 
3012
 
  /*
3013
 
    If the table type matches any of these, we do support delayed inserts.
3014
 
    Note: we do not want to skip dumping this table if if is not one of
3015
 
    these types, but we do want to use delayed inserts in the dump if
3016
 
    the table type is _NOT_ one of these types
 
3151
  if (!(row[1]))
 
3152
    strmake(table_type, "VIEW", NAME_LEN-1);
 
3153
  else
 
3154
  {
 
3155
    /*
 
3156
      If the table type matches any of these, we do support delayed inserts.
 
3157
      Note: we do not want to skip dumping this table if if is not one of
 
3158
      these types, but we do want to use delayed inserts in the dump if
 
3159
      the table type is _NOT_ one of these types
3017
3160
    */
3018
 
  {
3019
 
    strncpy(table_type, row[1], NAME_LEN-1);
 
3161
    strmake(table_type, row[1], NAME_LEN-1);
3020
3162
    if (opt_delayed)
3021
3163
    {
3022
3164
      if (strcmp(table_type,"MyISAM") &&
 
3165
          strcmp(table_type,"ISAM") &&
3023
3166
          strcmp(table_type,"ARCHIVE") &&
3024
3167
          strcmp(table_type,"HEAP") &&
3025
3168
          strcmp(table_type,"MEMORY"))
3026
3169
        result= IGNORE_INSERT_DELAYED;
3027
3170
    }
 
3171
 
 
3172
    /*
 
3173
      If these two types, we do want to skip dumping the table
 
3174
    */
 
3175
    if (!opt_no_data &&
 
3176
        (!my_strcasecmp(&my_charset_utf8_general_ci, table_type, "MRG_MyISAM") ||
 
3177
         !strcmp(table_type,"MRG_ISAM")))
 
3178
      result= IGNORE_DATA;
3028
3179
  }
3029
3180
  drizzle_free_result(res);
3030
3181
  return(result);
3093
3244
  {
3094
3245
    char *end;
3095
3246
    /* result (terminating \0 is already in result_length) */
3096
 
    result= (char *)malloc(result_length + 10);
 
3247
    result= (char *)my_malloc(result_length + 10, MYF(MY_WME));
3097
3248
    if (!result)
3098
3249
    {
3099
3250
      fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
3102
3253
    drizzle_data_seek(res, 0);
3103
3254
    row= drizzle_fetch_row(res);
3104
3255
    quoted_field= quote_name(row[4], buff, 0);
3105
 
    end= strcpy(result, quoted_field) + strlen(quoted_field);
 
3256
    end= my_stpcpy(result, quoted_field);
3106
3257
    while ((row= drizzle_fetch_row(res)) && atoi(row[3]) > 1)
3107
3258
    {
3108
3259
      quoted_field= quote_name(row[4], buff, 0);
3109
 
      end+= sprintf(end,",%s",quoted_field);
 
3260
      end= strxmov(end, ",", quoted_field, NULL);
3110
3261
    }
3111
3262
  }
3112
3263
 
3122
3273
{
3123
3274
  char bin_log_name[FN_REFLEN];
3124
3275
  int exit_code;
3125
 
  MY_INIT("drizzledump");
 
3276
  MY_INIT("mysqldump");
3126
3277
 
3127
3278
  compatible_mode_normal_str[0]= 0;
3128
3279
  default_charset= (char *)drizzle_universal_client_charset;
3135
3286
    exit(exit_code);
3136
3287
  }
3137
3288
 
 
3289
  if (log_error_file)
 
3290
  {
 
3291
    if(!(stderror_file= freopen(log_error_file, "a+", stderr)))
 
3292
    {
 
3293
      free_resources();
 
3294
      exit(EX_DRIZZLEERR);
 
3295
    }
 
3296
  }
 
3297
 
3138
3298
  if (connect_to_db(current_host, current_user, opt_password))
3139
3299
  {
3140
3300
    free_resources();