~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Monty Taylor
  • Date: 2009-03-25 21:06:47 UTC
  • mto: This revision was merged to the branch mainline in revision 964.
  • Revision ID: mordred@inaugust.com-20090325210647-7j1tm98gvct3jxsu
Removed legacy_db_type.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 *
34
34
 **/
35
35
 
36
 
#include "config.h"
37
 
 
 
36
#include "client_priv.h"
38
37
#include <string>
39
 
 
40
 
#include "client_priv.h"
 
38
#include <algorithm>
41
39
#include <mystrings/m_ctype.h>
42
40
#include <stdarg.h>
43
 
#ifndef __GNU_LIBRARY__
44
 
#define __GNU_LIBRARY__          // Skip warnings in getopt.h
45
 
#endif
46
 
#include <readline/history.h>
47
41
#include "my_readline.h"
48
42
#include <signal.h>
49
43
#include <sys/ioctl.h>
50
 
 
51
 
 
52
 
#if defined(HAVE_LOCALE_H)
53
 
#include <locale.h>
54
 
#endif
55
 
 
56
 
#include <libdrizzle/gettext.h>
57
 
 
58
 
const char *VER= "14.14";
59
 
 
60
 
/* Don't try to make a nice table if the data is too big */
61
 
#define MAX_COLUMN_LENGTH       (uint32_t)1024
62
 
 
63
 
/* Buffer to hold 'version' and 'version_comment' */
64
 
#define MAX_SERVER_VERSION_LENGTH     128
65
 
 
66
 
/* Array of options to pass to libdrizzled */
67
 
#define MAX_SERVER_ARGS               64
68
 
 
69
 
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
70
 
void sql_element_free(void *ptr);
71
 
 
 
44
#include <drizzled/configmake.h>
72
45
 
73
46
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
74
47
#include <curses.h>
99
72
#endif
100
73
#endif
101
74
 
102
 
#undef bcmp                             // Fix problem with new readline
 
75
#ifdef HAVE_LIBREADLINE
 
76
#  if defined(HAVE_READLINE_READLINE_H)
 
77
#    include <readline/readline.h>
 
78
#  elif defined(HAVE_READLINE_H)
 
79
#    include <readline.h>
 
80
#  else /* !defined(HAVE_READLINE_H) */
 
81
extern char *readline ();
 
82
#  endif /* !defined(HAVE_READLINE_H) */
 
83
char *cmdline = NULL;
 
84
#else /* !defined(HAVE_READLINE_READLINE_H) */
 
85
  /* no readline */
 
86
#  error Readline Required
 
87
#endif /* HAVE_LIBREADLINE */
103
88
 
104
 
#ifdef HAVE_READLINE_HISTORY_H
105
 
#include <readline/history.h>
106
 
#endif
107
 
#include <readline/readline.h>
 
89
#ifdef HAVE_READLINE_HISTORY
 
90
#  if defined(HAVE_READLINE_HISTORY_H)
 
91
#    include <readline/history.h>
 
92
#  elif defined(HAVE_HISTORY_H)
 
93
#    include <history.h>
 
94
#  else /* !defined(HAVE_HISTORY_H) */
 
95
extern void add_history ();
 
96
extern int write_history ();
 
97
extern int read_history ();
 
98
#  endif /* defined(HAVE_READLINE_HISTORY_H) */
 
99
    /* no history */
 
100
#endif /* HAVE_READLINE_HISTORY */
108
101
 
109
102
/**
110
103
 Make the old readline interface look like the new one.
116
109
  completion_matches((char *)str, (CPFunction *)func)
117
110
#endif
118
111
 
 
112
#if defined(HAVE_LOCALE_H)
 
113
#include <locale.h>
 
114
#endif
 
115
 
 
116
#include <drizzled/gettext.h>
 
117
 
 
118
 
 
119
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
 
120
void sql_element_free(void *ptr);
 
121
 
119
122
 
120
123
#if !defined(HAVE_VIDATTR)
121
124
#undef vidattr
122
125
#define vidattr(A) {}      // Can't get this to work
123
126
#endif
124
127
 
125
 
#ifdef FN_NO_CASE_SENCE
126
 
#define cmp_database(cs,A,B) my_strcasecmp((cs), (A), (B))
127
 
#else
128
 
#define cmp_database(cs,A,B) strcmp((A),(B))
129
 
#endif
130
 
 
131
 
#include "completion_hash.h"
 
128
#include <iostream>
 
129
#include <functional>
 
130
#include <map>
132
131
 
133
132
using namespace std;
134
133
 
 
134
const string VER("14.14");
 
135
/* Don't try to make a nice table if the data is too big */
 
136
const uint32_t MAX_COLUMN_LENGTH= 1024;
 
137
 
 
138
/* Buffer to hold 'version' and 'version_comment' */
 
139
const int MAX_SERVER_VERSION_LENGTH= 128;
 
140
 
135
141
#define PROMPT_CHAR '\\'
136
142
#define DEFAULT_DELIMITER ";"
137
143
 
145
151
} STATUS;
146
152
 
147
153
 
148
 
static HashTable ht;
 
154
static map<string, string>::iterator completion_iter;
 
155
static map<string, string>::iterator completion_end;
 
156
static map<string, string> completion_map;
 
157
static string completion_string;
 
158
 
149
159
static char **defaults_argv;
150
160
 
151
161
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
152
162
typedef enum enum_info_type INFO_TYPE;
153
163
 
154
164
static DRIZZLE drizzle;      /* The connection */
155
 
static bool ignore_errors=0,quick=0,
156
 
  connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
157
 
  opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
158
 
  opt_compress=0, using_opt_local_infile=0,
159
 
  vertical=0, line_numbers=1, column_names=1,
160
 
  opt_nopager=1, opt_outfile=0, named_cmds= 0,
161
 
  tty_password= 0, opt_nobeep=0, opt_reconnect=1,
162
 
  default_charset_used= 0, opt_secure_auth= 0,
163
 
  default_pager_set= 0, opt_sigint_ignore= 0,
164
 
  auto_vertical_output= 0,
165
 
  show_warnings= 0, executing_query= 0, interrupted_query= 0;
 
165
static bool ignore_errors= false, quick= false,
 
166
  connected= false, opt_raw_data= false, unbuffered= false,
 
167
  output_tables= false, opt_rehash= true, skip_updates= false,
 
168
  safe_updates= false, one_database= false,
 
169
  opt_compress= false,
 
170
  vertical= false, line_numbers= true, column_names= true,
 
171
  opt_nopager= true, opt_outfile= false, named_cmds= false,
 
172
  tty_password= false, opt_nobeep= false, opt_reconnect= true,
 
173
  default_charset_used= false, opt_secure_auth= false,
 
174
  default_pager_set= false, opt_sigint_ignore= false,
 
175
  auto_vertical_output= false,
 
176
  show_warnings= false, executing_query= false, interrupted_query= false;
 
177
static uint32_t  show_progress_size= 0;
166
178
static bool debug_info_flag, debug_check_flag;
167
179
static bool column_types_flag;
168
 
static bool preserve_comments= 0;
169
 
static uint32_t opt_max_allowed_packet, opt_net_buffer_length;
170
 
static int verbose=0,opt_silent=0,opt_drizzle_port=0, opt_local_infile=0;
171
 
static uint my_end_arg;
172
 
static char * opt_drizzle_unix_port=0;
173
 
static int connect_flag=CLIENT_INTERACTIVE;
174
 
static char *current_host,*current_db,*current_user=0,*opt_password=0,
175
 
  *delimiter_str= 0,* current_prompt= 0;
 
180
static bool preserve_comments= false;
 
181
static uint32_t opt_max_allowed_packet, opt_net_buffer_length,
 
182
  opt_drizzle_port= 0;
 
183
static int verbose= 0, opt_silent= 0, opt_local_infile= 0;
 
184
static uint32_t my_end_arg;
 
185
static char * opt_drizzle_unix_port= NULL;
 
186
static int connect_flag= 0;
 
187
static char *current_host, *current_db, *current_user= NULL,
 
188
  *opt_password= NULL, *delimiter_str= NULL, *current_prompt= NULL;
176
189
static char *histfile;
177
190
static char *histfile_tmp;
178
191
static string *glob_buffer;
179
192
static string *processed_prompt= NULL;
180
193
static char *default_prompt= NULL;
181
 
static char *full_username=0,*part_username=0;
 
194
static char *full_username= NULL,*part_username= NULL;
182
195
static STATUS status;
183
196
static uint32_t select_limit;
184
197
static uint32_t max_join_size;
185
198
static uint32_t opt_connect_timeout= 0;
186
 
static char drizzle_charsets_dir[FN_REFLEN+1];
187
199
// TODO: Need to i18n these
188
 
static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
189
 
static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
 
200
static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 
201
static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
190
202
                                  "Aug","Sep","Oct","Nov","Dec"};
191
203
static char default_pager[FN_REFLEN];
192
204
static char pager[FN_REFLEN], outfile[FN_REFLEN];
193
205
static FILE *PAGER, *OUTFILE;
194
 
static MEM_ROOT hash_mem_root;
195
 
static uint prompt_counter;
 
206
static uint32_t prompt_counter;
196
207
static char delimiter[16]= DEFAULT_DELIMITER;
197
 
static uint delimiter_length= 1;
 
208
static uint32_t delimiter_length= 1;
198
209
unsigned short terminal_width= 80;
199
210
 
200
211
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
201
212
 
202
 
int drizzle_real_query_for_lazy(const char *buf, int length);
203
 
int drizzle_store_result_for_lazy(DRIZZLE_RES **result);
 
213
int drizzleclient_real_query_for_lazy(const char *buf, int length);
 
214
int drizzleclient_store_result_for_lazy(DRIZZLE_RES **result);
204
215
 
205
216
 
206
217
void tee_fprintf(FILE *file, const char *fmt, ...);
210
221
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
211
222
/* The names of functions that actually do the manipulation. */
212
223
static int get_options(int argc,char **argv);
213
 
bool get_one_option(int optid, const struct my_option *opt,
214
 
                    char *argument);
 
224
extern "C" bool get_one_option(int optid, const struct my_option *opt,
 
225
                               char *argument);
215
226
static int com_quit(string *str,const char*),
216
227
  com_go(string *str,const char*), com_ego(string *str,const char*),
217
228
  com_print(string *str,const char*),
226
237
 
227
238
static int read_and_execute(bool interactive);
228
239
static int sql_connect(char *host,char *database,char *user,char *password,
229
 
                       uint silent);
 
240
                       uint32_t silent);
230
241
static const char *server_version_string(DRIZZLE *drizzle);
231
 
static int put_info(const char *str,INFO_TYPE info,uint error,
 
242
static int put_info(const char *str,INFO_TYPE info,uint32_t error,
232
243
                    const char *sql_state);
233
244
static int put_error(DRIZZLE *drizzle);
234
245
static void safe_put_field(const char *pos,uint32_t length);
256
267
 
257
268
 
258
269
static COMMANDS commands[] = {
259
 
  { "?",      '?', com_help,   1, N_("Synonym for `help'.") },
 
270
  { "?",      '?', com_help,   0, N_("Synonym for `help'.") },
260
271
  { "clear",  'c', com_clear,  0, N_("Clear command.")},
261
272
  { "connect",'r', com_connect,1,
262
273
    N_("Reconnect to the server. Optional arguments are db and host." }),
266
277
    N_("Send command to drizzle server, display result vertically.")},
267
278
  { "exit",   'q', com_quit,   0, N_("Exit drizzle. Same as quit.")},
268
279
  { "go",     'g', com_go,     0, N_("Send command to drizzle server.") },
269
 
  { "help",   'h', com_help,   1, N_("Display this help.") },
 
280
  { "help",   'h', com_help,   0, N_("Display this help.") },
270
281
  { "nopager",'n', com_nopager,0, N_("Disable pager, print to stdout.") },
271
282
  { "notee",  't', com_notee,  0, N_("Don't write into outfile.") },
272
283
  { "pager",  'P', com_pager,  1,
372
383
  { "CROSS", 0, 0, 0, ""},
373
384
  { "CUBE", 0, 0, 0, ""},
374
385
  { "CURRENT_DATE", 0, 0, 0, ""},
375
 
  { "CURRENT_TIME", 0, 0, 0, ""},
376
386
  { "CURRENT_TIMESTAMP", 0, 0, 0, ""},
377
387
  { "CURRENT_USER", 0, 0, 0, ""},
378
388
  { "CURSOR", 0, 0, 0, ""},
451
461
  { "FULL", 0, 0, 0, ""},
452
462
  { "FULLTEXT", 0, 0, 0, ""},
453
463
  { "FUNCTION", 0, 0, 0, ""},
454
 
  { "GET_FORMAT", 0, 0, 0, ""},
455
464
  { "GLOBAL", 0, 0, 0, ""},
456
465
  { "GRANT", 0, 0, 0, ""},
457
466
  { "GRANTS", 0, 0, 0, ""},
513
522
  { "LINESTRING", 0, 0, 0, ""},
514
523
  { "LOAD", 0, 0, 0, ""},
515
524
  { "LOCAL", 0, 0, 0, ""},
516
 
  { "LOCALTIME", 0, 0, 0, ""},
517
525
  { "LOCALTIMESTAMP", 0, 0, 0, ""},
518
526
  { "LOCK", 0, 0, 0, ""},
519
527
  { "LOCKS", 0, 0, 0, ""},
610
618
  { "QUARTER", 0, 0, 0, ""},
611
619
  { "QUERY", 0, 0, 0, ""},
612
620
  { "QUICK", 0, 0, 0, ""},
613
 
  { "RAID0", 0, 0, 0, ""},
614
 
  { "RAID_CHUNKS", 0, 0, 0, ""},
615
 
  { "RAID_CHUNKSIZE", 0, 0, 0, ""},
616
 
  { "RAID_TYPE", 0, 0, 0, ""},
617
621
  { "READ", 0, 0, 0, ""},
618
622
  { "READS", 0, 0, 0, ""},
619
623
  { "REAL", 0, 0, 0, ""},
715
719
  { "TERMINATED", 0, 0, 0, ""},
716
720
  { "TEXT", 0, 0, 0, ""},
717
721
  { "THEN", 0, 0, 0, ""},
718
 
  { "TIME", 0, 0, 0, ""},
719
722
  { "TIMESTAMP", 0, 0, 0, ""},
720
723
  { "TIMESTAMPADD", 0, 0, 0, ""},
721
724
  { "TIMESTAMPDIFF", 0, 0, 0, ""},
749
752
  { "USE_FRM", 0, 0, 0, ""},
750
753
  { "USING", 0, 0, 0, ""},
751
754
  { "UTC_DATE", 0, 0, 0, ""},
752
 
  { "UTC_TIME", 0, 0, 0, ""},
753
755
  { "UTC_TIMESTAMP", 0, 0, 0, ""},
754
756
  { "VALUE", 0, 0, 0, ""},
755
757
  { "VALUES", 0, 0, 0, ""},
776
778
  { "ABS", 0, 0, 0, ""},
777
779
  { "ACOS", 0, 0, 0, ""},
778
780
  { "ADDDATE", 0, 0, 0, ""},
779
 
  { "ADDTIME", 0, 0, 0, ""},
780
781
  { "AES_ENCRYPT", 0, 0, 0, ""},
781
782
  { "AES_DECRYPT", 0, 0, 0, ""},
782
783
  { "AREA", 0, 0, 0, ""},
814
815
  { "CRC32", 0, 0, 0, ""},
815
816
  { "CROSSES", 0, 0, 0, ""},
816
817
  { "CURDATE", 0, 0, 0, ""},
817
 
  { "CURTIME", 0, 0, 0, ""},
818
818
  { "DATE_ADD", 0, 0, 0, ""},
819
819
  { "DATEDIFF", 0, 0, 0, ""},
820
820
  { "DATE_FORMAT", 0, 0, 0, ""},
884
884
  { "LTRIM", 0, 0, 0, ""},
885
885
  { "MAKE_SET", 0, 0, 0, ""},
886
886
  { "MAKEDATE", 0, 0, 0, ""},
887
 
  { "MAKETIME", 0, 0, 0, ""},
888
887
  { "MASTER_POS_WAIT", 0, 0, 0, ""},
889
888
  { "MAX", 0, 0, 0, ""},
890
889
  { "MBRCONTAINS", 0, 0, 0, ""},
941
940
  { "ROW_COUNT", 0, 0, 0, ""},
942
941
  { "RPAD", 0, 0, 0, ""},
943
942
  { "RTRIM", 0, 0, 0, ""},
944
 
  { "SEC_TO_TIME", 0, 0, 0, ""},
945
943
  { "SESSION_USER", 0, 0, 0, ""},
946
944
  { "SUBDATE", 0, 0, 0, ""},
947
945
  { "SIGN", 0, 0, 0, ""},
963
961
  { "SUBSTR", 0, 0, 0, ""},
964
962
  { "SUBSTRING", 0, 0, 0, ""},
965
963
  { "SUBSTRING_INDEX", 0, 0, 0, ""},
966
 
  { "SUBTIME", 0, 0, 0, ""},
967
964
  { "SUM", 0, 0, 0, ""},
968
965
  { "SYSDATE", 0, 0, 0, ""},
969
966
  { "SYSTEM_USER", 0, 0, 0, ""},
970
967
  { "TAN", 0, 0, 0, ""},
971
968
  { "TIME_FORMAT", 0, 0, 0, ""},
972
 
  { "TIME_TO_SEC", 0, 0, 0, ""},
973
 
  { "TIMEDIFF", 0, 0, 0, ""},
974
969
  { "TO_DAYS", 0, 0, 0, ""},
975
970
  { "TOUCHES", 0, 0, 0, ""},
976
971
  { "TRIM", 0, 0, 0, ""},
1015
1010
static void end_timer(uint32_t start_time,char *buff);
1016
1011
static void drizzle_end_timer(uint32_t start_time,char *buff);
1017
1012
static void nice_time(double sec,char *buff,bool part_second);
1018
 
extern RETSIGTYPE drizzle_end(int sig);
1019
 
extern RETSIGTYPE handle_sigint(int sig);
 
1013
extern "C" void drizzle_end(int sig);
 
1014
extern "C" void handle_sigint(int sig);
1020
1015
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1021
 
static RETSIGTYPE window_resize(int sig);
 
1016
static void window_resize(int sig);
1022
1017
#endif
1023
1018
 
1024
1019
int main(int argc,char *argv[])
1035
1030
 
1036
1031
  MY_INIT(argv[0]);
1037
1032
  delimiter_str= delimiter;
1038
 
  default_prompt= my_strdup(getenv("DRIZZLE_PS1") ?
1039
 
                            getenv("DRIZZLE_PS1") :
1040
 
                            "drizzle>> ", MYF(0));
1041
 
  current_prompt= my_strdup(default_prompt, MYF(0));
 
1033
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
 
1034
                         getenv("DRIZZLE_PS1") :
 
1035
                         "drizzle> ");
 
1036
  
 
1037
  if (default_prompt == NULL)
 
1038
  {
 
1039
    fprintf(stderr, _("Memory allocation error while constructing initial "
 
1040
                      "prompt. Aborting.\n"));
 
1041
    exit(ENOMEM);
 
1042
  }
 
1043
  current_prompt= strdup(default_prompt);
 
1044
  if (current_prompt == NULL)
 
1045
  {
 
1046
    fprintf(stderr, _("Memory allocation error while constructing initial "
 
1047
                      "prompt. Aborting.\n"));
 
1048
    exit(ENOMEM);
 
1049
  }
1042
1050
  processed_prompt= new string();
1043
1051
  processed_prompt->reserve(32);
1044
1052
 
1045
1053
  prompt_counter=0;
1046
1054
 
1047
1055
  outfile[0]=0;      // no (default) outfile
1048
 
  my_stpcpy(pager, "stdout");  // the default, if --pager wasn't given
 
1056
  strcpy(pager, "stdout");  // the default, if --pager wasn't given
1049
1057
  {
1050
1058
    char *tmp=getenv("PAGER");
1051
1059
    if (tmp && strlen(tmp))
1052
1060
    {
1053
1061
      default_pager_set= 1;
1054
 
      my_stpcpy(default_pager, tmp);
 
1062
      strcpy(default_pager, tmp);
1055
1063
    }
1056
1064
  }
1057
1065
  if (!isatty(0) || !isatty(1))
1077
1085
      close(stdout_fileno_copy);             /* Clean up dup(). */
1078
1086
  }
1079
1087
 
1080
 
  load_defaults("my",load_default_groups,&argc,&argv);
 
1088
  load_defaults("drizzle",load_default_groups,&argc,&argv);
1081
1089
  defaults_argv=argv;
1082
1090
  if (get_options(argc, (char **) argv))
1083
1091
  {
1092
1100
    my_end(0);
1093
1101
    exit(1);
1094
1102
  }
1095
 
  completion_hash_init(&ht, 128);
1096
 
  init_alloc_root(&hash_mem_root, 16384, 0);
1097
1103
  memset(&drizzle, 0, sizeof(drizzle));
1098
1104
  if (sql_connect(current_host,current_db,current_user,opt_password,
1099
1105
                  opt_silent))
1123
1129
 
1124
1130
  glob_buffer= new string();
1125
1131
  glob_buffer->reserve(512);
1126
 
  
 
1132
 
1127
1133
  char * output_buff= (char *)malloc(512);
1128
1134
  memset(output_buff, '\0', 512);
1129
1135
 
1130
1136
  sprintf(output_buff,
1131
1137
          _("Your Drizzle connection id is %u\nServer version: %s\n"),
1132
 
          drizzle_thread_id(&drizzle),
 
1138
          drizzleclient_thread_id(&drizzle),
1133
1139
          server_version_string(&drizzle));
1134
1140
  put_info(output_buff, INFO_INFO, 0, 0);
1135
1141
 
1141
1147
      histfile= strdup(getenv("DRIZZLE_HISTFILE"));
1142
1148
    else if (getenv("HOME"))
1143
1149
    {
1144
 
      histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1145
 
                                 + (uint) strlen("/.drizzle_history")+2,
1146
 
                                 MYF(MY_WME));
 
1150
      histfile=(char*) malloc(strlen(getenv("HOME")) + strlen("/.drizzle_history") + 2);
1147
1151
      if (histfile)
1148
1152
        sprintf(histfile,"%s/.drizzle_history",getenv("HOME"));
1149
1153
      char link_name[FN_REFLEN];
1160
1164
      if (verbose)
1161
1165
        tee_fprintf(stdout, _("Reading history-file %s\n"),histfile);
1162
1166
      read_history(histfile);
1163
 
      if (!(histfile_tmp= (char*) my_malloc((uint) strlen(histfile) + 5,
1164
 
                                            MYF(MY_WME))))
 
1167
      if (!(histfile_tmp= (char*) malloc((uint32_t) strlen(histfile) + 5)))
1165
1168
      {
1166
1169
        fprintf(stderr, _("Couldn't allocate memory for temp histfile!\n"));
1167
1170
        exit(1);
1181
1184
  return(0);        // Keep compiler happy
1182
1185
}
1183
1186
 
1184
 
RETSIGTYPE drizzle_end(int sig)
 
1187
void drizzle_end(int sig)
1185
1188
{
1186
 
  drizzle_close(&drizzle);
 
1189
  drizzleclient_close(&drizzle);
1187
1190
  if (!status.batch && !quick && histfile)
1188
1191
  {
1189
1192
    /* write-history */
1193
1196
      my_rename(histfile_tmp, histfile, MYF(MY_WME));
1194
1197
  }
1195
1198
  batch_readline_end(status.line_buff);
1196
 
  completion_hash_free(&ht);
1197
 
  free_root(&hash_mem_root,MYF(0));
1198
1199
 
1199
1200
  if (sig >= 0)
1200
1201
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
1224
1225
  If query is in process, kill query
1225
1226
  no query in process, terminate like previous behavior
1226
1227
*/
1227
 
RETSIGTYPE handle_sigint(int sig)
 
1228
extern "C"
 
1229
void handle_sigint(int sig)
1228
1230
{
1229
1231
  char kill_buffer[40];
1230
1232
  DRIZZLE *kill_drizzle= NULL;
1234
1236
    goto err;
1235
1237
  }
1236
1238
 
1237
 
  kill_drizzle= drizzle_create(kill_drizzle);
1238
 
  if (!drizzle_connect(kill_drizzle,current_host, current_user, opt_password,
 
1239
  kill_drizzle= drizzleclient_create(kill_drizzle);
 
1240
  if (!drizzleclient_connect(kill_drizzle,current_host, current_user, opt_password,
1239
1241
                          "", opt_drizzle_port, opt_drizzle_unix_port,0))
1240
1242
  {
1241
1243
    goto err;
1242
1244
  }
1243
1245
 
1244
1246
  /* kill_buffer is always big enough because max length of %lu is 15 */
1245
 
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u", drizzle_thread_id(&drizzle));
1246
 
  drizzle_real_query(kill_drizzle, kill_buffer, strlen(kill_buffer));
1247
 
  drizzle_close(kill_drizzle);
 
1247
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u", drizzleclient_thread_id(&drizzle));
 
1248
  drizzleclient_real_query(kill_drizzle, kill_buffer, strlen(kill_buffer));
 
1249
  drizzleclient_close(kill_drizzle);
1248
1250
  tee_fprintf(stdout, _("Query aborted by Ctrl+C\n"));
1249
1251
 
1250
1252
  interrupted_query= 1;
1257
1259
 
1258
1260
 
1259
1261
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1260
 
RETSIGTYPE window_resize(int sig __attribute__((unused)))
 
1262
void window_resize(int)
1261
1263
{
1262
1264
  struct winsize window_size;
1263
1265
 
1284
1286
   (char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1285
1287
  {"batch", 'B',
1286
1288
   N_("Don't use history file. Disable interactive behavior. (Enables --silent)"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1287
 
  {"character-sets-dir", OPT_CHARSETS_DIR,
1288
 
   N_("Directory where character sets are."), (char**) &charsets_dir,
1289
 
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1290
1289
  {"column-type-info", OPT_COLUMN_TYPES, N_("Display column type information."),
1291
1290
   (char**) &column_types_flag, (char**) &column_types_flag,
1292
1291
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1360
1359
  {"no-pager", OPT_NOPAGER,
1361
1360
   N_("Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead."),
1362
1361
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1363
 
  {"password", 'p',
 
1362
  {"password", 'P',
1364
1363
   N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
1365
1364
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1366
 
  {"port", 'P', N_("Port number to use for connection or 0 for default to, in order of preference, my.cnf, $DRIZZLE_TCP_PORT, ")
 
1365
  {"port", 'p', N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, ")
1367
1366
   N_("built-in default") " (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
1368
 
   (char**) &opt_drizzle_port,
1369
 
   (char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,  0},
 
1367
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1370
1368
  {"prompt", OPT_PROMPT, N_("Set the drizzle prompt to this value."),
1371
1369
   (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
1372
1370
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1373
 
  {"protocol", OPT_DRIZZLE_PROTOCOL, N_("The protocol of connection (tcp,socket,pipe,memory)."),
1374
 
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1375
1371
  {"quick", 'q',
1376
1372
   N_("Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file."),
1377
1373
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1411
1407
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
1412
1408
   N_("Number of seconds before connection timeout."),
1413
1409
   (char**) &opt_connect_timeout,
1414
 
   (char**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
 
1410
   (char**) &opt_connect_timeout, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 3600*12, 0,
1415
1411
   0, 0},
1416
1412
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1417
1413
   N_("Max packet length to send to, or receive from server"),
1418
1414
   (char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
1419
 
   GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096,
 
1415
   GET_UINT32, REQUIRED_ARG, 16 *1024L*1024L, 4096,
1420
1416
   (int64_t) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1421
1417
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
1422
1418
   N_("Buffer for TCP/IP and socket communication"),
1423
 
   (char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0, GET_ULONG,
 
1419
   (char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0, GET_UINT32,
1424
1420
   REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
1425
1421
  {"select_limit", OPT_SELECT_LIMIT,
1426
1422
   N_("Automatic limit for SELECT when using --safe-updates"),
1427
1423
   (char**) &select_limit,
1428
 
   (char**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
 
1424
   (char**) &select_limit, 0, GET_UINT32, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
1429
1425
   0, 1, 0},
1430
1426
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1431
1427
   N_("Automatic limit for rows in a join when using --safe-updates"),
1432
1428
   (char**) &max_join_size,
1433
 
   (char**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
 
1429
   (char**) &max_join_size, 0, GET_UINT32, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
1434
1430
   0, 1, 0},
1435
1431
  {"secure-auth", OPT_SECURE_AUTH, N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"), (char**) &opt_secure_auth,
1436
1432
   (char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1437
1433
  {"show-warnings", OPT_SHOW_WARNINGS, N_("Show warnings after every statement."),
1438
1434
   (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
1439
1435
   0, 0, 0, 0, 0, 0},
 
1436
  {"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of lines before each import progress report."),
 
1437
   (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
 
1438
   0, 0, 0, 0, 0, 0},
1440
1439
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1441
1440
};
1442
1441
 
1446
1445
  const char* readline= "readline";
1447
1446
 
1448
1447
  printf(_("%s  Ver %s Distrib %s, for %s (%s) using %s %s\n"),
1449
 
         my_progname, VER, drizzle_get_client_info(),
 
1448
         my_progname, VER.c_str(), drizzleclient_get_client_info(),
1450
1449
         SYSTEM_TYPE, MACHINE_TYPE,
1451
1450
         readline, rl_library_version);
1452
1451
 
1453
1452
  if (version)
1454
1453
    return;
1455
 
  printf(_("\
1456
 
Copyright (C) 2000-2008 MySQL AB\n                                      \
1457
 
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n \
1458
 
and you are welcome to modify and redistribute it under the GPL license\n"));
 
1454
  printf(_("Copyright (C) 2008 Sun Microsystems\n"
 
1455
           "This software comes with ABSOLUTELY NO WARRANTY. "
 
1456
           "This is free software,\n"
 
1457
           "and you are welcome to modify and redistribute it "
 
1458
           "under the GPL license\n"));
1459
1459
  printf(_("Usage: %s [OPTIONS] [database]\n"), my_progname);
1460
1460
  my_print_help(my_long_options);
1461
 
  print_defaults("my", load_default_groups);
 
1461
  print_defaults("drizzle", load_default_groups);
1462
1462
  my_print_variables(my_long_options);
1463
1463
}
1464
1464
 
1465
1465
 
1466
 
bool
1467
 
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
1468
 
               char *argument)
 
1466
extern "C" bool
 
1467
get_one_option(int optid, const struct my_option *, char *argument)
1469
1468
{
 
1469
  char *endchar= NULL;
 
1470
  uint64_t temp_drizzle_port= 0;
 
1471
 
1470
1472
  switch(optid) {
1471
 
  case OPT_CHARSETS_DIR:
1472
 
    strmake(drizzle_charsets_dir, argument, sizeof(drizzle_charsets_dir) - 1);
1473
 
    charsets_dir = drizzle_charsets_dir;
1474
 
    break;
1475
1473
  case  OPT_DEFAULT_CHARSET:
1476
1474
    default_charset_used= 1;
1477
1475
    break;
1478
1476
  case OPT_DELIMITER:
1479
1477
    if (argument == disabled_my_option)
1480
1478
    {
1481
 
      my_stpcpy(delimiter, DEFAULT_DELIMITER);
 
1479
      strcpy(delimiter, DEFAULT_DELIMITER);
1482
1480
    }
1483
1481
    else
1484
1482
    {
1485
1483
      /* Check that delimiter does not contain a backslash */
1486
1484
      if (!strstr(argument, "\\"))
1487
1485
      {
1488
 
        strmake(delimiter, argument, sizeof(delimiter) - 1);
 
1486
        strncpy(delimiter, argument, sizeof(delimiter) - 1);
1489
1487
      }
1490
1488
      else
1491
1489
      {
1492
1490
        put_info(_("DELIMITER cannot contain a backslash character"),
1493
1491
                 INFO_ERROR,0,0);
1494
 
        return 0;
 
1492
        return false;
1495
1493
      }
1496
1494
    }
1497
 
    delimiter_length= (uint)strlen(delimiter);
 
1495
    delimiter_length= (uint32_t)strlen(delimiter);
1498
1496
    delimiter_str= delimiter;
1499
1497
    break;
1500
 
  case OPT_LOCAL_INFILE:
1501
 
    using_opt_local_infile=1;
1502
 
    break;
1503
1498
  case OPT_TEE:
1504
1499
    if (argument == disabled_my_option)
1505
1500
    {
1523
1518
      if (argument && strlen(argument))
1524
1519
      {
1525
1520
        default_pager_set= 1;
1526
 
        strmake(pager, argument, sizeof(pager) - 1);
1527
 
        my_stpcpy(default_pager, pager);
 
1521
        strncpy(pager, argument, sizeof(pager) - 1);
 
1522
        strcpy(default_pager, pager);
1528
1523
      }
1529
1524
      else if (default_pager_set)
1530
 
        my_stpcpy(pager, default_pager);
 
1525
        strcpy(pager, default_pager);
1531
1526
      else
1532
1527
        opt_nopager= 1;
1533
1528
    }
1560
1555
      one_database= skip_updates= 1;
1561
1556
    break;
1562
1557
  case 'p':
 
1558
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
 
1559
    /* if there is an alpha character this is not a valid port */
 
1560
    if (strlen(endchar) != 0)
 
1561
    {
 
1562
      put_info(_("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead."), INFO_ERROR, 0, 0);
 
1563
      return false;
 
1564
    }
 
1565
    /* If the port number is > 65535 it is not a valid port
 
1566
       This also helps with potential data loss casting unsigned long to a
 
1567
       uint32_t. */
 
1568
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
1569
    {
 
1570
      put_info(_("Value supplied for port is not valid."), INFO_ERROR, 0, 0);
 
1571
      return false;
 
1572
    }
 
1573
    else
 
1574
    {
 
1575
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
 
1576
    }
 
1577
    break;
 
1578
  case 'P':
 
1579
    /* Don't require password */
1563
1580
    if (argument == disabled_my_option)
1564
 
      argument= (char*) "";      // Don't require password
 
1581
    {
 
1582
      argument= (char*) "";
 
1583
    }
1565
1584
    if (argument)
1566
1585
    {
1567
1586
      char *start= argument;
1568
1587
      free(opt_password);
1569
1588
      opt_password= strdup(argument);
1570
 
      while (*argument) *argument++= 'x';        // Destroy argument
 
1589
      while (*argument)
 
1590
      {
 
1591
        /* Overwriting password with 'x' */
 
1592
        *argument++= 'x';
 
1593
      }
1571
1594
      if (*start)
1572
 
        start[1]=0 ;
 
1595
      {
 
1596
        start[1]= 0;
 
1597
      }
1573
1598
      tty_password= 0;
1574
1599
    }
1575
1600
    else
 
1601
    {
1576
1602
      tty_password= 1;
 
1603
    }
1577
1604
    break;
1578
1605
  case 's':
1579
1606
    if (argument == disabled_my_option)
1592
1619
    status.add_to_history= 0;
1593
1620
    set_if_bigger(opt_silent,1);                         // more silent
1594
1621
    break;
1595
 
    break;
1596
1622
  case 'V':
1597
1623
    usage(1);
1598
1624
    exit(0);
1609
1635
{
1610
1636
  char *tmp, *pagpoint;
1611
1637
  int ho_error;
1612
 
  const DRIZZLE_PARAMETERS *drizzle_params= drizzle_get_parameters();
 
1638
  const DRIZZLE_PARAMETERS *drizzle_params= drizzleclient_get_parameters();
1613
1639
 
1614
1640
  tmp= (char *) getenv("DRIZZLE_HOST");
1615
1641
  if (tmp)
1618
1644
  pagpoint= getenv("PAGER");
1619
1645
  if (!((char*) (pagpoint)))
1620
1646
  {
1621
 
    my_stpcpy(pager, "stdout");
 
1647
    strcpy(pager, "stdout");
1622
1648
    opt_nopager= 1;
1623
1649
  }
1624
1650
  else
1625
 
    my_stpcpy(pager, pagpoint);
1626
 
  my_stpcpy(default_pager, pager);
 
1651
    strcpy(pager, pagpoint);
 
1652
  strcpy(default_pager, pager);
1627
1653
 
1628
1654
  opt_max_allowed_packet= *drizzle_params->p_max_allowed_packet;
1629
1655
  opt_net_buffer_length= *drizzle_params->p_net_buffer_length;
1636
1662
 
1637
1663
  if (status.batch) /* disable pager and outfile in this case */
1638
1664
  {
1639
 
    my_stpcpy(default_pager, "stdout");
1640
 
    my_stpcpy(pager, "stdout");
 
1665
    strcpy(default_pager, "stdout");
 
1666
    strcpy(pager, "stdout");
1641
1667
    opt_nopager= 1;
1642
1668
    default_pager_set= 0;
1643
1669
    opt_outfile= 0;
1657
1683
    current_db= strdup(*argv);
1658
1684
  }
1659
1685
  if (tty_password)
1660
 
    opt_password= get_tty_password(NULL);
 
1686
    opt_password= drizzleclient_get_tty_password(NULL);
1661
1687
  if (debug_info_flag)
1662
1688
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
1663
1689
  if (debug_check_flag)
1691
1717
          (unsigned char) line[2] == 0xBF)
1692
1718
        line+= 3;
1693
1719
      line_number++;
 
1720
      if (show_progress_size > 0)
 
1721
      {
 
1722
        if ((line_number % show_progress_size) == 0)
 
1723
          fprintf(stderr, _("Processing line: %"PRIu32"\n"), line_number);
 
1724
      }
1694
1725
      if (!glob_buffer->empty())
1695
1726
        status.query_start_line=line_number;
1696
1727
    }
1762
1793
 
1763
1794
static COMMANDS *find_command(const char *name,char cmd_char)
1764
1795
{
1765
 
  uint len;
 
1796
  uint32_t len;
1766
1797
  const char *end;
1767
1798
 
1768
1799
  if (!name)
1788
1819
      return((COMMANDS *) 0);
1789
1820
    if ((end=strcont(name," \t")))
1790
1821
    {
1791
 
      len=(uint) (end - name);
 
1822
      len=(uint32_t) (end - name);
1792
1823
      while (my_isspace(charset_info,*end))
1793
1824
        end++;
1794
1825
      if (!*end)
1795
1826
        end=0;          // no arguments to function
1796
1827
    }
1797
1828
    else
1798
 
      len=(uint) strlen(name);
 
1829
      len=(uint32_t) strlen(name);
1799
1830
  }
1800
1831
 
1801
 
  for (uint i= 0; commands[i].name; i++)
 
1832
  for (uint32_t i= 0; commands[i].name; i++)
1802
1833
  {
1803
1834
    if (commands[i].func &&
1804
1835
        ((name && !my_strnncoll(charset_info,(const unsigned char*)name,len, (const unsigned char*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || (!name && commands[i].cmd_char == cmd_char)))
1824
1855
    return(0);
1825
1856
  if (status.add_to_history && line[0] && not_in_history(line))
1826
1857
    add_history(line);
1827
 
  char *end_of_line=line+(uint) strlen(line);
 
1858
  char *end_of_line=line+(uint32_t) strlen(line);
1828
1859
 
1829
1860
  for (pos=out=line ; (inchar= (unsigned char) *pos) ; pos++)
1830
1861
  {
2068
2099
  if (out != line || (buffer->length() > 0))
2069
2100
  {
2070
2101
    *out++='\n';
2071
 
    uint length=(uint) (out-line);
 
2102
    uint32_t length=(uint32_t) (out-line);
2072
2103
    if ((!*ml_comment || preserve_comments))
2073
2104
      buffer->append(line, length);
2074
2105
  }
2081
2112
 
2082
2113
 
2083
2114
static char **mysql_completion (const char *text, int start, int end);
2084
 
static char *new_command_generator(const char *text, int);
 
2115
extern "C" char *new_command_generator(const char *text, int);
2085
2116
 
2086
2117
/*
2087
2118
  Tell the GNU Readline library how to complete.  We want to try to complete
2088
2119
  on command names if this is the first word in the line, or on filenames
2089
2120
  if not.
2090
2121
*/
2091
 
static char *no_completion(const char * a __attribute__((unused)),
2092
 
                           int b __attribute__((unused)))
 
2122
static char *no_completion(const char *, int)
2093
2123
{
2094
2124
  /* No filename completion */
2095
2125
  return 0;
2184
2214
  entire line in case we want to do some simple parsing.  Return the
2185
2215
  array of matches, or NULL if there aren't any.
2186
2216
*/
2187
 
char **mysql_completion (const char *text,
2188
 
                        int start __attribute__((unused)),
2189
 
                        int end __attribute__((unused)))
 
2217
char **mysql_completion (const char *text, int, int)
2190
2218
{
2191
2219
  if (!status.batch && !quick)
2192
2220
    return rl_completion_matches(text, new_command_generator);
2194
2222
    return (char**) 0;
2195
2223
}
2196
2224
 
2197
 
 
2198
 
static char *new_command_generator(const char *text,int state)
2199
 
{
2200
 
  static int textlen;
2201
 
  char *ptr;
2202
 
  static Bucket *b;
2203
 
  static entry *e;
2204
 
  static uint i;
 
2225
inline string lower_string(const string &from_string)
 
2226
{
 
2227
  string to_string= from_string;
 
2228
  transform(to_string.begin(), to_string.end(),
 
2229
            to_string.begin(), ::tolower);
 
2230
  return to_string;
 
2231
}
 
2232
inline string lower_string(const char * from_string)
 
2233
{
 
2234
  string to_string= from_string;
 
2235
  return lower_string(to_string);
 
2236
}
 
2237
 
 
2238
template <class T>
 
2239
class CompletionMatch :
 
2240
  public unary_function<const string&, bool>
 
2241
{
 
2242
  string match_text; 
 
2243
  T match_func;
 
2244
public:
 
2245
  CompletionMatch(string text) : match_text(text) {}
 
2246
  inline bool operator() (const pair<string,string> &match_against) const
 
2247
  {
 
2248
    string sub_match=
 
2249
      lower_string(match_against.first.substr(0,match_text.size()));
 
2250
    return match_func(sub_match,match_text);
 
2251
  }
 
2252
};
 
2253
 
 
2254
 
 
2255
 
 
2256
extern "C"
 
2257
char *new_command_generator(const char *text, int state)
 
2258
{
2205
2259
 
2206
2260
  if (!state)
2207
 
    textlen=(uint) strlen(text);
2208
 
 
2209
 
  if (textlen>0)
2210
 
  {            /* lookup in the hash */
2211
 
    if (!state)
2212
 
    {
2213
 
      uint len;
2214
 
 
2215
 
      b = find_all_matches(&ht,text,(uint) strlen(text),&len);
2216
 
      if (!b)
2217
 
        return NULL;
2218
 
      e = b->pData;
2219
 
    }
2220
 
 
2221
 
    if (e)
2222
 
    {
2223
 
      ptr= strdup(e->str);
2224
 
      e = e->pNext;
2225
 
      return ptr;
2226
 
    }
2227
 
  }
2228
 
  else
2229
 
  { /* traverse the entire hash, ugly but works */
2230
 
 
2231
 
    if (!state)
2232
 
    {
2233
 
      /* find the first used bucket */
2234
 
      for (i=0 ; i < ht.nTableSize ; i++)
2235
 
      {
2236
 
        if (ht.arBuckets[i])
2237
 
        {
2238
 
          b = ht.arBuckets[i];
2239
 
          e = b->pData;
2240
 
          break;
2241
 
        }
2242
 
      }
2243
 
    }
2244
 
    ptr= NULL;
2245
 
    while (e && !ptr)
2246
 
    {          /* find valid entry in bucket */
2247
 
      if ((uint) strlen(e->str) == b->nKeyLength)
2248
 
        ptr = strdup(e->str);
2249
 
      /* find the next used entry */
2250
 
      e = e->pNext;
2251
 
      if (!e)
2252
 
      { /* find the next used bucket */
2253
 
        b = b->pNext;
2254
 
        if (!b)
2255
 
        {
2256
 
          for (i++ ; i<ht.nTableSize; i++)
2257
 
          {
2258
 
            if (ht.arBuckets[i])
2259
 
            {
2260
 
              b = ht.arBuckets[i];
2261
 
              e = b->pData;
2262
 
              break;
2263
 
            }
2264
 
          }
2265
 
        }
2266
 
        else
2267
 
          e = b->pData;
2268
 
      }
2269
 
    }
2270
 
    if (ptr)
2271
 
      return ptr;
2272
 
  }
2273
 
  return NULL;
 
2261
  {
 
2262
    completion_string= lower_string(text);
 
2263
    if (completion_string.size() == 0)
 
2264
    {
 
2265
      completion_iter= completion_map.begin();
 
2266
      completion_end= completion_map.end();
 
2267
    }
 
2268
    else
 
2269
    {
 
2270
      completion_iter= find_if(completion_map.begin(), completion_map.end(),
 
2271
                               CompletionMatch<equal_to<string> >(completion_string));
 
2272
      completion_end= find_if(completion_iter, completion_map.end(),
 
2273
                              CompletionMatch<not_equal_to<string> >(completion_string));
 
2274
    }
 
2275
  }
 
2276
  if (completion_iter == completion_end || (size_t)state > completion_map.size())
 
2277
    return NULL;
 
2278
  char *result= (char *)malloc((*completion_iter).second.size()+1);
 
2279
  strcpy(result, (*completion_iter).second.c_str());
 
2280
  completion_iter++;
 
2281
  return result;
2274
2282
}
2275
2283
 
2276
 
 
2277
2284
/* Build up the completion hash */
2278
2285
 
2279
2286
static void build_completion_hash(bool rehash, bool write_info)
2281
2288
  COMMANDS *cmd=commands;
2282
2289
  DRIZZLE_RES *databases=0,*tables=0;
2283
2290
  DRIZZLE_RES *fields;
2284
 
  static char ***field_names= 0;
2285
2291
  DRIZZLE_ROW database_row,table_row;
2286
2292
  DRIZZLE_FIELD *sql_field;
2287
 
  char buf[NAME_LEN*2+2];     // table name plus field name plus 2
2288
 
  int i,j,num_fields;
 
2293
  string tmp_str, tmp_str_lower;
2289
2294
 
2290
2295
 
2291
2296
  if (status.batch || quick || !current_db)
2293
2298
  if (!rehash)
2294
2299
    return;
2295
2300
 
2296
 
  /* Free old used memory */
2297
 
  if (field_names)
2298
 
    field_names=0;
2299
 
  completion_hash_clean(&ht);
2300
 
  free_root(&hash_mem_root,MYF(0));
 
2301
  completion_map.clear();
2301
2302
 
2302
2303
  /* hash this file's known subset of SQL commands */
2303
2304
  while (cmd->name) {
2304
 
    add_word(&ht,(char*) cmd->name);
 
2305
    tmp_str= cmd->name;
 
2306
    tmp_str_lower= lower_string(tmp_str);
 
2307
    completion_map[tmp_str_lower]= tmp_str;
2305
2308
    cmd++;
2306
2309
  }
2307
2310
 
2308
2311
  /* hash Drizzle functions (to be implemented) */
2309
2312
 
2310
2313
  /* hash all database names */
2311
 
  if (drizzle_query(&drizzle,"show databases") == 0)
 
2314
  if (drizzleclient_query(&drizzle,"show databases") == 0)
2312
2315
  {
2313
 
    if (!(databases = drizzle_store_result(&drizzle)))
2314
 
      put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
 
2316
    if (!(databases = drizzleclient_store_result(&drizzle)))
 
2317
      put_info(drizzleclient_error(&drizzle),INFO_INFO,0,0);
2315
2318
    else
2316
2319
    {
2317
 
      while ((database_row=drizzle_fetch_row(databases)))
 
2320
      while ((database_row=drizzleclient_fetch_row(databases)))
2318
2321
      {
2319
 
        char *str=strdup_root(&hash_mem_root, (char*) database_row[0]);
2320
 
        if (str)
2321
 
          add_word(&ht,(char*) str);
 
2322
        tmp_str= database_row[0];
 
2323
        tmp_str_lower= lower_string(tmp_str);
 
2324
        completion_map[tmp_str_lower]= tmp_str;
2322
2325
      }
2323
 
      drizzle_free_result(databases);
 
2326
      drizzleclient_free_result(databases);
2324
2327
    }
2325
2328
  }
2326
2329
  /* hash all table names */
2327
 
  if (drizzle_query(&drizzle,"show tables")==0)
 
2330
  if (drizzleclient_query(&drizzle,"show tables")==0)
2328
2331
  {
2329
 
    if (!(tables = drizzle_store_result(&drizzle)))
2330
 
      put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
 
2332
    if (!(tables = drizzleclient_store_result(&drizzle)))
 
2333
      put_info(drizzleclient_error(&drizzle),INFO_INFO,0,0);
2331
2334
    else
2332
2335
    {
2333
 
      if (drizzle_num_rows(tables) > 0 && !opt_silent && write_info)
 
2336
      if (drizzleclient_num_rows(tables) > 0 && !opt_silent && write_info)
2334
2337
      {
2335
2338
        tee_fprintf(stdout, _("\
2336
2339
Reading table information for completion of table and column names\n    \
2337
2340
You can turn off this feature to get a quicker startup with -A\n\n"));
2338
2341
      }
2339
 
      while ((table_row=drizzle_fetch_row(tables)))
 
2342
      while ((table_row=drizzleclient_fetch_row(tables)))
2340
2343
      {
2341
 
        char *str=strdup_root(&hash_mem_root, (char*) table_row[0]);
2342
 
        if (str &&
2343
 
            !completion_hash_exists(&ht,(char*) str, (uint) strlen(str)))
2344
 
          add_word(&ht,str);
 
2344
        tmp_str= table_row[0];
 
2345
        tmp_str_lower= lower_string(tmp_str);
 
2346
        completion_map[tmp_str_lower]= tmp_str;
2345
2347
      }
2346
2348
    }
2347
2349
  }
2351
2353
  {
2352
2354
    return;
2353
2355
  }
2354
 
  drizzle_data_seek(tables,0);
2355
 
  if (!(field_names= (char ***) alloc_root(&hash_mem_root,sizeof(char **) *
2356
 
                                           (uint) (drizzle_num_rows(tables)+1))))
2357
 
  {
2358
 
    drizzle_free_result(tables);
2359
 
    return;
2360
 
  }
2361
 
  i=0;
2362
 
  while ((table_row=drizzle_fetch_row(tables)))
2363
 
  {
2364
 
    if ((fields=drizzle_list_fields(&drizzle,(const char*) table_row[0],NULL)))
 
2356
  drizzleclient_data_seek(tables,0);
 
2357
 
 
2358
  while ((table_row=drizzleclient_fetch_row(tables)))
 
2359
  {
 
2360
    string query;
 
2361
 
 
2362
    query.append("show fields in `");
 
2363
    query.append(table_row[0]);
 
2364
    query.append("`");
 
2365
    
 
2366
    if (drizzleclient_query(&drizzle, query.c_str()) == 0)
2365
2367
    {
2366
 
      num_fields=drizzle_num_fields(fields);
2367
 
      if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
2368
 
                                                  sizeof(char *) *
2369
 
                                                  (num_fields*2+1))))
2370
 
      {
2371
 
        drizzle_free_result(fields);
2372
 
        break;
2373
 
      }
2374
 
      field_names[i][num_fields*2]= '\0';
2375
 
      j=0;
2376
 
      while ((sql_field=drizzle_fetch_field(fields)))
2377
 
      {
2378
 
        sprintf(buf,"%.64s.%.64s",table_row[0],sql_field->name);
2379
 
        field_names[i][j] = strdup_root(&hash_mem_root,buf);
2380
 
        add_word(&ht,field_names[i][j]);
2381
 
        field_names[i][num_fields+j] = strdup_root(&hash_mem_root,
2382
 
                                                   sql_field->name);
2383
 
        if (!completion_hash_exists(&ht,field_names[i][num_fields+j],
2384
 
                                    (uint) strlen(field_names[i][num_fields+j])))
2385
 
          add_word(&ht,field_names[i][num_fields+j]);
2386
 
        j++;
2387
 
      }
2388
 
      drizzle_free_result(fields);
 
2368
      fields= drizzleclient_store_result(&drizzle);
 
2369
      if (fields) 
 
2370
      {
 
2371
        while ((sql_field=drizzleclient_fetch_field(fields)))
 
2372
        {
 
2373
          tmp_str=table_row[0];
 
2374
          tmp_str.append(".");
 
2375
          tmp_str.append(sql_field->name);
 
2376
          tmp_str_lower= lower_string(tmp_str);
 
2377
          completion_map[tmp_str_lower]= tmp_str;
 
2378
 
 
2379
          tmp_str=sql_field->name;
 
2380
          tmp_str_lower= lower_string(tmp_str);
 
2381
          completion_map[tmp_str_lower]= tmp_str;
 
2382
 
 
2383
        }
 
2384
        drizzleclient_free_result(fields);
 
2385
      }
2389
2386
    }
2390
 
    else
2391
 
      field_names[i]= 0;
2392
 
 
2393
 
    i++;
2394
2387
  }
2395
 
  drizzle_free_result(tables);
2396
 
  field_names[i]=0;        // End pointer
2397
 
  return;
 
2388
  drizzleclient_free_result(tables);
 
2389
  completion_iter= completion_map.begin();
2398
2390
}
2399
2391
 
2400
2392
/* for gnu readline */
2447
2439
  free(current_db);
2448
2440
  current_db= NULL;
2449
2441
  /* In case of error below current_db will be NULL */
2450
 
  if (!drizzle_query(&drizzle, "SELECT DATABASE()") &&
2451
 
      (res= drizzle_use_result(&drizzle)))
 
2442
  if (!drizzleclient_query(&drizzle, "SELECT DATABASE()") &&
 
2443
      (res= drizzleclient_use_result(&drizzle)))
2452
2444
  {
2453
 
    DRIZZLE_ROW row= drizzle_fetch_row(res);
 
2445
    DRIZZLE_ROW row= drizzleclient_fetch_row(res);
2454
2446
    if (row[0])
2455
2447
      current_db= strdup(row[0]);
2456
 
    drizzle_free_result(res);
 
2448
    drizzleclient_free_result(res);
2457
2449
  }
2458
2450
}
2459
2451
 
2461
2453
 The different commands
2462
2454
***************************************************************************/
2463
2455
 
2464
 
int drizzle_real_query_for_lazy(const char *buf, int length)
 
2456
int drizzleclient_real_query_for_lazy(const char *buf, int length)
2465
2457
{
2466
 
  for (uint retry=0;; retry++)
 
2458
  for (uint32_t retry=0;; retry++)
2467
2459
  {
2468
2460
    int error;
2469
 
    if (!drizzle_real_query(&drizzle,buf,length))
 
2461
    if (!drizzleclient_real_query(&drizzle,buf,length))
2470
2462
      return 0;
2471
2463
    error= put_error(&drizzle);
2472
 
    if (drizzle_errno(&drizzle) != CR_SERVER_GONE_ERROR || retry > 1 ||
 
2464
    if (drizzleclient_errno(&drizzle) != CR_SERVER_GONE_ERROR || retry > 1 ||
2473
2465
        !opt_reconnect)
2474
2466
      return error;
2475
2467
    if (reconnect())
2477
2469
  }
2478
2470
}
2479
2471
 
2480
 
int drizzle_store_result_for_lazy(DRIZZLE_RES **result)
 
2472
int drizzleclient_store_result_for_lazy(DRIZZLE_RES **result)
2481
2473
{
2482
 
  if ((*result=drizzle_store_result(&drizzle)))
 
2474
  if ((*result=drizzleclient_store_result(&drizzle)))
2483
2475
    return 0;
2484
2476
 
2485
 
  if (drizzle_error(&drizzle)[0])
 
2477
  if (drizzleclient_error(&drizzle)[0])
2486
2478
    return put_error(&drizzle);
2487
2479
  return 0;
2488
2480
}
2489
2481
 
2490
 
static void print_help_item(DRIZZLE_ROW *cur, int num_name, int num_cat, char *last_char)
2491
 
{
2492
 
  char ccat= (*cur)[num_cat][0];
2493
 
  if (*last_char != ccat)
2494
 
  {
2495
 
    put_info(ccat == 'Y' ? _("categories:") : _("topics:"), INFO_INFO,0,0);
2496
 
    *last_char= ccat;
2497
 
  }
2498
 
  tee_fprintf(PAGER, "   %s\n", (*cur)[num_name]);
2499
 
}
2500
 
 
2501
 
 
2502
 
static int com_server_help(string *buffer,
2503
 
                           const char *line __attribute__((unused)),
2504
 
                           char *help_arg)
2505
 
{
2506
 
  DRIZZLE_ROW cur;
2507
 
  const char *server_cmd= buffer->c_str();
2508
 
  char cmd_buf[100];
2509
 
  DRIZZLE_RES *result;
2510
 
  int error;
2511
 
 
2512
 
  if (help_arg[0] != '\'')
2513
 
  {
2514
 
    char *end_arg= strchr(help_arg, '\0');
2515
 
    if(--end_arg)
2516
 
    {
2517
 
      while (my_isspace(charset_info,*end_arg))
2518
 
        end_arg--;
2519
 
      *++end_arg= '\0';
2520
 
    }
2521
 
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NULL);
2522
 
    server_cmd= cmd_buf;
2523
 
  }
2524
 
 
2525
 
  if (!connected && reconnect())
2526
 
    return 1;
2527
 
 
2528
 
  if ((error= drizzle_real_query_for_lazy(server_cmd,(int)strlen(server_cmd))) ||
2529
 
      (error= drizzle_store_result_for_lazy(&result)))
2530
 
    return error;
2531
 
 
2532
 
  if (result)
2533
 
  {
2534
 
    unsigned int num_fields= drizzle_num_fields(result);
2535
 
    uint64_t num_rows= drizzle_num_rows(result);
2536
 
    drizzle_fetch_fields(result);
2537
 
    if (num_fields==3 && num_rows==1)
2538
 
    {
2539
 
      if (!(cur= drizzle_fetch_row(result)))
2540
 
      {
2541
 
        error= -1;
2542
 
        goto err;
2543
 
      }
2544
 
 
2545
 
      init_pager();
2546
 
      tee_fprintf(PAGER,   _("Name: \'%s\'\n"), cur[0]);
2547
 
      tee_fprintf(PAGER,   _("Description:\n%s"), cur[1]);
2548
 
      if (cur[2] && *((char*)cur[2]))
2549
 
        tee_fprintf(PAGER, _("Examples:\n%s"), cur[2]);
2550
 
      tee_fprintf(PAGER,   "\n");
2551
 
      end_pager();
2552
 
    }
2553
 
    else if (num_fields >= 2 && num_rows)
2554
 
    {
2555
 
      init_pager();
2556
 
      char last_char= 0;
2557
 
 
2558
 
      int num_name= 0, num_cat= 0;
2559
 
 
2560
 
      if (num_fields == 2)
2561
 
      {
2562
 
        put_info(_("Many help items for your request exist."), INFO_INFO,0,0);
2563
 
        put_info(_("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following"), INFO_INFO,0,0);
2564
 
        num_name= 0;
2565
 
        num_cat= 1;
2566
 
      }
2567
 
      else if ((cur= drizzle_fetch_row(result)))
2568
 
      {
2569
 
        tee_fprintf(PAGER, _("You asked for help about help category: '%s'\n"), cur[0]);
2570
 
        put_info(_("For more information, type 'help <item>', where <item> is one of the following"), INFO_INFO,0,0);
2571
 
        num_name= 1;
2572
 
        num_cat= 2;
2573
 
        print_help_item(&cur,1,2,&last_char);
2574
 
      }
2575
 
 
2576
 
      while ((cur= drizzle_fetch_row(result)))
2577
 
        print_help_item(&cur,num_name,num_cat,&last_char);
2578
 
      tee_fprintf(PAGER, "\n");
2579
 
      end_pager();
2580
 
    }
2581
 
    else
2582
 
    {
2583
 
      put_info(_("\nNothing found"), INFO_INFO,0,0);
2584
 
      put_info(_("Please try to run 'help contents' for a list of all accessible topics\n"), INFO_INFO,0,0);
2585
 
    }
2586
 
  }
2587
 
 
2588
 
err:
2589
 
  drizzle_free_result(result);
2590
 
  return error;
2591
 
}
2592
 
 
2593
2482
static int
2594
 
com_help(string *buffer __attribute__((unused)),
2595
 
         const char *line __attribute__((unused)))
 
2483
com_help(string *buffer, const char *)
2596
2484
{
2597
2485
  register int i, j;
2598
 
  char * help_arg= strchr(line,' '), buff[32], *end;
2599
 
  if (help_arg)
2600
 
  {
2601
 
    while (my_isspace(charset_info,*help_arg))
2602
 
      help_arg++;
2603
 
    if (*help_arg) return com_server_help(buffer,line,help_arg);
2604
 
  }
 
2486
  char buff[32], *end;
2605
2487
 
2606
2488
  put_info(_("List of all Drizzle commands:"), INFO_INFO,0,0);
2607
2489
  if (!named_cmds)
2608
2490
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
2609
2491
  for (i = 0; commands[i].name; i++)
2610
2492
  {
2611
 
    end= my_stpcpy(buff, commands[i].name);
 
2493
    end= strcpy(buff, commands[i].name);
 
2494
    end+= strlen(commands[i].name);
2612
2495
    for (j= (int)strlen(commands[i].name); j < 10; j++)
2613
 
      end= my_stpcpy(end, " ");
 
2496
      end= strcpy(end, " ")+1;
2614
2497
    if (commands[i].func)
2615
2498
      tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2616
2499
                  commands[i].cmd_char, _(commands[i].doc));
2617
2500
  }
2618
 
  if (connected && drizzle_get_server_version(&drizzle) >= 40100)
2619
 
    put_info(_("\nFor server side help, type 'help contents'\n"), INFO_INFO,0,0);
 
2501
  tee_fprintf(stdout, "\n");
 
2502
  buffer->clear();
2620
2503
  return 0;
2621
2504
}
2622
2505
 
2623
2506
 
2624
2507
static int
2625
 
com_clear(string *buffer,
2626
 
          const char *line __attribute__((unused)))
 
2508
com_clear(string *buffer, const char *)
2627
2509
{
2628
2510
  if (status.add_to_history)
2629
2511
    fix_history(buffer);
2639
2521
  1  if fatal error
2640
2522
*/
2641
2523
static int
2642
 
com_go(string *buffer,
2643
 
       const char *line __attribute__((unused)))
 
2524
com_go(string *buffer, const char *)
2644
2525
{
2645
2526
  char          buff[200]; /* about 110 chars used so far */
2646
2527
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2647
2528
  DRIZZLE_RES     *result;
2648
2529
  uint32_t         timer, warnings= 0;
2649
 
  uint          error= 0;
 
2530
  uint32_t          error= 0;
2650
2531
  int           err= 0;
2651
2532
 
2652
2533
  interrupted_query= 0;
2680
2561
 
2681
2562
  timer=start_timer();
2682
2563
  executing_query= 1;
2683
 
  error= drizzle_real_query_for_lazy(buffer->c_str(),buffer->length());
 
2564
  error= drizzleclient_real_query_for_lazy(buffer->c_str(),buffer->length());
2684
2565
 
2685
2566
  if (status.add_to_history)
2686
2567
  {
2700
2581
 
2701
2582
    if (quick)
2702
2583
    {
2703
 
      if (!(result=drizzle_use_result(&drizzle)) && drizzle_field_count(&drizzle))
 
2584
      if (!(result=drizzleclient_use_result(&drizzle)) && drizzleclient_field_count(&drizzle))
2704
2585
      {
2705
2586
        error= put_error(&drizzle);
2706
2587
        goto end;
2708
2589
    }
2709
2590
    else
2710
2591
    {
2711
 
      error= drizzle_store_result_for_lazy(&result);
 
2592
      error= drizzleclient_store_result_for_lazy(&result);
2712
2593
      if (error)
2713
2594
        goto end;
2714
2595
    }
2721
2602
    /* Every branch must truncate  buff . */
2722
2603
    if (result)
2723
2604
    {
2724
 
      if (!drizzle_num_rows(result) && ! quick && !column_types_flag)
 
2605
      if (!drizzleclient_num_rows(result) && ! quick && !column_types_flag)
2725
2606
      {
2726
 
        my_stpcpy(buff, _("Empty set"));
 
2607
        strcpy(buff, _("Empty set"));
2727
2608
      }
2728
2609
      else
2729
2610
      {
2737
2618
          print_table_data(result);
2738
2619
        sprintf(buff,
2739
2620
                ngettext("%ld row in set","%ld rows in set",
2740
 
                         (long) drizzle_num_rows(result)),
2741
 
                (long) drizzle_num_rows(result));
 
2621
                         (long) drizzleclient_num_rows(result)),
 
2622
                (long) drizzleclient_num_rows(result));
2742
2623
        end_pager();
2743
 
        if (drizzle_errno(&drizzle))
 
2624
        if (drizzleclient_errno(&drizzle))
2744
2625
          error= put_error(&drizzle);
2745
2626
      }
2746
2627
    }
2747
 
    else if (drizzle_affected_rows(&drizzle) == ~(uint64_t) 0)
2748
 
      my_stpcpy(buff,_("Query OK"));
 
2628
    else if (drizzleclient_affected_rows(&drizzle) == ~(uint64_t) 0)
 
2629
      strcpy(buff,_("Query OK"));
2749
2630
    else
2750
2631
      sprintf(buff, ngettext("Query OK, %ld row affected",
2751
2632
                             "Query OK, %ld rows affected",
2752
 
                             (long) drizzle_affected_rows(&drizzle)),
2753
 
              (long) drizzle_affected_rows(&drizzle));
 
2633
                             (long) drizzleclient_affected_rows(&drizzle)),
 
2634
              (long) drizzleclient_affected_rows(&drizzle));
2754
2635
 
2755
2636
    pos= strchr(buff, '\0');
2756
 
    if ((warnings= drizzle_warning_count(&drizzle)))
 
2637
    if ((warnings= drizzleclient_warning_count(&drizzle)))
2757
2638
    {
2758
2639
      *pos++= ',';
2759
2640
      *pos++= ' ';
2760
 
      pos=int10_to_str(warnings, pos, 10);
2761
 
      pos=my_stpcpy(pos, " warning");
 
2641
      pos= int10_to_str(warnings, pos, 10);
 
2642
      pos= strcpy(pos, " warning")+8;
2762
2643
      if (warnings != 1)
2763
2644
        *pos++= 's';
2764
2645
    }
2765
 
    my_stpcpy(pos, time_buff);
 
2646
    strcpy(pos, time_buff);
2766
2647
    put_info(buff,INFO_RESULT,0,0);
2767
 
    if (drizzle_info(&drizzle))
2768
 
      put_info(drizzle_info(&drizzle),INFO_RESULT,0,0);
 
2648
    if (drizzleclient_info(&drizzle))
 
2649
      put_info(drizzleclient_info(&drizzle),INFO_RESULT,0,0);
2769
2650
    put_info("",INFO_RESULT,0,0);      // Empty row
2770
2651
 
2771
 
    if (result && !drizzle_eof(result))  /* Something wrong when using quick */
 
2652
    if (result && !drizzleclient_eof(result))  /* Something wrong when using quick */
2772
2653
      error= put_error(&drizzle);
2773
2654
    else if (unbuffered)
2774
2655
      fflush(stdout);
2775
 
    drizzle_free_result(result);
2776
 
  } while (!(err= drizzle_next_result(&drizzle)));
 
2656
    drizzleclient_free_result(result);
 
2657
  } while (!(err= drizzleclient_next_result(&drizzle)));
2777
2658
  if (err >= 1)
2778
2659
    error= put_error(&drizzle);
2779
2660
 
2818
2699
  FILE* new_outfile;
2819
2700
  if (opt_outfile)
2820
2701
    end_tee();
2821
 
  if (!(new_outfile= my_fopen(file_name, O_APPEND | O_WRONLY, MYF(MY_WME))))
 
2702
  if (!(new_outfile= fopen(file_name, "a")))
2822
2703
  {
2823
2704
    tee_fprintf(stdout, "Error logging to file '%s'\n", file_name);
2824
2705
    return;
2825
2706
  }
2826
2707
  OUTFILE = new_outfile;
2827
 
  strmake(outfile, file_name, FN_REFLEN-1);
 
2708
  strncpy(outfile, file_name, FN_REFLEN-1);
2828
2709
  tee_fprintf(stdout, "Logging to file '%s'\n", file_name);
2829
2710
  opt_outfile= 1;
 
2711
 
2830
2712
  return;
2831
2713
}
2832
2714
 
2833
2715
 
2834
2716
static void end_tee()
2835
2717
{
2836
 
  my_fclose(OUTFILE, MYF(0));
 
2718
  fclose(OUTFILE);
2837
2719
  OUTFILE= 0;
2838
2720
  opt_outfile= 0;
2839
2721
  return;
2856
2738
{
2857
2739
  switch (type) {
2858
2740
    case DRIZZLE_TYPE_BLOB:        return "BLOB";
2859
 
    case DRIZZLE_TYPE_NEWDATE:        return "DATE";
 
2741
    case DRIZZLE_TYPE_DATE:        return "DATE";
2860
2742
    case DRIZZLE_TYPE_DATETIME:    return "DATETIME";
2861
2743
    case DRIZZLE_TYPE_NEWDECIMAL:  return "DECIMAL";
2862
2744
    case DRIZZLE_TYPE_DOUBLE:      return "DOUBLE";
2864
2746
    case DRIZZLE_TYPE_LONG:        return "LONG";
2865
2747
    case DRIZZLE_TYPE_LONGLONG:    return "LONGLONG";
2866
2748
    case DRIZZLE_TYPE_NULL:        return "NULL";
2867
 
    case DRIZZLE_TYPE_TIME:        return "TIME";
2868
2749
    case DRIZZLE_TYPE_TIMESTAMP:   return "TIMESTAMP";
2869
2750
    case DRIZZLE_TYPE_TINY:        return "TINY";
 
2751
    case DRIZZLE_TYPE_VIRTUAL:     return "VIRTUAL";
2870
2752
    default:                     return "?-unknown-?";
2871
2753
  }
2872
2754
}
2873
2755
 
2874
 
static char *fieldflags2str(uint f) {
 
2756
static char *fieldflags2str(uint32_t f) {
2875
2757
  static char buf[1024];
2876
2758
  char *s=buf;
2877
2759
  *s=0;
2878
2760
#define ff2s_check_flag(X)                                              \
2879
 
  if (f & X ## _FLAG) { s=my_stpcpy(s, # X " "); f &= ~ X ## _FLAG; }
 
2761
  if (f & X ## _FLAG) { s=strcpy(s, # X " ")+strlen(# X " "); \
 
2762
                        f &= ~ X ## _FLAG; }
2880
2763
  ff2s_check_flag(NOT_NULL);
2881
2764
  ff2s_check_flag(PRI_KEY);
2882
2765
  ff2s_check_flag(UNIQUE_KEY);
2905
2788
print_field_types(DRIZZLE_RES *result)
2906
2789
{
2907
2790
  DRIZZLE_FIELD   *field;
2908
 
  uint i=0;
 
2791
  uint32_t i=0;
2909
2792
 
2910
 
  while ((field = drizzle_fetch_field(result)))
 
2793
  while ((field = drizzleclient_fetch_field(result)))
2911
2794
  {
2912
2795
    tee_fprintf(PAGER, "Field %3u:  `%s`\n"
2913
2796
                "Catalog:    `%s`\n"
2938
2821
  DRIZZLE_FIELD   *field;
2939
2822
  bool          *num_flag;
2940
2823
  string separator;
2941
 
  
 
2824
 
2942
2825
  separator.reserve(256);
2943
2826
 
2944
 
  num_flag=(bool*) my_malloc(sizeof(bool)*drizzle_num_fields(result),
2945
 
                             MYF(MY_WME));
 
2827
  num_flag=(bool*) malloc(sizeof(bool)*drizzleclient_num_fields(result));
2946
2828
  if (column_types_flag)
2947
2829
  {
2948
2830
    print_field_types(result);
2949
 
    if (!drizzle_num_rows(result))
 
2831
    if (!drizzleclient_num_rows(result))
2950
2832
      return;
2951
 
    drizzle_field_seek(result,0);
 
2833
    drizzleclient_field_seek(result,0);
2952
2834
  }
2953
2835
  separator.append("+");
2954
 
  while ((field = drizzle_fetch_field(result)))
 
2836
  while ((field = drizzleclient_fetch_field(result)))
2955
2837
  {
2956
 
    uint32_t length= column_names ? field->name_length : 0;
 
2838
    uint32_t x, length= 0;
 
2839
 
 
2840
    if (column_names)
 
2841
    {
 
2842
      /* Check if the max_byte value is really the maximum in terms
 
2843
         of visual length since multibyte characters can affect the
 
2844
         length of the separator. */
 
2845
      length= charset_info->cset->numcells(charset_info,
 
2846
                                           field->name,
 
2847
                                           field->name+field->name_length);
 
2848
 
 
2849
      if (field->name_length == field->max_length)
 
2850
      {
 
2851
        if (length < field->max_length)
 
2852
          field->max_length= length;
 
2853
      }
 
2854
      else
 
2855
      {
 
2856
        length= field->name_length;
 
2857
      }
 
2858
    }
 
2859
  
2957
2860
    if (quick)
2958
2861
      length=max(length,field->length);
2959
2862
    else
2962
2865
      // Room for "NULL"
2963
2866
      length=4;
2964
2867
    field->max_length=length;
2965
 
    uint x;
 
2868
 
2966
2869
    for (x=0; x< (length+2); x++)
2967
2870
      separator.append("-");
2968
2871
    separator.append("+");
2971
2874
  tee_puts((char*) separator.c_str(), PAGER);
2972
2875
  if (column_names)
2973
2876
  {
2974
 
    drizzle_field_seek(result,0);
 
2877
    drizzleclient_field_seek(result,0);
2975
2878
    (void) tee_fputs("|", PAGER);
2976
 
    for (uint off=0; (field = drizzle_fetch_field(result)) ; off++)
 
2879
    for (uint32_t off=0; (field = drizzleclient_fetch_field(result)) ; off++)
2977
2880
    {
2978
 
      uint name_length= (uint) strlen(field->name);
2979
 
      uint numcells= charset_info->cset->numcells(charset_info,
 
2881
      uint32_t name_length= (uint32_t) strlen(field->name);
 
2882
      uint32_t numcells= charset_info->cset->numcells(charset_info,
2980
2883
                                                  field->name,
2981
2884
                                                  field->name + name_length);
2982
2885
      uint32_t display_length= field->max_length + name_length - numcells;
2983
2886
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
2984
2887
                                             MAX_COLUMN_LENGTH),
2985
2888
                  field->name);
2986
 
      num_flag[off]= ((field->type <= DRIZZLE_TYPE_LONGLONG) || 
 
2889
      num_flag[off]= ((field->type <= DRIZZLE_TYPE_LONGLONG) ||
2987
2890
                      (field->type == DRIZZLE_TYPE_NEWDECIMAL));
2988
2891
    }
2989
2892
    (void) tee_fputs("\n", PAGER);
2990
2893
    tee_puts((char*) separator.c_str(), PAGER);
2991
2894
  }
2992
2895
 
2993
 
  while ((cur= drizzle_fetch_row(result)))
 
2896
  while ((cur= drizzleclient_fetch_row(result)))
2994
2897
  {
2995
2898
    if (interrupted_query)
2996
2899
      break;
2997
 
    uint32_t *lengths= drizzle_fetch_lengths(result);
 
2900
    uint32_t *lengths= drizzleclient_fetch_lengths(result);
2998
2901
    (void) tee_fputs("| ", PAGER);
2999
 
    drizzle_field_seek(result, 0);
3000
 
    for (uint off= 0; off < drizzle_num_fields(result); off++)
 
2902
    drizzleclient_field_seek(result, 0);
 
2903
    for (uint32_t off= 0; off < drizzleclient_num_fields(result); off++)
3001
2904
    {
3002
2905
      const char *buffer;
3003
 
      uint data_length;
3004
 
      uint field_max_length;
3005
 
      uint visible_length;
3006
 
      uint extra_padding;
 
2906
      uint32_t data_length;
 
2907
      uint32_t field_max_length;
 
2908
      uint32_t visible_length;
 
2909
      uint32_t extra_padding;
3007
2910
 
3008
2911
      if (cur[off] == NULL)
3009
2912
      {
3013
2916
      else
3014
2917
      {
3015
2918
        buffer= cur[off];
3016
 
        data_length= (uint) lengths[off];
 
2919
        data_length= (uint32_t) lengths[off];
3017
2920
      }
3018
2921
 
3019
 
      field= drizzle_fetch_field(result);
 
2922
      field= drizzleclient_fetch_field(result);
3020
2923
      field_max_length= field->max_length;
3021
2924
 
3022
2925
      /*
3066
2969
*/
3067
2970
static int get_field_disp_length(DRIZZLE_FIELD *field)
3068
2971
{
3069
 
  uint length= column_names ? field->name_length : 0;
 
2972
  uint32_t length= column_names ? field->name_length : 0;
3070
2973
 
3071
2974
  if (quick)
3072
2975
    length= max(length, field->length);
3093
2996
  DRIZZLE_FIELD *field;
3094
2997
  DRIZZLE_FIELD_OFFSET offset;
3095
2998
 
3096
 
  offset= drizzle_field_tell(result);
 
2999
  offset= drizzleclient_field_tell(result);
3097
3000
  assert(offset == 0);
3098
3001
 
3099
 
  while ((field= drizzle_fetch_field(result)) != NULL)
 
3002
  while ((field= drizzleclient_fetch_field(result)) != NULL)
3100
3003
    len+= get_field_disp_length(field) + 3; /* plus bar, space, & final space */
3101
3004
 
3102
 
  (void) drizzle_field_seek(result, offset);
 
3005
  (void) drizzleclient_field_seek(result, offset);
3103
3006
 
3104
3007
  return len + 1; /* plus final bar. */
3105
3008
}
3138
3041
print_table_data_vertically(DRIZZLE_RES *result)
3139
3042
{
3140
3043
  DRIZZLE_ROW  cur;
3141
 
  uint    max_length=0;
 
3044
  uint32_t    max_length=0;
3142
3045
  DRIZZLE_FIELD  *field;
3143
3046
 
3144
 
  while ((field = drizzle_fetch_field(result)))
 
3047
  while ((field = drizzleclient_fetch_field(result)))
3145
3048
  {
3146
 
    uint length= field->name_length;
 
3049
    uint32_t length= field->name_length;
3147
3050
    if (length > max_length)
3148
3051
      max_length= length;
3149
3052
    field->max_length=length;
3150
3053
  }
3151
3054
 
3152
 
  drizzle_field_seek(result,0);
3153
 
  for (uint row_count=1; (cur= drizzle_fetch_row(result)); row_count++)
 
3055
  drizzleclient_field_seek(result,0);
 
3056
  for (uint32_t row_count=1; (cur= drizzleclient_fetch_row(result)); row_count++)
3154
3057
  {
3155
3058
    if (interrupted_query)
3156
3059
      break;
3157
 
    drizzle_field_seek(result,0);
 
3060
    drizzleclient_field_seek(result,0);
3158
3061
    tee_fprintf(PAGER,
3159
3062
                "*************************** %d. row ***************************\n", row_count);
3160
 
    for (uint off=0; off < drizzle_num_fields(result); off++)
 
3063
    for (uint32_t off=0; off < drizzleclient_num_fields(result); off++)
3161
3064
    {
3162
 
      field= drizzle_fetch_field(result);
 
3065
      field= drizzleclient_fetch_field(result);
3163
3066
      tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
3164
3067
      tee_fprintf(PAGER, "%s\n",cur[off] ? (char*) cur[off] : "NULL");
3165
3068
    }
3175
3078
  DRIZZLE_RES    *result;
3176
3079
  DRIZZLE_ROW    cur;
3177
3080
  uint64_t num_rows;
3178
 
 
 
3081
 
3179
3082
  /* Save current error before calling "show warnings" */
3180
 
  uint error= drizzle_errno(&drizzle);
 
3083
  uint32_t error= drizzleclient_errno(&drizzle);
3181
3084
 
3182
3085
  /* Get the warnings */
3183
3086
  query= "show warnings";
3184
 
  drizzle_real_query_for_lazy(query, strlen(query));
3185
 
  drizzle_store_result_for_lazy(&result);
 
3087
  drizzleclient_real_query_for_lazy(query, strlen(query));
 
3088
  drizzleclient_store_result_for_lazy(&result);
3186
3089
 
3187
3090
  /* Bail out when no warnings */
3188
 
  if (!(num_rows= drizzle_num_rows(result)))
 
3091
  if (!(num_rows= drizzleclient_num_rows(result)))
3189
3092
    goto end;
3190
3093
 
3191
 
  cur= drizzle_fetch_row(result);
 
3094
  cur= drizzleclient_fetch_row(result);
3192
3095
 
3193
3096
  /*
3194
3097
    Don't print a duplicate of the current error.  It is possible for SHOW
3196
3099
    messages.  To be safe, skip printing the duplicate only if it is the only
3197
3100
    warning.
3198
3101
  */
3199
 
  if (!cur || (num_rows == 1 && error == (uint) strtoul(cur[1], NULL, 10)))
 
3102
  if (!cur || (num_rows == 1 && error == (uint32_t) strtoul(cur[1], NULL, 10)))
3200
3103
    goto end;
3201
3104
 
3202
3105
  /* Print the warnings */
3204
3107
  do
3205
3108
  {
3206
3109
    tee_fprintf(PAGER, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
3207
 
  } while ((cur= drizzle_fetch_row(result)));
 
3110
  } while ((cur= drizzleclient_fetch_row(result)));
3208
3111
  end_pager();
3209
3112
 
3210
3113
end:
3211
 
  drizzle_free_result(result);
 
3114
  drizzleclient_free_result(result);
3212
3115
}
3213
3116
 
3214
3117
 
3259
3162
  if (opt_silent < 2 && column_names)
3260
3163
  {
3261
3164
    int first=0;
3262
 
    while ((field = drizzle_fetch_field(result)))
 
3165
    while ((field = drizzleclient_fetch_field(result)))
3263
3166
    {
3264
3167
      if (first++)
3265
3168
        (void) tee_fputs("\t", PAGER);
3267
3170
    }
3268
3171
    (void) tee_fputs("\n", PAGER);
3269
3172
  }
3270
 
  while ((cur = drizzle_fetch_row(result)))
 
3173
  while ((cur = drizzleclient_fetch_row(result)))
3271
3174
  {
3272
 
    lengths= drizzle_fetch_lengths(result);
 
3175
    lengths= drizzleclient_fetch_lengths(result);
3273
3176
    safe_put_field(cur[0],lengths[0]);
3274
 
    for (uint off=1 ; off < drizzle_num_fields(result); off++)
 
3177
    for (uint32_t off=1 ; off < drizzleclient_num_fields(result); off++)
3275
3178
    {
3276
3179
      (void) tee_fputs("\t", PAGER);
3277
3180
      safe_put_field(cur[off], lengths[off]);
3281
3184
}
3282
3185
 
3283
3186
static int
3284
 
com_tee(string *buffer __attribute__((unused)), const char *line )
 
3187
com_tee(string *, const char *line )
3285
3188
{
3286
 
  char file_name[FN_REFLEN], *end, *param;
 
3189
  char file_name[FN_REFLEN], *end;
 
3190
  const char *param;
3287
3191
 
3288
3192
  if (status.batch)
3289
3193
    return 0;
3308
3212
  /* eliminate the spaces before the parameters */
3309
3213
  while (my_isspace(charset_info,*param))
3310
3214
    param++;
3311
 
  end= strmake(file_name, param, sizeof(file_name) - 1);
 
3215
  strncpy(file_name, param, sizeof(file_name) - 1);
 
3216
  end= file_name + strlen(file_name);
3312
3217
  /* remove end space from command line */
3313
3218
  while (end > file_name && (my_isspace(charset_info,end[-1]) ||
3314
3219
                             my_iscntrl(charset_info,end[-1])))
3325
3230
 
3326
3231
 
3327
3232
static int
3328
 
com_notee(string *buffer __attribute__((unused)),
3329
 
          const char *line __attribute__((unused)))
 
3233
com_notee(string *, const char *)
3330
3234
{
3331
3235
  if (opt_outfile)
3332
3236
    end_tee();
3339
3243
*/
3340
3244
 
3341
3245
static int
3342
 
com_pager(string *buffer __attribute__((unused)),
3343
 
          const char *line __attribute__((unused)))
 
3246
com_pager(string *, const char *line)
3344
3247
{
3345
 
  char pager_name[FN_REFLEN], *end, *param;
 
3248
  char pager_name[FN_REFLEN], *end;
 
3249
  const char *param;
3346
3250
 
3347
3251
  if (status.batch)
3348
3252
    return 0;
3360
3264
    {
3361
3265
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3362
3266
      opt_nopager=1;
3363
 
      my_stpcpy(pager, "stdout");
 
3267
      strcpy(pager, "stdout");
3364
3268
      PAGER= stdout;
3365
3269
      return 0;
3366
3270
    }
3367
 
    my_stpcpy(pager, default_pager);
 
3271
    strcpy(pager, default_pager);
3368
3272
  }
3369
3273
  else
3370
3274
  {
3371
 
    end= strmake(pager_name, param, sizeof(pager_name)-1);
 
3275
    end= strncpy(pager_name, param, sizeof(pager_name)-1);
 
3276
    end+= strlen(pager_name);
3372
3277
    while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
3373
3278
                                my_iscntrl(charset_info,end[-1])))
3374
3279
      end--;
3375
3280
    end[0]=0;
3376
 
    my_stpcpy(pager, pager_name);
3377
 
    my_stpcpy(default_pager, pager_name);
 
3281
    strcpy(pager, pager_name);
 
3282
    strcpy(default_pager, pager_name);
3378
3283
  }
3379
3284
  opt_nopager=0;
3380
3285
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3383
3288
 
3384
3289
 
3385
3290
static int
3386
 
com_nopager(string *buffer __attribute__((unused)),
3387
 
            const char *line __attribute__((unused)))
 
3291
com_nopager(string *, const char *)
3388
3292
{
3389
 
  my_stpcpy(pager, "stdout");
 
3293
  strcpy(pager, "stdout");
3390
3294
  opt_nopager=1;
3391
3295
  PAGER= stdout;
3392
3296
  tee_fprintf(stdout, "PAGER set to stdout\n");
3396
3300
/* If arg is given, exit without errors. This happens on command 'quit' */
3397
3301
 
3398
3302
static int
3399
 
com_quit(string *buffer __attribute__((unused)),
3400
 
         const char *line __attribute__((unused)))
 
3303
com_quit(string *, const char *)
3401
3304
{
3402
3305
  /* let the screen auto close on a normal shutdown */
3403
3306
  status.exit_status=0;
3405
3308
}
3406
3309
 
3407
3310
static int
3408
 
com_rehash(string *buffer __attribute__((unused)),
3409
 
           const char *line __attribute__((unused)))
 
3311
com_rehash(string *, const char *)
3410
3312
{
3411
3313
  build_completion_hash(1, 0);
3412
3314
  return 0;
3415
3317
 
3416
3318
 
3417
3319
static int
3418
 
com_print(string *buffer,const char *line __attribute__((unused)))
 
3320
com_print(string *buffer,const char *)
3419
3321
{
3420
3322
  tee_puts("--------------", stdout);
3421
3323
  (void) tee_fputs(buffer->c_str(), stdout);
3442
3344
      Two null bytes are needed in the end of buff to allow
3443
3345
      get_arg to find end of string the second time it's called.
3444
3346
    */
3445
 
    tmp= strmake(buff, line, sizeof(buff)-2);
 
3347
    tmp= strncpy(buff, line, sizeof(buff)-2);
3446
3348
#ifdef EXTRA_DEBUG
3447
3349
    tmp[1]= 0;
3448
3350
#endif
3474
3376
 
3475
3377
  if (connected)
3476
3378
  {
3477
 
    sprintf(buff,"Connection id:    %u",drizzle_thread_id(&drizzle));
 
3379
    sprintf(buff,"Connection id:    %u",drizzleclient_thread_id(&drizzle));
3478
3380
    put_info(buff,INFO_INFO,0,0);
3479
3381
    sprintf(buff,"Current database: %.128s\n",
3480
3382
            current_db ? current_db : "*** NONE ***");
3484
3386
}
3485
3387
 
3486
3388
 
3487
 
static int com_source(string *buffer __attribute__((unused)), const char *line)
 
3389
static int com_source(string *, const char *line)
3488
3390
{
3489
 
  char source_name[FN_REFLEN], *end, *param;
 
3391
  char source_name[FN_REFLEN], *end;
 
3392
  const char *param;
3490
3393
  LINE_BUFFER *line_buff;
3491
3394
  int error;
3492
3395
  STATUS old_status;
3500
3403
                    INFO_ERROR, 0,0);
3501
3404
  while (my_isspace(charset_info,*param))
3502
3405
    param++;
3503
 
  end=strmake(source_name,param,sizeof(source_name)-1);
 
3406
  end= strncpy(source_name,param,sizeof(source_name)-1);
 
3407
  end+= strlen(source_name);
3504
3408
  while (end > source_name && (my_isspace(charset_info,end[-1]) ||
3505
3409
                               my_iscntrl(charset_info,end[-1])))
3506
3410
    end--;
3507
3411
  end[0]=0;
3508
3412
  unpack_filename(source_name,source_name);
3509
3413
  /* open file name */
3510
 
  if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0))))
 
3414
  if (!(sql_file = fopen(source_name, "r")))
3511
3415
  {
3512
3416
    char buff[FN_REFLEN+60];
3513
3417
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3516
3420
 
3517
3421
  if (!(line_buff=batch_readline_init(opt_max_allowed_packet+512,sql_file)))
3518
3422
  {
3519
 
    my_fclose(sql_file,MYF(0));
 
3423
    fclose(sql_file);
3520
3424
    return put_info("Can't initialize batch_readline", INFO_ERROR, 0 ,0);
3521
3425
  }
3522
3426
 
3534
3438
  error= read_and_execute(false);
3535
3439
  // Continue as before
3536
3440
  status=old_status;
3537
 
  my_fclose(sql_file,MYF(0));
 
3441
  fclose(sql_file);
3538
3442
  batch_readline_end(line_buff);
3539
3443
  return error;
3540
3444
}
3542
3446
 
3543
3447
/* ARGSUSED */
3544
3448
static int
3545
 
com_delimiter(string *buffer __attribute__((unused)), const char *line)
 
3449
com_delimiter(string *, const char *line)
3546
3450
{
3547
3451
  char buff[256], *tmp;
3548
3452
 
3549
 
  strmake(buff, line, sizeof(buff) - 1);
 
3453
  strncpy(buff, line, sizeof(buff) - 1);
3550
3454
  tmp= get_arg(buff, 0);
3551
3455
 
3552
3456
  if (!tmp || !*tmp)
3564
3468
      return 0;
3565
3469
    }
3566
3470
  }
3567
 
  strmake(delimiter, tmp, sizeof(delimiter) - 1);
 
3471
  strncpy(delimiter, tmp, sizeof(delimiter) - 1);
3568
3472
  delimiter_length= (int)strlen(delimiter);
3569
3473
  delimiter_str= delimiter;
3570
3474
  return 0;
3572
3476
 
3573
3477
/* ARGSUSED */
3574
3478
static int
3575
 
com_use(string *buffer __attribute__((unused)), const char *line)
 
3479
com_use(string *, const char *line)
3576
3480
{
3577
3481
  char *tmp, buff[FN_REFLEN + 1];
3578
3482
  int select_db;
3579
3483
 
3580
3484
  memset(buff, 0, sizeof(buff));
3581
 
  strmake(buff, line, sizeof(buff) - 1);
 
3485
  strncpy(buff, line, sizeof(buff) - 1);
3582
3486
  tmp= get_arg(buff, 0);
3583
3487
  if (!tmp || !*tmp)
3584
3488
  {
3592
3496
  */
3593
3497
  get_current_db();
3594
3498
 
3595
 
  if (!current_db || cmp_database(charset_info, current_db,tmp))
 
3499
  if (!current_db || strcmp(current_db,tmp))
3596
3500
  {
3597
3501
    if (one_database)
3598
3502
    {
3599
3503
      skip_updates= 1;
3600
 
      select_db= 0;    // don't do drizzle_select_db()
 
3504
      select_db= 0;    // don't do drizzleclient_select_db()
3601
3505
    }
3602
3506
    else
3603
 
      select_db= 2;    // do drizzle_select_db() and build_completion_hash()
 
3507
      select_db= 2;    // do drizzleclient_select_db() and build_completion_hash()
3604
3508
  }
3605
3509
  else
3606
3510
  {
3607
3511
    /*
3608
3512
      USE to the current db specified.
3609
 
      We do need to send drizzle_select_db() to make server
 
3513
      We do need to send drizzleclient_select_db() to make server
3610
3514
      update database level privileges, which might
3611
3515
      change since last USE (see bug#10979).
3612
3516
      For performance purposes, we'll skip rebuilding of completion hash.
3613
3517
    */
3614
3518
    skip_updates= 0;
3615
 
    select_db= 1;      // do only drizzle_select_db(), without completion
 
3519
    select_db= 1;      // do only drizzleclient_select_db(), without completion
3616
3520
  }
3617
3521
 
3618
3522
  if (select_db)
3623
3527
    */
3624
3528
    if (!connected && reconnect())
3625
3529
      return opt_reconnect ? -1 : 1;                        // Fatal error
3626
 
    if (drizzle_select_db(&drizzle,tmp))
 
3530
    if (drizzleclient_select_db(&drizzle,tmp))
3627
3531
    {
3628
 
      if (drizzle_errno(&drizzle) != CR_SERVER_GONE_ERROR)
 
3532
      if (drizzleclient_errno(&drizzle) != CR_SERVER_GONE_ERROR)
3629
3533
        return put_error(&drizzle);
3630
3534
 
3631
3535
      if (reconnect())
3632
3536
        return opt_reconnect ? -1 : 1;                      // Fatal error
3633
 
      if (drizzle_select_db(&drizzle,tmp))
 
3537
      if (drizzleclient_select_db(&drizzle,tmp))
3634
3538
        return put_error(&drizzle);
3635
3539
    }
3636
3540
    free(current_db);
3644
3548
}
3645
3549
 
3646
3550
static int
3647
 
com_warnings(string *buffer __attribute__((unused)),
3648
 
             const char *line __attribute__((unused)))
 
3551
com_warnings(string *, const char *)
3649
3552
{
3650
3553
  show_warnings = 1;
3651
3554
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
3653
3556
}
3654
3557
 
3655
3558
static int
3656
 
com_nowarnings(string *buffer __attribute__((unused)),
3657
 
               const char *line __attribute__((unused)))
 
3559
com_nowarnings(string *, const char *)
3658
3560
{
3659
3561
  show_warnings = 0;
3660
3562
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
3710
3612
    if (*ptr == '\\' && ptr[1]) // escaped character
3711
3613
    {
3712
3614
      // Remove the backslash
3713
 
      my_stpcpy(ptr, ptr+1);
 
3615
      strcpy(ptr, ptr+1);
3714
3616
    }
3715
3617
    else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
3716
3618
    {
3725
3627
 
3726
3628
static int
3727
3629
sql_connect(char *host,char *database,char *user,char *password,
3728
 
                 uint silent)
 
3630
                 uint32_t silent)
3729
3631
{
3730
3632
  if (connected)
3731
3633
  {
3732
3634
    connected= 0;
3733
 
    drizzle_close(&drizzle);
 
3635
    drizzleclient_close(&drizzle);
3734
3636
  }
3735
 
  drizzle_create(&drizzle);
 
3637
  drizzleclient_create(&drizzle);
3736
3638
  if (opt_connect_timeout)
3737
3639
  {
3738
 
    uint timeout=opt_connect_timeout;
3739
 
    drizzle_options(&drizzle,DRIZZLE_OPT_CONNECT_TIMEOUT,
 
3640
    uint32_t timeout=opt_connect_timeout;
 
3641
    drizzleclient_options(&drizzle,DRIZZLE_OPT_CONNECT_TIMEOUT,
3740
3642
                  (char*) &timeout);
3741
3643
  }
3742
3644
  if (opt_compress)
3743
 
    drizzle_options(&drizzle,DRIZZLE_OPT_COMPRESS,NULL);
 
3645
    drizzleclient_options(&drizzle,DRIZZLE_OPT_COMPRESS,NULL);
3744
3646
  if (opt_secure_auth)
3745
 
    drizzle_options(&drizzle, DRIZZLE_SECURE_AUTH, (char *) &opt_secure_auth);
3746
 
  if (using_opt_local_infile)
3747
 
    drizzle_options(&drizzle,DRIZZLE_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
 
3647
    drizzleclient_options(&drizzle, DRIZZLE_SECURE_AUTH, (char *) &opt_secure_auth);
3748
3648
  if (safe_updates)
3749
3649
  {
3750
3650
    char init_command[100];
3751
3651
    sprintf(init_command,
3752
3652
            "SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%"PRIu32
3753
 
            ",SQL_MAX_JOIN_SIZE=%"PRIu32,
 
3653
            ",MAX_JOIN_SIZE=%"PRIu32,
3754
3654
            select_limit, max_join_size);
3755
 
    drizzle_options(&drizzle, DRIZZLE_INIT_COMMAND, init_command);
 
3655
    drizzleclient_options(&drizzle, DRIZZLE_INIT_COMMAND, init_command);
3756
3656
  }
3757
 
  if (!drizzle_connect(&drizzle, host, user, password,
 
3657
  if (!drizzleclient_connect(&drizzle, host, user, password,
3758
3658
                          database, opt_drizzle_port, opt_drizzle_unix_port,
3759
3659
                          connect_flag | CLIENT_MULTI_STATEMENTS))
3760
3660
  {
3761
3661
    if (!silent ||
3762
 
        (drizzle_errno(&drizzle) != CR_CONN_HOST_ERROR &&
3763
 
         drizzle_errno(&drizzle) != CR_CONNECTION_ERROR))
 
3662
        (drizzleclient_errno(&drizzle) != CR_CONN_HOST_ERROR &&
 
3663
         drizzleclient_errno(&drizzle) != CR_CONNECTION_ERROR))
3764
3664
    {
3765
3665
      (void) put_error(&drizzle);
3766
3666
      (void) fflush(stdout);
3776
3676
 
3777
3677
 
3778
3678
static int
3779
 
com_status(string *buffer __attribute__((unused)),
3780
 
           const char *line __attribute__((unused)))
 
3679
com_status(string *, const char *)
3781
3680
{
3782
3681
  char buff[40];
3783
3682
  uint64_t id;
3787
3686
  usage(1);          /* Print version */
3788
3687
  if (connected)
3789
3688
  {
3790
 
    tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_thread_id(&drizzle));
 
3689
    tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzleclient_thread_id(&drizzle));
3791
3690
    /*
3792
3691
      Don't remove "limit 1",
3793
3692
      it is protection againts SQL_SELECT_LIMIT=0
3794
3693
    */
3795
 
    if (!drizzle_query(&drizzle,"select DATABASE(), USER() limit 1") &&
3796
 
        (result=drizzle_use_result(&drizzle)))
 
3694
    if (!drizzleclient_query(&drizzle,"select DATABASE(), USER() limit 1") &&
 
3695
        (result=drizzleclient_use_result(&drizzle)))
3797
3696
    {
3798
 
      DRIZZLE_ROW cur=drizzle_fetch_row(result);
 
3697
      DRIZZLE_ROW cur=drizzleclient_fetch_row(result);
3799
3698
      if (cur)
3800
3699
      {
3801
3700
        tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
3802
3701
        tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
3803
3702
      }
3804
 
      drizzle_free_result(result);
 
3703
      drizzleclient_free_result(result);
3805
3704
    }
3806
3705
    tee_puts("SSL:\t\t\tNot in use", stdout);
3807
3706
  }
3822
3721
  tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
3823
3722
  tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
3824
3723
  tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&drizzle));
3825
 
  tee_fprintf(stdout, "Protocol version:\t%d\n", drizzle_get_proto_info(&drizzle));
3826
 
  tee_fprintf(stdout, "Connection:\t\t%s\n", drizzle_get_host_info(&drizzle));
3827
 
  if ((id= drizzle_insert_id(&drizzle)))
 
3724
  tee_fprintf(stdout, "Protocol version:\t%d\n", drizzleclient_get_proto_info(&drizzle));
 
3725
  tee_fprintf(stdout, "Connection:\t\t%s\n", drizzleclient_get_host_info(&drizzle));
 
3726
  if ((id= drizzleclient_insert_id(&drizzle)))
3828
3727
    tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff));
3829
3728
 
3830
3729
  /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
3831
 
  if (!drizzle_query(&drizzle,"select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1") &&
3832
 
      (result=drizzle_use_result(&drizzle)))
 
3730
  if (!drizzleclient_query(&drizzle,"select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1") &&
 
3731
      (result=drizzleclient_use_result(&drizzle)))
3833
3732
  {
3834
 
    DRIZZLE_ROW cur=drizzle_fetch_row(result);
 
3733
    DRIZZLE_ROW cur=drizzleclient_fetch_row(result);
3835
3734
    if (cur)
3836
3735
    {
3837
3736
      tee_fprintf(stdout, "Server characterset:\t%s\n", cur[2] ? cur[2] : "");
3839
3738
      tee_fprintf(stdout, "Client characterset:\t%s\n", cur[0] ? cur[0] : "");
3840
3739
      tee_fprintf(stdout, "Conn.  characterset:\t%s\n", cur[1] ? cur[1] : "");
3841
3740
    }
3842
 
    drizzle_free_result(result);
 
3741
    drizzleclient_free_result(result);
3843
3742
  }
3844
3743
 
3845
 
  if (strstr(drizzle_get_host_info(&drizzle),"TCP/IP") || ! drizzle.unix_socket)
 
3744
  if (strstr(drizzleclient_get_host_info(&drizzle),"TCP/IP") || ! drizzle.unix_socket)
3846
3745
    tee_fprintf(stdout, "TCP port:\t\t%d\n", drizzle.port);
3847
3746
  else
3848
3747
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", drizzle.unix_socket);
3868
3767
static const char *
3869
3768
server_version_string(DRIZZLE *con)
3870
3769
{
3871
 
  static char buf[MAX_SERVER_VERSION_LENGTH] = "";
 
3770
  static string buf("");
 
3771
  static bool server_version_string_reserved= false;
3872
3772
 
 
3773
  if (!server_version_string_reserved)
 
3774
  {
 
3775
    buf.reserve(MAX_SERVER_VERSION_LENGTH);
 
3776
    server_version_string_reserved= true;
 
3777
  }
3873
3778
  /* Only one thread calls this, so no synchronization is needed */
3874
3779
  if (buf[0] == '\0')
3875
3780
  {
3876
 
    char *bufp = buf;
3877
3781
    DRIZZLE_RES *result;
3878
3782
 
3879
 
    bufp= my_stpncpy(buf, drizzle_get_server_info(con), sizeof buf);
 
3783
    buf.append(drizzleclient_get_server_info(con));
3880
3784
 
3881
3785
    /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
3882
 
    if (!drizzle_query(con, "select @@version_comment limit 1") &&
3883
 
        (result = drizzle_use_result(con)))
 
3786
    if (!drizzleclient_query(con, "select @@version_comment limit 1") &&
 
3787
        (result = drizzleclient_use_result(con)))
3884
3788
    {
3885
 
      DRIZZLE_ROW cur = drizzle_fetch_row(result);
 
3789
      DRIZZLE_ROW cur = drizzleclient_fetch_row(result);
3886
3790
      if (cur && cur[0])
3887
3791
      {
3888
 
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NULL);
 
3792
        buf.append(" ");
 
3793
        buf.append(cur[0]);
3889
3794
      }
3890
 
      drizzle_free_result(result);
 
3795
      drizzleclient_free_result(result);
3891
3796
    }
3892
 
 
3893
 
    /* str*nmov doesn't guarantee NUL-termination */
3894
 
    if (bufp == buf + sizeof buf)
3895
 
      buf[sizeof buf - 1] = '\0';
3896
3797
  }
3897
3798
 
3898
 
  return buf;
 
3799
  return buf.c_str();
3899
3800
}
3900
3801
 
3901
3802
static int
3902
 
put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
 
3803
put_info(const char *str,INFO_TYPE info_type, uint32_t error, const char *sqlstate)
3903
3804
{
3904
3805
  FILE *file= (info_type == INFO_ERROR ? stderr : stdout);
3905
3806
  static int inited=0;
3973
3874
static int
3974
3875
put_error(DRIZZLE *con)
3975
3876
{
3976
 
  return put_info(drizzle_error(con), INFO_ERROR, drizzle_errno(con),
3977
 
                  drizzle_sqlstate(con));
 
3877
  return put_info(drizzleclient_error(con), INFO_ERROR, drizzleclient_errno(con),
 
3878
                  drizzleclient_sqlstate(con));
3978
3879
}
3979
3880
 
3980
3881
 
3984
3885
  const char *end= start + (buffer->length());
3985
3886
  while (start < end && !my_isgraph(charset_info,end[-1]))
3986
3887
    end--;
3987
 
  uint pos_to_truncate= (end-start);
 
3888
  uint32_t pos_to_truncate= (end-start);
3988
3889
  if (buffer->length() > pos_to_truncate)
3989
3890
    buffer->erase(pos_to_truncate);
3990
3891
}
4058
3959
  if (sec >= 3600.0*24)
4059
3960
  {
4060
3961
    tmp=(uint32_t) floor(sec/(3600.0*24));
4061
 
    sec-=3600.0*24*tmp;
4062
 
    buff=int10_to_str((long) tmp, buff, 10);
4063
 
    buff=my_stpcpy(buff,tmp > 1 ? " days " : " day ");
 
3962
    sec-= 3600.0*24*tmp;
 
3963
    buff= int10_to_str((long) tmp, buff, 10);
 
3964
 
 
3965
    if (tmp > 1)
 
3966
      buff= strcpy(buff," days ")+6;
 
3967
    else
 
3968
      buff= strcpy(buff," day ")+5;
 
3969
 
4064
3970
  }
4065
3971
  if (sec >= 3600.0)
4066
3972
  {
4067
3973
    tmp=(uint32_t) floor(sec/3600.0);
4068
3974
    sec-=3600.0*tmp;
4069
3975
    buff=int10_to_str((long) tmp, buff, 10);
4070
 
    buff=my_stpcpy(buff,tmp > 1 ? " hours " : " hour ");
 
3976
 
 
3977
    if (tmp > 1)
 
3978
      buff= strcpy(buff, " hours ")+7;
 
3979
    else
 
3980
      buff= strcpy(buff, " hour ")+6;
4071
3981
  }
4072
3982
  if (sec >= 60.0)
4073
3983
  {
4074
3984
    tmp=(uint32_t) floor(sec/60.0);
4075
3985
    sec-=60.0*tmp;
4076
3986
    buff=int10_to_str((long) tmp, buff, 10);
4077
 
    buff=my_stpcpy(buff," min ");
 
3987
    buff= strcpy(buff," min ")+5;
4078
3988
  }
4079
3989
  if (part_second)
4080
3990
    sprintf(buff,"%.2f sec",sec);
4095
4005
  buff[0]=' ';
4096
4006
  buff[1]='(';
4097
4007
  end_timer(start_time,buff+2);
4098
 
  my_stpcpy(strchr(buff, '\0'),")");
 
4008
  strcpy(strchr(buff, '\0'),")");
4099
4009
}
4100
4010
 
4101
4011
static const char * construct_prompt()
4130
4040
        break;
4131
4041
      case 'v':
4132
4042
        if (connected)
4133
 
          processed_prompt->append(drizzle_get_server_info(&drizzle));
 
4043
          processed_prompt->append(drizzleclient_get_server_info(&drizzle));
4134
4044
        else
4135
4045
          processed_prompt->append("not_connected");
4136
4046
        break;
4140
4050
      case 'h':
4141
4051
      {
4142
4052
        const char *prompt;
4143
 
        prompt= connected ? drizzle_get_host_info(&drizzle) : "not_connected";
 
4053
        prompt= connected ? drizzleclient_get_host_info(&drizzle) : "not_connected";
4144
4054
        if (strstr(prompt, "Localhost"))
4145
4055
          processed_prompt->append("localhost");
4146
4056
        else
4159
4069
          break;
4160
4070
        }
4161
4071
 
4162
 
        const char *host_info = drizzle_get_host_info(&drizzle);
 
4072
        const char *host_info = drizzleclient_get_host_info(&drizzle);
4163
4073
        if (strstr(host_info, "memory"))
4164
4074
        {
4165
4075
          processed_prompt->append(drizzle.host);
4188
4098
        break;
4189
4099
      case PROMPT_CHAR:
4190
4100
        {
4191
 
          char c= PROMPT_CHAR;
4192
 
          processed_prompt->append(&c, 1);
 
4101
          processed_prompt->append(PROMPT_CHAR, 1);
4193
4102
        }
4194
4103
        break;
4195
4104
      case 'n':
4196
4105
        {
4197
 
          char c= '\n';
4198
 
          processed_prompt->append(&c, 1);
 
4106
          processed_prompt->append('\n', 1);
4199
4107
        }
4200
4108
        break;
4201
4109
      case ' ':
4202
4110
      case '_':
4203
4111
        {
4204
 
          char c= ' ';
4205
 
          processed_prompt->append(&c, 1);
 
4112
          processed_prompt->append(' ', 1);
4206
4113
        }
4207
4114
        break;
4208
4115
      case 'R':
4290
4197
  free(part_username);
4291
4198
 
4292
4199
  DRIZZLE_RES *result;
4293
 
  if (!drizzle_query(&drizzle,"select USER()") &&
4294
 
      (result=drizzle_use_result(&drizzle)))
 
4200
  if (!drizzleclient_query(&drizzle,"select USER()") &&
 
4201
      (result=drizzleclient_use_result(&drizzle)))
4295
4202
  {
4296
 
    DRIZZLE_ROW cur=drizzle_fetch_row(result);
 
4203
    DRIZZLE_ROW cur=drizzleclient_fetch_row(result);
4297
4204
    full_username= strdup(cur[0]);
4298
4205
    part_username= strdup(strtok(cur[0],"@"));
4299
 
    (void) drizzle_fetch_row(result);        // Read eof
 
4206
    (void) drizzleclient_fetch_row(result);        // Read eof
4300
4207
  }
4301
4208
}
4302
4209
 
4303
 
static int com_prompt(string *buffer __attribute__((unused)),
4304
 
                      const char *line)
 
4210
static int com_prompt(string *, const char *line)
4305
4211
{
4306
 
  char *ptr=strchr(line, ' ');
4307
 
  prompt_counter = 0;
4308
 
  free(current_prompt);
4309
 
  current_prompt= strdup(ptr ? ptr+1 : default_prompt);
4310
 
  if (!ptr)
 
4212
  const char *ptr=strchr(line, ' ');
 
4213
  if (ptr == NULL)
4311
4214
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4312
4215
                default_prompt);
 
4216
  prompt_counter = 0;
 
4217
  char * tmpptr= strdup(ptr ? ptr+1 : default_prompt);
 
4218
  if (tmpptr == NULL)
 
4219
    tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");
4313
4220
  else
 
4221
  {
 
4222
    free(current_prompt);
 
4223
    current_prompt= tmpptr;
4314
4224
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
 
4225
  }
4315
4226
  return 0;
4316
4227
}
4317
4228