1
/* Copyright (C) 2000-2008 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 MySQL
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16
21
/* mysql command tool
17
22
* Commands compatible with mSQL by David J. Hughes
129
131
static MYSQL mysql; /* The connection */
130
132
static bool ignore_errors=0,wait_flag=0,quick=0,
131
connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
132
opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
133
opt_compress=0, using_opt_local_infile=0,
134
vertical=0, line_numbers=1, column_names=1,opt_html=0,
135
opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
136
tty_password= 0, opt_nobeep=0, opt_reconnect=1,
137
default_charset_used= 0, opt_secure_auth= 0,
138
default_pager_set= 0, opt_sigint_ignore= 0,
139
auto_vertical_output= 0,
140
show_warnings= 0, executing_query= 0, interrupted_query= 0;
133
connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
134
opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
135
opt_compress=0, using_opt_local_infile=0,
136
vertical=0, line_numbers=1, column_names=1,opt_html=0,
137
opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
138
tty_password= 0, opt_nobeep=0, opt_reconnect=1,
139
default_charset_used= 0, opt_secure_auth= 0,
140
default_pager_set= 0, opt_sigint_ignore= 0,
141
auto_vertical_output= 0,
142
show_warnings= 0, executing_query= 0, interrupted_query= 0;
141
143
static bool debug_info_flag, debug_check_flag;
142
144
static bool column_types_flag;
143
145
static bool preserve_comments= 0;
191
197
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
192
198
/* The names of functions that actually do the manipulation. */
193
199
static int get_options(int argc,char **argv);
194
extern "C" bool get_one_option(int optid, const struct my_option *opt,
196
static int com_quit(String *str,char*),
197
com_go(String *str,char*), com_ego(String *str,char*),
198
com_print(String *str,char*),
199
com_help(String *str,char*), com_clear(String *str,char*),
200
com_connect(String *str,char*), com_status(String *str,char*),
201
com_use(String *str,char*), com_source(String *str, char*),
202
com_rehash(String *str, char*), com_tee(String *str, char*),
203
com_notee(String *str, char*), com_charset(String *str,char*),
204
com_prompt(String *str, char*), com_delimiter(String *str, char*),
205
com_warnings(String *str, char*), com_nowarnings(String *str, char*);
208
static int com_nopager(String *str, char*), com_pager(String *str, char*),
209
com_edit(String *str,char*), com_shell(String *str, char *);
200
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*);
212
214
static int read_and_execute(bool interactive);
213
215
static int sql_connect(char *host,char *database,char *user,char *password,
215
217
static const char *server_version_string(MYSQL *mysql);
216
static int put_info(const char *str,INFO_TYPE info,uint error=0,
217
const char *sql_state=0);
218
static int put_info(const char *str,INFO_TYPE info,uint error,
219
const char *sql_state);
218
220
static int put_error(MYSQL *mysql);
219
221
static void safe_put_field(const char *pos,ulong length);
220
222
static void xmlencode_print(const char *src, uint length);
221
static void init_pager();
222
static void end_pager();
223
static void init_pager(void);
224
static void end_pager(void);
223
225
static void init_tee(const char *);
224
static void end_tee();
225
static const char* construct_prompt();
226
static void end_tee(void);
227
static const char* construct_prompt(void);
226
228
static char *get_arg(char *line, bool get_next_arg);
227
static void init_username();
229
static void init_username(void);
228
230
static void add_int_to_prompt(int toadd);
229
231
static int get_result_width(MYSQL_RES *res);
230
232
static int get_field_disp_length(MYSQL_FIELD * field);
232
234
/* A structure which contains information on the commands this program
233
235
can understand. */
236
237
const char *name; /* User printable name of the function. */
237
238
char cmd_char; /* msql command character */
238
int (*func)(String *str,char *); /* Function to call to do the job. */
239
int (*func)(GString *str,char *); /* Function to call to do the job. */
239
240
bool takes_params; /* Max parameters for command */
240
241
const char *doc; /* Documentation for this function. */
243
245
static COMMANDS commands[] = {
244
246
{ "?", '?', com_help, 1, "Synonym for `help'." },
245
247
{ "clear", 'c', com_clear, 0, "Clear command."},
247
249
"Reconnect to the server. Optional arguments are db and host." },
248
250
{ "delimiter", 'd', com_delimiter, 1,
249
251
"Set statement delimiter. NOTE: Takes the rest of the line as new delimiter." },
251
{ "edit", 'e', com_edit, 0, "Edit command with $EDITOR."},
253
252
{ "ego", 'G', com_ego, 0,
254
253
"Send command to mysql server, display result vertically."},
255
254
{ "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."},
256
255
{ "go", 'g', com_go, 0, "Send command to mysql server." },
257
256
{ "help", 'h', com_help, 1, "Display this help." },
259
257
{ "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
261
258
{ "notee", 't', com_notee, 0, "Don't write into outfile." },
263
{ "pager", 'P', com_pager, 1,
259
{ "pager", 'P', com_pager, 1,
264
260
"Set PAGER [to_pager]. Print the query results via PAGER." },
266
261
{ "print", 'p', com_print, 0, "Print current command." },
267
262
{ "prompt", 'R', com_prompt, 1, "Change your mysql prompt."},
268
263
{ "quit", 'q', com_quit, 0, "Quit mysql." },
1124
1115
put_info("Welcome to the Drizzle client.. Commands end with ; or \\g.",
1126
sprintf((char*) glob_buffer.ptr(),
1127
"Your Drizzle connection id is %u\nServer version: %s\n",
1128
mysql_thread_id(&mysql), server_version_string(&mysql));
1129
put_info((char*) glob_buffer.ptr(),INFO_INFO);
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);
1131
#ifdef HAVE_READLINE
1132
initialize_readline((char*) my_progname);
1124
initialize_readline(my_progname);
1133
1125
if (!status.batch && !quick && !opt_html && !opt_xml)
1135
1127
/* read-history from file, default ~/.mysql_history*/
1136
1128
if (getenv("MYSQL_HISTFILE"))
1137
histfile=my_strdup(getenv("MYSQL_HISTFILE"),MYF(MY_WME));
1129
histfile=g_strdup(getenv("MYSQL_HISTFILE"));
1138
1130
else if (getenv("HOME"))
1140
1132
histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1141
+ (uint) strlen("/.mysql_history")+2,
1133
+ (uint) strlen("/.mysql_history")+2,
1144
sprintf(histfile,"%s/.mysql_history",getenv("HOME"));
1136
sprintf(histfile,"%s/.mysql_history",getenv("HOME"));
1145
1137
char link_name[FN_REFLEN];
1146
1138
if (my_readlink(link_name, histfile, 0) == 0 &&
1147
1139
strncmp(link_name, "/dev/null", 10) == 0)
1281
1273
{"no-auto-rehash", 'A',
1282
1274
"No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
1283
1275
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1284
{"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
1285
"Automatically switch to vertical output mode if the result is wider than the terminal width.",
1286
(char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1276
{"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
1277
"Automatically switch to vertical output mode if the result is wider than the terminal width.",
1278
(char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1288
1280
"Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1289
1281
{"character-sets-dir", OPT_CHARSETS_DIR,
1332
1324
(char**) &opt_local_infile,
1333
1325
(char**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
1334
1326
{"no-beep", 'b', "Turn off beep on error.", (char**) &opt_nobeep,
1335
(char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1327
(char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1336
1328
{"host", 'h', "Connect to host.", (char**) ¤t_host,
1337
1329
(char**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1338
1330
{"html", 'H', "Produce HTML output.", (char**) &opt_html, (char**) &opt_html,
1341
1333
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1342
1334
{"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
1343
1335
(char**) &line_numbers, (char**) &line_numbers, 0, GET_BOOL,
1344
NO_ARG, 1, 0, 0, 0, 0, 0},
1336
NO_ARG, 1, 0, 0, 0, 0, 0},
1345
1337
{"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
1346
1338
NO_ARG, 0, 0, 0, 0, 0, 0},
1347
1339
{"unbuffered", 'n', "Flush buffer after each query.", (char**) &unbuffered,
1361
1353
{"one-database", 'o',
1362
1354
"Only update the default database. This is useful for skipping updates to other database in the update log.",
1363
1355
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1365
1356
{"pager", OPT_PAGER,
1366
1357
"Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default.",
1367
1358
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1368
1359
{"no-pager", OPT_NOPAGER,
1369
1360
"Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
1370
1361
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1372
1362
{"password", 'p',
1373
1363
"Password to use when connecting to server. If password is not given it's asked from the tty.",
1374
1364
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1391
1381
{"raw", 'r', "Write fields without conversion. Used with --batch.",
1392
1382
(char**) &opt_raw_data, (char**) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1394
{"reconnect", OPT_RECONNECT, "Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default.",
1384
{"reconnect", OPT_RECONNECT, "Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default.",
1395
1385
(char**) &opt_reconnect, (char**) &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
1396
1386
{"silent", 's', "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,
1446
1436
(char**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
1448
1438
{"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it"
1449
" uses old (pre-4.1.1) protocol", (char**) &opt_secure_auth,
1450
(char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1439
" uses old (pre-4.1.1) protocol", (char**) &opt_secure_auth,
1440
(char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1451
1441
{"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.",
1452
1442
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1453
1443
{"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
1454
(char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
1444
(char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
1456
1446
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1460
1450
static void usage(int version)
1462
#if defined(USE_LIBEDIT_INTERFACE)
1463
const char* readline= "";
1465
1452
const char* readline= "readline";
1468
#ifdef HAVE_READLINE
1469
1454
printf("%s Ver %s Distrib %s, for %s (%s) using %s %s\n",
1470
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
1455
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
1471
1456
readline, rl_library_version);
1473
printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER,
1474
MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
1480
Copyright (C) 2000-2008 MySQL AB\n\
1481
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
1461
Copyright (C) 2000-2008 MySQL AB\n \
1462
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n \
1482
1463
and you are welcome to modify and redistribute it under the GPL license\n");
1483
1464
printf("Usage: %s [OPTIONS] [database]\n", my_progname);
1484
1465
my_print_help(my_long_options);
2020
2000
my_isspace(charset_info, pos[2]))))
2022
2002
// Add trailing single line comments to this statement
2003
g_string_append(buffer, pos);
2024
2004
pos+= strlen(pos);
2029
if ((com= find_command(buffer.c_ptr(), 0)))
2009
if ((com= find_command(buffer->str, 0)))
2032
if ((*com->func)(&buffer, buffer.c_ptr()) > 0)
2012
if ((*com->func)(buffer, buffer->str) > 0)
2037
if (com_go(&buffer, 0) > 0) // < 0 is not fatal
2017
if (com_go(buffer, 0) > 0) // < 0 is not fatal
2020
g_string_truncate(buffer,0);
2042
else if (!*ml_comment && (!*in_string && (inchar == '#' ||
2043
(inchar == '-' && pos[1] == '-' && my_isspace(charset_info,pos[2])))))
2022
else if (!*ml_comment
2027
&& my_isspace(charset_info,pos[2])))))
2045
2029
// Flush previously accepted characters
2046
2030
if (out != line)
2048
buffer.append(line, (uint32) (out - line));
2032
g_string_append_len(buffer, line, (gssize) (out - line));
2052
2036
// comment to end of line
2053
2037
if (preserve_comments)
2038
g_string_append(buffer,pos);
2058
2042
else if (!*in_string && inchar == '/' && *(pos+1) == '*' &&
2061
2045
if (preserve_comments)
2142
2125
#if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE)
2143
extern "C" char *no_completion(const char*,int)
2126
extern char *no_completion(const char*,int);
2145
extern "C" char *no_completion()
2128
char *no_completion(void);
2129
char *no_completion(void)
2131
/* No filename completion */
2148
return 0; /* No filename completion */
2151
/* glues pieces of history back together if in pieces */
2152
static void fix_history(String *final_command)
2136
/* glues pieces of history back together if in pieces */
2137
static void fix_history(GString *final_command)
2154
2139
int total_lines = 1;
2155
char *ptr = final_command->c_ptr();
2156
String fixed_buffer; /* Converted buffer */
2140
const char *ptr = final_command->str;
2141
/* Converted buffer */
2142
GString * fixed_buffer;
2143
fixed_buffer = g_string_sized_new(16);
2157
2144
char str_char = '\0'; /* Character if we are in a string or not */
2159
2146
/* find out how many lines we have and remove newlines */
2160
while (*ptr != '\0')
2147
while (*ptr != '\0')
2162
2149
switch (*ptr) {
2163
2150
/* string character */
2167
if (str_char == '\0') /* open string */
2155
if (str_char == '\0')
2169
2157
else if (str_char == *ptr) /* close string */
2171
fixed_buffer.append(ptr,1);
2159
g_string_append_len(fixed_buffer, ptr, 1);
2175
not in string, change to space
2176
if in string, leave it alone
2163
not in string, change to space
2164
if in string, leave it alone
2178
fixed_buffer.append(str_char == '\0' ? " " : "\n");
2166
g_string_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2182
fixed_buffer.append('\\');
2170
g_string_append_c(fixed_buffer, '\\');
2183
2171
/* need to see if the backslash is escaping anything */
2187
/* special characters that need escaping */
2188
if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2189
fixed_buffer.append(ptr,1);
2175
/* special characters that need escaping */
2176
if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2177
g_string_append_len(fixed_buffer, ptr, 1);
2196
fixed_buffer.append(ptr,1);
2183
g_string_append_len(fixed_buffer, ptr, 1);
2200
if (total_lines > 1)
2201
add_history(fixed_buffer.ptr());
2187
if (total_lines > 1)
2188
add_history(fixed_buffer->str);
2205
2192
returns 0 if line matches the previous history entry
2206
2193
returns 1 if the line doesn't match the previous history entry
2208
static int not_in_history(const char *line)
2195
static int not_in_history(const char *line)
2210
2197
HIST_ENTRY *oldhist = history_get(history_length);
2212
2199
if (oldhist == 0)
2214
2201
if (strcmp(oldhist->line,line) == 0)
2541
2527
char ccat= (*cur)[num_cat][0];
2542
2528
if (*last_char != ccat)
2544
put_info(ccat == 'Y' ? "categories:" : "topics:", INFO_INFO);
2530
put_info(ccat == 'Y' ? "categories:" : "topics:", INFO_INFO,0,0);
2545
2531
*last_char= ccat;
2547
2533
tee_fprintf(PAGER, " %s\n", (*cur)[num_name]);
2551
static int com_server_help(String *buffer __attribute__((unused)),
2552
char *line __attribute__((unused)), char *help_arg)
2537
static int com_server_help(GString *buffer,
2538
char *line __attribute__((unused)),
2555
const char *server_cmd= buffer->ptr();
2542
const char *server_cmd= buffer->str;
2556
2543
char cmd_buf[100];
2557
2544
MYSQL_RES *result;
2560
2547
if (help_arg[0] != '\'')
2562
char *end_arg= strend(help_arg);
2565
while (my_isspace(charset_info,*end_arg))
2569
(void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
2549
char *end_arg= strend(help_arg);
2552
while (my_isspace(charset_info,*end_arg))
2556
(void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
2570
2557
server_cmd= cmd_buf;
2575
old_buffer= *buffer;
2579
2560
if (!connected && reconnect())
2614
2595
if (num_fields == 2)
2616
put_info("Many help items for your request exist.", INFO_INFO);
2617
put_info("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following", INFO_INFO);
2597
put_info("Many help items for your request exist.", INFO_INFO,0,0);
2598
put_info("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following", INFO_INFO,0,0);
2621
2602
else if ((cur= mysql_fetch_row(result)))
2623
tee_fprintf(PAGER, "You asked for help about help category: \"%s\"\n", cur[0]);
2624
put_info("For more information, type 'help <item>', where <item> is one of the following", INFO_INFO);
2627
print_help_item(&cur,1,2,&last_char);
2604
tee_fprintf(PAGER, "You asked for help about help category: \"%s\"\n", cur[0]);
2605
put_info("For more information, type 'help <item>', where <item> is one of the following", INFO_INFO,0,0);
2608
print_help_item(&cur,1,2,&last_char);
2630
2611
while ((cur= mysql_fetch_row(result)))
2631
print_help_item(&cur,num_name,num_cat,&last_char);
2612
print_help_item(&cur,num_name,num_cat,&last_char);
2632
2613
tee_fprintf(PAGER, "\n");
2637
put_info("\nNothing found", INFO_INFO);
2638
put_info("Please try to run 'help contents' for a list of all accessible topics\n", INFO_INFO);
2618
put_info("\nNothing found", INFO_INFO,0,0);
2619
put_info("Please try to run 'help contents' for a list of all accessible topics\n", INFO_INFO,0,0);
2708
2685
mysql_set_character_set(&mysql, charset_info->csname);
2709
2686
default_charset= (char *)charset_info->csname;
2710
2687
default_charset_used= 1;
2711
put_info("Charset changed", INFO_INFO);
2688
put_info("Charset changed", INFO_INFO,0,0);
2713
else put_info("Charset is not found", INFO_INFO);
2690
else put_info("Charset is not found", INFO_INFO,0,0);
2718
2695
Execute command
2719
2696
Returns: 0 if ok
2720
-1 if not fatal error
2697
-1 if not fatal error
2726
com_go(String *buffer,char *line __attribute__((unused)))
2701
com_go(GString *buffer,
2702
char *line __attribute__((unused)))
2728
char buff[200]; /* about 110 chars used so far */
2729
char time_buff[52+3+1]; /* time max + space&parens + NUL */
2731
ulong timer, warnings= 0;
2704
char buff[200]; /* about 110 chars used so far */
2705
char time_buff[52+3+1]; /* time max + space&parens + NUL */
2707
ulong timer, warnings= 0;
2735
2711
interrupted_query= 0;
2738
old_buffer= *buffer; // Save for edit command
2742
2713
/* Remove garbage for nicer messages */
2743
remove_cntrl(*buffer);
2714
remove_cntrl(buffer);
2745
if (buffer->is_empty())
2716
if (buffer->len == 0)
2747
if (status.batch) // Ignore empty quries
2718
// Ignore empty quries
2749
return put_info("No query specified\n",INFO_ERROR);
2721
return put_info("No query specified\n",INFO_ERROR,0,0);
2752
2724
if (!connected && reconnect())
2754
buffer->length(0); // Remove query on error
2726
// Remove query on error
2727
g_string_truncate(buffer, 0);
2755
2728
return opt_reconnect ? -1 : 1; // Fatal error
2758
(void) com_print(buffer,0);
2731
(void) com_print(buffer, 0);
2760
2733
if (skip_updates &&
2761
(buffer->length() < 4 || my_strnncoll(charset_info,
2762
(const uchar*)buffer->ptr(),4,
2763
(const uchar*)"SET ",4)))
2735
|| g_string_equal(g_string_new_len(buffer->str,4),
2736
g_string_new("SET "))))
2765
(void) put_info("Ignoring query to other database",INFO_INFO);
2738
(void) put_info("Ignoring query to other database",INFO_INFO,0,0);
2769
2742
timer=start_timer();
2770
2743
executing_query= 1;
2771
error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length());
2744
error= mysql_real_query_for_lazy(buffer->str,buffer->len);
2773
#ifdef HAVE_READLINE
2774
if (status.add_to_history)
2776
buffer->append(vertical ? "\\G" : delimiter);
2746
if (status.add_to_history)
2748
g_string_append(buffer, vertical ? "\\G" : delimiter);
2777
2749
/* Append final command onto history */
2778
2750
fix_history(buffer);
2753
g_string_truncate(buffer, 0);
3142
3116
if (num_flag[off] != 0) /* if it is numeric, we right-justify it */
3143
3117
tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, TRUE);
3145
tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, FALSE);
3119
tee_print_sized_data(buffer, data_length,
3120
field_max_length+extra_padding, FALSE);
3147
3122
tee_fputs(" | ", PAGER);
3149
3124
(void) tee_fputs("\n", PAGER);
3151
tee_puts((char*) separator.ptr(), PAGER);
3152
my_afree((uchar*) num_flag);
3126
tee_puts(separator->str, PAGER);
3127
my_free(num_flag, MYF(MY_ALLOW_ZERO_PTR));
3156
Return the length of a field after it would be rendered into text.
3158
This doesn't know or care about multibyte characters. Assume we're
3159
using such a charset. We can't know that all of the upcoming rows
3160
for this column will have bytes that each render into some fraction
3161
of a character. It's at least possible that a row has bytes that
3162
all render into one character each, and so the maximum length is
3163
still the number of bytes. (Assumption 1: This can't be better
3164
because we can never know the number of characters that the DB is
3165
going to send -- only the number of bytes. 2: Chars <= Bytes.)
3167
@param field Pointer to a field to be inspected
3169
@returns number of character positions to be used, at most
3131
Return the length of a field after it would be rendered into text.
3133
This doesn't know or care about multibyte characters. Assume we're
3134
using such a charset. We can't know that all of the upcoming rows
3135
for this column will have bytes that each render into some fraction
3136
of a character. It's at least possible that a row has bytes that
3137
all render into one character each, and so the maximum length is
3138
still the number of bytes. (Assumption 1: This can't be better
3139
because we can never know the number of characters that the DB is
3140
going to send -- only the number of bytes. 2: Chars <= Bytes.)
3142
@param field Pointer to a field to be inspected
3144
@returns number of character positions to be used, at most
3171
3146
static int get_field_disp_length(MYSQL_FIELD *field)
3599
3574
tee_fprintf(stdout, "PAGER set to stdout\n");
3606
Sorry, you can't send the result to an editor in Win32
3611
com_edit(String *buffer,char *line __attribute__((unused)))
3613
char filename[FN_REFLEN],buff[160];
3617
if ((fd=create_temp_file(filename,NullS,"sql", O_CREAT | O_WRONLY,
3620
if (buffer->is_empty() && !old_buffer.is_empty())
3621
(void) my_write(fd,(uchar*) old_buffer.ptr(),old_buffer.length(),
3624
(void) my_write(fd,(uchar*) buffer->ptr(),buffer->length(),MYF(MY_WME));
3625
(void) my_close(fd,MYF(0));
3627
if (!(editor = (char *)getenv("EDITOR")) &&
3628
!(editor = (char *)getenv("VISUAL")))
3630
strxmov(buff,editor," ",filename,NullS);
3631
(void) system(buff);
3633
struct stat stat_arg;
3634
if (stat(filename,&stat_arg))
3636
if ((fd = my_open(filename,O_RDONLY, MYF(MY_WME))) < 0)
3638
(void) buffer->alloc((uint) stat_arg.st_size);
3639
if ((tmp=read(fd,(char*) buffer->ptr(),buffer->alloced_length())) >= 0L)
3640
buffer->length((uint) tmp);
3643
(void) my_close(fd,MYF(0));
3644
(void) my_delete(filename,MYF(MY_WME));
3651
3578
/* If arg is given, exit without errors. This happens on command 'quit' */
3654
com_quit(String *buffer __attribute__((unused)),
3655
char *line __attribute__((unused)))
3581
com_quit(GString *buffer __attribute__((unused)),
3582
char *line __attribute__((unused)))
3657
3584
/* let the screen auto close on a normal shutdown */
3658
3585
status.exit_status=0;
3663
com_rehash(String *buffer __attribute__((unused)),
3664
char *line __attribute__((unused)))
3590
com_rehash(GString *buffer __attribute__((unused)),
3591
char *line __attribute__((unused)))
3666
#ifdef HAVE_READLINE
3667
3593
build_completion_hash(1, 0);
3675
com_shell(String *buffer, char *line __attribute__((unused)))
3679
/* Skip space from line begin */
3680
while (my_isspace(charset_info, *line))
3682
if (!(shell_cmd = strchr(line, ' ')))
3684
put_info("Usage: \\! shell-command", INFO_ERROR);
3688
The output of the shell command does not
3689
get directed to the pager or the outfile
3691
if (system(shell_cmd) == -1)
3693
put_info(strerror(errno), INFO_ERROR, errno);
3702
com_print(String *buffer,char *line __attribute__((unused)))
3600
com_print(GString *buffer,char *line __attribute__((unused)))
3704
3602
tee_puts("--------------", stdout);
3705
(void) tee_fputs(buffer->c_ptr(), stdout);
3706
if (!buffer->length() || (*buffer)[buffer->length()-1] != '\n')
3603
(void) tee_fputs(buffer->str, stdout);
3604
if ( (buffer->len == 0)
3605
|| (buffer->str)[(buffer->len)-1] != '\n')
3707
3606
tee_putc('\n', stdout);
3708
3607
tee_puts("--------------\n", stdout);
3709
return 0; /* If empty buffer */
3608
/* If empty buffer */
3714
com_connect(String *buffer, char *line)
3614
com_connect(GString *buffer, char *line)
3716
3616
char *tmp, buff[256];
3717
3617
bool save_rehash= opt_rehash;
3792
3694
char buff[FN_REFLEN+60];
3793
3695
sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3794
return put_info(buff, INFO_ERROR, 0);
3696
return put_info(buff, INFO_ERROR, 0 ,0);
3797
3699
if (!(line_buff=batch_readline_init(opt_max_allowed_packet+512,sql_file)))
3799
3701
my_fclose(sql_file,MYF(0));
3800
return put_info("Can't initialize batch_readline", INFO_ERROR, 0);
3702
return put_info("Can't initialize batch_readline", INFO_ERROR, 0 ,0);
3803
3705
/* Save old status */
3804
3706
old_status=status;
3805
3707
bfill((char*) &status,sizeof(status),(char) 0);
3807
status.batch=old_status.batch; // Run in batch mode
3709
// Run in batch mode
3710
status.batch=old_status.batch;
3808
3711
status.line_buff=line_buff;
3809
3712
status.file_name=source_name;
3810
glob_buffer.length(0); // Empty command buffer
3713
// Empty command buffer
3714
assert(glob_buffer!=NULL);
3715
g_string_truncate(glob_buffer, 0);
3811
3716
error= read_and_execute(false);
3812
status=old_status; // Continue as before
3717
// Continue as before
3813
3719
my_fclose(sql_file,MYF(0));
3814
3720
batch_readline_end(line_buff);
3821
com_delimiter(String *buffer __attribute__((unused)), char *line)
3727
com_delimiter(GString *buffer __attribute__((unused)), char *line)
3823
3729
char buff[256], *tmp;
3909
3816
return put_error(&mysql);
3911
3818
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
3912
current_db=my_strdup(tmp,MYF(MY_WME));
3913
#ifdef HAVE_READLINE
3819
current_db=g_strdup(tmp);
3914
3820
if (select_db > 1)
3915
3821
build_completion_hash(opt_rehash, 1);
3919
put_info("Database changed",INFO_INFO);
3824
put_info("Database changed",INFO_INFO, 0, 0);
3924
com_warnings(String *buffer __attribute__((unused)),
3925
char *line __attribute__((unused)))
3829
com_warnings(GString *buffer __attribute__((unused)),
3830
char *line __attribute__((unused)))
3927
3832
show_warnings = 1;
3928
put_info("Show warnings enabled.",INFO_INFO);
3833
put_info("Show warnings enabled.",INFO_INFO, 0, 0);
3933
com_nowarnings(String *buffer __attribute__((unused)),
3934
char *line __attribute__((unused)))
3838
com_nowarnings(GString *buffer __attribute__((unused)),
3839
char *line __attribute__((unused)))
3936
3841
show_warnings = 0;
3937
put_info("Show warnings disabled.",INFO_INFO);
3842
put_info("Show warnings disabled.",INFO_INFO, 0, 0);
4029
3934
char init_command[100];
4030
3935
sprintf(init_command,
4031
"SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%"PRIu32
3936
"SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%"PRIu32
4032
3937
",SQL_MAX_JOIN_SIZE=%"PRIu32,
4033
select_limit, max_join_size);
3938
select_limit, max_join_size);
4034
3939
mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command);
4036
3941
if (default_charset_used)
4037
3942
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
4038
3943
if (!mysql_real_connect(&mysql, host, user, password,
4039
database, opt_mysql_port, opt_mysql_unix_port,
4040
connect_flag | CLIENT_MULTI_STATEMENTS))
3944
database, opt_mysql_port, opt_mysql_unix_port,
3945
connect_flag | CLIENT_MULTI_STATEMENTS))
4043
(mysql_errno(&mysql) != CR_CONN_HOST_ERROR &&
4044
mysql_errno(&mysql) != CR_CONNECTION_ERROR))
3948
(mysql_errno(&mysql) != CR_CONN_HOST_ERROR &&
3949
mysql_errno(&mysql) != CR_CONNECTION_ERROR))
4046
3951
(void) put_error(&mysql);
4047
3952
(void) fflush(stdout);
4443
4343
strmov(strend(buff),")");
4446
static const char* construct_prompt()
4346
static const char * construct_prompt()
4448
processed_prompt.free(); // Erase the old prompt
4449
time_t lclock = time(NULL); // Get the date struct
4348
// Erase the old prompt
4349
assert(processed_prompt!=NULL);
4350
g_string_truncate(processed_prompt, 0);
4352
// Get the date struct
4353
time_t lclock = time(NULL);
4450
4354
struct tm *t = localtime(&lclock);
4452
4356
/* parse thru the settings for the prompt */
4453
for (char *c = current_prompt; *c ; *c++)
4357
for (char *c= current_prompt; *c; (void)*c++)
4455
4359
if (*c != PROMPT_CHAR)
4456
processed_prompt.append(*c);
4361
g_string_append_c(processed_prompt, c[0]);
4367
char* dateTime= NULL;
4459
4368
switch (*++c) {
4461
c--; // stop it from going beyond if ends with %
4370
// stop it from going beyond if ends with %
4464
add_int_to_prompt(++prompt_counter);
4374
add_int_to_prompt(++prompt_counter);
4468
processed_prompt.append(mysql_get_server_info(&mysql));
4470
processed_prompt.append("not_connected");
4378
g_string_append(processed_prompt, mysql_get_server_info(&mysql));
4380
g_string_append(processed_prompt, "not_connected");
4473
processed_prompt.append(current_db ? current_db : "(none)");
4383
g_string_append(processed_prompt, current_db ? current_db : "(none)");
4478
prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
4479
if (strstr(prompt, "Localhost"))
4480
processed_prompt.append("localhost");
4483
const char *end=strcend(prompt,' ');
4484
processed_prompt.append(prompt, (uint) (end-prompt));
4388
prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
4389
if (strstr(prompt, "Localhost"))
4390
g_string_append(processed_prompt, "localhost");
4393
const char *end=strcend(prompt,' ');
4394
g_string_append_len(processed_prompt, prompt, (gssize) (end-prompt));
4490
#ifndef EMBEDDED_LIBRARY
4493
processed_prompt.append("not_connected");
4402
g_string_append(processed_prompt, "not_connected");
4497
const char *host_info = mysql_get_host_info(&mysql);
4498
if (strstr(host_info, "memory"))
4500
processed_prompt.append( mysql.host );
4502
else if (strstr(host_info,"TCP/IP") ||
4504
add_int_to_prompt(mysql.port);
4507
char *pos=strrchr(mysql.unix_socket,'/');
4508
processed_prompt.append(pos ? pos+1 : mysql.unix_socket);
4406
const char *host_info = mysql_get_host_info(&mysql);
4407
if (strstr(host_info, "memory"))
4409
g_string_append(processed_prompt, mysql.host );
4411
else if (strstr(host_info,"TCP/IP") ||
4413
add_int_to_prompt(mysql.port);
4416
char *pos=strrchr(mysql.unix_socket,'/');
4417
g_string_append(processed_prompt, pos ? pos+1 : mysql.unix_socket);
4516
processed_prompt.append(full_username ? full_username :
4517
(current_user ? current_user : "(unknown)"));
4424
g_string_append(processed_prompt, full_username ? full_username :
4425
(current_user ? current_user : "(unknown)"));
4522
processed_prompt.append(part_username ? part_username :
4523
(current_user ? current_user : "(unknown)"));
4430
g_string_append(processed_prompt, part_username ? part_username :
4431
(current_user ? current_user : "(unknown)"));
4525
4433
case PROMPT_CHAR:
4526
processed_prompt.append(PROMPT_CHAR);
4434
g_string_append_c(processed_prompt, PROMPT_CHAR);
4529
processed_prompt.append('\n');
4437
g_string_append_c(processed_prompt, '\n');
4533
processed_prompt.append(' ');
4441
g_string_append_c(processed_prompt, ' ');
4536
if (t->tm_hour < 10)
4537
processed_prompt.append('0');
4538
add_int_to_prompt(t->tm_hour);
4444
if (t->tm_hour < 10)
4445
g_string_append_c(processed_prompt, '0');
4446
add_int_to_prompt(t->tm_hour);
4542
getHour = t->tm_hour % 12;
4546
processed_prompt.append('0');
4547
add_int_to_prompt(getHour);
4449
getHour = t->tm_hour % 12;
4453
g_string_append_c(processed_prompt, '0');
4454
add_int_to_prompt(getHour);
4551
processed_prompt.append('0');
4552
add_int_to_prompt(t->tm_min);
4458
g_string_append_c(processed_prompt, '0');
4459
add_int_to_prompt(t->tm_min);
4556
getYear = t->tm_year % 100;
4558
processed_prompt.append('0');
4559
add_int_to_prompt(getYear);
4462
getYear = t->tm_year % 100;
4464
g_string_append_c(processed_prompt, '0');
4465
add_int_to_prompt(getYear);
4562
add_int_to_prompt(t->tm_year+1900);
4468
add_int_to_prompt(t->tm_year+1900);
4566
dateTime = ctime(&lclock);
4567
processed_prompt.append(strtok(dateTime,"\n"));
4471
dateTime = ctime(&lclock);
4472
g_string_append(processed_prompt, strtok(dateTime,"\n"));
4571
processed_prompt.append('0');
4572
add_int_to_prompt(t->tm_sec);
4476
g_string_append_c(processed_prompt, '0');
4477
add_int_to_prompt(t->tm_sec);
4575
processed_prompt.append(day_names[t->tm_wday]);
4480
g_string_append(processed_prompt, (day_names[t->tm_wday]));
4578
processed_prompt.append(t->tm_hour < 12 ? "am" : "pm");
4483
g_string_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4581
add_int_to_prompt(t->tm_mon+1);
4486
add_int_to_prompt(t->tm_mon+1);
4584
processed_prompt.append(month_names[t->tm_mon]);
4489
g_string_append(processed_prompt, month_names[t->tm_mon]);
4587
processed_prompt.append("'");
4492
g_string_append(processed_prompt, "'");
4590
processed_prompt.append('"');
4495
g_string_append_c(processed_prompt, '"');
4593
processed_prompt.append(';');
4498
g_string_append_c(processed_prompt, ';');
4596
processed_prompt.append('\t');
4501
g_string_append_c(processed_prompt, '\t');
4599
processed_prompt.append(delimiter_str);
4504
g_string_append(processed_prompt, delimiter_str);
4602
processed_prompt.append(c);
4507
g_string_append(processed_prompt, c);
4606
processed_prompt.append('\0');
4607
return processed_prompt.ptr();
4511
// TODO: Is this needed with GString?
4512
g_string_append_c(processed_prompt, '\0');
4513
return processed_prompt->str;
4625
4531
(result=mysql_use_result(&mysql)))
4627
4533
MYSQL_ROW cur=mysql_fetch_row(result);
4628
full_username=my_strdup(cur[0],MYF(MY_WME));
4629
part_username=my_strdup(strtok(cur[0],"@"),MYF(MY_WME));
4534
full_username=g_strdup(cur[0]);
4535
part_username=g_strdup(strtok(cur[0],"@"));
4630
4536
(void) mysql_fetch_row(result); // Read eof
4634
static int com_prompt(String *buffer __attribute__((__unused__)), char *line)
4540
static int com_prompt(GString *buffer __attribute__((__unused__)), char *line)
4636
4542
char *ptr=strchr(line, ' ');
4637
4543
prompt_counter = 0;
4638
4544
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
4639
current_prompt=my_strdup(ptr ? ptr+1 : default_prompt,MYF(MY_WME));
4545
current_prompt=g_strdup(ptr ? ptr+1 : default_prompt->str);
4641
tee_fprintf(stdout, "Returning to default PROMPT of %s\n", default_prompt);
4547
tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4548
default_prompt->str);
4643
4550
tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4647
#ifndef EMBEDDED_LIBRARY
4648
/* Keep sql_string library happy */
4650
void *sql_alloc(size_t Size)
4652
return my_malloc(Size,MYF(MY_WME));
4655
void sql_element_free(void *ptr)
4657
my_free(ptr,MYF(0));
4659
#endif /* EMBEDDED_LIBRARY */