153
152
*default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
154
153
static char *histfile;
155
154
static char *histfile_tmp;
156
static GString *glob_buffer;
157
static GString *processed_prompt= NULL;
158
static GString *default_prompt= NULL;
155
static DYNAMIC_STRING *glob_buffer;
156
static DYNAMIC_STRING *processed_prompt= NULL;
157
static char *default_prompt= NULL;
159
158
static char *full_username=0,*part_username=0;
160
159
static int wait_time = 5;
161
160
static STATUS status;
199
198
static int get_options(int argc,char **argv);
200
199
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*);
201
static int com_quit(DYNAMIC_STRING *str,char*),
202
com_go(DYNAMIC_STRING *str,char*), com_ego(DYNAMIC_STRING *str,char*),
203
com_print(DYNAMIC_STRING *str,char*),
204
com_help(DYNAMIC_STRING *str,char*), com_clear(DYNAMIC_STRING *str,char*),
205
com_connect(DYNAMIC_STRING *str,char*), com_status(DYNAMIC_STRING *str,char*),
206
com_use(DYNAMIC_STRING *str,char*), com_source(DYNAMIC_STRING *str, char*),
207
com_rehash(DYNAMIC_STRING *str, char*), com_tee(DYNAMIC_STRING *str, char*),
208
com_notee(DYNAMIC_STRING *str, char*), com_charset(DYNAMIC_STRING *str,char*),
209
com_prompt(DYNAMIC_STRING *str, char*), com_delimiter(DYNAMIC_STRING *str, char*),
210
com_warnings(DYNAMIC_STRING *str, char*), com_nowarnings(DYNAMIC_STRING *str, char*),
211
com_nopager(DYNAMIC_STRING *str, char*), com_pager(DYNAMIC_STRING *str, char*);
214
213
static int read_and_execute(bool interactive);
215
214
static int sql_connect(char *host,char *database,char *user,char *password,
995
994
int history_length;
996
995
static int not_in_history(const char *line);
997
996
static void initialize_readline (const char *name);
998
static void fix_history(GString *final_command);
997
static void fix_history(DYNAMIC_STRING *final_command);
1000
999
static COMMANDS *find_command(char *name,char cmd_name);
1001
static bool add_line(GString *buffer,char *line,char *in_string,
1000
static bool add_line(DYNAMIC_STRING *buffer,char *line,char *in_string,
1002
1001
bool *ml_comment);
1003
static void remove_cntrl(GString *buffer);
1002
static void remove_cntrl(DYNAMIC_STRING *buffer);
1004
1003
static void print_table_data(MYSQL_RES *result);
1005
1004
static void print_table_data_html(MYSQL_RES *result);
1006
1005
static void print_table_data_xml(MYSQL_RES *result);
1024
1023
MY_INIT(argv[0]);
1025
1024
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);
1025
default_prompt= my_strdup(getenv("DRIZZLE_PS1") ?
1026
getenv("DRIZZLE_PS1") :
1027
"drizzle>> ", MYF(0));
1028
current_prompt= my_strdup(default_prompt, MYF(0));
1030
processed_prompt= (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
1031
init_dynamic_string(processed_prompt, "", 32, 32);
1031
1033
prompt_counter=0;
1033
1035
outfile[0]=0; // no (default) outfile
1115
1117
put_info("Welcome to the Drizzle client.. Commands end with ; or \\g.",
1116
1118
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);
1120
glob_buffer= (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
1121
init_dynamic_string(glob_buffer, "", 512, 512);
1123
/* this is a slight abuse of the DYNAMIC_STRING interface. deal. */
1124
sprintf(glob_buffer->str,
1125
"Your Drizzle connection id is %u\nServer version: %s\n",
1126
mysql_thread_id(&mysql), server_version_string(&mysql));
1127
put_info(glob_buffer->str, INFO_INFO, 0, 0);
1128
dynstr_set(glob_buffer, NULL);
1124
1130
initialize_readline(my_progname);
1125
1131
if (!status.batch && !quick && !opt_html && !opt_xml)
1127
1133
/* read-history from file, default ~/.mysql_history*/
1128
1134
if (getenv("MYSQL_HISTFILE"))
1129
histfile=g_strdup(getenv("MYSQL_HISTFILE"));
1135
histfile= strdup(getenv("MYSQL_HISTFILE"));
1130
1136
else if (getenv("HOME"))
1132
1138
histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1189
1195
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);
1197
dynstr_free(glob_buffer);
1198
my_free(glob_buffer, MYF(MY_ALLOW_ZERO_PTR));
1199
if (processed_prompt)
1200
dynstr_free(processed_prompt);
1201
my_free(processed_prompt,MYF(MY_ALLOW_ZERO_PTR));
1196
1202
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
1197
1203
my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
1198
1204
my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
1548
1554
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
1555
printf("WARNING: --server-arg option not supported in this configuration.\n");
1760
1746
Check if line is a mysql command line
1761
1747
(We want to allow help, print and clear anywhere at line start
1763
if ((named_cmds || (glob_buffer->len==0))
1749
if ((named_cmds || (glob_buffer->length==0))
1764
1750
&& !ml_comment && !in_string && (com=find_command(line,0)))
1766
1752
if ((*com->func)(glob_buffer,line) > 0)
1768
1754
// If buffer was emptied
1769
if (glob_buffer->len==0)
1755
if (glob_buffer->length==0)
1771
1757
if (interactive && status.add_to_history && not_in_history(line))
1772
1758
add_history(line);
1953
1939
// Flush previously accepted characters
1954
1940
if (out != line)
1956
g_string_append_len(buffer, line, (gssize) (out - line));
1942
dynstr_append_mem(buffer, line, (out - line));
1960
1946
// Flush possible comments in the buffer
1961
if (buffer->len != 0)
1947
if (buffer->length != 0)
1963
1949
if (com_go(buffer, 0) > 0) // < 0 is not fatal
1965
1951
assert(buffer!=NULL);
1966
g_string_truncate(buffer,0);
1952
dynstr_set(buffer, NULL);
1970
1956
Delimiter wants the get rest of the given line as argument to
1971
1957
allow one to change ';' to ';;' and back
1973
g_string_append(buffer,pos);
1959
dynstr_append(buffer,pos);
1974
1960
if (com_delimiter(buffer, pos) > 0)
1977
g_string_truncate(buffer,0);
1963
dynstr_set(buffer, NULL);
1980
1966
else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
2136
2124
/* glues pieces of history back together if in pieces */
2137
static void fix_history(GString *final_command)
2125
static void fix_history(DYNAMIC_STRING *final_command)
2139
2127
int total_lines = 1;
2140
2128
const char *ptr = final_command->str;
2129
char str_char = '\0'; /* Character if we are in a string or not */
2141
2131
/* 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 */
2132
DYNAMIC_STRING *fixed_buffer=
2133
(DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
2135
init_dynamic_string(fixed_buffer, "", 512, 512);
2146
2137
/* find out how many lines we have and remove newlines */
2147
2138
while (*ptr != '\0')
2156
2147
str_char = *ptr;
2157
2148
else if (str_char == *ptr) /* close string */
2158
2149
str_char = '\0';
2159
g_string_append_len(fixed_buffer, ptr, 1);
2150
dynstr_append_mem(fixed_buffer, ptr, 1);
2163
2154
not in string, change to space
2164
2155
if in string, leave it alone
2166
g_string_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2157
dynstr_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2170
g_string_append_c(fixed_buffer, '\\');
2161
dynstr_append(fixed_buffer, "\\");
2171
2162
/* need to see if the backslash is escaping anything */
2175
2166
/* special characters that need escaping */
2176
2167
if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2177
g_string_append_len(fixed_buffer, ptr, 1);
2168
dynstr_append_mem(fixed_buffer, ptr, 1);
2183
g_string_append_len(fixed_buffer, ptr, 1);
2174
dynstr_append_mem(fixed_buffer, ptr, 1);
2206
2197
static void initialize_readline (const char *name)
2208
2199
/* Allow conditional parsing of the ~/.inputrc file. */
2209
rl_readline_name= name;
2200
rl_readline_name= (char *)name;
2202
#ifdef HAVE_READLINE_COMPLETION
2211
2203
/* Tell the completer that we want a crack first. */
2212
2204
rl_attempted_completion_function= (rl_completion_func_t*)&new_mysql_completion;
2213
2205
rl_completion_entry_function= (rl_compentry_func_t*)&no_completion;
2209
#ifdef HAVE_READLINE_COMPLETION
2217
2211
Attempt to complete on the contents of TEXT. START and END show the
2218
2212
region of TEXT that contains the word to complete. We can use the
2661
com_clear(GString *buffer,char *line __attribute__((unused)))
2656
com_clear(DYNAMIC_STRING *buffer,char *line __attribute__((unused)))
2663
2658
if (status.add_to_history)
2664
2659
fix_history(buffer);
2665
g_string_truncate(buffer, 0);
2660
dynstr_set(buffer, NULL);
2670
com_charset(GString *buffer __attribute__((unused)), char *line)
2665
com_charset(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
2672
2667
char buff[256], *param;
2673
2668
CHARSET_INFO * new_cs;
2724
2719
if (!connected && reconnect())
2726
2721
// Remove query on error
2727
g_string_truncate(buffer, 0);
2722
dynstr_set(buffer, NULL);
2728
2723
return opt_reconnect ? -1 : 1; // Fatal error
2731
2726
(void) com_print(buffer, 0);
2733
2728
if (skip_updates &&
2735
|| g_string_equal(g_string_new_len(buffer->str,4),
2736
g_string_new("SET "))))
2729
((buffer->length < 4) || !strncmp(buffer->str, "SET ", 4)))
2738
2731
(void) put_info("Ignoring query to other database",INFO_INFO,0,0);
2742
2735
timer=start_timer();
2743
2736
executing_query= 1;
2744
error= mysql_real_query_for_lazy(buffer->str,buffer->len);
2737
error= mysql_real_query_for_lazy(buffer->str,buffer->length);
2746
2739
if (status.add_to_history)
2748
g_string_append(buffer, vertical ? "\\G" : delimiter);
2741
dynstr_append(buffer, vertical ? "\\G" : delimiter);
2749
2742
/* Append final command onto history */
2750
2743
fix_history(buffer);
2753
g_string_truncate(buffer, 0);
2746
dynstr_set(buffer, NULL);
3041
3036
field->max_length=length;
3043
3038
for (x=0; x< (length+2); x++)
3044
g_string_append_c(separator, '-');
3045
g_string_append_c(separator, '+');
3039
dynstr_append(separator, "-");
3040
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
3043
tee_puts((char*) separator->str, PAGER);
3052
3044
if (column_names)
3600
com_print(GString *buffer,char *line __attribute__((unused)))
3592
com_print(DYNAMIC_STRING *buffer,char *line __attribute__((unused)))
3602
3594
tee_puts("--------------", stdout);
3603
3595
(void) tee_fputs(buffer->str, stdout);
3604
if ( (buffer->len == 0)
3605
|| (buffer->str)[(buffer->len)-1] != '\n')
3596
if ( (buffer->length == 0)
3597
|| (buffer->str)[(buffer->length)-1] != '\n')
3606
3598
tee_putc('\n', stdout);
3607
3599
tee_puts("--------------\n", stdout);
3608
3600
/* If empty buffer */
4070
4062
tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->csname);
4073
#ifndef EMBEDDED_LIBRARY
4074
4065
if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket)
4075
4066
tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port);
4077
4068
tee_fprintf(stdout, "UNIX socket:\t\t%s\n", mysql.unix_socket);
4078
4069
if (mysql.net.compress)
4079
4070
tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
4082
4072
if ((status_str= mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
4227
static void remove_cntrl(GString *buffer)
4217
static void remove_cntrl(DYNAMIC_STRING *buffer)
4229
4219
char *start= buffer->str;
4230
char *end= start + (buffer->len);
4220
char *end= start + (buffer->length);
4231
4221
while (start < end && !my_isgraph(charset_info,end[-1]))
4233
4223
uint chars_to_truncate = end-start;
4234
if (buffer->len > chars_to_truncate)
4235
g_string_truncate(buffer, chars_to_truncate);
4224
if (buffer->length > chars_to_truncate)
4225
dynstr_trunc(buffer, chars_to_truncate);
4378
g_string_append(processed_prompt, mysql_get_server_info(&mysql));
4368
dynstr_append(processed_prompt, mysql_get_server_info(&mysql));
4380
g_string_append(processed_prompt, "not_connected");
4370
dynstr_append(processed_prompt, "not_connected");
4383
g_string_append(processed_prompt, current_db ? current_db : "(none)");
4373
dynstr_append(processed_prompt, current_db ? current_db : "(none)");
4387
4377
const char *prompt;
4388
4378
prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
4389
4379
if (strstr(prompt, "Localhost"))
4390
g_string_append(processed_prompt, "localhost");
4380
dynstr_append(processed_prompt, "localhost");
4393
4383
const char *end=strcend(prompt,' ');
4394
g_string_append_len(processed_prompt, prompt, (gssize) (end-prompt));
4384
dynstr_append_mem(processed_prompt, prompt, (end-prompt));
4400
4390
if (!connected)
4402
g_string_append(processed_prompt, "not_connected");
4392
dynstr_append(processed_prompt, "not_connected");
4406
4396
const char *host_info = mysql_get_host_info(&mysql);
4407
4397
if (strstr(host_info, "memory"))
4409
g_string_append(processed_prompt, mysql.host );
4399
dynstr_append(processed_prompt, mysql.host);
4411
4401
else if (strstr(host_info,"TCP/IP") ||
4412
4402
!mysql.unix_socket)
4416
4406
char *pos=strrchr(mysql.unix_socket,'/');
4417
g_string_append(processed_prompt, pos ? pos+1 : mysql.unix_socket);
4407
dynstr_append(processed_prompt, pos ? pos+1 : mysql.unix_socket);
4422
4412
if (!full_username)
4423
4413
init_username();
4424
g_string_append(processed_prompt, full_username ? full_username :
4414
dynstr_append(processed_prompt, full_username ? full_username :
4425
4415
(current_user ? current_user : "(unknown)"));
4428
4418
if (!full_username)
4429
4419
init_username();
4430
g_string_append(processed_prompt, part_username ? part_username :
4420
dynstr_append(processed_prompt, part_username ? part_username :
4431
4421
(current_user ? current_user : "(unknown)"));
4433
4423
case PROMPT_CHAR:
4434
g_string_append_c(processed_prompt, PROMPT_CHAR);
4425
char c= PROMPT_CHAR;
4426
dynstr_append_mem(processed_prompt, &c, 1);
4437
g_string_append_c(processed_prompt, '\n');
4432
dynstr_append_mem(processed_prompt, &c, 1);
4441
g_string_append_c(processed_prompt, ' ');
4439
dynstr_append_mem(processed_prompt, &c, 1);
4444
4443
if (t->tm_hour < 10)
4445
g_string_append_c(processed_prompt, '0');
4444
add_int_to_prompt(0);
4446
4445
add_int_to_prompt(t->tm_hour);
4471
4470
dateTime = ctime(&lclock);
4472
g_string_append(processed_prompt, strtok(dateTime,"\n"));
4471
dynstr_append(processed_prompt, strtok(dateTime,"\n"));
4475
4474
if (t->tm_sec < 10)
4476
g_string_append_c(processed_prompt, '0');
4475
add_int_to_prompt(0);
4477
4476
add_int_to_prompt(t->tm_sec);
4480
g_string_append(processed_prompt, (day_names[t->tm_wday]));
4479
dynstr_append(processed_prompt, (day_names[t->tm_wday]));
4483
g_string_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4482
dynstr_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4486
4485
add_int_to_prompt(t->tm_mon+1);
4489
g_string_append(processed_prompt, month_names[t->tm_mon]);
4488
dynstr_append(processed_prompt, month_names[t->tm_mon]);
4492
g_string_append(processed_prompt, "'");
4491
dynstr_append(processed_prompt, "'");
4495
g_string_append_c(processed_prompt, '"');
4494
dynstr_append(processed_prompt, "\"");
4498
g_string_append_c(processed_prompt, ';');
4497
dynstr_append(processed_prompt, ";");
4501
g_string_append_c(processed_prompt, '\t');
4500
dynstr_append(processed_prompt, "\t");
4504
g_string_append(processed_prompt, delimiter_str);
4503
dynstr_append(processed_prompt, delimiter_str);
4507
g_string_append(processed_prompt, c);
4506
dynstr_append_mem(processed_prompt, c, 1);
4511
// TODO: Is this needed with GString?
4512
g_string_append_c(processed_prompt, '\0');
4513
4510
return processed_prompt->str;
4531
4528
(result=mysql_use_result(&mysql)))
4533
4530
MYSQL_ROW cur=mysql_fetch_row(result);
4534
full_username=g_strdup(cur[0]);
4535
part_username=g_strdup(strtok(cur[0],"@"));
4531
full_username= strdup(cur[0]);
4532
part_username= strdup(strtok(cur[0],"@"));
4536
4533
(void) mysql_fetch_row(result); // Read eof
4540
static int com_prompt(GString *buffer __attribute__((__unused__)), char *line)
4537
static int com_prompt(DYNAMIC_STRING *buffer __attribute__((__unused__)), char *line)
4542
4539
char *ptr=strchr(line, ' ');
4543
4540
prompt_counter = 0;
4544
4541
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
4545
current_prompt=g_strdup(ptr ? ptr+1 : default_prompt->str);
4542
current_prompt= strdup(ptr ? ptr+1 : default_prompt);
4547
4544
tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4548
default_prompt->str);
4550
4547
tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);