~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Monty Taylor
  • Date: 2009-06-08 13:39:05 UTC
  • mto: This revision was merged to the branch mainline in revision 1060.
  • Revision ID: mordred@inaugust.com-20090608133905-3hogrrafmfg6e5hs
Removed CHARSET_INFO stuff from protocol plugin interface - it makes no sense.

Show diffs side-by-side

added added

removed removed

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