153
162
*default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
154
163
static char *histfile;
155
164
static char *histfile_tmp;
156
static GString *glob_buffer;
157
static GString *processed_prompt= NULL;
158
static GString *default_prompt= NULL;
165
static DYNAMIC_STRING *glob_buffer;
166
static DYNAMIC_STRING *processed_prompt= NULL;
167
static char *default_prompt= NULL;
159
168
static char *full_username=0,*part_username=0;
160
169
static int wait_time = 5;
161
170
static STATUS status;
199
208
static int get_options(int argc,char **argv);
200
209
bool get_one_option(int optid, const struct my_option *opt,
202
static int com_quit(GString *str,char*),
203
com_go(GString *str,char*), com_ego(GString *str,char*),
204
com_print(GString *str,char*),
205
com_help(GString *str,char*), com_clear(GString *str,char*),
206
com_connect(GString *str,char*), com_status(GString *str,char*),
207
com_use(GString *str,char*), com_source(GString *str, char*),
208
com_rehash(GString *str, char*), com_tee(GString *str, char*),
209
com_notee(GString *str, char*), com_charset(GString *str,char*),
210
com_prompt(GString *str, char*), com_delimiter(GString *str, char*),
211
com_warnings(GString *str, char*), com_nowarnings(GString *str, char*),
212
com_nopager(GString *str, char*), com_pager(GString *str, char*);
211
static int com_quit(DYNAMIC_STRING *str,char*),
212
com_go(DYNAMIC_STRING *str,char*), com_ego(DYNAMIC_STRING *str,char*),
213
com_print(DYNAMIC_STRING *str,char*),
214
com_help(DYNAMIC_STRING *str,char*), com_clear(DYNAMIC_STRING *str,char*),
215
com_connect(DYNAMIC_STRING *str,char*), com_status(DYNAMIC_STRING *str,char*),
216
com_use(DYNAMIC_STRING *str,char*), com_source(DYNAMIC_STRING *str, char*),
217
com_rehash(DYNAMIC_STRING *str, char*), com_tee(DYNAMIC_STRING *str, char*),
218
com_notee(DYNAMIC_STRING *str, char*), com_charset(DYNAMIC_STRING *str,char*),
219
com_prompt(DYNAMIC_STRING *str, char*), com_delimiter(DYNAMIC_STRING *str, char*),
220
com_warnings(DYNAMIC_STRING *str, char*), com_nowarnings(DYNAMIC_STRING *str, char*),
221
com_nopager(DYNAMIC_STRING *str, char*), com_pager(DYNAMIC_STRING *str, char*);
214
223
static int read_and_execute(bool interactive);
215
224
static int sql_connect(char *host,char *database,char *user,char *password,
995
1004
int history_length;
996
1005
static int not_in_history(const char *line);
997
1006
static void initialize_readline (const char *name);
998
static void fix_history(GString *final_command);
1007
static void fix_history(DYNAMIC_STRING *final_command);
1000
1009
static COMMANDS *find_command(char *name,char cmd_name);
1001
static bool add_line(GString *buffer,char *line,char *in_string,
1010
static bool add_line(DYNAMIC_STRING *buffer,char *line,char *in_string,
1002
1011
bool *ml_comment);
1003
static void remove_cntrl(GString *buffer);
1012
static void remove_cntrl(DYNAMIC_STRING *buffer);
1004
1013
static void print_table_data(MYSQL_RES *result);
1005
1014
static void print_table_data_html(MYSQL_RES *result);
1006
1015
static void print_table_data_xml(MYSQL_RES *result);
1024
1033
MY_INIT(argv[0]);
1025
1034
delimiter_str= delimiter;
1026
default_prompt = g_string_new(g_strdup(getenv("DRIZZLE_PS1") ?
1027
getenv("DRIZZLE_PS1") :
1029
current_prompt = g_strdup(default_prompt->str);
1030
processed_prompt = g_string_sized_new(16);
1035
default_prompt= my_strdup(getenv("DRIZZLE_PS1") ?
1036
getenv("DRIZZLE_PS1") :
1037
"drizzle>> ", MYF(0));
1038
current_prompt= my_strdup(default_prompt, MYF(0));
1040
processed_prompt= (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
1041
init_dynamic_string(processed_prompt, "", 32, 32);
1031
1043
prompt_counter=0;
1033
1045
outfile[0]=0; // no (default) outfile
1115
1127
put_info("Welcome to the Drizzle client.. Commands end with ; or \\g.",
1116
1128
INFO_INFO,0,0);
1117
glob_buffer = g_string_sized_new(512);
1118
g_string_printf(glob_buffer,
1119
"Your Drizzle connection id is %u\nServer version: %s\n",
1120
mysql_thread_id(&mysql), server_version_string(&mysql));
1121
put_info(glob_buffer->str,INFO_INFO,0,0);
1122
g_string_truncate(glob_buffer,0);
1130
glob_buffer= (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
1131
init_dynamic_string(glob_buffer, "", 512, 512);
1133
/* this is a slight abuse of the DYNAMIC_STRING interface. deal. */
1134
sprintf(glob_buffer->str,
1135
"Your Drizzle connection id is %u\nServer version: %s\n",
1136
mysql_thread_id(&mysql), server_version_string(&mysql));
1137
put_info(glob_buffer->str, INFO_INFO, 0, 0);
1138
dynstr_set(glob_buffer, NULL);
1124
1140
initialize_readline(my_progname);
1125
1141
if (!status.batch && !quick && !opt_html && !opt_xml)
1127
1143
/* read-history from file, default ~/.mysql_history*/
1128
1144
if (getenv("MYSQL_HISTFILE"))
1129
histfile=g_strdup(getenv("MYSQL_HISTFILE"));
1145
histfile= strdup(getenv("MYSQL_HISTFILE"));
1130
1146
else if (getenv("HOME"))
1132
1148
histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1189
1205
put_info(sig ? "Aborted" : "Bye", INFO_RESULT,0,0);
1190
assert(glob_buffer != NULL);
1191
g_string_free(glob_buffer,true);
1192
assert(processed_prompt != NULL);
1193
g_string_free(processed_prompt,true);
1194
assert(default_prompt != NULL);
1195
g_string_free(default_prompt,true);
1207
dynstr_free(glob_buffer);
1208
my_free(glob_buffer, MYF(MY_ALLOW_ZERO_PTR));
1209
if (processed_prompt)
1210
dynstr_free(processed_prompt);
1211
my_free(processed_prompt,MYF(MY_ALLOW_ZERO_PTR));
1196
1212
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
1197
1213
my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
1198
1214
my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
1548
1564
case OPT_SERVER_ARG:
1549
#ifdef EMBEDDED_LIBRARY
1551
When the embedded server is being tested, the client needs to be
1552
able to pass command-line arguments to the embedded server so it can
1553
locate the language files and data directory.
1555
if (!embedded_server_arg_count)
1557
embedded_server_arg_count= 1;
1558
embedded_server_args[0]= (char*) "";
1560
if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
1561
!(embedded_server_args[embedded_server_arg_count++]=
1562
g_strdup(argument)))
1564
put_info("Can't use server argument", INFO_ERROR);
1567
#else /*EMBEDDED_LIBRARY */
1568
1565
printf("WARNING: --server-arg option not supported in this configuration.\n");
1760
1756
Check if line is a mysql command line
1761
1757
(We want to allow help, print and clear anywhere at line start
1763
if ((named_cmds || (glob_buffer->len==0))
1759
if ((named_cmds || (glob_buffer->length==0))
1764
1760
&& !ml_comment && !in_string && (com=find_command(line,0)))
1766
1762
if ((*com->func)(glob_buffer,line) > 0)
1768
1764
// If buffer was emptied
1769
if (glob_buffer->len==0)
1765
if (glob_buffer->length==0)
1771
1767
if (interactive && status.add_to_history && not_in_history(line))
1772
1768
add_history(line);
1953
1949
// Flush previously accepted characters
1954
1950
if (out != line)
1956
g_string_append_len(buffer, line, (gssize) (out - line));
1952
dynstr_append_mem(buffer, line, (out - line));
1960
1956
// Flush possible comments in the buffer
1961
if (buffer->len != 0)
1957
if (buffer->length != 0)
1963
1959
if (com_go(buffer, 0) > 0) // < 0 is not fatal
1965
1961
assert(buffer!=NULL);
1966
g_string_truncate(buffer,0);
1962
dynstr_set(buffer, NULL);
1970
1966
Delimiter wants the get rest of the given line as argument to
1971
1967
allow one to change ';' to ';;' and back
1973
g_string_append(buffer,pos);
1969
dynstr_append(buffer,pos);
1974
1970
if (com_delimiter(buffer, pos) > 0)
1977
g_string_truncate(buffer,0);
1973
dynstr_set(buffer, NULL);
1980
1976
else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
2113
2109
******************************************************************/
2112
static char **mysql_completion (const char *text, int start, int end);
2116
2113
static char *new_command_generator(const char *text, int);
2117
extern char **new_mysql_completion (const char *text, int start, int end);
2120
2117
Tell the GNU Readline library how to complete. We want to try to complete
2121
2118
on command names if this is the first word in the line, or on filenames
2125
#if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE)
2126
extern char *no_completion(const char*,int);
2128
char *no_completion(void);
2129
char *no_completion(void)
2121
static char *no_completion(const char * a __attribute__((unused)),
2122
int b __attribute__((unused)))
2131
2124
/* No filename completion */
2136
2129
/* glues pieces of history back together if in pieces */
2137
static void fix_history(GString *final_command)
2130
static void fix_history(DYNAMIC_STRING *final_command)
2139
2132
int total_lines = 1;
2140
2133
const char *ptr = final_command->str;
2134
char str_char = '\0'; /* Character if we are in a string or not */
2141
2136
/* Converted buffer */
2142
GString * fixed_buffer;
2143
fixed_buffer = g_string_sized_new(16);
2144
char str_char = '\0'; /* Character if we are in a string or not */
2137
DYNAMIC_STRING *fixed_buffer=
2138
(DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
2140
init_dynamic_string(fixed_buffer, "", 512, 512);
2146
2142
/* find out how many lines we have and remove newlines */
2147
2143
while (*ptr != '\0')
2156
2152
str_char = *ptr;
2157
2153
else if (str_char == *ptr) /* close string */
2158
2154
str_char = '\0';
2159
g_string_append_len(fixed_buffer, ptr, 1);
2155
dynstr_append_mem(fixed_buffer, ptr, 1);
2163
2159
not in string, change to space
2164
2160
if in string, leave it alone
2166
g_string_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2162
dynstr_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2170
g_string_append_c(fixed_buffer, '\\');
2166
dynstr_append(fixed_buffer, "\\");
2171
2167
/* need to see if the backslash is escaping anything */
2175
2171
/* special characters that need escaping */
2176
2172
if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2177
g_string_append_len(fixed_buffer, ptr, 1);
2173
dynstr_append_mem(fixed_buffer, ptr, 1);
2183
g_string_append_len(fixed_buffer, ptr, 1);
2179
dynstr_append_mem(fixed_buffer, ptr, 1);
2206
2202
static void initialize_readline (const char *name)
2208
2204
/* Allow conditional parsing of the ~/.inputrc file. */
2209
rl_readline_name= name;
2205
rl_readline_name= (char *)name;
2211
2207
/* Tell the completer that we want a crack first. */
2212
rl_attempted_completion_function= (rl_completion_func_t*)&new_mysql_completion;
2208
rl_attempted_completion_function= (rl_completion_func_t*)&mysql_completion;
2213
2209
rl_completion_entry_function= (rl_compentry_func_t*)&no_completion;
2217
2214
Attempt to complete on the contents of TEXT. START and END show the
2218
2215
region of TEXT that contains the word to complete. We can use the
2219
2216
entire line in case we want to do some simple parsing. Return the
2220
2217
array of matches, or NULL if there aren't any.
2223
char **new_mysql_completion (const char *text,
2224
int start __attribute__((unused)),
2225
int end __attribute__((unused)))
2219
char **mysql_completion (const char *text,
2220
int start __attribute__((unused)),
2221
int end __attribute__((unused)))
2227
2223
if (!status.batch && !quick)
2228
2224
return rl_completion_matches(text, new_command_generator);
2661
com_clear(GString *buffer,char *line __attribute__((unused)))
2658
com_clear(DYNAMIC_STRING *buffer,char *line __attribute__((unused)))
2663
2660
if (status.add_to_history)
2664
2661
fix_history(buffer);
2665
g_string_truncate(buffer, 0);
2662
dynstr_set(buffer, NULL);
2670
com_charset(GString *buffer __attribute__((unused)), char *line)
2667
com_charset(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
2672
2669
char buff[256], *param;
2673
2670
CHARSET_INFO * new_cs;
2724
2721
if (!connected && reconnect())
2726
2723
// Remove query on error
2727
g_string_truncate(buffer, 0);
2724
dynstr_set(buffer, NULL);
2728
2725
return opt_reconnect ? -1 : 1; // Fatal error
2731
2728
(void) com_print(buffer, 0);
2733
2730
if (skip_updates &&
2735
|| g_string_equal(g_string_new_len(buffer->str,4),
2736
g_string_new("SET "))))
2731
((buffer->length < 4) || !strncmp(buffer->str, "SET ", 4)))
2738
2733
(void) put_info("Ignoring query to other database",INFO_INFO,0,0);
2742
2737
timer=start_timer();
2743
2738
executing_query= 1;
2744
error= mysql_real_query_for_lazy(buffer->str,buffer->len);
2739
error= mysql_real_query_for_lazy(buffer->str,buffer->length);
2746
2741
if (status.add_to_history)
2748
g_string_append(buffer, vertical ? "\\G" : delimiter);
2743
dynstr_append(buffer, vertical ? "\\G" : delimiter);
2749
2744
/* Append final command onto history */
2750
2745
fix_history(buffer);
2753
g_string_truncate(buffer, 0);
2748
dynstr_set(buffer, NULL);
3041
3038
field->max_length=length;
3043
3040
for (x=0; x< (length+2); x++)
3044
g_string_append_c(separator, '-');
3045
g_string_append_c(separator, '+');
3041
dynstr_append(separator, "-");
3042
dynstr_append(separator, "+");
3047
// End marker for \0
3048
// TODO: Huh? Do we need this with GString?
3049
g_string_append_c(separator, '\0');
3051
3045
tee_puts((char*) separator->str, PAGER);
3052
3046
if (column_names)
3600
com_print(GString *buffer,char *line __attribute__((unused)))
3594
com_print(DYNAMIC_STRING *buffer,char *line __attribute__((unused)))
3602
3596
tee_puts("--------------", stdout);
3603
3597
(void) tee_fputs(buffer->str, stdout);
3604
if ( (buffer->len == 0)
3605
|| (buffer->str)[(buffer->len)-1] != '\n')
3598
if ( (buffer->length == 0)
3599
|| (buffer->str)[(buffer->length)-1] != '\n')
3606
3600
tee_putc('\n', stdout);
3607
3601
tee_puts("--------------\n", stdout);
3608
3602
/* If empty buffer */
4070
4064
tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->csname);
4073
#ifndef EMBEDDED_LIBRARY
4074
4067
if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket)
4075
4068
tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port);
4077
4070
tee_fprintf(stdout, "UNIX socket:\t\t%s\n", mysql.unix_socket);
4078
4071
if (mysql.net.compress)
4079
4072
tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
4082
4074
if ((status_str= mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
4227
static void remove_cntrl(GString *buffer)
4219
static void remove_cntrl(DYNAMIC_STRING *buffer)
4229
4221
char *start= buffer->str;
4230
char *end= start + (buffer->len);
4222
char *end= start + (buffer->length);
4231
4223
while (start < end && !my_isgraph(charset_info,end[-1]))
4233
4225
uint chars_to_truncate = end-start;
4234
if (buffer->len > chars_to_truncate)
4235
g_string_truncate(buffer, chars_to_truncate);
4226
if (buffer->length > chars_to_truncate)
4227
dynstr_trunc(buffer, chars_to_truncate);
4378
g_string_append(processed_prompt, mysql_get_server_info(&mysql));
4370
dynstr_append(processed_prompt, mysql_get_server_info(&mysql));
4380
g_string_append(processed_prompt, "not_connected");
4372
dynstr_append(processed_prompt, "not_connected");
4383
g_string_append(processed_prompt, current_db ? current_db : "(none)");
4375
dynstr_append(processed_prompt, current_db ? current_db : "(none)");
4387
4379
const char *prompt;
4388
4380
prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
4389
4381
if (strstr(prompt, "Localhost"))
4390
g_string_append(processed_prompt, "localhost");
4382
dynstr_append(processed_prompt, "localhost");
4393
4385
const char *end=strcend(prompt,' ');
4394
g_string_append_len(processed_prompt, prompt, (gssize) (end-prompt));
4386
dynstr_append_mem(processed_prompt, prompt, (end-prompt));
4400
4392
if (!connected)
4402
g_string_append(processed_prompt, "not_connected");
4394
dynstr_append(processed_prompt, "not_connected");
4406
4398
const char *host_info = mysql_get_host_info(&mysql);
4407
4399
if (strstr(host_info, "memory"))
4409
g_string_append(processed_prompt, mysql.host );
4401
dynstr_append(processed_prompt, mysql.host);
4411
4403
else if (strstr(host_info,"TCP/IP") ||
4412
4404
!mysql.unix_socket)
4416
4408
char *pos=strrchr(mysql.unix_socket,'/');
4417
g_string_append(processed_prompt, pos ? pos+1 : mysql.unix_socket);
4409
dynstr_append(processed_prompt, pos ? pos+1 : mysql.unix_socket);
4422
4414
if (!full_username)
4423
4415
init_username();
4424
g_string_append(processed_prompt, full_username ? full_username :
4416
dynstr_append(processed_prompt, full_username ? full_username :
4425
4417
(current_user ? current_user : "(unknown)"));
4428
4420
if (!full_username)
4429
4421
init_username();
4430
g_string_append(processed_prompt, part_username ? part_username :
4422
dynstr_append(processed_prompt, part_username ? part_username :
4431
4423
(current_user ? current_user : "(unknown)"));
4433
4425
case PROMPT_CHAR:
4434
g_string_append_c(processed_prompt, PROMPT_CHAR);
4427
char c= PROMPT_CHAR;
4428
dynstr_append_mem(processed_prompt, &c, 1);
4437
g_string_append_c(processed_prompt, '\n');
4434
dynstr_append_mem(processed_prompt, &c, 1);
4441
g_string_append_c(processed_prompt, ' ');
4441
dynstr_append_mem(processed_prompt, &c, 1);
4444
4445
if (t->tm_hour < 10)
4445
g_string_append_c(processed_prompt, '0');
4446
add_int_to_prompt(0);
4446
4447
add_int_to_prompt(t->tm_hour);
4471
4472
dateTime = ctime(&lclock);
4472
g_string_append(processed_prompt, strtok(dateTime,"\n"));
4473
dynstr_append(processed_prompt, strtok(dateTime,"\n"));
4475
4476
if (t->tm_sec < 10)
4476
g_string_append_c(processed_prompt, '0');
4477
add_int_to_prompt(0);
4477
4478
add_int_to_prompt(t->tm_sec);
4480
g_string_append(processed_prompt, (day_names[t->tm_wday]));
4481
dynstr_append(processed_prompt, (day_names[t->tm_wday]));
4483
g_string_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4484
dynstr_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4486
4487
add_int_to_prompt(t->tm_mon+1);
4489
g_string_append(processed_prompt, month_names[t->tm_mon]);
4490
dynstr_append(processed_prompt, month_names[t->tm_mon]);
4492
g_string_append(processed_prompt, "'");
4493
dynstr_append(processed_prompt, "'");
4495
g_string_append_c(processed_prompt, '"');
4496
dynstr_append(processed_prompt, "\"");
4498
g_string_append_c(processed_prompt, ';');
4499
dynstr_append(processed_prompt, ";");
4501
g_string_append_c(processed_prompt, '\t');
4502
dynstr_append(processed_prompt, "\t");
4504
g_string_append(processed_prompt, delimiter_str);
4505
dynstr_append(processed_prompt, delimiter_str);
4507
g_string_append(processed_prompt, c);
4508
dynstr_append_mem(processed_prompt, c, 1);
4511
// TODO: Is this needed with GString?
4512
g_string_append_c(processed_prompt, '\0');
4513
4512
return processed_prompt->str;
4531
4530
(result=mysql_use_result(&mysql)))
4533
4532
MYSQL_ROW cur=mysql_fetch_row(result);
4534
full_username=g_strdup(cur[0]);
4535
part_username=g_strdup(strtok(cur[0],"@"));
4533
full_username= strdup(cur[0]);
4534
part_username= strdup(strtok(cur[0],"@"));
4536
4535
(void) mysql_fetch_row(result); // Read eof
4540
static int com_prompt(GString *buffer __attribute__((__unused__)), char *line)
4539
static int com_prompt(DYNAMIC_STRING *buffer __attribute__((__unused__)), char *line)
4542
4541
char *ptr=strchr(line, ' ');
4543
4542
prompt_counter = 0;
4544
4543
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
4545
current_prompt=g_strdup(ptr ? ptr+1 : default_prompt->str);
4544
current_prompt= strdup(ptr ? ptr+1 : default_prompt);
4547
4546
tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4548
default_prompt->str);
4550
4549
tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);