~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

Show diffs side-by-side

added added

removed removed

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