~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Brian Aker
  • Date: 2009-07-11 08:51:36 UTC
  • mfrom: (1089.3.11 merge)
  • Revision ID: brian@gaz-20090711085136-qj01nwm3qynghwtc
Merge Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 *
34
34
 **/
35
35
 
 
36
#include "client_priv.h"
36
37
#include <string>
37
 
 
38
 
#include "client_priv.h"
 
38
#include <algorithm>
39
39
#include <mystrings/m_ctype.h>
40
40
#include <stdarg.h>
41
 
#ifndef __GNU_LIBRARY__
42
 
#define __GNU_LIBRARY__          // Skip warnings in getopt.h
43
 
#endif
44
 
#include <readline/history.h>
45
 
#include "my_readline.h"
 
41
#include "client/my_readline.h"
46
42
#include <signal.h>
47
 
#include <vio/violite.h>
48
43
#include <sys/ioctl.h>
49
 
 
50
 
 
51
 
#if defined(HAVE_LOCALE_H)
52
 
#include <locale.h>
53
 
#endif
54
 
 
55
 
#include <libdrizzle/gettext.h>
56
 
 
57
 
const char *VER= "14.14";
58
 
 
59
 
/* Don't try to make a nice table if the data is too big */
60
 
#define MAX_COLUMN_LENGTH       (uint32_t)1024
61
 
 
62
 
/* Buffer to hold 'version' and 'version_comment' */
63
 
#define MAX_SERVER_VERSION_LENGTH     128
64
 
 
65
 
/* Array of options to pass to libdrizzled */
66
 
#define MAX_SERVER_ARGS               64
67
 
 
68
 
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
69
 
void sql_element_free(void *ptr);
 
44
#include <drizzled/configmake.h>
70
45
 
71
46
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
72
47
#include <curses.h>
 
48
#ifdef __sun
 
49
#undef clear
 
50
#undef erase
 
51
#endif
73
52
#include <term.h>
74
53
#else
75
54
#if defined(HAVE_TERMIOS_H)
80
59
#elif defined(HAVE_ASM_TERMBITS_H) && (!defined __GLIBC__ || !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ > 0))
81
60
#include <asm/termbits.h>    // Standard linux
82
61
#endif
83
 
#undef VOID
84
62
#if defined(HAVE_TERMCAP_H)
85
63
#include <termcap.h>
86
64
#else
94
72
#endif
95
73
#endif
96
74
 
97
 
#undef bcmp                             // Fix problem with new readline
98
 
 
99
 
#ifdef HAVE_READLINE_HISTORY_H
100
 
#include <readline/history.h>
101
 
#endif
102
 
#include <readline/readline.h>
 
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 */
 
88
 
 
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 */
 
101
 
 
102
#define DRIZZLE_DEFAULT_INPUT_LINE 65536
103
103
 
104
104
/**
105
105
 Make the old readline interface look like the new one.
111
111
  completion_matches((char *)str, (CPFunction *)func)
112
112
#endif
113
113
 
 
114
#if defined(HAVE_LOCALE_H)
 
115
#include <locale.h>
 
116
#endif
 
117
 
 
118
#include <drizzled/gettext.h>
 
119
 
 
120
 
 
121
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
 
122
void sql_element_free(void *ptr);
 
123
 
114
124
 
115
125
#if !defined(HAVE_VIDATTR)
116
126
#undef vidattr
117
127
#define vidattr(A) {}      // Can't get this to work
118
128
#endif
119
129
 
120
 
#ifdef FN_NO_CASE_SENCE
121
 
#define cmp_database(cs,A,B) my_strcasecmp((cs), (A), (B))
122
 
#else
123
 
#define cmp_database(cs,A,B) strcmp((A),(B))
124
 
#endif
125
 
 
126
 
#include "completion_hash.h"
 
130
#include <iostream>
 
131
#include <map>
127
132
 
128
133
using namespace std;
129
134
 
 
135
const string VER("14.14");
 
136
/* Don't try to make a nice table if the data is too big */
 
137
const uint32_t MAX_COLUMN_LENGTH= 1024;
 
138
 
 
139
/* Buffer to hold 'version' and 'version_comment' */
 
140
const int MAX_SERVER_VERSION_LENGTH= 128;
 
141
 
130
142
#define PROMPT_CHAR '\\'
131
143
#define DEFAULT_DELIMITER ";"
132
144
 
140
152
} STATUS;
141
153
 
142
154
 
143
 
static HashTable ht;
 
155
static map<string, string>::iterator completion_iter;
 
156
static map<string, string>::iterator completion_end;
 
157
static map<string, string> completion_map;
 
158
static string completion_string;
 
159
 
144
160
static char **defaults_argv;
145
161
 
146
162
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
147
163
typedef enum enum_info_type INFO_TYPE;
148
164
 
149
 
static DRIZZLE drizzle;      /* The connection */
150
 
static bool ignore_errors=0,quick=0,
151
 
  connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
152
 
  opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
153
 
  opt_compress=0, using_opt_local_infile=0,
154
 
  vertical=0, line_numbers=1, column_names=1,
155
 
  opt_nopager=1, opt_outfile=0, named_cmds= 0,
156
 
  tty_password= 0, opt_nobeep=0, opt_reconnect=1,
157
 
  default_charset_used= 0, opt_secure_auth= 0,
158
 
  default_pager_set= 0, opt_sigint_ignore= 0,
159
 
  auto_vertical_output= 0,
160
 
  show_warnings= 0, executing_query= 0, interrupted_query= 0;
 
165
static drizzle_st drizzle;      /* The library handle */
 
166
static drizzle_con_st con;      /* The connection */
 
167
static bool ignore_errors= false, quick= false,
 
168
  connected= false, opt_raw_data= false, unbuffered= false,
 
169
  output_tables= false, opt_rehash= true, skip_updates= false,
 
170
  safe_updates= false, one_database= false,
 
171
  opt_compress= false, opt_shutdown= false, opt_ping= false,
 
172
  vertical= false, line_numbers= true, column_names= true,
 
173
  opt_nopager= true, opt_outfile= false, named_cmds= false,
 
174
  tty_password= false, opt_nobeep= false, opt_reconnect= true,
 
175
  default_charset_used= false, opt_secure_auth= false,
 
176
  default_pager_set= false, opt_sigint_ignore= false,
 
177
  auto_vertical_output= false,
 
178
  show_warnings= false, executing_query= false, interrupted_query= false;
 
179
static uint32_t  show_progress_size= 0;
161
180
static bool debug_info_flag, debug_check_flag;
162
181
static bool column_types_flag;
163
 
static bool preserve_comments= 0;
164
 
static uint32_t opt_max_allowed_packet, opt_net_buffer_length;
165
 
static int verbose=0,opt_silent=0,opt_drizzle_port=0, opt_local_infile=0;
166
 
static uint my_end_arg;
167
 
static char * opt_drizzle_unix_port=0;
168
 
static int connect_flag=CLIENT_INTERACTIVE;
169
 
static char *current_host,*current_db,*current_user=0,*opt_password=0,
170
 
  *delimiter_str= 0,* current_prompt= 0,
171
 
  *default_charset= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
 
182
static bool preserve_comments= false;
 
183
static uint32_t opt_max_input_line, opt_drizzle_port= 0;
 
184
static int verbose= 0, opt_silent= 0, opt_local_infile= 0;
 
185
static uint32_t my_end_arg;
 
186
static char * opt_drizzle_unix_port= NULL;
 
187
static drizzle_capabilities_t connect_flag= DRIZZLE_CAPABILITIES_NONE;
 
188
static char *current_host, *current_db, *current_user= NULL,
 
189
  *opt_password= NULL, *delimiter_str= NULL, *current_prompt= NULL;
172
190
static char *histfile;
173
191
static char *histfile_tmp;
174
192
static string *glob_buffer;
175
193
static string *processed_prompt= NULL;
176
194
static char *default_prompt= NULL;
177
 
static char *full_username=0,*part_username=0;
 
195
static char *full_username= NULL,*part_username= NULL;
178
196
static STATUS status;
179
197
static uint32_t select_limit;
180
198
static uint32_t max_join_size;
181
199
static uint32_t opt_connect_timeout= 0;
182
 
static char drizzle_charsets_dir[FN_REFLEN+1];
183
200
// TODO: Need to i18n these
184
 
static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
185
 
static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
 
201
static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 
202
static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
186
203
                                  "Aug","Sep","Oct","Nov","Dec"};
187
204
static char default_pager[FN_REFLEN];
188
205
static char pager[FN_REFLEN], outfile[FN_REFLEN];
189
206
static FILE *PAGER, *OUTFILE;
190
 
static MEM_ROOT hash_mem_root;
191
 
static uint prompt_counter;
 
207
static uint32_t prompt_counter;
192
208
static char delimiter[16]= DEFAULT_DELIMITER;
193
 
static uint delimiter_length= 1;
 
209
static uint32_t delimiter_length= 1;
194
210
unsigned short terminal_width= 80;
195
211
 
196
 
static uint opt_protocol= DRIZZLE_PROTOCOL_TCP;
197
 
static const CHARSET_INFO *charset_info= &my_charset_latin1;
 
212
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
198
213
 
199
 
int drizzle_real_query_for_lazy(const char *buf, int length);
200
 
int drizzle_store_result_for_lazy(DRIZZLE_RES **result);
 
214
int drizzleclient_real_query_for_lazy(const char *buf, int length,
 
215
                                      drizzle_result_st *result,
 
216
                                      uint32_t *error_code);
 
217
int drizzleclient_store_result_for_lazy(drizzle_result_st *result);
201
218
 
202
219
 
203
220
void tee_fprintf(FILE *file, const char *fmt, ...);
207
224
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
208
225
/* The names of functions that actually do the manipulation. */
209
226
static int get_options(int argc,char **argv);
210
 
bool get_one_option(int optid, const struct my_option *opt,
211
 
                    char *argument);
 
227
extern "C" bool get_one_option(int optid, const struct my_option *opt,
 
228
                               char *argument);
212
229
static int com_quit(string *str,const char*),
213
230
  com_go(string *str,const char*), com_ego(string *str,const char*),
214
231
  com_print(string *str,const char*),
216
233
  com_connect(string *str,const char*), com_status(string *str,const char*),
217
234
  com_use(string *str,const char*), com_source(string *str, const char*),
218
235
  com_rehash(string *str, const char*), com_tee(string *str, const char*),
219
 
  com_notee(string *str, const char*), com_charset(string *str,const char*),
 
236
  com_notee(string *str, const char*),
220
237
  com_prompt(string *str, const char*), com_delimiter(string *str, const char*),
221
238
  com_warnings(string *str, const char*), com_nowarnings(string *str, const char*),
222
239
  com_nopager(string *str, const char*), com_pager(string *str, const char*);
223
240
 
224
241
static int read_and_execute(bool interactive);
225
242
static int sql_connect(char *host,char *database,char *user,char *password,
226
 
                       uint silent);
227
 
static const char *server_version_string(DRIZZLE *drizzle);
228
 
static int put_info(const char *str,INFO_TYPE info,uint error,
 
243
                       uint32_t silent);
 
244
static const char *server_version_string(drizzle_con_st *con);
 
245
static int put_info(const char *str,INFO_TYPE info,uint32_t error,
229
246
                    const char *sql_state);
230
 
static int put_error(DRIZZLE *drizzle);
 
247
static int put_error(drizzle_con_st *con, drizzle_result_st *res);
231
248
static void safe_put_field(const char *pos,uint32_t length);
232
249
static void init_pager(void);
233
250
static void end_pager(void);
237
254
static char *get_arg(char *line, bool get_next_arg);
238
255
static void init_username(void);
239
256
static void add_int_to_prompt(int toadd);
240
 
static int get_result_width(DRIZZLE_RES *res);
241
 
static int get_field_disp_length(DRIZZLE_FIELD * field);
 
257
static int get_result_width(drizzle_result_st *res);
 
258
static int get_field_disp_length(drizzle_column_st * field);
242
259
static const char * strcont(register const char *str, register const char *set);
243
260
 
244
261
/* A structure which contains information on the commands this program
253
270
 
254
271
 
255
272
static COMMANDS commands[] = {
256
 
  { "?",      '?', com_help,   1, N_("Synonym for `help'.") },
 
273
  { "?",      '?', com_help,   0, N_("Synonym for `help'.") },
257
274
  { "clear",  'c', com_clear,  0, N_("Clear command.")},
258
275
  { "connect",'r', com_connect,1,
259
 
    N_("Reconnect to the server. Optional arguments are db and host." }),
 
276
    N_("Reconnect to the server. Optional arguments are db and host.")},
260
277
  { "delimiter", 'd', com_delimiter,    1,
261
278
    N_("Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.") },
262
279
  { "ego",    'G', com_ego,    0,
263
280
    N_("Send command to drizzle server, display result vertically.")},
264
281
  { "exit",   'q', com_quit,   0, N_("Exit drizzle. Same as quit.")},
265
282
  { "go",     'g', com_go,     0, N_("Send command to drizzle server.") },
266
 
  { "help",   'h', com_help,   1, N_("Display this help.") },
 
283
  { "help",   'h', com_help,   0, N_("Display this help.") },
267
284
  { "nopager",'n', com_nopager,0, N_("Disable pager, print to stdout.") },
268
285
  { "notee",  't', com_notee,  0, N_("Don't write into outfile.") },
269
286
  { "pager",  'P', com_pager,  1,
279
296
    N_("Set outfile [to_outfile]. Append everything into given outfile.") },
280
297
  { "use",    'u', com_use,    1,
281
298
    N_("Use another database. Takes database name as argument.") },
282
 
  { "charset",    'C', com_charset,    1,
283
 
    N_("Switch to another charset. Might be needed for processing binlog with multi-byte charsets.") },
284
299
  { "warnings", 'W', com_warnings,  0,
285
300
    N_("Show warnings after every statement.") },
286
301
  { "nowarning", 'w', com_nowarnings, 0,
371
386
  { "CROSS", 0, 0, 0, ""},
372
387
  { "CUBE", 0, 0, 0, ""},
373
388
  { "CURRENT_DATE", 0, 0, 0, ""},
374
 
  { "CURRENT_TIME", 0, 0, 0, ""},
375
389
  { "CURRENT_TIMESTAMP", 0, 0, 0, ""},
376
390
  { "CURRENT_USER", 0, 0, 0, ""},
377
391
  { "CURSOR", 0, 0, 0, ""},
450
464
  { "FULL", 0, 0, 0, ""},
451
465
  { "FULLTEXT", 0, 0, 0, ""},
452
466
  { "FUNCTION", 0, 0, 0, ""},
453
 
  { "GET_FORMAT", 0, 0, 0, ""},
454
467
  { "GLOBAL", 0, 0, 0, ""},
455
468
  { "GRANT", 0, 0, 0, ""},
456
469
  { "GRANTS", 0, 0, 0, ""},
512
525
  { "LINESTRING", 0, 0, 0, ""},
513
526
  { "LOAD", 0, 0, 0, ""},
514
527
  { "LOCAL", 0, 0, 0, ""},
515
 
  { "LOCALTIME", 0, 0, 0, ""},
516
528
  { "LOCALTIMESTAMP", 0, 0, 0, ""},
517
529
  { "LOCK", 0, 0, 0, ""},
518
530
  { "LOCKS", 0, 0, 0, ""},
609
621
  { "QUARTER", 0, 0, 0, ""},
610
622
  { "QUERY", 0, 0, 0, ""},
611
623
  { "QUICK", 0, 0, 0, ""},
612
 
  { "RAID0", 0, 0, 0, ""},
613
 
  { "RAID_CHUNKS", 0, 0, 0, ""},
614
 
  { "RAID_CHUNKSIZE", 0, 0, 0, ""},
615
 
  { "RAID_TYPE", 0, 0, 0, ""},
616
624
  { "READ", 0, 0, 0, ""},
617
625
  { "READS", 0, 0, 0, ""},
618
626
  { "REAL", 0, 0, 0, ""},
714
722
  { "TERMINATED", 0, 0, 0, ""},
715
723
  { "TEXT", 0, 0, 0, ""},
716
724
  { "THEN", 0, 0, 0, ""},
717
 
  { "TIME", 0, 0, 0, ""},
718
725
  { "TIMESTAMP", 0, 0, 0, ""},
719
726
  { "TIMESTAMPADD", 0, 0, 0, ""},
720
727
  { "TIMESTAMPDIFF", 0, 0, 0, ""},
748
755
  { "USE_FRM", 0, 0, 0, ""},
749
756
  { "USING", 0, 0, 0, ""},
750
757
  { "UTC_DATE", 0, 0, 0, ""},
751
 
  { "UTC_TIME", 0, 0, 0, ""},
752
758
  { "UTC_TIMESTAMP", 0, 0, 0, ""},
753
759
  { "VALUE", 0, 0, 0, ""},
754
760
  { "VALUES", 0, 0, 0, ""},
775
781
  { "ABS", 0, 0, 0, ""},
776
782
  { "ACOS", 0, 0, 0, ""},
777
783
  { "ADDDATE", 0, 0, 0, ""},
778
 
  { "ADDTIME", 0, 0, 0, ""},
779
784
  { "AES_ENCRYPT", 0, 0, 0, ""},
780
785
  { "AES_DECRYPT", 0, 0, 0, ""},
781
786
  { "AREA", 0, 0, 0, ""},
788
793
  { "ATAN2", 0, 0, 0, ""},
789
794
  { "BENCHMARK", 0, 0, 0, ""},
790
795
  { "BIN", 0, 0, 0, ""},
791
 
  { "BIT_COUNT", 0, 0, 0, ""},
792
796
  { "BIT_OR", 0, 0, 0, ""},
793
797
  { "BIT_AND", 0, 0, 0, ""},
794
798
  { "BIT_XOR", 0, 0, 0, ""},
795
799
  { "CAST", 0, 0, 0, ""},
796
800
  { "CEIL", 0, 0, 0, ""},
797
801
  { "CEILING", 0, 0, 0, ""},
798
 
  { "BIT_LENGTH", 0, 0, 0, ""},
799
802
  { "CENTROID", 0, 0, 0, ""},
800
803
  { "CHAR_LENGTH", 0, 0, 0, ""},
801
804
  { "CHARACTER_LENGTH", 0, 0, 0, ""},
813
816
  { "CRC32", 0, 0, 0, ""},
814
817
  { "CROSSES", 0, 0, 0, ""},
815
818
  { "CURDATE", 0, 0, 0, ""},
816
 
  { "CURTIME", 0, 0, 0, ""},
817
819
  { "DATE_ADD", 0, 0, 0, ""},
818
820
  { "DATEDIFF", 0, 0, 0, ""},
819
821
  { "DATE_FORMAT", 0, 0, 0, ""},
883
885
  { "LTRIM", 0, 0, 0, ""},
884
886
  { "MAKE_SET", 0, 0, 0, ""},
885
887
  { "MAKEDATE", 0, 0, 0, ""},
886
 
  { "MAKETIME", 0, 0, 0, ""},
887
888
  { "MASTER_POS_WAIT", 0, 0, 0, ""},
888
889
  { "MAX", 0, 0, 0, ""},
889
890
  { "MBRCONTAINS", 0, 0, 0, ""},
940
941
  { "ROW_COUNT", 0, 0, 0, ""},
941
942
  { "RPAD", 0, 0, 0, ""},
942
943
  { "RTRIM", 0, 0, 0, ""},
943
 
  { "SEC_TO_TIME", 0, 0, 0, ""},
944
944
  { "SESSION_USER", 0, 0, 0, ""},
945
945
  { "SUBDATE", 0, 0, 0, ""},
946
946
  { "SIGN", 0, 0, 0, ""},
962
962
  { "SUBSTR", 0, 0, 0, ""},
963
963
  { "SUBSTRING", 0, 0, 0, ""},
964
964
  { "SUBSTRING_INDEX", 0, 0, 0, ""},
965
 
  { "SUBTIME", 0, 0, 0, ""},
966
965
  { "SUM", 0, 0, 0, ""},
967
966
  { "SYSDATE", 0, 0, 0, ""},
968
967
  { "SYSTEM_USER", 0, 0, 0, ""},
969
968
  { "TAN", 0, 0, 0, ""},
970
969
  { "TIME_FORMAT", 0, 0, 0, ""},
971
 
  { "TIME_TO_SEC", 0, 0, 0, ""},
972
 
  { "TIMEDIFF", 0, 0, 0, ""},
973
970
  { "TO_DAYS", 0, 0, 0, ""},
974
971
  { "TOUCHES", 0, 0, 0, ""},
975
972
  { "TRIM", 0, 0, 0, ""},
1006
1003
static bool add_line(string *buffer,char *line,char *in_string,
1007
1004
                     bool *ml_comment);
1008
1005
static void remove_cntrl(string *buffer);
1009
 
static void print_table_data(DRIZZLE_RES *result);
1010
 
static void print_tab_data(DRIZZLE_RES *result);
1011
 
static void print_table_data_vertically(DRIZZLE_RES *result);
1012
 
static void print_warnings(void);
 
1006
static void print_table_data(drizzle_result_st *result);
 
1007
static void print_tab_data(drizzle_result_st *result);
 
1008
static void print_table_data_vertically(drizzle_result_st *result);
 
1009
static void print_warnings(uint32_t error_code);
1013
1010
static uint32_t start_timer(void);
1014
1011
static void end_timer(uint32_t start_time,char *buff);
1015
1012
static void drizzle_end_timer(uint32_t start_time,char *buff);
1016
1013
static void nice_time(double sec,char *buff,bool part_second);
1017
 
extern sig_handler drizzle_end(int sig);
1018
 
extern sig_handler handle_sigint(int sig);
 
1014
extern "C" void drizzle_end(int sig);
 
1015
extern "C" void handle_sigint(int sig);
1019
1016
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1020
 
static sig_handler window_resize(int sig);
 
1017
static void window_resize(int sig);
1021
1018
#endif
1022
1019
 
 
1020
static inline int is_prefix(const char *s, const char *t)
 
1021
{
 
1022
  while (*t)
 
1023
    if (*s++ != *t++) return 0;
 
1024
  return 1;                                     /* WRONG */
 
1025
}
 
1026
 
 
1027
/**
 
1028
  Shutdown the server that we are currently connected to.
 
1029
 
 
1030
  @retval
 
1031
    true success
 
1032
  @retval
 
1033
    false failure
 
1034
*/
 
1035
static bool server_shutdown(void)
 
1036
{
 
1037
  drizzle_result_st result;
 
1038
  drizzle_return_t ret;
 
1039
 
 
1040
  if (verbose)
 
1041
  {
 
1042
    printf("shutting down drizzled");
 
1043
    if (opt_drizzle_port > 0)
 
1044
      printf(" on port %d", opt_drizzle_port);
 
1045
    printf("... ");
 
1046
  }
 
1047
 
 
1048
  if (drizzle_shutdown(&con, &result, DRIZZLE_SHUTDOWN_DEFAULT,
 
1049
                       &ret) == NULL || ret != DRIZZLE_RETURN_OK)
 
1050
  {
 
1051
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
1052
    {
 
1053
      fprintf(stderr, "shutdown failed; error: '%s'",
 
1054
              drizzle_result_error(&result));
 
1055
      drizzle_result_free(&result);
 
1056
    }
 
1057
    else
 
1058
    {
 
1059
      fprintf(stderr, "shutdown failed; error: '%s'",
 
1060
              drizzle_con_error(&con));
 
1061
    }
 
1062
    return false;
 
1063
  }
 
1064
 
 
1065
  drizzle_result_free(&result);
 
1066
 
 
1067
  if (verbose)
 
1068
    printf("done\n");
 
1069
 
 
1070
  return true;
 
1071
}
 
1072
 
 
1073
/**
 
1074
  Ping the server that we are currently connected to.
 
1075
 
 
1076
  @retval
 
1077
    true success
 
1078
  @retval
 
1079
    false failure
 
1080
*/
 
1081
static bool server_ping(void)
 
1082
{
 
1083
  drizzle_result_st result;
 
1084
  drizzle_return_t ret;
 
1085
 
 
1086
  if (drizzle_ping(&con, &result, &ret) != NULL && ret == DRIZZLE_RETURN_OK)
 
1087
  {
 
1088
    if (opt_silent < 2)
 
1089
      printf("drizzled is alive\n");
 
1090
  }
 
1091
  else
 
1092
  {
 
1093
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
1094
    {
 
1095
      fprintf(stderr, "ping failed; error: '%s'",
 
1096
              drizzle_result_error(&result));
 
1097
      drizzle_result_free(&result);
 
1098
    }
 
1099
    else
 
1100
    {
 
1101
      fprintf(stderr, "drizzled won't answer to ping, error: '%s'",
 
1102
              drizzle_con_error(&con));
 
1103
    }
 
1104
    return false;
 
1105
  }
 
1106
  drizzle_result_free(&result);
 
1107
  return true;
 
1108
}
 
1109
 
 
1110
/**
 
1111
  Execute command(s) specified by the user.
 
1112
 
 
1113
  @param error  error status of command execution.
 
1114
                If an error had occurred, this variable will be set
 
1115
                to 1 whereas on success, it shall be set to 0. This
 
1116
                value will be supplied to the exit() function used
 
1117
                by the caller.
 
1118
 
 
1119
  @retval
 
1120
    false no commands were executed
 
1121
  @retval
 
1122
    true  at least one command was executed
 
1123
*/
 
1124
static bool execute_commands(int *error)
 
1125
{
 
1126
  bool executed= false;
 
1127
  *error= 0;
 
1128
 
 
1129
  if (opt_ping)
 
1130
  {
 
1131
    if (server_ping() == false)
 
1132
      *error= 1;
 
1133
    executed= true;
 
1134
  }
 
1135
 
 
1136
  if (opt_shutdown)
 
1137
  {
 
1138
    if (server_shutdown() == false)
 
1139
      *error= 1;
 
1140
    executed= true;
 
1141
  }
 
1142
  return executed;
 
1143
}
 
1144
 
1023
1145
int main(int argc,char *argv[])
1024
1146
{
1025
1147
  char buff[80];
1034
1156
 
1035
1157
  MY_INIT(argv[0]);
1036
1158
  delimiter_str= delimiter;
1037
 
  default_prompt= my_strdup(getenv("DRIZZLE_PS1") ?
1038
 
                            getenv("DRIZZLE_PS1") :
1039
 
                            "drizzle>> ", MYF(0));
1040
 
  current_prompt= my_strdup(default_prompt, MYF(0));
 
1159
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
 
1160
                         getenv("DRIZZLE_PS1") :
 
1161
                         "drizzle> ");
 
1162
  
 
1163
  if (default_prompt == NULL)
 
1164
  {
 
1165
    fprintf(stderr, _("Memory allocation error while constructing initial "
 
1166
                      "prompt. Aborting.\n"));
 
1167
    exit(ENOMEM);
 
1168
  }
 
1169
  current_prompt= strdup(default_prompt);
 
1170
  if (current_prompt == NULL)
 
1171
  {
 
1172
    fprintf(stderr, _("Memory allocation error while constructing initial "
 
1173
                      "prompt. Aborting.\n"));
 
1174
    exit(ENOMEM);
 
1175
  }
1041
1176
  processed_prompt= new string();
1042
1177
  processed_prompt->reserve(32);
1043
1178
 
1044
1179
  prompt_counter=0;
1045
1180
 
1046
1181
  outfile[0]=0;      // no (default) outfile
1047
 
  stpcpy(pager, "stdout");  // the default, if --pager wasn't given
 
1182
  strcpy(pager, "stdout");  // the default, if --pager wasn't given
1048
1183
  {
1049
1184
    char *tmp=getenv("PAGER");
1050
1185
    if (tmp && strlen(tmp))
1051
1186
    {
1052
1187
      default_pager_set= 1;
1053
 
      stpcpy(default_pager, tmp);
 
1188
      strcpy(default_pager, tmp);
1054
1189
    }
1055
1190
  }
1056
1191
  if (!isatty(0) || !isatty(1))
1076
1211
      close(stdout_fileno_copy);             /* Clean up dup(). */
1077
1212
  }
1078
1213
 
1079
 
  load_defaults("my",load_default_groups,&argc,&argv);
 
1214
  load_defaults("drizzle",load_default_groups,&argc,&argv);
1080
1215
  defaults_argv=argv;
1081
1216
  if (get_options(argc, (char **) argv))
1082
1217
  {
1084
1219
    my_end(0);
1085
1220
    exit(1);
1086
1221
  }
1087
 
  if (status.batch && !status.line_buff &&
1088
 
      !(status.line_buff=batch_readline_init(opt_max_allowed_packet+512,stdin)))
1089
 
  {
1090
 
    free_defaults(defaults_argv);
1091
 
    my_end(0);
1092
 
    exit(1);
1093
 
  }
1094
 
  completion_hash_init(&ht, 128);
1095
 
  init_alloc_root(&hash_mem_root, 16384, 0);
 
1222
 
1096
1223
  memset(&drizzle, 0, sizeof(drizzle));
1097
1224
  if (sql_connect(current_host,current_db,current_user,opt_password,
1098
1225
                  opt_silent))
1101
1228
    status.exit_status= 1;
1102
1229
    drizzle_end(-1);
1103
1230
  }
 
1231
 
 
1232
  int command_error;
 
1233
  if (execute_commands(&command_error) != false)
 
1234
  {
 
1235
    /* we've executed a command so exit before we go into readline mode */
 
1236
    free_defaults(defaults_argv);
 
1237
    my_end(0);
 
1238
    exit(command_error);
 
1239
  }
 
1240
 
 
1241
  if (status.batch && !status.line_buff)
 
1242
  {
 
1243
    status.line_buff =batch_readline_init(opt_max_input_line+512, stdin);
 
1244
    if (status.line_buff == NULL)
 
1245
    {
 
1246
      free_defaults(defaults_argv);
 
1247
      my_end(0);
 
1248
      exit(1);
 
1249
    }
 
1250
  }
 
1251
 
1104
1252
  if (!status.batch)
1105
1253
    ignore_errors=1;        // Don't abort monitor
1106
1254
 
1122
1270
 
1123
1271
  glob_buffer= new string();
1124
1272
  glob_buffer->reserve(512);
1125
 
  
 
1273
 
1126
1274
  char * output_buff= (char *)malloc(512);
1127
1275
  memset(output_buff, '\0', 512);
1128
1276
 
1129
1277
  sprintf(output_buff,
1130
1278
          _("Your Drizzle connection id is %u\nServer version: %s\n"),
1131
 
          drizzle_thread_id(&drizzle),
1132
 
          server_version_string(&drizzle));
 
1279
          drizzle_con_thread_id(&con),
 
1280
          server_version_string(&con));
1133
1281
  put_info(output_buff, INFO_INFO, 0, 0);
1134
1282
 
1135
1283
  initialize_readline(current_prompt);
1140
1288
      histfile= strdup(getenv("DRIZZLE_HISTFILE"));
1141
1289
    else if (getenv("HOME"))
1142
1290
    {
1143
 
      histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1144
 
                                 + (uint) strlen("/.drizzle_history")+2,
1145
 
                                 MYF(MY_WME));
 
1291
      histfile=(char*) malloc(strlen(getenv("HOME")) + strlen("/.drizzle_history") + 2);
1146
1292
      if (histfile)
1147
1293
        sprintf(histfile,"%s/.drizzle_history",getenv("HOME"));
1148
1294
      char link_name[FN_REFLEN];
1149
 
      if (my_readlink(link_name, histfile, 0) == 0 &&
1150
 
          strncmp(link_name, "/dev/null", 10) == 0)
 
1295
      ssize_t sym_link_size= readlink(histfile,link_name,FN_REFLEN-1);
 
1296
      if (sym_link_size >= 0)
1151
1297
      {
1152
 
        /* The .drizzle_history file is a symlink to /dev/null, don't use it */
1153
 
        my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
1154
 
        histfile= 0;
 
1298
        link_name[sym_link_size]= '\0';
 
1299
        if (strncmp(link_name, "/dev/null", 10) == 0)
 
1300
        {
 
1301
          /* The .drizzle_history file is a symlink to /dev/null, don't use it */
 
1302
          free(histfile);
 
1303
          histfile= 0;
 
1304
        }
1155
1305
      }
1156
1306
    }
1157
1307
    if (histfile)
1159
1309
      if (verbose)
1160
1310
        tee_fprintf(stdout, _("Reading history-file %s\n"),histfile);
1161
1311
      read_history(histfile);
1162
 
      if (!(histfile_tmp= (char*) my_malloc((uint) strlen(histfile) + 5,
1163
 
                                            MYF(MY_WME))))
 
1312
      if (!(histfile_tmp= (char*) malloc((uint32_t) strlen(histfile) + 5)))
1164
1313
      {
1165
1314
        fprintf(stderr, _("Couldn't allocate memory for temp histfile!\n"));
1166
1315
        exit(1);
1180
1329
  return(0);        // Keep compiler happy
1181
1330
}
1182
1331
 
1183
 
sig_handler drizzle_end(int sig)
 
1332
void drizzle_end(int sig)
1184
1333
{
1185
 
  drizzle_close(&drizzle);
 
1334
  drizzle_con_free(&con);
 
1335
  drizzle_free(&drizzle);
1186
1336
  if (!status.batch && !quick && histfile)
1187
1337
  {
1188
1338
    /* write-history */
1192
1342
      my_rename(histfile_tmp, histfile, MYF(MY_WME));
1193
1343
  }
1194
1344
  batch_readline_end(status.line_buff);
1195
 
  completion_hash_free(&ht);
1196
 
  free_root(&hash_mem_root,MYF(0));
1197
1345
 
1198
1346
  if (sig >= 0)
1199
1347
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
1201
1349
    delete glob_buffer;
1202
1350
  if (processed_prompt)
1203
1351
    delete processed_prompt;
1204
 
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
1205
 
  my_free(opt_drizzle_unix_port,MYF(MY_ALLOW_ZERO_PTR));
1206
 
  my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
1207
 
  my_free(histfile_tmp,MYF(MY_ALLOW_ZERO_PTR));
1208
 
  my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
1209
 
  my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
1210
 
  my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
1211
 
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
1212
 
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
1213
 
  my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
1214
 
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
1215
 
  drizzle_server_end();
 
1352
  free(opt_password);
 
1353
  free(opt_drizzle_unix_port);
 
1354
  free(histfile);
 
1355
  free(histfile_tmp);
 
1356
  free(current_db);
 
1357
  free(current_host);
 
1358
  free(current_user);
 
1359
  free(full_username);
 
1360
  free(part_username);
 
1361
  free(default_prompt);
 
1362
  free(current_prompt);
1216
1363
  free_defaults(defaults_argv);
1217
1364
  my_end(my_end_arg);
1218
1365
  exit(status.exit_status);
1224
1371
  If query is in process, kill query
1225
1372
  no query in process, terminate like previous behavior
1226
1373
*/
1227
 
sig_handler handle_sigint(int sig)
 
1374
extern "C"
 
1375
void handle_sigint(int sig)
1228
1376
{
1229
1377
  char kill_buffer[40];
1230
 
  DRIZZLE *kill_drizzle= NULL;
 
1378
  drizzle_con_st kill_drizzle;
 
1379
  drizzle_result_st res;
 
1380
  drizzle_return_t ret;
1231
1381
 
1232
1382
  /* terminate if no query being executed, or we already tried interrupting */
1233
1383
  if (!executing_query || interrupted_query) {
1234
1384
    goto err;
1235
1385
  }
1236
1386
 
1237
 
  kill_drizzle= drizzle_create(kill_drizzle);
1238
 
  if (!drizzle_connect(kill_drizzle,current_host, current_user, opt_password,
1239
 
                          "", opt_drizzle_port, opt_drizzle_unix_port,0))
 
1387
  if (drizzle_con_add_tcp(&drizzle, &kill_drizzle, current_host,
 
1388
                          opt_drizzle_port, current_user, opt_password, NULL,
 
1389
                          DRIZZLE_CON_NONE) == NULL)
1240
1390
  {
1241
1391
    goto err;
1242
1392
  }
1243
1393
 
1244
1394
  /* 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);
 
1395
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u",
 
1396
          drizzle_con_thread_id(&con));
 
1397
 
 
1398
  if (drizzle_query_str(&kill_drizzle, &res, kill_buffer, &ret) != NULL)
 
1399
    drizzle_result_free(&res);
 
1400
 
 
1401
  drizzle_con_free(&kill_drizzle);
1248
1402
  tee_fprintf(stdout, _("Query aborted by Ctrl+C\n"));
1249
1403
 
1250
1404
  interrupted_query= 1;
1257
1411
 
1258
1412
 
1259
1413
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1260
 
sig_handler window_resize(int sig __attribute__((unused)))
 
1414
void window_resize(int)
1261
1415
{
1262
1416
  struct winsize window_size;
1263
1417
 
1277
1431
   (char**) &opt_rehash, (char**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
1278
1432
   0, 0},
1279
1433
  {"no-auto-rehash", 'A',
1280
 
   N_("No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of DRIZZLE and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead."),
 
1434
   N_("No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of drizzle_st and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead."),
1281
1435
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1282
1436
  {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
1283
1437
   N_("Automatically switch to vertical output mode if the result is wider than the terminal width."),
1284
1438
   (char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1285
1439
  {"batch", 'B',
1286
1440
   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
1441
  {"column-type-info", OPT_COLUMN_TYPES, N_("Display column type information."),
1291
1442
   (char**) &column_types_flag, (char**) &column_types_flag,
1292
1443
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1304
1455
  {"database", 'D', N_("Database to use."), (char**) &current_db,
1305
1456
   (char**) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1306
1457
  {"default-character-set", OPT_DEFAULT_CHARSET,
1307
 
   N_("Set the default character set."), (char**) &default_charset,
1308
 
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1458
   N_("(not used)"), 0,
 
1459
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1309
1460
  {"delimiter", OPT_DELIMITER, N_("Delimiter to be used."), (char**) &delimiter_str,
1310
1461
   (char**) &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1311
1462
  {"execute", 'e', N_("Execute command and quit. (Disables --force and history file)"), 0,
1360
1511
  {"no-pager", OPT_NOPAGER,
1361
1512
   N_("Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead."),
1362
1513
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1363
 
  {"password", 'p',
 
1514
  {"password", 'P',
1364
1515
   N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
1365
1516
   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, ")
 
1517
  {"port", 'p', N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, ")
1367
1518
   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},
 
1519
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1370
1520
  {"prompt", OPT_PROMPT, N_("Set the drizzle prompt to this value."),
1371
1521
   (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
1372
1522
   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
1523
  {"quick", 'q',
1376
1524
   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
1525
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1380
1528
   0, 0, 0},
1381
1529
  {"reconnect", OPT_RECONNECT, N_("Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default."),
1382
1530
   (char**) &opt_reconnect, (char**) &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
1531
  {"shutdown", OPT_SHUTDOWN, N_("Shutdown the server."),
 
1532
   (char**) &opt_shutdown, (char**) &opt_shutdown, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1383
1533
  {"silent", 's', N_("Be more silent. Print results with a tab as separator, each row on new line."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
1384
1534
   0, 0},
1385
1535
  {"socket", 'S', N_("Socket file to use for connection."),
1392
1542
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1393
1543
  {"no-tee", OPT_NOTEE, N_("Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead"), 0, 0, 0, GET_NO_ARG,
1394
1544
   NO_ARG, 0, 0, 0, 0, 0, 0},
1395
 
#ifndef DONT_ALLOW_USER_CHANGE
1396
1545
  {"user", 'u', N_("User for login if not current user."), (char**) &current_user,
1397
1546
   (char**) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1398
 
#endif
1399
1547
  {"safe-updates", 'U', N_("Only allow UPDATE and DELETE that uses keys."),
1400
1548
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
1401
1549
   0, 0, 0, 0},
1411
1559
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
1412
1560
   N_("Number of seconds before connection timeout."),
1413
1561
   (char**) &opt_connect_timeout,
1414
 
   (char**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
 
1562
   (char**) &opt_connect_timeout, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 3600*12, 0,
1415
1563
   0, 0},
1416
 
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1417
 
   N_("Max packet length to send to, or receive from server"),
1418
 
   (char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
1419
 
   GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096,
 
1564
  {"max_input_line", OPT_MAX_INPUT_LINE,
 
1565
   N_("Max length of input line"),
 
1566
   (char**) &opt_max_input_line, (char**) &opt_max_input_line, 0,
 
1567
   GET_UINT32, REQUIRED_ARG, 16 *1024L*1024L, 4096,
1420
1568
   (int64_t) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1421
 
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
1422
 
   N_("Buffer for TCP/IP and socket communication"),
1423
 
   (char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0, GET_ULONG,
1424
 
   REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
1425
1569
  {"select_limit", OPT_SELECT_LIMIT,
1426
1570
   N_("Automatic limit for SELECT when using --safe-updates"),
1427
1571
   (char**) &select_limit,
1428
 
   (char**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
 
1572
   (char**) &select_limit, 0, GET_UINT32, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
1429
1573
   0, 1, 0},
1430
1574
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1431
1575
   N_("Automatic limit for rows in a join when using --safe-updates"),
1432
1576
   (char**) &max_join_size,
1433
 
   (char**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
 
1577
   (char**) &max_join_size, 0, GET_UINT32, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
1434
1578
   0, 1, 0},
1435
1579
  {"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
1580
   (char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1437
1581
  {"show-warnings", OPT_SHOW_WARNINGS, N_("Show warnings after every statement."),
1438
1582
   (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
1439
1583
   0, 0, 0, 0, 0, 0},
 
1584
  {"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of lines before each import progress report."),
 
1585
   (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
 
1586
   0, 0, 0, 0, 0, 0},
 
1587
  {"ping", OPT_PING, N_("Ping the server to check if it's alive."),
 
1588
   (char**) &opt_ping, (char**) &opt_ping, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1440
1589
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1441
1590
};
1442
1591
 
1445
1594
{
1446
1595
  const char* readline= "readline";
1447
1596
 
1448
 
  printf(_("%s  Ver %s Distrib %s, for %s (%s) using %s %s\n"),
1449
 
         my_progname, VER, drizzle_get_client_info(),
1450
 
         SYSTEM_TYPE, MACHINE_TYPE,
 
1597
  printf(_("%s  Ver %s Distrib %s, for %s-%s (%s) using %s %s\n"),
 
1598
         my_progname, VER.c_str(), drizzle_version(),
 
1599
         HOST_VENDOR, HOST_OS, HOST_CPU,
1451
1600
         readline, rl_library_version);
1452
1601
 
1453
1602
  if (version)
1454
1603
    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"));
 
1604
  printf(_("Copyright (C) 2008 Sun Microsystems\n"
 
1605
           "This software comes with ABSOLUTELY NO WARRANTY. "
 
1606
           "This is free software,\n"
 
1607
           "and you are welcome to modify and redistribute it "
 
1608
           "under the GPL license\n"));
1459
1609
  printf(_("Usage: %s [OPTIONS] [database]\n"), my_progname);
1460
1610
  my_print_help(my_long_options);
1461
 
  print_defaults("my", load_default_groups);
 
1611
  print_defaults("drizzle", load_default_groups);
1462
1612
  my_print_variables(my_long_options);
1463
1613
}
1464
1614
 
1465
1615
 
1466
 
bool
1467
 
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
1468
 
               char *argument)
 
1616
extern "C" bool
 
1617
get_one_option(int optid, const struct my_option *, char *argument)
1469
1618
{
 
1619
  char *endchar= NULL;
 
1620
  uint64_t temp_drizzle_port= 0;
 
1621
 
1470
1622
  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
1623
  case  OPT_DEFAULT_CHARSET:
1476
1624
    default_charset_used= 1;
1477
1625
    break;
1478
1626
  case OPT_DELIMITER:
1479
1627
    if (argument == disabled_my_option)
1480
1628
    {
1481
 
      stpcpy(delimiter, DEFAULT_DELIMITER);
 
1629
      strcpy(delimiter, DEFAULT_DELIMITER);
1482
1630
    }
1483
1631
    else
1484
1632
    {
1485
1633
      /* Check that delimiter does not contain a backslash */
1486
1634
      if (!strstr(argument, "\\"))
1487
1635
      {
1488
 
        strmake(delimiter, argument, sizeof(delimiter) - 1);
 
1636
        strncpy(delimiter, argument, sizeof(delimiter) - 1);
1489
1637
      }
1490
1638
      else
1491
1639
      {
1492
1640
        put_info(_("DELIMITER cannot contain a backslash character"),
1493
1641
                 INFO_ERROR,0,0);
1494
 
        return 0;
 
1642
        return false;
1495
1643
      }
1496
1644
    }
1497
 
    delimiter_length= (uint)strlen(delimiter);
 
1645
    delimiter_length= (uint32_t)strlen(delimiter);
1498
1646
    delimiter_str= delimiter;
1499
1647
    break;
1500
 
  case OPT_LOCAL_INFILE:
1501
 
    using_opt_local_infile=1;
1502
 
    break;
1503
1648
  case OPT_TEE:
1504
1649
    if (argument == disabled_my_option)
1505
1650
    {
1523
1668
      if (argument && strlen(argument))
1524
1669
      {
1525
1670
        default_pager_set= 1;
1526
 
        strmake(pager, argument, sizeof(pager) - 1);
1527
 
        stpcpy(default_pager, pager);
 
1671
        strncpy(pager, argument, sizeof(pager) - 1);
 
1672
        strcpy(default_pager, pager);
1528
1673
      }
1529
1674
      else if (default_pager_set)
1530
 
        stpcpy(pager, default_pager);
 
1675
        strcpy(pager, default_pager);
1531
1676
      else
1532
1677
        opt_nopager= 1;
1533
1678
    }
1560
1705
      one_database= skip_updates= 1;
1561
1706
    break;
1562
1707
  case 'p':
 
1708
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
 
1709
    /* if there is an alpha character this is not a valid port */
 
1710
    if (strlen(endchar) != 0)
 
1711
    {
 
1712
      put_info(_("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead."), INFO_ERROR, 0, 0);
 
1713
      return false;
 
1714
    }
 
1715
    /* If the port number is > 65535 it is not a valid port
 
1716
       This also helps with potential data loss casting unsigned long to a
 
1717
       uint32_t. */
 
1718
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
1719
    {
 
1720
      put_info(_("Value supplied for port is not valid."), INFO_ERROR, 0, 0);
 
1721
      return false;
 
1722
    }
 
1723
    else
 
1724
    {
 
1725
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
 
1726
    }
 
1727
    break;
 
1728
  case 'P':
 
1729
    /* Don't require password */
1563
1730
    if (argument == disabled_my_option)
1564
 
      argument= (char*) "";      // Don't require password
 
1731
    {
 
1732
      argument= (char*) "";
 
1733
    }
1565
1734
    if (argument)
1566
1735
    {
1567
1736
      char *start= argument;
1568
 
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
 
1737
      free(opt_password);
1569
1738
      opt_password= strdup(argument);
1570
 
      while (*argument) *argument++= 'x';        // Destroy argument
 
1739
      while (*argument)
 
1740
      {
 
1741
        /* Overwriting password with 'x' */
 
1742
        *argument++= 'x';
 
1743
      }
1571
1744
      if (*start)
1572
 
        start[1]=0 ;
 
1745
      {
 
1746
        start[1]= 0;
 
1747
      }
1573
1748
      tty_password= 0;
1574
1749
    }
1575
1750
    else
 
1751
    {
1576
1752
      tty_password= 1;
 
1753
    }
1577
1754
    break;
1578
1755
  case 's':
1579
1756
    if (argument == disabled_my_option)
1592
1769
    status.add_to_history= 0;
1593
1770
    set_if_bigger(opt_silent,1);                         // more silent
1594
1771
    break;
1595
 
    break;
1596
1772
  case 'V':
1597
1773
    usage(1);
1598
1774
    exit(0);
1609
1785
{
1610
1786
  char *tmp, *pagpoint;
1611
1787
  int ho_error;
1612
 
  const DRIZZLE_PARAMETERS *drizzle_params= drizzle_get_parameters();
1613
1788
 
1614
1789
  tmp= (char *) getenv("DRIZZLE_HOST");
1615
1790
  if (tmp)
1618
1793
  pagpoint= getenv("PAGER");
1619
1794
  if (!((char*) (pagpoint)))
1620
1795
  {
1621
 
    stpcpy(pager, "stdout");
 
1796
    strcpy(pager, "stdout");
1622
1797
    opt_nopager= 1;
1623
1798
  }
1624
1799
  else
1625
 
    stpcpy(pager, pagpoint);
1626
 
  stpcpy(default_pager, pager);
1627
 
 
1628
 
  opt_max_allowed_packet= *drizzle_params->p_max_allowed_packet;
1629
 
  opt_net_buffer_length= *drizzle_params->p_net_buffer_length;
 
1800
    strcpy(pager, pagpoint);
 
1801
  strcpy(default_pager, pager);
1630
1802
 
1631
1803
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
1632
1804
    exit(ho_error);
1633
1805
 
1634
 
  *drizzle_params->p_max_allowed_packet= opt_max_allowed_packet;
1635
 
  *drizzle_params->p_net_buffer_length= opt_net_buffer_length;
1636
 
 
1637
1806
  if (status.batch) /* disable pager and outfile in this case */
1638
1807
  {
1639
 
    stpcpy(default_pager, "stdout");
1640
 
    stpcpy(pager, "stdout");
 
1808
    strcpy(default_pager, "stdout");
 
1809
    strcpy(pager, "stdout");
1641
1810
    opt_nopager= 1;
1642
1811
    default_pager_set= 0;
1643
1812
    opt_outfile= 0;
1644
1813
    opt_reconnect= 0;
1645
 
    connect_flag= 0; /* Not in interactive mode */
 
1814
    connect_flag= DRIZZLE_CAPABILITIES_NONE; /* Not in interactive mode */
1646
1815
  }
1647
1816
 
1648
 
  if (strcmp(default_charset, charset_info->csname) &&
1649
 
      !(charset_info= get_charset_by_csname(default_charset,
1650
 
                                            MY_CS_PRIMARY, MYF(MY_WME))))
1651
 
    exit(1);
1652
1817
  if (argc > 1)
1653
1818
  {
1654
1819
    usage(0);
1657
1822
  if (argc == 1)
1658
1823
  {
1659
1824
    skip_updates= 0;
1660
 
    my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
 
1825
    free(current_db);
1661
1826
    current_db= strdup(*argv);
1662
1827
  }
1663
1828
  if (tty_password)
1664
 
    opt_password= get_tty_password(NullS);
 
1829
    opt_password= client_get_tty_password(NULL);
1665
1830
  if (debug_info_flag)
1666
1831
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
1667
1832
  if (debug_check_flag)
1690
1855
        you save the file using "Unicode UTF-8" format.
1691
1856
      */
1692
1857
      if (!line_number &&
1693
 
          (uchar) line[0] == 0xEF &&
1694
 
          (uchar) line[1] == 0xBB &&
1695
 
          (uchar) line[2] == 0xBF)
 
1858
          (unsigned char) line[0] == 0xEF &&
 
1859
          (unsigned char) line[1] == 0xBB &&
 
1860
          (unsigned char) line[2] == 0xBF)
1696
1861
        line+= 3;
1697
1862
      line_number++;
 
1863
      if (show_progress_size > 0)
 
1864
      {
 
1865
        if ((line_number % show_progress_size) == 0)
 
1866
          fprintf(stderr, _("Processing line: %"PRIu32"\n"), line_number);
 
1867
      }
1698
1868
      if (!glob_buffer->empty())
1699
1869
        status.query_start_line=line_number;
1700
1870
    }
1766
1936
 
1767
1937
static COMMANDS *find_command(const char *name,char cmd_char)
1768
1938
{
1769
 
  uint len;
 
1939
  uint32_t len;
1770
1940
  const char *end;
1771
1941
 
1772
1942
  if (!name)
1786
1956
    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
1787
1957
                                !(strlen(name) >= 9 &&
1788
1958
                                  !my_strnncoll(charset_info,
1789
 
                                                (uchar*) name, 9,
1790
 
                                                (const uchar*) "delimiter",
 
1959
                                                (unsigned char*) name, 9,
 
1960
                                                (const unsigned char*) "delimiter",
1791
1961
                                                9))))
1792
1962
      return((COMMANDS *) 0);
1793
1963
    if ((end=strcont(name," \t")))
1794
1964
    {
1795
 
      len=(uint) (end - name);
 
1965
      len=(uint32_t) (end - name);
1796
1966
      while (my_isspace(charset_info,*end))
1797
1967
        end++;
1798
1968
      if (!*end)
1799
1969
        end=0;          // no arguments to function
1800
1970
    }
1801
1971
    else
1802
 
      len=(uint) strlen(name);
 
1972
      len=(uint32_t) strlen(name);
1803
1973
  }
1804
1974
 
1805
 
  for (uint i= 0; commands[i].name; i++)
 
1975
  for (uint32_t i= 0; commands[i].name; i++)
1806
1976
  {
1807
1977
    if (commands[i].func &&
1808
 
        ((name && !my_strnncoll(charset_info,(const uchar*)name,len, (const uchar*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || (!name && commands[i].cmd_char == cmd_char)))
 
1978
        ((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)))
1809
1979
    {
1810
1980
      return(&commands[i]);
1811
1981
    }
1817
1987
static bool add_line(string *buffer, char *line, char *in_string,
1818
1988
                        bool *ml_comment)
1819
1989
{
1820
 
  uchar inchar;
 
1990
  unsigned char inchar;
1821
1991
  char buff[80], *pos, *out;
1822
1992
  COMMANDS *com;
1823
1993
  bool need_space= 0;
1828
1998
    return(0);
1829
1999
  if (status.add_to_history && line[0] && not_in_history(line))
1830
2000
    add_history(line);
1831
 
  char *end_of_line=line+(uint) strlen(line);
 
2001
  char *end_of_line=line+(uint32_t) strlen(line);
1832
2002
 
1833
 
  for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
 
2003
  for (pos=out=line ; (inchar= (unsigned char) *pos) ; pos++)
1834
2004
  {
1835
2005
    if (!preserve_comments)
1836
2006
    {
1858
2028
    }
1859
2029
#endif
1860
2030
        if (!*ml_comment && inchar == '\\' &&
1861
 
            !(*in_string && (drizzle.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)))
 
2031
            !(*in_string && (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_NO_BACKSLASH_ESCAPES)))
1862
2032
    {
1863
2033
      // Found possbile one character command like \c
1864
2034
 
1865
 
      if (!(inchar = (uchar) *++pos))
 
2035
      if (!(inchar = (unsigned char) *++pos))
1866
2036
        break;        // readline adds one '\'
1867
2037
      if (*in_string || inchar == 'N')  // \N is short for NULL
1868
2038
      {          // Don't allow commands in string
1870
2040
        *out++= (char) inchar;
1871
2041
        continue;
1872
2042
      }
1873
 
      if ((com=find_command(NullS,(char) inchar)))
 
2043
      if ((com=find_command(NULL,(char) inchar)))
1874
2044
      {
1875
2045
        // Flush previously accepted characters
1876
2046
        if (out != line)
1898
2068
          {
1899
2069
            for (pos++ ;
1900
2070
                 *pos && (*pos != *delimiter ||
1901
 
                          !is_prefix(pos + 1, delimiter + 1)) ; pos++)
 
2071
                          strncmp(pos + 1, delimiter + 1,
 
2072
                                  strlen(delimiter + 1))) ; pos++)
1902
2073
              ;  // Remove parameters
1903
2074
            if (!*pos)
1904
2075
              pos--;
1919
2090
    }
1920
2091
    else if (!*ml_comment && !*in_string &&
1921
2092
             (end_of_line - pos) >= 10 &&
1922
 
             !my_strnncoll(charset_info, (uchar*) pos, 10,
1923
 
                           (const uchar*) "delimiter ", 10))
 
2093
             !my_strnncoll(charset_info, (unsigned char*) pos, 10,
 
2094
                           (const unsigned char*) "delimiter ", 10))
1924
2095
    {
1925
2096
      // Flush previously accepted characters
1926
2097
      if (out != line)
1949
2120
      buffer->clear();
1950
2121
      break;
1951
2122
    }
1952
 
    else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
 
2123
    else if (!*ml_comment && !*in_string && !strncmp(pos, delimiter,
 
2124
                                                     strlen(delimiter)))
1953
2125
    {
1954
2126
      // Found a statement. Continue parsing after the delimiter
1955
2127
      pos+= delimiter_length;
2072
2244
  if (out != line || (buffer->length() > 0))
2073
2245
  {
2074
2246
    *out++='\n';
2075
 
    uint length=(uint) (out-line);
 
2247
    uint32_t length=(uint32_t) (out-line);
2076
2248
    if ((!*ml_comment || preserve_comments))
2077
2249
      buffer->append(line, length);
2078
2250
  }
2085
2257
 
2086
2258
 
2087
2259
static char **mysql_completion (const char *text, int start, int end);
2088
 
static char *new_command_generator(const char *text, int);
 
2260
extern "C" char *new_command_generator(const char *text, int);
2089
2261
 
2090
2262
/*
2091
2263
  Tell the GNU Readline library how to complete.  We want to try to complete
2092
2264
  on command names if this is the first word in the line, or on filenames
2093
2265
  if not.
2094
2266
*/
2095
 
static char *no_completion(const char * a __attribute__((unused)),
2096
 
                           int b __attribute__((unused)))
 
2267
static char *no_completion(const char *, int)
2097
2268
{
2098
2269
  /* No filename completion */
2099
2270
  return 0;
2188
2359
  entire line in case we want to do some simple parsing.  Return the
2189
2360
  array of matches, or NULL if there aren't any.
2190
2361
*/
2191
 
char **mysql_completion (const char *text,
2192
 
                        int start __attribute__((unused)),
2193
 
                        int end __attribute__((unused)))
 
2362
char **mysql_completion (const char *text, int, int)
2194
2363
{
2195
2364
  if (!status.batch && !quick)
2196
2365
    return rl_completion_matches(text, new_command_generator);
2198
2367
    return (char**) 0;
2199
2368
}
2200
2369
 
2201
 
 
2202
 
static char *new_command_generator(const char *text,int state)
2203
 
{
2204
 
  static int textlen;
2205
 
  char *ptr;
2206
 
  static Bucket *b;
2207
 
  static entry *e;
2208
 
  static uint i;
 
2370
inline string lower_string(const string &from_string)
 
2371
{
 
2372
  string to_string= from_string;
 
2373
  transform(to_string.begin(), to_string.end(),
 
2374
            to_string.begin(), ::tolower);
 
2375
  return to_string;
 
2376
}
 
2377
inline string lower_string(const char * from_string)
 
2378
{
 
2379
  string to_string= from_string;
 
2380
  return lower_string(to_string);
 
2381
}
 
2382
 
 
2383
template <class T>
 
2384
class CompletionMatch :
 
2385
  public unary_function<const string&, bool>
 
2386
{
 
2387
  string match_text; 
 
2388
  T match_func;
 
2389
public:
 
2390
  CompletionMatch(string text) : match_text(text) {}
 
2391
  inline bool operator() (const pair<string,string> &match_against) const
 
2392
  {
 
2393
    string sub_match=
 
2394
      lower_string(match_against.first.substr(0,match_text.size()));
 
2395
    return match_func(sub_match,match_text);
 
2396
  }
 
2397
};
 
2398
 
 
2399
 
 
2400
 
 
2401
extern "C"
 
2402
char *new_command_generator(const char *text, int state)
 
2403
{
2209
2404
 
2210
2405
  if (!state)
2211
 
    textlen=(uint) strlen(text);
2212
 
 
2213
 
  if (textlen>0)
2214
 
  {            /* lookup in the hash */
2215
 
    if (!state)
2216
 
    {
2217
 
      uint len;
2218
 
 
2219
 
      b = find_all_matches(&ht,text,(uint) strlen(text),&len);
2220
 
      if (!b)
2221
 
        return NullS;
2222
 
      e = b->pData;
2223
 
    }
2224
 
 
2225
 
    if (e)
2226
 
    {
2227
 
      ptr= strdup(e->str);
2228
 
      e = e->pNext;
2229
 
      return ptr;
2230
 
    }
2231
 
  }
2232
 
  else
2233
 
  { /* traverse the entire hash, ugly but works */
2234
 
 
2235
 
    if (!state)
2236
 
    {
2237
 
      /* find the first used bucket */
2238
 
      for (i=0 ; i < ht.nTableSize ; i++)
2239
 
      {
2240
 
        if (ht.arBuckets[i])
2241
 
        {
2242
 
          b = ht.arBuckets[i];
2243
 
          e = b->pData;
2244
 
          break;
2245
 
        }
2246
 
      }
2247
 
    }
2248
 
    ptr= NullS;
2249
 
    while (e && !ptr)
2250
 
    {          /* find valid entry in bucket */
2251
 
      if ((uint) strlen(e->str) == b->nKeyLength)
2252
 
        ptr = strdup(e->str);
2253
 
      /* find the next used entry */
2254
 
      e = e->pNext;
2255
 
      if (!e)
2256
 
      { /* find the next used bucket */
2257
 
        b = b->pNext;
2258
 
        if (!b)
2259
 
        {
2260
 
          for (i++ ; i<ht.nTableSize; i++)
2261
 
          {
2262
 
            if (ht.arBuckets[i])
2263
 
            {
2264
 
              b = ht.arBuckets[i];
2265
 
              e = b->pData;
2266
 
              break;
2267
 
            }
2268
 
          }
2269
 
        }
2270
 
        else
2271
 
          e = b->pData;
2272
 
      }
2273
 
    }
2274
 
    if (ptr)
2275
 
      return ptr;
2276
 
  }
2277
 
  return NullS;
 
2406
  {
 
2407
    completion_string= lower_string(text);
 
2408
    if (completion_string.size() == 0)
 
2409
    {
 
2410
      completion_iter= completion_map.begin();
 
2411
      completion_end= completion_map.end();
 
2412
    }
 
2413
    else
 
2414
    {
 
2415
      completion_iter= find_if(completion_map.begin(), completion_map.end(),
 
2416
                               CompletionMatch<equal_to<string> >(completion_string));
 
2417
      completion_end= find_if(completion_iter, completion_map.end(),
 
2418
                              CompletionMatch<not_equal_to<string> >(completion_string));
 
2419
    }
 
2420
  }
 
2421
  if (completion_iter == completion_end || (size_t)state > completion_map.size())
 
2422
    return NULL;
 
2423
  char *result= (char *)malloc((*completion_iter).second.size()+1);
 
2424
  strcpy(result, (*completion_iter).second.c_str());
 
2425
  completion_iter++;
 
2426
  return result;
2278
2427
}
2279
2428
 
2280
 
 
2281
2429
/* Build up the completion hash */
2282
2430
 
2283
2431
static void build_completion_hash(bool rehash, bool write_info)
2284
2432
{
2285
2433
  COMMANDS *cmd=commands;
2286
 
  DRIZZLE_RES *databases=0,*tables=0;
2287
 
  DRIZZLE_RES *fields;
2288
 
  static char ***field_names= 0;
2289
 
  DRIZZLE_ROW database_row,table_row;
2290
 
  DRIZZLE_FIELD *sql_field;
2291
 
  char buf[NAME_LEN*2+2];     // table name plus field name plus 2
2292
 
  int i,j,num_fields;
2293
 
 
 
2434
  drizzle_return_t ret;
 
2435
  drizzle_result_st databases,tables,fields;
 
2436
  drizzle_row_t database_row,table_row;
 
2437
  drizzle_column_st *sql_field;
 
2438
  string tmp_str, tmp_str_lower;
2294
2439
 
2295
2440
  if (status.batch || quick || !current_db)
2296
2441
    return;      // We don't need completion in batches
2297
2442
  if (!rehash)
2298
2443
    return;
2299
2444
 
2300
 
  /* Free old used memory */
2301
 
  if (field_names)
2302
 
    field_names=0;
2303
 
  completion_hash_clean(&ht);
2304
 
  free_root(&hash_mem_root,MYF(0));
 
2445
  completion_map.clear();
2305
2446
 
2306
2447
  /* hash this file's known subset of SQL commands */
2307
2448
  while (cmd->name) {
2308
 
    add_word(&ht,(char*) cmd->name);
 
2449
    tmp_str= cmd->name;
 
2450
    tmp_str_lower= lower_string(tmp_str);
 
2451
    completion_map[tmp_str_lower]= tmp_str;
2309
2452
    cmd++;
2310
2453
  }
2311
2454
 
2312
2455
  /* hash Drizzle functions (to be implemented) */
2313
2456
 
2314
2457
  /* hash all database names */
2315
 
  if (drizzle_query(&drizzle,"show databases") == 0)
 
2458
  if (drizzle_query_str(&con, &databases, "show databases", &ret) != NULL)
2316
2459
  {
2317
 
    if (!(databases = drizzle_store_result(&drizzle)))
2318
 
      put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
2319
 
    else
 
2460
    if (ret == DRIZZLE_RETURN_OK)
2320
2461
    {
2321
 
      while ((database_row=drizzle_fetch_row(databases)))
 
2462
      if (drizzle_result_buffer(&databases) != DRIZZLE_RETURN_OK)
 
2463
        put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
 
2464
      else
2322
2465
      {
2323
 
        char *str=strdup_root(&hash_mem_root, (char*) database_row[0]);
2324
 
        if (str)
2325
 
          add_word(&ht,(char*) str);
 
2466
        while ((database_row=drizzle_row_next(&databases)))
 
2467
        {
 
2468
          tmp_str= database_row[0];
 
2469
          tmp_str_lower= lower_string(tmp_str);
 
2470
          completion_map[tmp_str_lower]= tmp_str;
 
2471
        }
2326
2472
      }
2327
 
      drizzle_free_result(databases);
2328
2473
    }
 
2474
 
 
2475
    drizzle_result_free(&databases);
2329
2476
  }
 
2477
 
2330
2478
  /* hash all table names */
2331
 
  if (drizzle_query(&drizzle,"show tables")==0)
 
2479
  if (drizzle_query_str(&con, &tables, "show tables", &ret) != NULL)
2332
2480
  {
2333
 
    if (!(tables = drizzle_store_result(&drizzle)))
 
2481
    if (ret != DRIZZLE_RETURN_OK)
 
2482
    {
 
2483
      drizzle_result_free(&tables);
 
2484
      return;
 
2485
    }
 
2486
 
 
2487
    if (drizzle_result_buffer(&tables) != DRIZZLE_RETURN_OK)
2334
2488
      put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
2335
2489
    else
2336
2490
    {
2337
 
      if (drizzle_num_rows(tables) > 0 && !opt_silent && write_info)
 
2491
      if (drizzle_result_row_count(&tables) > 0 && !opt_silent && write_info)
2338
2492
      {
2339
2493
        tee_fprintf(stdout, _("\
2340
2494
Reading table information for completion of table and column names\n    \
2341
2495
You can turn off this feature to get a quicker startup with -A\n\n"));
2342
2496
      }
2343
 
      while ((table_row=drizzle_fetch_row(tables)))
 
2497
      while ((table_row=drizzle_row_next(&tables)))
2344
2498
      {
2345
 
        char *str=strdup_root(&hash_mem_root, (char*) table_row[0]);
2346
 
        if (str &&
2347
 
            !completion_hash_exists(&ht,(char*) str, (uint) strlen(str)))
2348
 
          add_word(&ht,str);
 
2499
        tmp_str= table_row[0];
 
2500
        tmp_str_lower= lower_string(tmp_str);
 
2501
        completion_map[tmp_str_lower]= tmp_str;
2349
2502
      }
2350
2503
    }
2351
2504
  }
 
2505
  else
 
2506
    return;
2352
2507
 
2353
2508
  /* hash all field names, both with the table prefix and without it */
2354
 
  if (!tables)          /* no tables */
2355
 
  {
2356
 
    return;
2357
 
  }
2358
 
  drizzle_data_seek(tables,0);
2359
 
  if (!(field_names= (char ***) alloc_root(&hash_mem_root,sizeof(char **) *
2360
 
                                           (uint) (drizzle_num_rows(tables)+1))))
2361
 
  {
2362
 
    drizzle_free_result(tables);
2363
 
    return;
2364
 
  }
2365
 
  i=0;
2366
 
  while ((table_row=drizzle_fetch_row(tables)))
2367
 
  {
2368
 
    if ((fields=drizzle_list_fields(&drizzle,(const char*) table_row[0],NullS)))
 
2509
  if (drizzle_result_row_count(&tables) == 0)
 
2510
  {
 
2511
    drizzle_result_free(&tables);
 
2512
    return;
 
2513
  }
 
2514
 
 
2515
  drizzle_row_seek(&tables, 0);
 
2516
 
 
2517
  while ((table_row=drizzle_row_next(&tables)))
 
2518
  {
 
2519
    string query;
 
2520
 
 
2521
    query.append("show fields in '");
 
2522
    query.append(table_row[0]);
 
2523
    query.append("'");
 
2524
    
 
2525
    if (drizzle_query(&con, &fields, query.c_str(), query.length(),
 
2526
                      &ret) != NULL)
2369
2527
    {
2370
 
      num_fields=drizzle_num_fields(fields);
2371
 
      if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
2372
 
                                                  sizeof(char *) *
2373
 
                                                  (num_fields*2+1))))
2374
 
      {
2375
 
        drizzle_free_result(fields);
2376
 
        break;
2377
 
      }
2378
 
      field_names[i][num_fields*2]= '\0';
2379
 
      j=0;
2380
 
      while ((sql_field=drizzle_fetch_field(fields)))
2381
 
      {
2382
 
        sprintf(buf,"%.64s.%.64s",table_row[0],sql_field->name);
2383
 
        field_names[i][j] = strdup_root(&hash_mem_root,buf);
2384
 
        add_word(&ht,field_names[i][j]);
2385
 
        field_names[i][num_fields+j] = strdup_root(&hash_mem_root,
2386
 
                                                   sql_field->name);
2387
 
        if (!completion_hash_exists(&ht,field_names[i][num_fields+j],
2388
 
                                    (uint) strlen(field_names[i][num_fields+j])))
2389
 
          add_word(&ht,field_names[i][num_fields+j]);
2390
 
        j++;
2391
 
      }
2392
 
      drizzle_free_result(fields);
 
2528
      if (ret == DRIZZLE_RETURN_OK &&
 
2529
          drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
 
2530
      {
 
2531
        while ((sql_field=drizzle_column_next(&fields)))
 
2532
        {
 
2533
          tmp_str=table_row[0];
 
2534
          tmp_str.append(".");
 
2535
          tmp_str.append(drizzle_column_name(sql_field));
 
2536
          tmp_str_lower= lower_string(tmp_str);
 
2537
          completion_map[tmp_str_lower]= tmp_str;
 
2538
 
 
2539
          tmp_str=drizzle_column_name(sql_field);
 
2540
          tmp_str_lower= lower_string(tmp_str);
 
2541
          completion_map[tmp_str_lower]= tmp_str;
 
2542
        }
 
2543
      }
 
2544
      drizzle_result_free(&fields);
2393
2545
    }
2394
 
    else
2395
 
      field_names[i]= 0;
2396
 
 
2397
 
    i++;
2398
2546
  }
2399
 
  drizzle_free_result(tables);
2400
 
  field_names[i]=0;        // End pointer
2401
 
  return;
 
2547
  drizzle_result_free(&tables);
 
2548
  completion_iter= completion_map.begin();
2402
2549
}
2403
2550
 
2404
2551
/* for gnu readline */
2412
2559
    for (;;)
2413
2560
    {
2414
2561
      if (*s == (char) c) return (char*) s;
2415
 
      if (!*s++) return NullS;
 
2562
      if (!*s++) return NULL;
2416
2563
    }
2417
2564
  }
2418
2565
 
2420
2567
  {
2421
2568
    register char *t;
2422
2569
 
2423
 
    t = NullS;
 
2570
    t = NULL;
2424
2571
    do if (*s == (char) c) t = (char*) s; while (*s++);
2425
2572
    return (char*) t;
2426
2573
  }
2446
2593
 
2447
2594
static void get_current_db(void)
2448
2595
{
2449
 
  DRIZZLE_RES *res;
 
2596
  drizzle_return_t ret;
 
2597
  drizzle_result_st res;
2450
2598
 
2451
 
  my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
 
2599
  free(current_db);
2452
2600
  current_db= NULL;
2453
2601
  /* In case of error below current_db will be NULL */
2454
 
  if (!drizzle_query(&drizzle, "SELECT DATABASE()") &&
2455
 
      (res= drizzle_use_result(&drizzle)))
 
2602
  if (drizzle_query_str(&con, &res, "SELECT DATABASE()", &ret) != NULL)
2456
2603
  {
2457
 
    DRIZZLE_ROW row= drizzle_fetch_row(res);
2458
 
    if (row[0])
2459
 
      current_db= strdup(row[0]);
2460
 
    drizzle_free_result(res);
 
2604
    if (ret == DRIZZLE_RETURN_OK &&
 
2605
        drizzle_result_buffer(&res) == DRIZZLE_RETURN_OK)
 
2606
    {
 
2607
      drizzle_row_t row= drizzle_row_next(&res);
 
2608
      if (row[0])
 
2609
        current_db= strdup(row[0]);
 
2610
    }
 
2611
    drizzle_result_free(&res);
2461
2612
  }
2462
2613
}
2463
2614
 
2465
2616
 The different commands
2466
2617
***************************************************************************/
2467
2618
 
2468
 
int drizzle_real_query_for_lazy(const char *buf, int length)
 
2619
int drizzleclient_real_query_for_lazy(const char *buf, int length,
 
2620
                                      drizzle_result_st *result,
 
2621
                                      uint32_t *error_code)
2469
2622
{
2470
 
  for (uint retry=0;; retry++)
 
2623
  drizzle_return_t ret;
 
2624
 
 
2625
  for (uint32_t retry=0;; retry++)
2471
2626
  {
2472
2627
    int error;
2473
 
    if (!drizzle_real_query(&drizzle,buf,length))
 
2628
    if (drizzle_query(&con,result,buf,length,&ret) != NULL &&
 
2629
        ret == DRIZZLE_RETURN_OK)
 
2630
    {
2474
2631
      return 0;
2475
 
    error= put_error(&drizzle);
2476
 
    if (drizzle_errno(&drizzle) != CR_SERVER_GONE_ERROR || retry > 1 ||
 
2632
    }
 
2633
    error= put_error(&con, result);
 
2634
 
 
2635
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
2636
    {
 
2637
      *error_code= drizzle_result_error_code(result);
 
2638
      drizzle_result_free(result);
 
2639
    }
 
2640
 
 
2641
    if (ret != DRIZZLE_RETURN_SERVER_GONE || retry > 1 ||
2477
2642
        !opt_reconnect)
 
2643
    {
2478
2644
      return error;
 
2645
    }
 
2646
 
2479
2647
    if (reconnect())
2480
2648
      return error;
2481
2649
  }
2482
2650
}
2483
2651
 
2484
 
int drizzle_store_result_for_lazy(DRIZZLE_RES **result)
 
2652
int drizzleclient_store_result_for_lazy(drizzle_result_st *result)
2485
2653
{
2486
 
  if ((*result=drizzle_store_result(&drizzle)))
 
2654
  if (drizzle_result_buffer(result) == DRIZZLE_RETURN_OK)
2487
2655
    return 0;
2488
2656
 
2489
 
  if (drizzle_error(&drizzle)[0])
2490
 
    return put_error(&drizzle);
 
2657
  if (drizzle_con_error(&con)[0])
 
2658
    return put_error(&con, result);
2491
2659
  return 0;
2492
2660
}
2493
2661
 
2494
 
static void print_help_item(DRIZZLE_ROW *cur, int num_name, int num_cat, char *last_char)
2495
 
{
2496
 
  char ccat= (*cur)[num_cat][0];
2497
 
  if (*last_char != ccat)
2498
 
  {
2499
 
    put_info(ccat == 'Y' ? _("categories:") : _("topics:"), INFO_INFO,0,0);
2500
 
    *last_char= ccat;
2501
 
  }
2502
 
  tee_fprintf(PAGER, "   %s\n", (*cur)[num_name]);
2503
 
}
2504
 
 
2505
 
 
2506
 
static int com_server_help(string *buffer,
2507
 
                           const char *line __attribute__((unused)),
2508
 
                           char *help_arg)
2509
 
{
2510
 
  DRIZZLE_ROW cur;
2511
 
  const char *server_cmd= buffer->c_str();
2512
 
  char cmd_buf[100];
2513
 
  DRIZZLE_RES *result;
2514
 
  int error;
2515
 
 
2516
 
  if (help_arg[0] != '\'')
2517
 
  {
2518
 
    char *end_arg= strend(help_arg);
2519
 
    if(--end_arg)
2520
 
    {
2521
 
      while (my_isspace(charset_info,*end_arg))
2522
 
        end_arg--;
2523
 
      *++end_arg= '\0';
2524
 
    }
2525
 
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
2526
 
    server_cmd= cmd_buf;
2527
 
  }
2528
 
 
2529
 
  if (!connected && reconnect())
2530
 
    return 1;
2531
 
 
2532
 
  if ((error= drizzle_real_query_for_lazy(server_cmd,(int)strlen(server_cmd))) ||
2533
 
      (error= drizzle_store_result_for_lazy(&result)))
2534
 
    return error;
2535
 
 
2536
 
  if (result)
2537
 
  {
2538
 
    unsigned int num_fields= drizzle_num_fields(result);
2539
 
    uint64_t num_rows= drizzle_num_rows(result);
2540
 
    drizzle_fetch_fields(result);
2541
 
    if (num_fields==3 && num_rows==1)
2542
 
    {
2543
 
      if (!(cur= drizzle_fetch_row(result)))
2544
 
      {
2545
 
        error= -1;
2546
 
        goto err;
2547
 
      }
2548
 
 
2549
 
      init_pager();
2550
 
      tee_fprintf(PAGER,   _("Name: \'%s\'\n"), cur[0]);
2551
 
      tee_fprintf(PAGER,   _("Description:\n%s"), cur[1]);
2552
 
      if (cur[2] && *((char*)cur[2]))
2553
 
        tee_fprintf(PAGER, _("Examples:\n%s"), cur[2]);
2554
 
      tee_fprintf(PAGER,   "\n");
2555
 
      end_pager();
2556
 
    }
2557
 
    else if (num_fields >= 2 && num_rows)
2558
 
    {
2559
 
      init_pager();
2560
 
      char last_char= 0;
2561
 
 
2562
 
      int num_name= 0, num_cat= 0;
2563
 
 
2564
 
      if (num_fields == 2)
2565
 
      {
2566
 
        put_info(_("Many help items for your request exist."), INFO_INFO,0,0);
2567
 
        put_info(_("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following"), INFO_INFO,0,0);
2568
 
        num_name= 0;
2569
 
        num_cat= 1;
2570
 
      }
2571
 
      else if ((cur= drizzle_fetch_row(result)))
2572
 
      {
2573
 
        tee_fprintf(PAGER, _("You asked for help about help category: '%s'\n"), cur[0]);
2574
 
        put_info(_("For more information, type 'help <item>', where <item> is one of the following"), INFO_INFO,0,0);
2575
 
        num_name= 1;
2576
 
        num_cat= 2;
2577
 
        print_help_item(&cur,1,2,&last_char);
2578
 
      }
2579
 
 
2580
 
      while ((cur= drizzle_fetch_row(result)))
2581
 
        print_help_item(&cur,num_name,num_cat,&last_char);
2582
 
      tee_fprintf(PAGER, "\n");
2583
 
      end_pager();
2584
 
    }
2585
 
    else
2586
 
    {
2587
 
      put_info(_("\nNothing found"), INFO_INFO,0,0);
2588
 
      put_info(_("Please try to run 'help contents' for a list of all accessible topics\n"), INFO_INFO,0,0);
2589
 
    }
2590
 
  }
2591
 
 
2592
 
err:
2593
 
  drizzle_free_result(result);
2594
 
  return error;
2595
 
}
2596
 
 
2597
2662
static int
2598
 
com_help(string *buffer __attribute__((unused)),
2599
 
         const char *line __attribute__((unused)))
 
2663
com_help(string *buffer, const char *)
2600
2664
{
2601
2665
  register int i, j;
2602
 
  char * help_arg= strchr(line,' '), buff[32], *end;
2603
 
  if (help_arg)
2604
 
  {
2605
 
    while (my_isspace(charset_info,*help_arg))
2606
 
      help_arg++;
2607
 
    if (*help_arg) return com_server_help(buffer,line,help_arg);
2608
 
  }
 
2666
  char buff[32], *end;
2609
2667
 
2610
2668
  put_info(_("List of all Drizzle commands:"), INFO_INFO,0,0);
2611
2669
  if (!named_cmds)
2612
2670
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
2613
2671
  for (i = 0; commands[i].name; i++)
2614
2672
  {
2615
 
    end= stpcpy(buff, commands[i].name);
 
2673
    end= strcpy(buff, commands[i].name);
 
2674
    end+= strlen(commands[i].name);
2616
2675
    for (j= (int)strlen(commands[i].name); j < 10; j++)
2617
 
      end= stpcpy(end, " ");
 
2676
      end= strcpy(end, " ")+1;
2618
2677
    if (commands[i].func)
2619
2678
      tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2620
2679
                  commands[i].cmd_char, _(commands[i].doc));
2621
2680
  }
2622
 
  if (connected && drizzle_get_server_version(&drizzle) >= 40100)
2623
 
    put_info(_("\nFor server side help, type 'help contents'\n"), INFO_INFO,0,0);
 
2681
  tee_fprintf(stdout, "\n");
 
2682
  buffer->clear();
2624
2683
  return 0;
2625
2684
}
2626
2685
 
2627
2686
 
2628
2687
static int
2629
 
com_clear(string *buffer,
2630
 
          const char *line __attribute__((unused)))
 
2688
com_clear(string *buffer, const char *)
2631
2689
{
2632
2690
  if (status.add_to_history)
2633
2691
    fix_history(buffer);
2635
2693
  return 0;
2636
2694
}
2637
2695
 
2638
 
static int
2639
 
com_charset(string *buffer __attribute__((unused)),
2640
 
            const char *line)
2641
 
{
2642
 
  char buff[256], *param;
2643
 
  const CHARSET_INFO * new_cs;
2644
 
  strmake(buff, line, sizeof(buff) - 1);
2645
 
  param= get_arg(buff, 0);
2646
 
  if (!param || !*param)
2647
 
  {
2648
 
    return put_info(_("Usage: \\C char_setname | charset charset_name"),
2649
 
                    INFO_ERROR, 0, 0);
2650
 
  }
2651
 
  new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME));
2652
 
  if (new_cs)
2653
 
  {
2654
 
    charset_info= new_cs;
2655
 
    drizzle_set_character_set(&drizzle, charset_info->csname);
2656
 
    default_charset= (char *)charset_info->csname;
2657
 
    default_charset_used= 1;
2658
 
    put_info(_("Charset changed"), INFO_INFO,0,0);
2659
 
  }
2660
 
  else put_info(_("Charset is not found"), INFO_INFO,0,0);
2661
 
  return 0;
2662
 
}
2663
2696
 
2664
2697
/*
2665
2698
  Execute command
2668
2701
  1  if fatal error
2669
2702
*/
2670
2703
static int
2671
 
com_go(string *buffer,
2672
 
       const char *line __attribute__((unused)))
 
2704
com_go(string *buffer, const char *)
2673
2705
{
2674
2706
  char          buff[200]; /* about 110 chars used so far */
2675
2707
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2676
 
  DRIZZLE_RES     *result;
2677
 
  uint32_t         timer, warnings= 0;
2678
 
  uint          error= 0;
 
2708
  drizzle_result_st result;
 
2709
  drizzle_return_t ret;
 
2710
  uint32_t      timer, warnings= 0;
 
2711
  uint32_t      error= 0;
 
2712
  uint32_t      error_code= 0;
2679
2713
  int           err= 0;
2680
2714
 
2681
2715
  interrupted_query= 0;
2709
2743
 
2710
2744
  timer=start_timer();
2711
2745
  executing_query= 1;
2712
 
  error= drizzle_real_query_for_lazy(buffer->c_str(),buffer->length());
 
2746
  error= drizzleclient_real_query_for_lazy(buffer->c_str(),buffer->length(),&result, &error_code);
2713
2747
 
2714
2748
  if (status.add_to_history)
2715
2749
  {
2729
2763
 
2730
2764
    if (quick)
2731
2765
    {
2732
 
      if (!(result=drizzle_use_result(&drizzle)) && drizzle_field_count(&drizzle))
 
2766
      if (drizzle_column_buffer(&result) != DRIZZLE_RETURN_OK)
2733
2767
      {
2734
 
        error= put_error(&drizzle);
 
2768
        error= put_error(&con, &result);
2735
2769
        goto end;
2736
2770
      }
2737
2771
    }
2738
2772
    else
2739
2773
    {
2740
 
      error= drizzle_store_result_for_lazy(&result);
 
2774
      error= drizzleclient_store_result_for_lazy(&result);
2741
2775
      if (error)
2742
2776
        goto end;
2743
2777
    }
2748
2782
      time_buff[0]= '\0';
2749
2783
 
2750
2784
    /* Every branch must truncate  buff . */
2751
 
    if (result)
 
2785
    if (drizzle_result_column_count(&result) > 0)
2752
2786
    {
2753
 
      if (!drizzle_num_rows(result) && ! quick && !column_types_flag)
 
2787
      if (!quick && drizzle_result_row_count(&result) == 0 &&
 
2788
          !column_types_flag)
2754
2789
      {
2755
 
        stpcpy(buff, _("Empty set"));
 
2790
        strcpy(buff, _("Empty set"));
2756
2791
      }
2757
2792
      else
2758
2793
      {
2759
2794
        init_pager();
2760
2795
        if (vertical || (auto_vertical_output &&
2761
 
                         (terminal_width < get_result_width(result))))
2762
 
          print_table_data_vertically(result);
 
2796
                         (terminal_width < get_result_width(&result))))
 
2797
          print_table_data_vertically(&result);
2763
2798
        else if (opt_silent && verbose <= 2 && !output_tables)
2764
 
          print_tab_data(result);
 
2799
          print_tab_data(&result);
2765
2800
        else
2766
 
          print_table_data(result);
 
2801
          print_table_data(&result);
2767
2802
        sprintf(buff,
2768
2803
                ngettext("%ld row in set","%ld rows in set",
2769
 
                         (long) drizzle_num_rows(result)),
2770
 
                (long) drizzle_num_rows(result));
 
2804
                         (long) drizzle_result_row_count(&result)),
 
2805
                (long) drizzle_result_row_count(&result));
2771
2806
        end_pager();
2772
 
        if (drizzle_errno(&drizzle))
2773
 
          error= put_error(&drizzle);
 
2807
        if (drizzle_result_error_code(&result))
 
2808
          error= put_error(&con, &result);
2774
2809
      }
2775
2810
    }
2776
 
    else if (drizzle_affected_rows(&drizzle) == ~(uint64_t) 0)
2777
 
      stpcpy(buff,_("Query OK"));
 
2811
    else if (drizzle_result_affected_rows(&result) == ~(uint64_t) 0)
 
2812
      strcpy(buff,_("Query OK"));
2778
2813
    else
2779
2814
      sprintf(buff, ngettext("Query OK, %ld row affected",
2780
2815
                             "Query OK, %ld rows affected",
2781
 
                             (long) drizzle_affected_rows(&drizzle)),
2782
 
              (long) drizzle_affected_rows(&drizzle));
 
2816
                             (long) drizzle_result_affected_rows(&result)),
 
2817
              (long) drizzle_result_affected_rows(&result));
2783
2818
 
2784
 
    pos=strend(buff);
2785
 
    if ((warnings= drizzle_warning_count(&drizzle)))
 
2819
    pos= strchr(buff, '\0');
 
2820
    if ((warnings= drizzle_result_warning_count(&result)))
2786
2821
    {
2787
2822
      *pos++= ',';
2788
2823
      *pos++= ' ';
2789
 
      pos=int10_to_str(warnings, pos, 10);
2790
 
      pos=stpcpy(pos, " warning");
 
2824
      char warnings_buff[20];
 
2825
      memset(warnings_buff,0,20);
 
2826
      sprintf(warnings_buff, "%d", warnings);
 
2827
      strcpy(pos, warnings_buff);
 
2828
      pos+= strlen(warnings_buff);
 
2829
      pos= strcpy(pos, " warning")+8;
2791
2830
      if (warnings != 1)
2792
2831
        *pos++= 's';
2793
2832
    }
2794
 
    stpcpy(pos, time_buff);
 
2833
    strcpy(pos, time_buff);
2795
2834
    put_info(buff,INFO_RESULT,0,0);
2796
 
    if (drizzle_info(&drizzle))
2797
 
      put_info(drizzle_info(&drizzle),INFO_RESULT,0,0);
 
2835
    if (strcmp(drizzle_result_info(&result), ""))
 
2836
      put_info(drizzle_result_info(&result),INFO_RESULT,0,0);
2798
2837
    put_info("",INFO_RESULT,0,0);      // Empty row
2799
2838
 
2800
 
    if (result && !drizzle_eof(result))  /* Something wrong when using quick */
2801
 
      error= put_error(&drizzle);
2802
 
    else if (unbuffered)
 
2839
    if (unbuffered)
2803
2840
      fflush(stdout);
2804
 
    drizzle_free_result(result);
2805
 
  } while (!(err= drizzle_next_result(&drizzle)));
 
2841
    drizzle_result_free(&result);
 
2842
 
 
2843
    if (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_MORE_RESULTS_EXISTS)
 
2844
    {
 
2845
      if (drizzle_result_read(&con, &result, &ret) == NULL ||
 
2846
          ret != DRIZZLE_RETURN_OK)
 
2847
      {
 
2848
        if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
2849
        {
 
2850
          error_code= drizzle_result_error_code(&result);
 
2851
          drizzle_result_free(&result);
 
2852
        }
 
2853
 
 
2854
        error= put_error(&con, NULL);
 
2855
        goto end;
 
2856
      }
 
2857
    }
 
2858
 
 
2859
  } while (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_MORE_RESULTS_EXISTS);
2806
2860
  if (err >= 1)
2807
 
    error= put_error(&drizzle);
 
2861
    error= put_error(&con, NULL);
2808
2862
 
2809
2863
end:
2810
2864
 
2811
2865
  /* Show warnings if any or error occured */
2812
2866
  if (show_warnings == 1 && (warnings >= 1 || error))
2813
 
    print_warnings();
 
2867
    print_warnings(error_code);
2814
2868
 
2815
2869
  if (!error && !status.batch &&
2816
 
      (drizzle.server_status & SERVER_STATUS_DB_DROPPED))
 
2870
      drizzle_con_status(&con) & DRIZZLE_CON_STATUS_DB_DROPPED)
 
2871
  {
2817
2872
    get_current_db();
 
2873
  }
2818
2874
 
2819
2875
  executing_query= 0;
2820
2876
  return error;        /* New command follows */
2847
2903
  FILE* new_outfile;
2848
2904
  if (opt_outfile)
2849
2905
    end_tee();
2850
 
  if (!(new_outfile= my_fopen(file_name, O_APPEND | O_WRONLY, MYF(MY_WME))))
 
2906
  if (!(new_outfile= fopen(file_name, "a")))
2851
2907
  {
2852
2908
    tee_fprintf(stdout, "Error logging to file '%s'\n", file_name);
2853
2909
    return;
2854
2910
  }
2855
2911
  OUTFILE = new_outfile;
2856
 
  strmake(outfile, file_name, FN_REFLEN-1);
 
2912
  strncpy(outfile, file_name, FN_REFLEN-1);
2857
2913
  tee_fprintf(stdout, "Logging to file '%s'\n", file_name);
2858
2914
  opt_outfile= 1;
 
2915
 
2859
2916
  return;
2860
2917
}
2861
2918
 
2862
2919
 
2863
2920
static void end_tee()
2864
2921
{
2865
 
  my_fclose(OUTFILE, MYF(0));
 
2922
  fclose(OUTFILE);
2866
2923
  OUTFILE= 0;
2867
2924
  opt_outfile= 0;
2868
2925
  return;
2881
2938
}
2882
2939
 
2883
2940
 
2884
 
static const char *fieldtype2str(enum enum_field_types type)
 
2941
static const char *fieldtype2str(drizzle_column_type_t type)
2885
2942
{
2886
2943
  switch (type) {
2887
 
    case DRIZZLE_TYPE_BLOB:        return "BLOB";
2888
 
    case DRIZZLE_TYPE_NEWDATE:        return "DATE";
2889
 
    case DRIZZLE_TYPE_DATETIME:    return "DATETIME";
2890
 
    case DRIZZLE_TYPE_NEWDECIMAL:  return "DECIMAL";
2891
 
    case DRIZZLE_TYPE_DOUBLE:      return "DOUBLE";
2892
 
    case DRIZZLE_TYPE_ENUM:        return "ENUM";
2893
 
    case DRIZZLE_TYPE_LONG:        return "LONG";
2894
 
    case DRIZZLE_TYPE_LONGLONG:    return "LONGLONG";
2895
 
    case DRIZZLE_TYPE_NULL:        return "NULL";
2896
 
    case DRIZZLE_TYPE_SHORT:       return "SHORT";
2897
 
    case DRIZZLE_TYPE_TIME:        return "TIME";
2898
 
    case DRIZZLE_TYPE_TIMESTAMP:   return "TIMESTAMP";
2899
 
    case DRIZZLE_TYPE_TINY:        return "TINY";
 
2944
    case DRIZZLE_COLUMN_TYPE_BLOB:        return "BLOB";
 
2945
    case DRIZZLE_COLUMN_TYPE_DATE:        return "DATE";
 
2946
    case DRIZZLE_COLUMN_TYPE_DATETIME:    return "DATETIME";
 
2947
    case DRIZZLE_COLUMN_TYPE_NEWDECIMAL:  return "DECIMAL";
 
2948
    case DRIZZLE_COLUMN_TYPE_DOUBLE:      return "DOUBLE";
 
2949
    case DRIZZLE_COLUMN_TYPE_ENUM:        return "ENUM";
 
2950
    case DRIZZLE_COLUMN_TYPE_LONG:        return "LONG";
 
2951
    case DRIZZLE_COLUMN_TYPE_LONGLONG:    return "LONGLONG";
 
2952
    case DRIZZLE_COLUMN_TYPE_NULL:        return "NULL";
 
2953
    case DRIZZLE_COLUMN_TYPE_TIMESTAMP:   return "TIMESTAMP";
 
2954
    case DRIZZLE_COLUMN_TYPE_TINY:        return "TINY";
 
2955
    case DRIZZLE_COLUMN_TYPE_VIRTUAL:     return "VIRTUAL";
2900
2956
    default:                     return "?-unknown-?";
2901
2957
  }
2902
2958
}
2903
2959
 
2904
 
static char *fieldflags2str(uint f) {
 
2960
static char *fieldflags2str(uint32_t f) {
2905
2961
  static char buf[1024];
2906
2962
  char *s=buf;
2907
2963
  *s=0;
2908
2964
#define ff2s_check_flag(X)                                              \
2909
 
  if (f & X ## _FLAG) { s=stpcpy(s, # X " "); f &= ~ X ## _FLAG; }
 
2965
  if (f & DRIZZLE_COLUMN_FLAGS_ ## X) { s=strcpy(s, # X " ")+strlen(# X " "); \
 
2966
                        f &= ~ DRIZZLE_COLUMN_FLAGS_ ## X; }
2910
2967
  ff2s_check_flag(NOT_NULL);
2911
2968
  ff2s_check_flag(PRI_KEY);
2912
2969
  ff2s_check_flag(UNIQUE_KEY);
2932
2989
}
2933
2990
 
2934
2991
static void
2935
 
print_field_types(DRIZZLE_RES *result)
 
2992
print_field_types(drizzle_result_st *result)
2936
2993
{
2937
 
  DRIZZLE_FIELD   *field;
2938
 
  uint i=0;
 
2994
  drizzle_column_st   *field;
 
2995
  uint32_t i=0;
2939
2996
 
2940
 
  while ((field = drizzle_fetch_field(result)))
 
2997
  while ((field = drizzle_column_next(result)))
2941
2998
  {
2942
2999
    tee_fprintf(PAGER, "Field %3u:  `%s`\n"
2943
3000
                "Catalog:    `%s`\n"
2951
3008
                "Decimals:   %u\n"
2952
3009
                "Flags:      %s\n\n",
2953
3010
                ++i,
2954
 
                field->name, field->catalog, field->db, field->table,
2955
 
                field->org_table, fieldtype2str(field->type),
2956
 
                get_charset_name(field->charsetnr), field->charsetnr,
2957
 
                field->length, field->max_length, field->decimals,
2958
 
                fieldflags2str(field->flags));
 
3011
                drizzle_column_name(field), drizzle_column_catalog(field),
 
3012
                drizzle_column_db(field), drizzle_column_table(field),
 
3013
                drizzle_column_orig_table(field),
 
3014
                fieldtype2str(drizzle_column_type(field)),
 
3015
                get_charset_name(drizzle_column_charset(field)),
 
3016
                drizzle_column_charset(field), drizzle_column_size(field),
 
3017
                drizzle_column_max_size(field), drizzle_column_decimals(field),
 
3018
                fieldflags2str(drizzle_column_flags(field)));
2959
3019
  }
2960
3020
  tee_puts("", PAGER);
2961
3021
}
2962
3022
 
2963
3023
 
2964
3024
static void
2965
 
print_table_data(DRIZZLE_RES *result)
 
3025
print_table_data(drizzle_result_st *result)
2966
3026
{
2967
 
  DRIZZLE_ROW     cur;
2968
 
  DRIZZLE_FIELD   *field;
2969
 
  bool          *num_flag;
 
3027
  drizzle_row_t cur;
 
3028
  drizzle_return_t ret;
 
3029
  drizzle_column_st *field;
 
3030
  bool *num_flag;
2970
3031
  string separator;
2971
 
  
 
3032
 
2972
3033
  separator.reserve(256);
2973
3034
 
2974
 
  num_flag=(bool*) my_malloc(sizeof(bool)*drizzle_num_fields(result),
2975
 
                             MYF(MY_WME));
 
3035
  num_flag=(bool*) malloc(sizeof(bool)*drizzle_result_column_count(result));
2976
3036
  if (column_types_flag)
2977
3037
  {
2978
3038
    print_field_types(result);
2979
 
    if (!drizzle_num_rows(result))
 
3039
    if (!drizzle_result_row_count(result))
2980
3040
      return;
2981
 
    drizzle_field_seek(result,0);
 
3041
    drizzle_column_seek(result,0);
2982
3042
  }
2983
3043
  separator.append("+");
2984
 
  while ((field = drizzle_fetch_field(result)))
 
3044
  while ((field = drizzle_column_next(result)))
2985
3045
  {
2986
 
    uint32_t length= column_names ? field->name_length : 0;
 
3046
    uint32_t x, length= 0;
 
3047
 
 
3048
    if (column_names)
 
3049
    {
 
3050
      uint32_t name_length= strlen(drizzle_column_name(field));
 
3051
 
 
3052
      /* Check if the max_byte value is really the maximum in terms
 
3053
         of visual length since multibyte characters can affect the
 
3054
         length of the separator. */
 
3055
      length= charset_info->cset->numcells(charset_info,
 
3056
                                           drizzle_column_name(field),
 
3057
                                           drizzle_column_name(field) +
 
3058
                                           name_length);
 
3059
 
 
3060
      if (name_length == drizzle_column_max_size(field))
 
3061
      {
 
3062
        if (length < drizzle_column_max_size(field))
 
3063
          drizzle_column_set_max_size(field, length);
 
3064
      }
 
3065
      else
 
3066
      {
 
3067
        length= name_length;
 
3068
      }
 
3069
    }
 
3070
  
2987
3071
    if (quick)
2988
 
      length=max(length,field->length);
 
3072
      length=max(length,drizzle_column_size(field));
2989
3073
    else
2990
 
      length=max(length,field->max_length);
2991
 
    if (length < 4 && !IS_NOT_NULL(field->flags))
 
3074
      length=max(length,(uint32_t)drizzle_column_max_size(field));
 
3075
    if (length < 4 &&
 
3076
        !(drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_NOT_NULL))
 
3077
    {
2992
3078
      // Room for "NULL"
2993
3079
      length=4;
2994
 
    field->max_length=length;
2995
 
    uint x;
 
3080
    }
 
3081
    drizzle_column_set_max_size(field, length);
 
3082
 
2996
3083
    for (x=0; x< (length+2); x++)
2997
3084
      separator.append("-");
2998
3085
    separator.append("+");
3001
3088
  tee_puts((char*) separator.c_str(), PAGER);
3002
3089
  if (column_names)
3003
3090
  {
3004
 
    drizzle_field_seek(result,0);
 
3091
    drizzle_column_seek(result,0);
3005
3092
    (void) tee_fputs("|", PAGER);
3006
 
    for (uint off=0; (field = drizzle_fetch_field(result)) ; off++)
 
3093
    for (uint32_t off=0; (field = drizzle_column_next(result)) ; off++)
3007
3094
    {
3008
 
      uint name_length= (uint) strlen(field->name);
3009
 
      uint numcells= charset_info->cset->numcells(charset_info,
3010
 
                                                  field->name,
3011
 
                                                  field->name + name_length);
3012
 
      uint32_t display_length= field->max_length + name_length - numcells;
 
3095
      uint32_t name_length= (uint32_t) strlen(drizzle_column_name(field));
 
3096
      uint32_t numcells= charset_info->cset->numcells(charset_info,
 
3097
                                                  drizzle_column_name(field),
 
3098
                                                  drizzle_column_name(field) +
 
3099
                                                  name_length);
 
3100
      uint32_t display_length= drizzle_column_max_size(field) + name_length -
 
3101
                               numcells;
3013
3102
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
3014
3103
                                             MAX_COLUMN_LENGTH),
3015
 
                  field->name);
3016
 
      num_flag[off]= IS_NUM(field->type);
 
3104
                  drizzle_column_name(field));
 
3105
      num_flag[off]= ((drizzle_column_type(field) <= DRIZZLE_COLUMN_TYPE_LONGLONG) ||
 
3106
                      (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_NEWDECIMAL));
3017
3107
    }
3018
3108
    (void) tee_fputs("\n", PAGER);
3019
3109
    tee_puts((char*) separator.c_str(), PAGER);
3020
3110
  }
3021
3111
 
3022
 
  while ((cur= drizzle_fetch_row(result)))
 
3112
  while (1)
3023
3113
  {
3024
 
    if (interrupted_query)
 
3114
    if (quick)
 
3115
    {
 
3116
      cur= drizzle_row_buffer(result, &ret);
 
3117
      if (ret != DRIZZLE_RETURN_OK)
 
3118
      {
 
3119
        (void)put_error(&con, result);
 
3120
        break;
 
3121
      }
 
3122
    }
 
3123
    else
 
3124
      cur= drizzle_row_next(result);
 
3125
 
 
3126
    if (cur == NULL || interrupted_query)
3025
3127
      break;
3026
 
    uint32_t *lengths= drizzle_fetch_lengths(result);
 
3128
 
 
3129
    size_t *lengths= drizzle_row_field_sizes(result);
3027
3130
    (void) tee_fputs("| ", PAGER);
3028
 
    drizzle_field_seek(result, 0);
3029
 
    for (uint off= 0; off < drizzle_num_fields(result); off++)
 
3131
    drizzle_column_seek(result, 0);
 
3132
    for (uint32_t off= 0; off < drizzle_result_column_count(result); off++)
3030
3133
    {
3031
3134
      const char *buffer;
3032
 
      uint data_length;
3033
 
      uint field_max_length;
3034
 
      uint visible_length;
3035
 
      uint extra_padding;
 
3135
      uint32_t data_length;
 
3136
      uint32_t field_max_length;
 
3137
      uint32_t visible_length;
 
3138
      uint32_t extra_padding;
3036
3139
 
3037
3140
      if (cur[off] == NULL)
3038
3141
      {
3042
3145
      else
3043
3146
      {
3044
3147
        buffer= cur[off];
3045
 
        data_length= (uint) lengths[off];
 
3148
        data_length= (uint32_t) lengths[off];
3046
3149
      }
3047
3150
 
3048
 
      field= drizzle_fetch_field(result);
3049
 
      field_max_length= field->max_length;
 
3151
      field= drizzle_column_next(result);
 
3152
      field_max_length= drizzle_column_max_size(field);
3050
3153
 
3051
3154
      /*
3052
3155
        How many text cells on the screen will this string span?  If it contains
3060
3163
      extra_padding= data_length - visible_length;
3061
3164
 
3062
3165
      if (field_max_length > MAX_COLUMN_LENGTH)
3063
 
        tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
 
3166
        tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, false);
3064
3167
      else
3065
3168
      {
3066
3169
        if (num_flag[off] != 0) /* if it is numeric, we right-justify it */
3067
 
          tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, TRUE);
 
3170
          tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, true);
3068
3171
        else
3069
3172
          tee_print_sized_data(buffer, data_length,
3070
 
                               field_max_length+extra_padding, FALSE);
 
3173
                               field_max_length+extra_padding, false);
3071
3174
      }
3072
3175
      tee_fputs(" | ", PAGER);
3073
3176
    }
3074
3177
    (void) tee_fputs("\n", PAGER);
 
3178
    if (quick)
 
3179
      drizzle_row_free(result, cur);
3075
3180
  }
3076
3181
  tee_puts(separator.c_str(), PAGER);
3077
 
  my_free(num_flag, MYF(MY_ALLOW_ZERO_PTR));
 
3182
  free(num_flag);
3078
3183
}
3079
3184
 
3080
3185
/**
3093
3198
 
3094
3199
   @returns  number of character positions to be used, at most
3095
3200
*/
3096
 
static int get_field_disp_length(DRIZZLE_FIELD *field)
 
3201
static int get_field_disp_length(drizzle_column_st *field)
3097
3202
{
3098
 
  uint length= column_names ? field->name_length : 0;
 
3203
  uint32_t length= column_names ? strlen(drizzle_column_name(field)) : 0;
3099
3204
 
3100
3205
  if (quick)
3101
 
    length= max(length, field->length);
 
3206
    length= max(length, drizzle_column_size(field));
3102
3207
  else
3103
 
    length= max(length, field->max_length);
 
3208
    length= max(length, (uint32_t)drizzle_column_max_size(field));
3104
3209
 
3105
 
  if (length < 4 && !IS_NOT_NULL(field->flags))
 
3210
  if (length < 4 &&
 
3211
    !(drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_NOT_NULL))
 
3212
  {
3106
3213
    length= 4;        /* Room for "NULL" */
 
3214
  }
3107
3215
 
3108
3216
  return length;
3109
3217
}
3116
3224
 
3117
3225
   @returns  The max number of characters in any row of this result
3118
3226
*/
3119
 
static int get_result_width(DRIZZLE_RES *result)
 
3227
static int get_result_width(drizzle_result_st *result)
3120
3228
{
3121
3229
  unsigned int len= 0;
3122
 
  DRIZZLE_FIELD *field;
3123
 
  DRIZZLE_FIELD_OFFSET offset;
 
3230
  drizzle_column_st *field;
 
3231
  uint16_t offset;
3124
3232
 
3125
 
  offset= drizzle_field_tell(result);
 
3233
  offset= drizzle_column_current(result);
3126
3234
  assert(offset == 0);
3127
3235
 
3128
 
  while ((field= drizzle_fetch_field(result)) != NULL)
 
3236
  while ((field= drizzle_column_next(result)) != NULL)
3129
3237
    len+= get_field_disp_length(field) + 3; /* plus bar, space, & final space */
3130
3238
 
3131
 
  (void) drizzle_field_seek(result, offset);
 
3239
  (void) drizzle_column_seek(result, offset);
3132
3240
 
3133
3241
  return len + 1; /* plus final bar. */
3134
3242
}
3164
3272
 
3165
3273
 
3166
3274
static void
3167
 
print_table_data_vertically(DRIZZLE_RES *result)
 
3275
print_table_data_vertically(drizzle_result_st *result)
3168
3276
{
3169
 
  DRIZZLE_ROW  cur;
3170
 
  uint    max_length=0;
3171
 
  DRIZZLE_FIELD  *field;
 
3277
  drizzle_row_t cur;
 
3278
  drizzle_return_t ret;
 
3279
  uint32_t max_length=0;
 
3280
  drizzle_column_st *field;
3172
3281
 
3173
 
  while ((field = drizzle_fetch_field(result)))
 
3282
  while ((field = drizzle_column_next(result)))
3174
3283
  {
3175
 
    uint length= field->name_length;
 
3284
    uint32_t length= strlen(drizzle_column_name(field));
3176
3285
    if (length > max_length)
3177
3286
      max_length= length;
3178
 
    field->max_length=length;
 
3287
    drizzle_column_set_max_size(field, length);
3179
3288
  }
3180
3289
 
3181
 
  drizzle_field_seek(result,0);
3182
 
  for (uint row_count=1; (cur= drizzle_fetch_row(result)); row_count++)
 
3290
  for (uint32_t row_count=1;; row_count++)
3183
3291
  {
3184
 
    if (interrupted_query)
 
3292
    if (quick)
 
3293
    {
 
3294
      cur= drizzle_row_buffer(result, &ret);
 
3295
      if (ret != DRIZZLE_RETURN_OK)
 
3296
      {
 
3297
        (void)put_error(&con, result);
 
3298
        break;
 
3299
      }
 
3300
    }
 
3301
    else
 
3302
      cur= drizzle_row_next(result);
 
3303
 
 
3304
    if (cur == NULL || interrupted_query)
3185
3305
      break;
3186
 
    drizzle_field_seek(result,0);
 
3306
    drizzle_column_seek(result,0);
3187
3307
    tee_fprintf(PAGER,
3188
3308
                "*************************** %d. row ***************************\n", row_count);
3189
 
    for (uint off=0; off < drizzle_num_fields(result); off++)
 
3309
    for (uint32_t off=0; off < drizzle_result_column_count(result); off++)
3190
3310
    {
3191
 
      field= drizzle_fetch_field(result);
3192
 
      tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
 
3311
      field= drizzle_column_next(result);
 
3312
      tee_fprintf(PAGER, "%*s: ",(int) max_length,drizzle_column_name(field));
3193
3313
      tee_fprintf(PAGER, "%s\n",cur[off] ? (char*) cur[off] : "NULL");
3194
3314
    }
 
3315
    if (quick)
 
3316
      drizzle_row_free(result, cur);
3195
3317
  }
3196
3318
}
3197
3319
 
3198
3320
 
3199
3321
/* print_warnings should be called right after executing a statement */
3200
3322
 
3201
 
static void print_warnings()
 
3323
static void print_warnings(uint32_t error_code)
3202
3324
{
3203
 
  const char   *query;
3204
 
  DRIZZLE_RES    *result;
3205
 
  DRIZZLE_ROW    cur;
 
3325
  const char *query;
 
3326
  drizzle_result_st result;
 
3327
  drizzle_row_t cur;
3206
3328
  uint64_t num_rows;
3207
 
 
3208
 
  /* Save current error before calling "show warnings" */
3209
 
  uint error= drizzle_errno(&drizzle);
 
3329
  uint32_t new_code= 0;
3210
3330
 
3211
3331
  /* Get the warnings */
3212
3332
  query= "show warnings";
3213
 
  drizzle_real_query_for_lazy(query, strlen(query));
3214
 
  drizzle_store_result_for_lazy(&result);
 
3333
  drizzleclient_real_query_for_lazy(query, strlen(query),&result,&new_code);
 
3334
  drizzleclient_store_result_for_lazy(&result);
3215
3335
 
3216
3336
  /* Bail out when no warnings */
3217
 
  if (!(num_rows= drizzle_num_rows(result)))
 
3337
  if (!(num_rows= drizzle_result_row_count(&result)))
3218
3338
    goto end;
3219
3339
 
3220
 
  cur= drizzle_fetch_row(result);
 
3340
  cur= drizzle_row_next(&result);
3221
3341
 
3222
3342
  /*
3223
3343
    Don't print a duplicate of the current error.  It is possible for SHOW
3225
3345
    messages.  To be safe, skip printing the duplicate only if it is the only
3226
3346
    warning.
3227
3347
  */
3228
 
  if (!cur || (num_rows == 1 && error == (uint) strtoul(cur[1], NULL, 10)))
 
3348
  if (!cur || (num_rows == 1 &&
 
3349
      error_code == (uint32_t) strtoul(cur[1], NULL, 10)))
 
3350
  {
3229
3351
    goto end;
 
3352
  }
3230
3353
 
3231
3354
  /* Print the warnings */
3232
3355
  init_pager();
3233
3356
  do
3234
3357
  {
3235
3358
    tee_fprintf(PAGER, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
3236
 
  } while ((cur= drizzle_fetch_row(result)));
 
3359
  } while ((cur= drizzle_row_next(&result)));
3237
3360
  end_pager();
3238
3361
 
3239
3362
end:
3240
 
  drizzle_free_result(result);
 
3363
  drizzle_result_free(&result);
3241
3364
}
3242
3365
 
3243
3366
 
3279
3402
 
3280
3403
 
3281
3404
static void
3282
 
print_tab_data(DRIZZLE_RES *result)
 
3405
print_tab_data(drizzle_result_st *result)
3283
3406
{
3284
 
  DRIZZLE_ROW  cur;
3285
 
  DRIZZLE_FIELD  *field;
3286
 
  uint32_t    *lengths;
 
3407
  drizzle_row_t cur;
 
3408
  drizzle_return_t ret;
 
3409
  drizzle_column_st *field;
 
3410
  size_t *lengths;
3287
3411
 
3288
3412
  if (opt_silent < 2 && column_names)
3289
3413
  {
3290
3414
    int first=0;
3291
 
    while ((field = drizzle_fetch_field(result)))
 
3415
    while ((field = drizzle_column_next(result)))
3292
3416
    {
3293
3417
      if (first++)
3294
3418
        (void) tee_fputs("\t", PAGER);
3295
 
      (void) tee_fputs(field->name, PAGER);
 
3419
      (void) tee_fputs(drizzle_column_name(field), PAGER);
3296
3420
    }
3297
3421
    (void) tee_fputs("\n", PAGER);
3298
3422
  }
3299
 
  while ((cur = drizzle_fetch_row(result)))
 
3423
  while (1)
3300
3424
  {
3301
 
    lengths= drizzle_fetch_lengths(result);
 
3425
    if (quick)
 
3426
    {
 
3427
      cur= drizzle_row_buffer(result, &ret);
 
3428
      if (ret != DRIZZLE_RETURN_OK)
 
3429
      {
 
3430
        (void)put_error(&con, result);
 
3431
        break;
 
3432
      }
 
3433
    }
 
3434
    else
 
3435
      cur= drizzle_row_next(result);
 
3436
 
 
3437
    if (cur == NULL)
 
3438
      break;
 
3439
 
 
3440
    lengths= drizzle_row_field_sizes(result);
3302
3441
    safe_put_field(cur[0],lengths[0]);
3303
 
    for (uint off=1 ; off < drizzle_num_fields(result); off++)
 
3442
    for (uint32_t off=1 ; off < drizzle_result_column_count(result); off++)
3304
3443
    {
3305
3444
      (void) tee_fputs("\t", PAGER);
3306
3445
      safe_put_field(cur[off], lengths[off]);
3307
3446
    }
3308
3447
    (void) tee_fputs("\n", PAGER);
 
3448
    if (quick)
 
3449
      drizzle_row_free(result, cur);
3309
3450
  }
3310
3451
}
3311
3452
 
3312
3453
static int
3313
 
com_tee(string *buffer __attribute__((unused)), const char *line )
 
3454
com_tee(string *, const char *line )
3314
3455
{
3315
 
  char file_name[FN_REFLEN], *end, *param;
 
3456
  char file_name[FN_REFLEN], *end;
 
3457
  const char *param;
3316
3458
 
3317
3459
  if (status.batch)
3318
3460
    return 0;
3337
3479
  /* eliminate the spaces before the parameters */
3338
3480
  while (my_isspace(charset_info,*param))
3339
3481
    param++;
3340
 
  end= strmake(file_name, param, sizeof(file_name) - 1);
 
3482
  strncpy(file_name, param, sizeof(file_name) - 1);
 
3483
  end= file_name + strlen(file_name);
3341
3484
  /* remove end space from command line */
3342
3485
  while (end > file_name && (my_isspace(charset_info,end[-1]) ||
3343
3486
                             my_iscntrl(charset_info,end[-1])))
3354
3497
 
3355
3498
 
3356
3499
static int
3357
 
com_notee(string *buffer __attribute__((unused)),
3358
 
          const char *line __attribute__((unused)))
 
3500
com_notee(string *, const char *)
3359
3501
{
3360
3502
  if (opt_outfile)
3361
3503
    end_tee();
3368
3510
*/
3369
3511
 
3370
3512
static int
3371
 
com_pager(string *buffer __attribute__((unused)),
3372
 
          const char *line __attribute__((unused)))
 
3513
com_pager(string *, const char *line)
3373
3514
{
3374
 
  char pager_name[FN_REFLEN], *end, *param;
 
3515
  char pager_name[FN_REFLEN], *end;
 
3516
  const char *param;
3375
3517
 
3376
3518
  if (status.batch)
3377
3519
    return 0;
3389
3531
    {
3390
3532
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3391
3533
      opt_nopager=1;
3392
 
      stpcpy(pager, "stdout");
 
3534
      strcpy(pager, "stdout");
3393
3535
      PAGER= stdout;
3394
3536
      return 0;
3395
3537
    }
3396
 
    stpcpy(pager, default_pager);
 
3538
    strcpy(pager, default_pager);
3397
3539
  }
3398
3540
  else
3399
3541
  {
3400
 
    end= strmake(pager_name, param, sizeof(pager_name)-1);
 
3542
    end= strncpy(pager_name, param, sizeof(pager_name)-1);
 
3543
    end+= strlen(pager_name);
3401
3544
    while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
3402
3545
                                my_iscntrl(charset_info,end[-1])))
3403
3546
      end--;
3404
3547
    end[0]=0;
3405
 
    stpcpy(pager, pager_name);
3406
 
    stpcpy(default_pager, pager_name);
 
3548
    strcpy(pager, pager_name);
 
3549
    strcpy(default_pager, pager_name);
3407
3550
  }
3408
3551
  opt_nopager=0;
3409
3552
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3412
3555
 
3413
3556
 
3414
3557
static int
3415
 
com_nopager(string *buffer __attribute__((unused)),
3416
 
            const char *line __attribute__((unused)))
 
3558
com_nopager(string *, const char *)
3417
3559
{
3418
 
  stpcpy(pager, "stdout");
 
3560
  strcpy(pager, "stdout");
3419
3561
  opt_nopager=1;
3420
3562
  PAGER= stdout;
3421
3563
  tee_fprintf(stdout, "PAGER set to stdout\n");
3425
3567
/* If arg is given, exit without errors. This happens on command 'quit' */
3426
3568
 
3427
3569
static int
3428
 
com_quit(string *buffer __attribute__((unused)),
3429
 
         const char *line __attribute__((unused)))
 
3570
com_quit(string *, const char *)
3430
3571
{
3431
3572
  /* let the screen auto close on a normal shutdown */
3432
3573
  status.exit_status=0;
3434
3575
}
3435
3576
 
3436
3577
static int
3437
 
com_rehash(string *buffer __attribute__((unused)),
3438
 
           const char *line __attribute__((unused)))
 
3578
com_rehash(string *, const char *)
3439
3579
{
3440
3580
  build_completion_hash(1, 0);
3441
3581
  return 0;
3444
3584
 
3445
3585
 
3446
3586
static int
3447
 
com_print(string *buffer,const char *line __attribute__((unused)))
 
3587
com_print(string *buffer,const char *)
3448
3588
{
3449
3589
  tee_puts("--------------", stdout);
3450
3590
  (void) tee_fputs(buffer->c_str(), stdout);
3471
3611
      Two null bytes are needed in the end of buff to allow
3472
3612
      get_arg to find end of string the second time it's called.
3473
3613
    */
3474
 
    tmp= strmake(buff, line, sizeof(buff)-2);
 
3614
    tmp= strncpy(buff, line, sizeof(buff)-2);
3475
3615
#ifdef EXTRA_DEBUG
3476
3616
    tmp[1]= 0;
3477
3617
#endif
3478
3618
    tmp= get_arg(buff, 0);
3479
3619
    if (tmp && *tmp)
3480
3620
    {
3481
 
      my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
 
3621
      free(current_db);
3482
3622
      current_db= strdup(tmp);
3483
3623
      tmp= get_arg(buff, 1);
3484
3624
      if (tmp)
3485
3625
      {
3486
 
        my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
 
3626
        free(current_host);
3487
3627
        current_host=strdup(tmp);
3488
3628
      }
3489
3629
    }
3503
3643
 
3504
3644
  if (connected)
3505
3645
  {
3506
 
    sprintf(buff,"Connection id:    %u",drizzle_thread_id(&drizzle));
 
3646
    sprintf(buff,"Connection id:    %u",drizzle_con_thread_id(&con));
3507
3647
    put_info(buff,INFO_INFO,0,0);
3508
3648
    sprintf(buff,"Current database: %.128s\n",
3509
3649
            current_db ? current_db : "*** NONE ***");
3513
3653
}
3514
3654
 
3515
3655
 
3516
 
static int com_source(string *buffer __attribute__((unused)), const char *line)
 
3656
static int com_source(string *, const char *line)
3517
3657
{
3518
 
  char source_name[FN_REFLEN], *end, *param;
 
3658
  char source_name[FN_REFLEN], *end;
 
3659
  const char *param;
3519
3660
  LINE_BUFFER *line_buff;
3520
3661
  int error;
3521
3662
  STATUS old_status;
3529
3670
                    INFO_ERROR, 0,0);
3530
3671
  while (my_isspace(charset_info,*param))
3531
3672
    param++;
3532
 
  end=strmake(source_name,param,sizeof(source_name)-1);
 
3673
  end= strncpy(source_name,param,sizeof(source_name)-1);
 
3674
  end+= strlen(source_name);
3533
3675
  while (end > source_name && (my_isspace(charset_info,end[-1]) ||
3534
3676
                               my_iscntrl(charset_info,end[-1])))
3535
3677
    end--;
3536
3678
  end[0]=0;
3537
3679
  unpack_filename(source_name,source_name);
3538
3680
  /* open file name */
3539
 
  if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0))))
 
3681
  if (!(sql_file = fopen(source_name, "r")))
3540
3682
  {
3541
3683
    char buff[FN_REFLEN+60];
3542
3684
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3543
3685
    return put_info(buff, INFO_ERROR, 0 ,0);
3544
3686
  }
3545
3687
 
3546
 
  if (!(line_buff=batch_readline_init(opt_max_allowed_packet+512,sql_file)))
 
3688
  if (!(line_buff=batch_readline_init(opt_max_input_line+512,sql_file)))
3547
3689
  {
3548
 
    my_fclose(sql_file,MYF(0));
 
3690
    fclose(sql_file);
3549
3691
    return put_info("Can't initialize batch_readline", INFO_ERROR, 0 ,0);
3550
3692
  }
3551
3693
 
3563
3705
  error= read_and_execute(false);
3564
3706
  // Continue as before
3565
3707
  status=old_status;
3566
 
  my_fclose(sql_file,MYF(0));
 
3708
  fclose(sql_file);
3567
3709
  batch_readline_end(line_buff);
3568
3710
  return error;
3569
3711
}
3571
3713
 
3572
3714
/* ARGSUSED */
3573
3715
static int
3574
 
com_delimiter(string *buffer __attribute__((unused)), const char *line)
 
3716
com_delimiter(string *, const char *line)
3575
3717
{
3576
3718
  char buff[256], *tmp;
3577
3719
 
3578
 
  strmake(buff, line, sizeof(buff) - 1);
 
3720
  strncpy(buff, line, sizeof(buff) - 1);
3579
3721
  tmp= get_arg(buff, 0);
3580
3722
 
3581
3723
  if (!tmp || !*tmp)
3593
3735
      return 0;
3594
3736
    }
3595
3737
  }
3596
 
  strmake(delimiter, tmp, sizeof(delimiter) - 1);
 
3738
  strncpy(delimiter, tmp, sizeof(delimiter) - 1);
3597
3739
  delimiter_length= (int)strlen(delimiter);
3598
3740
  delimiter_str= delimiter;
3599
3741
  return 0;
3601
3743
 
3602
3744
/* ARGSUSED */
3603
3745
static int
3604
 
com_use(string *buffer __attribute__((unused)), const char *line)
 
3746
com_use(string *, const char *line)
3605
3747
{
3606
3748
  char *tmp, buff[FN_REFLEN + 1];
3607
3749
  int select_db;
 
3750
  drizzle_result_st result;
 
3751
  drizzle_return_t ret;
3608
3752
 
3609
3753
  memset(buff, 0, sizeof(buff));
3610
 
  strmake(buff, line, sizeof(buff) - 1);
 
3754
  strncpy(buff, line, sizeof(buff) - 1);
3611
3755
  tmp= get_arg(buff, 0);
3612
3756
  if (!tmp || !*tmp)
3613
3757
  {
3621
3765
  */
3622
3766
  get_current_db();
3623
3767
 
3624
 
  if (!current_db || cmp_database(charset_info, current_db,tmp))
 
3768
  if (!current_db || strcmp(current_db,tmp))
3625
3769
  {
3626
3770
    if (one_database)
3627
3771
    {
3628
3772
      skip_updates= 1;
3629
 
      select_db= 0;    // don't do drizzle_select_db()
 
3773
      select_db= 0;    // don't do drizzleclient_select_db()
3630
3774
    }
3631
3775
    else
3632
 
      select_db= 2;    // do drizzle_select_db() and build_completion_hash()
 
3776
      select_db= 2;    // do drizzleclient_select_db() and build_completion_hash()
3633
3777
  }
3634
3778
  else
3635
3779
  {
3636
3780
    /*
3637
3781
      USE to the current db specified.
3638
 
      We do need to send drizzle_select_db() to make server
 
3782
      We do need to send drizzleclient_select_db() to make server
3639
3783
      update database level privileges, which might
3640
3784
      change since last USE (see bug#10979).
3641
3785
      For performance purposes, we'll skip rebuilding of completion hash.
3642
3786
    */
3643
3787
    skip_updates= 0;
3644
 
    select_db= 1;      // do only drizzle_select_db(), without completion
 
3788
    select_db= 1;      // do only drizzleclient_select_db(), without completion
3645
3789
  }
3646
3790
 
3647
3791
  if (select_db)
3652
3796
    */
3653
3797
    if (!connected && reconnect())
3654
3798
      return opt_reconnect ? -1 : 1;                        // Fatal error
3655
 
    if (drizzle_select_db(&drizzle,tmp))
 
3799
    for (bool try_again= true; try_again; try_again= false)
3656
3800
    {
3657
 
      if (drizzle_errno(&drizzle) != CR_SERVER_GONE_ERROR)
3658
 
        return put_error(&drizzle);
3659
 
 
3660
 
      if (reconnect())
3661
 
        return opt_reconnect ? -1 : 1;                      // Fatal error
3662
 
      if (drizzle_select_db(&drizzle,tmp))
3663
 
        return put_error(&drizzle);
 
3801
      if (drizzle_select_db(&con,&result,tmp,&ret) == NULL ||
 
3802
          ret != DRIZZLE_RETURN_OK)
 
3803
      {
 
3804
        if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
3805
        {
 
3806
          int error= put_error(&con, &result);
 
3807
          drizzle_result_free(&result);
 
3808
          return error;
 
3809
        }
 
3810
 
 
3811
        if (ret != DRIZZLE_RETURN_SERVER_GONE || !try_again)
 
3812
          return put_error(&con, NULL);
 
3813
 
 
3814
        if (reconnect())
 
3815
          return opt_reconnect ? -1 : 1;                      // Fatal error
 
3816
      }
 
3817
      else
 
3818
        drizzle_result_free(&result);
3664
3819
    }
3665
 
    my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
 
3820
    free(current_db);
3666
3821
    current_db= strdup(tmp);
3667
3822
    if (select_db > 1)
3668
3823
      build_completion_hash(opt_rehash, 1);
3673
3828
}
3674
3829
 
3675
3830
static int
3676
 
com_warnings(string *buffer __attribute__((unused)),
3677
 
             const char *line __attribute__((unused)))
 
3831
com_warnings(string *, const char *)
3678
3832
{
3679
3833
  show_warnings = 1;
3680
3834
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
3682
3836
}
3683
3837
 
3684
3838
static int
3685
 
com_nowarnings(string *buffer __attribute__((unused)),
3686
 
               const char *line __attribute__((unused)))
 
3839
com_nowarnings(string *, const char *)
3687
3840
{
3688
3841
  show_warnings = 0;
3689
3842
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
3725
3878
        ptr++;
3726
3879
  }
3727
3880
  if (!*ptr)
3728
 
    return NullS;
 
3881
    return NULL;
3729
3882
  while (my_isspace(charset_info, *ptr))
3730
3883
    ptr++;
3731
3884
  if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
3739
3892
    if (*ptr == '\\' && ptr[1]) // escaped character
3740
3893
    {
3741
3894
      // Remove the backslash
3742
 
      stpcpy(ptr, ptr+1);
 
3895
      strcpy(ptr, ptr+1);
3743
3896
    }
3744
3897
    else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
3745
3898
    {
3748
3901
    }
3749
3902
  }
3750
3903
  valid_arg= ptr != start;
3751
 
  return valid_arg ? start : NullS;
 
3904
  return valid_arg ? start : NULL;
3752
3905
}
3753
3906
 
3754
3907
 
3755
3908
static int
3756
3909
sql_connect(char *host,char *database,char *user,char *password,
3757
 
                 uint silent)
 
3910
                 uint32_t silent)
3758
3911
{
 
3912
  drizzle_return_t ret;
 
3913
 
3759
3914
  if (connected)
3760
3915
  {
3761
3916
    connected= 0;
3762
 
    drizzle_close(&drizzle);
 
3917
    drizzle_con_free(&con);
 
3918
    drizzle_free(&drizzle);
3763
3919
  }
3764
3920
  drizzle_create(&drizzle);
 
3921
  if (drizzle_con_add_tcp(&drizzle, &con, host, opt_drizzle_port, user,
 
3922
                          password, database, DRIZZLE_CON_NONE) == NULL)
 
3923
  {
 
3924
    (void) put_error(&con, NULL);
 
3925
    (void) fflush(stdout);
 
3926
    return 1;
 
3927
  }
 
3928
 
 
3929
/* XXX add this back in
3765
3930
  if (opt_connect_timeout)
3766
3931
  {
3767
 
    uint timeout=opt_connect_timeout;
3768
 
    drizzle_options(&drizzle,DRIZZLE_OPT_CONNECT_TIMEOUT,
 
3932
    uint32_t timeout=opt_connect_timeout;
 
3933
    drizzleclient_options(&drizzle,DRIZZLE_OPT_CONNECT_TIMEOUT,
3769
3934
                  (char*) &timeout);
3770
3935
  }
3771
 
  if (opt_compress)
3772
 
    drizzle_options(&drizzle,DRIZZLE_OPT_COMPRESS,NullS);
3773
 
  if (opt_secure_auth)
3774
 
    drizzle_options(&drizzle, DRIZZLE_SECURE_AUTH, (char *) &opt_secure_auth);
3775
 
  if (using_opt_local_infile)
3776
 
    drizzle_options(&drizzle,DRIZZLE_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
3777
 
  drizzle_options(&drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
 
3936
*/
 
3937
 
 
3938
/* XXX Do we need this?
3778
3939
  if (safe_updates)
3779
3940
  {
3780
3941
    char init_command[100];
3781
3942
    sprintf(init_command,
3782
3943
            "SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%"PRIu32
3783
 
            ",SQL_MAX_JOIN_SIZE=%"PRIu32,
 
3944
            ",MAX_JOIN_SIZE=%"PRIu32,
3784
3945
            select_limit, max_join_size);
3785
 
    drizzle_options(&drizzle, DRIZZLE_INIT_COMMAND, init_command);
 
3946
    drizzleclient_options(&drizzle, DRIZZLE_INIT_COMMAND, init_command);
3786
3947
  }
3787
 
  if (default_charset_used)
3788
 
    drizzle_options(&drizzle, DRIZZLE_SET_CHARSET_NAME, default_charset);
3789
 
  if (!drizzle_connect(&drizzle, host, user, password,
3790
 
                          database, opt_drizzle_port, opt_drizzle_unix_port,
3791
 
                          connect_flag | CLIENT_MULTI_STATEMENTS))
 
3948
*/
 
3949
  if ((ret= drizzle_con_connect(&con)) != DRIZZLE_RETURN_OK)
3792
3950
  {
3793
 
    if (!silent ||
3794
 
        (drizzle_errno(&drizzle) != CR_CONN_HOST_ERROR &&
3795
 
         drizzle_errno(&drizzle) != CR_CONNECTION_ERROR))
 
3951
    if (!silent || (ret != DRIZZLE_RETURN_GETADDRINFO &&
 
3952
                    ret != DRIZZLE_RETURN_COULD_NOT_CONNECT))
3796
3953
    {
3797
 
      (void) put_error(&drizzle);
 
3954
      (void) put_error(&con, NULL);
3798
3955
      (void) fflush(stdout);
3799
3956
      return ignore_errors ? -1 : 1;    // Abort
3800
3957
    }
3801
3958
    return -1;          // Retryable
3802
3959
  }
3803
3960
  connected=1;
 
3961
/* XXX hmm?
3804
3962
  drizzle.reconnect= debug_info_flag; // We want to know if this happens
 
3963
*/
3805
3964
  build_completion_hash(opt_rehash, 1);
3806
3965
  return 0;
3807
3966
}
3808
3967
 
3809
3968
 
3810
3969
static int
3811
 
com_status(string *buffer __attribute__((unused)),
3812
 
           const char *line __attribute__((unused)))
 
3970
com_status(string *, const char *)
3813
3971
{
 
3972
/*
3814
3973
  char buff[40];
3815
3974
  uint64_t id;
3816
 
  DRIZZLE_RES *result;
 
3975
*/
 
3976
  drizzle_result_st result;
 
3977
  drizzle_return_t ret;
3817
3978
 
3818
3979
  tee_puts("--------------", stdout);
3819
3980
  usage(1);          /* Print version */
3820
3981
  if (connected)
3821
3982
  {
3822
 
    tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_thread_id(&drizzle));
 
3983
    tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_con_thread_id(&con));
3823
3984
    /*
3824
3985
      Don't remove "limit 1",
3825
3986
      it is protection againts SQL_SELECT_LIMIT=0
3826
3987
    */
3827
 
    if (!drizzle_query(&drizzle,"select DATABASE(), USER() limit 1") &&
3828
 
        (result=drizzle_use_result(&drizzle)))
 
3988
    if (drizzle_query_str(&con,&result,"select DATABASE(), USER() limit 1",
 
3989
                          &ret) != NULL && ret == DRIZZLE_RETURN_OK &&
 
3990
        drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
3829
3991
    {
3830
 
      DRIZZLE_ROW cur=drizzle_fetch_row(result);
 
3992
      drizzle_row_t cur=drizzle_row_next(&result);
3831
3993
      if (cur)
3832
3994
      {
3833
3995
        tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
3834
3996
        tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
3835
3997
      }
3836
 
      drizzle_free_result(result);
 
3998
      drizzle_result_free(&result);
3837
3999
    }
 
4000
    else if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
4001
      drizzle_result_free(&result);
3838
4002
    tee_puts("SSL:\t\t\tNot in use", stdout);
3839
4003
  }
3840
4004
  else
3853
4017
  tee_fprintf(stdout, "Current pager:\t\t%s\n", pager);
3854
4018
  tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
3855
4019
  tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
3856
 
  tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&drizzle));
3857
 
  tee_fprintf(stdout, "Protocol version:\t%d\n", drizzle_get_proto_info(&drizzle));
3858
 
  tee_fprintf(stdout, "Connection:\t\t%s\n", drizzle_get_host_info(&drizzle));
3859
 
  if ((id= drizzle_insert_id(&drizzle)))
 
4020
  tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&con));
 
4021
  tee_fprintf(stdout, "Protocol version:\t%d\n", drizzle_con_protocol_version(&con));
 
4022
  tee_fprintf(stdout, "Connection:\t\t%s\n", drizzle_con_host(&con));
 
4023
/* XXX need to save this from result
 
4024
  if ((id= drizzleclient_insert_id(&drizzle)))
3860
4025
    tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff));
3861
 
 
3862
 
  /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
3863
 
  if (!drizzle_query(&drizzle,"select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1") &&
3864
 
      (result=drizzle_use_result(&drizzle)))
3865
 
  {
3866
 
    DRIZZLE_ROW cur=drizzle_fetch_row(result);
3867
 
    if (cur)
3868
 
    {
3869
 
      tee_fprintf(stdout, "Server characterset:\t%s\n", cur[2] ? cur[2] : "");
3870
 
      tee_fprintf(stdout, "Db     characterset:\t%s\n", cur[3] ? cur[3] : "");
3871
 
      tee_fprintf(stdout, "Client characterset:\t%s\n", cur[0] ? cur[0] : "");
3872
 
      tee_fprintf(stdout, "Conn.  characterset:\t%s\n", cur[1] ? cur[1] : "");
3873
 
    }
3874
 
    drizzle_free_result(result);
3875
 
  }
3876
 
  else
3877
 
  {
3878
 
    /* Probably pre-4.1 server */
3879
 
    tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->csname);
3880
 
    tee_fprintf(stdout, "Server characterset:\t%s\n", drizzle.charset->csname);
3881
 
  }
3882
 
 
3883
 
  if (strstr(drizzle_get_host_info(&drizzle),"TCP/IP") || ! drizzle.unix_socket)
3884
 
    tee_fprintf(stdout, "TCP port:\t\t%d\n", drizzle.port);
3885
 
  else
3886
 
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", drizzle.unix_socket);
3887
 
  if (drizzle.net.compress)
3888
 
    tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
 
4026
*/
 
4027
 
 
4028
  if (strcmp(drizzle_con_uds(&con), ""))
 
4029
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", drizzle_con_uds(&con));
 
4030
  else
 
4031
    tee_fprintf(stdout, "TCP port:\t\t%d\n", drizzle_con_port(&con));
3889
4032
 
3890
4033
  if (safe_updates)
3891
4034
  {
3904
4047
}
3905
4048
 
3906
4049
static const char *
3907
 
server_version_string(DRIZZLE *con)
 
4050
server_version_string(drizzle_con_st *local_con)
3908
4051
{
3909
 
  static char buf[MAX_SERVER_VERSION_LENGTH] = "";
 
4052
  static string buf("");
 
4053
  static bool server_version_string_reserved= false;
3910
4054
 
 
4055
  if (!server_version_string_reserved)
 
4056
  {
 
4057
    buf.reserve(MAX_SERVER_VERSION_LENGTH);
 
4058
    server_version_string_reserved= true;
 
4059
  }
3911
4060
  /* Only one thread calls this, so no synchronization is needed */
3912
4061
  if (buf[0] == '\0')
3913
4062
  {
3914
 
    char *bufp = buf;
3915
 
    DRIZZLE_RES *result;
 
4063
    drizzle_result_st result;
 
4064
    drizzle_return_t ret;
3916
4065
 
3917
 
    bufp= stpncpy(buf, drizzle_get_server_info(con), sizeof buf);
 
4066
    buf.append(drizzle_con_server_version(local_con));
3918
4067
 
3919
4068
    /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
3920
 
    if (!drizzle_query(con, "select @@version_comment limit 1") &&
3921
 
        (result = drizzle_use_result(con)))
 
4069
    (void)drizzle_query_str(local_con, &result,
 
4070
                            "select @@version_comment limit 1", &ret);
 
4071
    if (ret == DRIZZLE_RETURN_OK &&
 
4072
        drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
3922
4073
    {
3923
 
      DRIZZLE_ROW cur = drizzle_fetch_row(result);
 
4074
      drizzle_row_t cur = drizzle_row_next(&result);
3924
4075
      if (cur && cur[0])
3925
4076
      {
3926
 
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NullS);
 
4077
        buf.append(" ");
 
4078
        buf.append(cur[0]);
3927
4079
      }
3928
 
      drizzle_free_result(result);
 
4080
      drizzle_result_free(&result);
3929
4081
    }
3930
 
 
3931
 
    /* str*nmov doesn't guarantee NUL-termination */
3932
 
    if (bufp == buf + sizeof buf)
3933
 
      buf[sizeof buf - 1] = '\0';
 
4082
    else if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
4083
      drizzle_result_free(&result);
3934
4084
  }
3935
4085
 
3936
 
  return buf;
 
4086
  return buf.c_str();
3937
4087
}
3938
4088
 
3939
4089
static int
3940
 
put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
 
4090
put_info(const char *str,INFO_TYPE info_type, uint32_t error, const char *sqlstate)
3941
4091
{
3942
4092
  FILE *file= (info_type == INFO_ERROR ? stderr : stdout);
3943
4093
  static int inited=0;
4009
4159
 
4010
4160
 
4011
4161
static int
4012
 
put_error(DRIZZLE *con)
 
4162
put_error(drizzle_con_st *local_con, drizzle_result_st *res)
4013
4163
{
4014
 
  return put_info(drizzle_error(con), INFO_ERROR, drizzle_errno(con),
4015
 
                  drizzle_sqlstate(con));
 
4164
  const char *error;
 
4165
 
 
4166
  if (res != NULL)
 
4167
  {
 
4168
    error= drizzle_result_error(res);
 
4169
    if (!strcmp(error, ""))
 
4170
      error= drizzle_con_error(local_con);
 
4171
  }
 
4172
  else
 
4173
    error= drizzle_con_error(local_con);
 
4174
 
 
4175
  return put_info(error, INFO_ERROR,
 
4176
                  res == NULL ? drizzle_con_error_code(local_con) :
 
4177
                                drizzle_result_error_code(res),
 
4178
                  res == NULL ? drizzle_con_sqlstate(local_con) :
 
4179
                                drizzle_result_sqlstate(res));
4016
4180
}
4017
4181
 
4018
4182
 
4022
4186
  const char *end= start + (buffer->length());
4023
4187
  while (start < end && !my_isgraph(charset_info,end[-1]))
4024
4188
    end--;
4025
 
  uint pos_to_truncate= (end-start);
 
4189
  uint32_t pos_to_truncate= (end-start);
4026
4190
  if (buffer->length() > pos_to_truncate)
4027
4191
    buffer->erase(pos_to_truncate);
4028
4192
}
4093
4257
static void nice_time(double sec,char *buff,bool part_second)
4094
4258
{
4095
4259
  uint32_t tmp;
 
4260
  ostringstream tmp_buff_str;
 
4261
 
4096
4262
  if (sec >= 3600.0*24)
4097
4263
  {
4098
4264
    tmp=(uint32_t) floor(sec/(3600.0*24));
4099
 
    sec-=3600.0*24*tmp;
4100
 
    buff=int10_to_str((long) tmp, buff, 10);
4101
 
    buff=stpcpy(buff,tmp > 1 ? " days " : " day ");
 
4265
    sec-= 3600.0*24*tmp;
 
4266
    tmp_buff_str << tmp;
 
4267
 
 
4268
    if (tmp > 1)
 
4269
      tmp_buff_str << " days ";
 
4270
    else
 
4271
      tmp_buff_str << " day ";
 
4272
 
4102
4273
  }
4103
4274
  if (sec >= 3600.0)
4104
4275
  {
4105
4276
    tmp=(uint32_t) floor(sec/3600.0);
4106
4277
    sec-=3600.0*tmp;
4107
 
    buff=int10_to_str((long) tmp, buff, 10);
4108
 
    buff=stpcpy(buff,tmp > 1 ? " hours " : " hour ");
 
4278
    tmp_buff_str << tmp;
 
4279
 
 
4280
    if (tmp > 1)
 
4281
      tmp_buff_str << " hours ";
 
4282
    else
 
4283
      tmp_buff_str << " hour ";
4109
4284
  }
4110
4285
  if (sec >= 60.0)
4111
4286
  {
4112
4287
    tmp=(uint32_t) floor(sec/60.0);
4113
4288
    sec-=60.0*tmp;
4114
 
    buff=int10_to_str((long) tmp, buff, 10);
4115
 
    buff=stpcpy(buff," min ");
 
4289
    tmp_buff_str << tmp << " min ";
4116
4290
  }
4117
4291
  if (part_second)
4118
 
    sprintf(buff,"%.2f sec",sec);
 
4292
    tmp_buff_str.precision(2);
4119
4293
  else
4120
 
    sprintf(buff,"%d sec",(int) sec);
 
4294
    tmp_buff_str.precision(0);
 
4295
  tmp_buff_str << sec << " sec";
 
4296
  strcpy(buff, tmp_buff_str.str().c_str());
4121
4297
}
4122
4298
 
4123
4299
 
4133
4309
  buff[0]=' ';
4134
4310
  buff[1]='(';
4135
4311
  end_timer(start_time,buff+2);
4136
 
  stpcpy(strend(buff),")");
 
4312
  strcpy(strchr(buff, '\0'),")");
4137
4313
}
4138
4314
 
4139
4315
static const char * construct_prompt()
4157
4333
    {
4158
4334
      int getHour;
4159
4335
      int getYear;
4160
 
      char* dateTime= NULL;
 
4336
      /* Room for Dow MMM DD HH:MM:SS YYYY */ 
 
4337
      char dateTime[32];
4161
4338
      switch (*++c) {
4162
4339
      case '\0':
4163
4340
        // stop it from going beyond if ends with %
4168
4345
        break;
4169
4346
      case 'v':
4170
4347
        if (connected)
4171
 
          processed_prompt->append(drizzle_get_server_info(&drizzle));
 
4348
          processed_prompt->append(drizzle_con_server_version(&con));
4172
4349
        else
4173
4350
          processed_prompt->append("not_connected");
4174
4351
        break;
4178
4355
      case 'h':
4179
4356
      {
4180
4357
        const char *prompt;
4181
 
        prompt= connected ? drizzle_get_host_info(&drizzle) : "not_connected";
 
4358
        prompt= connected ? drizzle_con_host(&con) : "not_connected";
4182
4359
        if (strstr(prompt, "Localhost"))
4183
4360
          processed_prompt->append("localhost");
4184
4361
        else
4197
4374
          break;
4198
4375
        }
4199
4376
 
4200
 
        const char *host_info = drizzle_get_host_info(&drizzle);
4201
 
        if (strstr(host_info, "memory"))
 
4377
        if (strcmp(drizzle_con_uds(&con), ""))
4202
4378
        {
4203
 
          processed_prompt->append(drizzle.host);
 
4379
          const char *pos=strrchr(drizzle_con_uds(&con),'/');
 
4380
          processed_prompt->append(pos ? pos+1 : drizzle_con_uds(&con));
4204
4381
        }
4205
 
        else if (strstr(host_info,"TCP/IP") ||
4206
 
                 !drizzle.unix_socket)
4207
 
          add_int_to_prompt(drizzle.port);
4208
4382
        else
4209
 
        {
4210
 
          char *pos=strrchr(drizzle.unix_socket,'/');
4211
 
          processed_prompt->append(pos ? pos+1 : drizzle.unix_socket);
4212
 
        }
 
4383
          add_int_to_prompt(drizzle_con_port(&con));
4213
4384
      }
4214
4385
      break;
4215
4386
      case 'U':
4226
4397
        break;
4227
4398
      case PROMPT_CHAR:
4228
4399
        {
4229
 
          char c= PROMPT_CHAR;
4230
 
          processed_prompt->append(&c, 1);
 
4400
          processed_prompt->append(PROMPT_CHAR, 1);
4231
4401
        }
4232
4402
        break;
4233
4403
      case 'n':
4234
4404
        {
4235
 
          char c= '\n';
4236
 
          processed_prompt->append(&c, 1);
 
4405
          processed_prompt->append('\n', 1);
4237
4406
        }
4238
4407
        break;
4239
4408
      case ' ':
4240
4409
      case '_':
4241
4410
        {
4242
 
          char c= ' ';
4243
 
          processed_prompt->append(&c, 1);
 
4411
          processed_prompt->append(' ', 1);
4244
4412
        }
4245
4413
        break;
4246
4414
      case 'R':
4271
4439
        add_int_to_prompt(t->tm_year+1900);
4272
4440
        break;
4273
4441
      case 'D':
4274
 
        dateTime = ctime(&lclock);
4275
 
        processed_prompt->append(strtok(dateTime,"\n"));
 
4442
        strftime(dateTime, 32, "%a %b %d %H:%M:%S %Y", localtime(&lclock));
 
4443
        processed_prompt->append(dateTime);
4276
4444
        break;
4277
4445
      case 's':
4278
4446
        if (t->tm_sec < 10)
4317
4485
 
4318
4486
static void add_int_to_prompt(int toadd)
4319
4487
{
4320
 
  char buffer[16];
4321
 
  int10_to_str(toadd, buffer, 10);
4322
 
  processed_prompt->append(buffer);
 
4488
  ostringstream buffer;
 
4489
  buffer << toadd;
 
4490
  processed_prompt->append(buffer.str().c_str());
4323
4491
}
4324
4492
 
4325
4493
static void init_username()
4326
4494
{
4327
 
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
4328
 
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
 
4495
/* XXX need this?
 
4496
  free(full_username);
 
4497
  free(part_username);
4329
4498
 
4330
 
  DRIZZLE_RES *result;
4331
 
  if (!drizzle_query(&drizzle,"select USER()") &&
4332
 
      (result=drizzle_use_result(&drizzle)))
 
4499
  drizzle_result_st *result;
 
4500
  if (!drizzleclient_query(&drizzle,"select USER()") &&
 
4501
      (result=drizzleclient_use_result(&drizzle)))
4333
4502
  {
4334
 
    DRIZZLE_ROW cur=drizzle_fetch_row(result);
 
4503
    drizzle_row_t cur=drizzleclient_fetch_row(result);
4335
4504
    full_username= strdup(cur[0]);
4336
4505
    part_username= strdup(strtok(cur[0],"@"));
4337
 
    (void) drizzle_fetch_row(result);        // Read eof
 
4506
    (void) drizzleclient_fetch_row(result);        // Read eof
4338
4507
  }
 
4508
*/
4339
4509
}
4340
4510
 
4341
 
static int com_prompt(string *buffer __attribute__((unused)),
4342
 
                      const char *line)
 
4511
static int com_prompt(string *, const char *line)
4343
4512
{
4344
 
  char *ptr=strchr(line, ' ');
4345
 
  prompt_counter = 0;
4346
 
  my_free(current_prompt, MYF(MY_ALLOW_ZERO_PTR));
4347
 
  current_prompt= strdup(ptr ? ptr+1 : default_prompt);
4348
 
  if (!ptr)
 
4513
  const char *ptr=strchr(line, ' ');
 
4514
  if (ptr == NULL)
4349
4515
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4350
4516
                default_prompt);
 
4517
  prompt_counter = 0;
 
4518
  char * tmpptr= strdup(ptr ? ptr+1 : default_prompt);
 
4519
  if (tmpptr == NULL)
 
4520
    tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");
4351
4521
  else
 
4522
  {
 
4523
    free(current_prompt);
 
4524
    current_prompt= tmpptr;
4352
4525
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
 
4526
  }
4353
4527
  return 0;
4354
4528
}
4355
4529
 
4356
4530
/*
4357
4531
    strcont(str, set) if str contanies any character in the string set.
4358
 
    The result is the position of the first found character in str, or NullS
 
4532
    The result is the position of the first found character in str, or NULL
4359
4533
    if there isn't anything found.
4360
4534
*/
4361
4535