38 #include <libdrizzle-2.0/libdrizzle.h>
40 #include "server_detect.h"
41 #include "get_password.h"
43 #include <boost/date_time/posix_time/posix_time.hpp>
47 #include <drizzled/gettext.h>
57 #include <client/linebuffer.h>
59 #include <sys/ioctl.h>
60 #include <drizzled/configmake.h>
61 #include <drizzled/utf8/utf8.h>
64 #if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
72 #if defined(HAVE_TERMIOS_H)
75 #elif defined(HAVE_TERMBITS_H)
77 #elif defined(HAVE_ASM_TERMBITS_H) && (!defined __GLIBC__ || !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ > 0))
78 #include <asm/termbits.h>
80 #if defined(HAVE_TERMCAP_H)
86 #undef SYSV // hack to avoid syntax error
93 #ifdef HAVE_LIBREADLINE
94 # if defined(HAVE_READLINE_READLINE_H)
95 # include <readline/readline.h>
96 # elif defined(HAVE_READLINE_H)
97 # include <readline.h>
99 extern char *readline ();
101 char *cmdline = NULL;
104 # error Readline Required
107 #ifdef HAVE_READLINE_HISTORY
108 # if defined(HAVE_READLINE_HISTORY_H)
109 # include <readline/history.h>
110 # elif defined(HAVE_HISTORY_H)
111 # include <history.h>
113 extern void add_history ();
114 extern int write_history ();
115 extern int read_history ();
123 #ifndef HAVE_RL_COMPLETION
124 typedef char **rl_completion_func_t(
const char *,
int,
int);
125 #define rl_completion_matches(str, func) \
126 completion_matches((char *)str, (CPFunction *)func)
129 #ifdef HAVE_RL_COMPENTRY
130 # ifdef HAVE_WORKING_RL_COMPENTRY
143 #if defined(HAVE_LOCALE_H)
149 #if !defined(HAVE_VIDATTR)
151 #define vidattr(A) {} // Can't get this to work
153 #include <boost/program_options.hpp>
154 #include <boost/scoped_ptr.hpp>
155 #include <drizzled/program_options/config_file.h>
157 #include "user_detect.h"
160 namespace po=boost::program_options;
164 const uint32_t MAX_COLUMN_LENGTH= 1024;
167 const int MAX_SERVER_VERSION_LENGTH= 128;
170 drizzle_con_options_t global_con_options= DRIZZLE_CON_NONE;
172 #define PROMPT_CHAR '\\'
178 Status(
int in_exit_status,
179 uint32_t in_query_start_line,
183 bool in_add_to_history)
185 exit_status(in_exit_status),
186 query_start_line(in_query_start_line),
187 file_name(in_file_name),
188 line_buff(in_line_buff),
190 add_to_history(in_add_to_history)
199 add_to_history(
false)
202 int getExitStatus()
const
207 uint32_t getQueryStartLine()
const
209 return query_start_line;
212 const char *getFileName()
const
222 bool getBatch()
const
227 bool getAddToHistory()
const
229 return add_to_history;
232 void setExitStatus(
int in_exit_status)
234 exit_status= in_exit_status;
237 void setQueryStartLine(uint32_t in_query_start_line)
239 query_start_line= in_query_start_line;
242 void setFileName(
char *in_file_name)
244 file_name= in_file_name;
247 void setLineBuff(
int max_size, FILE *file=NULL)
254 line_buff= in_line_buff;
257 void setBatch(
bool in_batch)
262 void setAddToHistory(
bool in_add_to_history)
264 add_to_history= in_add_to_history;
269 uint32_t query_start_line;
272 bool batch,add_to_history;
275 static map<string, string>::iterator completion_iter;
276 static map<string, string>::iterator completion_end;
277 static map<string, string> completion_map;
278 static string completion_string;
281 enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
282 typedef enum enum_info_type INFO_TYPE;
284 static drizzle_st *drizzle= NULL;
285 static drizzle_con_st *con= NULL;
286 static bool ignore_errors=
false, quick=
false,
287 connected=
false, opt_raw_data=
false, unbuffered=
false,
288 output_tables=
false, opt_rehash=
true, skip_updates=
false,
289 safe_updates=
false, one_database=
false,
290 opt_shutdown=
false, opt_ping=
false,
291 vertical=
false, line_numbers=
true, column_names=
true,
292 opt_nopager=
true, opt_outfile=
false, named_cmds=
false,
293 opt_nobeep=
false, opt_reconnect=
true,
294 opt_secure_auth=
false,
295 default_pager_set=
false, opt_sigint_ignore=
false,
296 auto_vertical_output=
false,
297 show_warnings=
false, executing_query=
false, interrupted_query=
false,
298 use_drizzle_protocol=
false, opt_local_infile;
299 static uint32_t opt_kill= 0;
300 static uint32_t show_progress_size= 0;
301 static bool column_types_flag;
302 static bool preserve_comments=
false;
303 static uint32_t opt_max_input_line;
304 static uint32_t opt_drizzle_port= 0;
305 static int opt_silent, verbose= 0;
306 static char *histfile;
307 static char *histfile_tmp;
308 static string *glob_buffer;
309 static string *processed_prompt= NULL;
310 static char *default_prompt= NULL;
311 static char *full_username= NULL,*part_username= NULL;
313 static uint32_t select_limit;
314 static uint32_t max_join_size;
315 static uint32_t opt_connect_timeout= 0;
316 static ServerDetect::server_type server_type= ServerDetect::SERVER_UNKNOWN_FOUND;
317 std::string current_db,
327 static std::string socket_file;
352 static const char* get_month_name(
int month)
386 #define FN_REFLEN 512
388 static string default_pager(
"");
389 static string pager(
"");
390 static string outfile(
"");
391 static FILE *PAGER, *OUTFILE;
392 static uint32_t prompt_counter;
393 static const char *delimiter= NULL;
394 static uint32_t delimiter_length= 1;
395 unsigned short terminal_width= 80;
397 int drizzleclient_real_query_for_lazy(
const char *buf,
size_t length, drizzle_result_st *result, uint32_t *error_code);
398 int drizzleclient_store_result_for_lazy(drizzle_result_st *result);
400 void tee_fprintf(FILE *file,
const char *fmt, ...);
401 void tee_fputs(
const char *s, FILE *file);
402 void tee_puts(
const char *s, FILE *file);
403 void tee_putc(
int c, FILE *file);
404 static void tee_print_sized_data(
const char *,
unsigned int,
unsigned int,
bool);
406 static int process_options(
void);
407 static int com_quit(
string *str,
const char*),
408 com_go(
string *str,
const char*), com_ego(
string *str,
const char*),
409 com_print(
string *str,
const char*),
410 com_help(
string *str,
const char*), com_clear(
string *str,
const char*),
411 com_connect(
string *str,
const char*), com_status(
string *str,
const char*),
412 com_use(
string *str,
const char*), com_source(
string *str,
const char*),
413 com_shutdown(
string *str,
const char*),
414 com_rehash(
string *str,
const char*), com_tee(
string *str,
const char*),
415 com_notee(
string *str,
const char*),
416 com_prompt(
string *str,
const char*), com_delimiter(
string *str,
const char*),
417 com_warnings(
string *str,
const char*), com_nowarnings(
string *str,
const char*),
418 com_nopager(
string *str,
const char*), com_pager(
string *str,
const char*);
420 static int read_and_execute(
bool interactive);
421 static int sql_connect(
const string &host,
const string &database,
const string &user,
const string &password);
422 static const char *server_version_string(drizzle_con_st *con);
423 static int put_info(
const char *str,INFO_TYPE info,uint32_t error,
424 const char *sql_state);
425 static int put_error(drizzle_con_st *con, drizzle_result_st *res);
426 static void safe_put_field(
const char *pos,uint32_t length);
427 static void init_pager(
void);
428 static void end_pager(
void);
429 static void init_tee(
const char *);
430 static void end_tee(
void);
431 static const char* construct_prompt(
void);
432 static char *get_arg(
char *line,
bool get_next_arg);
433 static void init_username(
void);
434 static void add_int_to_prompt(
int toadd);
435 static int get_result_width(drizzle_result_st *res);
436 static int get_field_disp_length(drizzle_column_st * field);
437 static const char * strcont(
const char *str,
const char *set);
449 int (*in_func)(
string *str,
const char *name),
450 bool in_takes_params,
451 const char *in_doc) :
453 cmd_char(in_cmd_char),
455 takes_params(in_takes_params),
467 int (*func)(
string *str,
const char *);
469 const char *getName()
const
474 char getCmdChar()
const
479 bool getTakesParams()
const
484 const char *getDoc()
const
489 void setName(
const char *in_name)
494 void setCmdChar(
char in_cmd_char)
496 cmd_char= in_cmd_char;
499 void setTakesParams(
bool in_takes_params)
501 takes_params= in_takes_params;
504 void setDoc(
const char *in_doc)
516 Commands(
"?",
'?', com_help, 0, N_(
"Synonym for `help'.") ),
517 Commands(
"clear",
'c', com_clear, 0, N_(
"Clear command.")),
518 Commands(
"connect",
'r', com_connect,1,
519 N_(
"Reconnect to the server. Optional arguments are db and host.")),
520 Commands(
"delimiter",
'd', com_delimiter, 1,
521 N_(
"Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.") ),
523 N_(
"Send command to drizzle server, display result vertically.")),
524 Commands(
"exit",
'q', com_quit, 0, N_(
"Exit drizzle. Same as quit.")),
525 Commands(
"go",
'g', com_go, 0, N_(
"Send command to drizzle server.") ),
526 Commands(
"help",
'h', com_help, 0, N_(
"Display this help.") ),
527 Commands(
"nopager",
'n', com_nopager,0, N_(
"Disable pager, print to stdout.") ),
528 Commands(
"notee",
't', com_notee, 0, N_(
"Don't write into outfile.") ),
529 Commands(
"pager",
'P', com_pager, 1,
530 N_(
"Set PAGER [to_pager]. Print the query results via PAGER.") ),
531 Commands(
"print",
'p', com_print, 0, N_(
"Print current command.") ),
532 Commands(
"prompt",
'R', com_prompt, 1, N_(
"Change your drizzle prompt.")),
533 Commands(
"quit",
'q', com_quit, 0, N_(
"Quit drizzle.") ),
534 Commands(
"rehash",
'#', com_rehash, 0, N_(
"Rebuild completion hash.") ),
535 Commands(
"source",
'.', com_source, 1,
536 N_(
"Execute an SQL script file. Takes a file name as an argument.")),
537 Commands(
"status",
's', com_status, 0, N_(
"Get status information from the server.")),
539 N_(
"Set outfile [to_outfile]. Append everything into given outfile.") ),
541 N_(
"Use another schema. Takes schema name as argument.") ),
542 Commands(
"shutdown",
'Q', com_shutdown,
false,
543 N_(
"Shutdown the instance you are connected too.") ),
544 Commands(
"warnings",
'W', com_warnings,
false,
545 N_(
"Show warnings after every statement.") ),
546 Commands(
"nowarning",
'w', com_nowarnings, 0,
547 N_(
"Don't show warnings after every statement.") ),
549 Commands(
"create table", 0, 0, 0,
""),
550 Commands(
"create database", 0, 0, 0,
""),
551 Commands(
"show databases", 0, 0, 0,
""),
552 Commands(
"show fields from", 0, 0, 0,
""),
553 Commands(
"show keys from", 0, 0, 0,
""),
554 Commands(
"show tables", 0, 0, 0,
""),
555 Commands(
"load data from", 0, 0, 0,
""),
556 Commands(
"alter table", 0, 0, 0,
""),
557 Commands(
"set option", 0, 0, 0,
""),
558 Commands(
"lock tables", 0, 0, 0,
""),
559 Commands(
"unlock tables", 0, 0, 0,
""),
565 Commands(
"AGGREGATE", 0, 0, 0,
""),
567 Commands(
"ALGORITHM", 0, 0, 0,
""),
575 Commands(
"ASENSITIVE", 0, 0, 0,
""),
576 Commands(
"AUTO_INCREMENT", 0, 0, 0,
""),
578 Commands(
"AVG_ROW_LENGTH", 0, 0, 0,
""),
601 Commands(
"CHARACTER", 0, 0, 0,
""),
607 Commands(
"COLLATION", 0, 0, 0,
""),
612 Commands(
"COMMITTED", 0, 0, 0,
""),
614 Commands(
"COMPRESSED", 0, 0, 0,
""),
615 Commands(
"CONCURRENT", 0, 0, 0,
""),
616 Commands(
"CONDITION", 0, 0, 0,
""),
617 Commands(
"CONNECTION", 0, 0, 0,
""),
618 Commands(
"CONSISTENT", 0, 0, 0,
""),
619 Commands(
"CONSTRAINT", 0, 0, 0,
""),
626 Commands(
"CURRENT_DATE", 0, 0, 0,
""),
627 Commands(
"CURRENT_TIMESTAMP", 0, 0, 0,
""),
628 Commands(
"CURRENT_USER", 0, 0, 0,
""),
632 Commands(
"DATABASES", 0, 0, 0,
""),
637 Commands(
"DAY_MICROSECOND", 0, 0, 0,
""),
638 Commands(
"DAY_MINUTE", 0, 0, 0,
""),
639 Commands(
"DAY_SECOND", 0, 0, 0,
""),
640 Commands(
"DEALLOCATE", 0, 0, 0,
""),
650 Commands(
"DETERMINISTIC", 0, 0, 0,
""),
654 Commands(
"DISTINCTROW", 0, 0, 0,
""),
659 Commands(
"DUPLICATE", 0, 0, 0,
""),
692 Commands(
"FRAC_SECOND", 0, 0, 0,
""),
704 Commands(
"HIGH_PRIORITY", 0, 0, 0,
""),
707 Commands(
"HOUR_MICROSECOND", 0, 0, 0,
""),
708 Commands(
"HOUR_MINUTE", 0, 0, 0,
""),
709 Commands(
"HOUR_SECOND", 0, 0, 0,
""),
710 Commands(
"IDENTIFIED", 0, 0, 0,
""),
722 Commands(
"INSENSITIVE", 0, 0, 0,
""),
724 Commands(
"INSERT_METHOD", 0, 0, 0,
""),
734 Commands(
"IO_THREAD", 0, 0, 0,
""),
736 Commands(
"ISOLATION", 0, 0, 0,
""),
754 Commands(
"LINESTRING", 0, 0, 0,
""),
757 Commands(
"LOCALTIMESTAMP", 0, 0, 0,
""),
764 Commands(
"MAX_CONNECTIONS_PER_HOUR", 0, 0, 0,
""),
765 Commands(
"MAX_QUERIES_PER_HOUR", 0, 0, 0,
""),
767 Commands(
"MAX_UPDATES_PER_HOUR", 0, 0, 0,
""),
768 Commands(
"MAX_USER_CONNECTIONS", 0, 0, 0,
""),
771 Commands(
"MICROSECOND", 0, 0, 0,
""),
774 Commands(
"MINUTE_MICROSECOND", 0, 0, 0,
""),
775 Commands(
"MINUTE_SECOND", 0, 0, 0,
""),
782 Commands(
"MULTILINESTRING", 0, 0, 0,
""),
783 Commands(
"MULTIPOINT", 0, 0, 0,
""),
784 Commands(
"MULTIPOLYGON", 0, 0, 0,
""),
806 Commands(
"OPTIONALLY", 0, 0, 0,
""),
812 Commands(
"PACK_KEYS", 0, 0, 0,
""),
816 Commands(
"PRECISION", 0, 0, 0,
""),
820 Commands(
"PRIVILEGES", 0, 0, 0,
""),
821 Commands(
"PROCEDURE", 0, 0, 0,
""),
823 Commands(
"PROCESSLIST", 0, 0, 0,
""),
832 Commands(
"REDUNDANT", 0, 0, 0,
""),
833 Commands(
"REFERENCES", 0, 0, 0,
""),
839 Commands(
"REPEATABLE", 0, 0, 0,
""),
857 Commands(
"ROW_FORMAT", 0, 0, 0,
""),
859 Commands(
"SAVEPOINT", 0, 0, 0,
""),
863 Commands(
"SECOND_MICROSECOND", 0, 0, 0,
""),
866 Commands(
"SENSITIVE", 0, 0, 0,
""),
867 Commands(
"SEPARATOR", 0, 0, 0,
""),
869 Commands(
"SERIALIZABLE", 0, 0, 0,
""),
885 Commands(
"SQLEXCEPTION", 0, 0, 0,
""),
887 Commands(
"SQLWARNING", 0, 0, 0,
""),
888 Commands(
"SQL_BIG_RESULT", 0, 0, 0,
""),
889 Commands(
"SQL_BUFFER_RESULT", 0, 0, 0,
""),
890 Commands(
"SQL_CACHE", 0, 0, 0,
""),
891 Commands(
"SQL_CALC_FOUND_ROWS", 0, 0, 0,
""),
892 Commands(
"SQL_NO_CACHE", 0, 0, 0,
""),
893 Commands(
"SQL_SMALL_RESULT", 0, 0, 0,
""),
894 Commands(
"SQL_THREAD", 0, 0, 0,
""),
895 Commands(
"SQL_TSI_FRAC_SECOND", 0, 0, 0,
""),
896 Commands(
"SQL_TSI_SECOND", 0, 0, 0,
""),
897 Commands(
"SQL_TSI_MINUTE", 0, 0, 0,
""),
898 Commands(
"SQL_TSI_HOUR", 0, 0, 0,
""),
899 Commands(
"SQL_TSI_DAY", 0, 0, 0,
""),
900 Commands(
"SQL_TSI_WEEK", 0, 0, 0,
""),
901 Commands(
"SQL_TSI_MONTH", 0, 0, 0,
""),
902 Commands(
"SQL_TSI_QUARTER", 0, 0, 0,
""),
903 Commands(
"SQL_TSI_YEAR", 0, 0, 0,
""),
910 Commands(
"STRAIGHT_JOIN", 0, 0, 0,
""),
918 Commands(
"TABLESPACE", 0, 0, 0,
""),
919 Commands(
"TEMPORARY", 0, 0, 0,
""),
920 Commands(
"TEMPTABLE", 0, 0, 0,
""),
921 Commands(
"TERMINATED", 0, 0, 0,
""),
924 Commands(
"TIMESTAMP", 0, 0, 0,
""),
925 Commands(
"TIMESTAMPADD", 0, 0, 0,
""),
926 Commands(
"TIMESTAMPDIFF", 0, 0, 0,
""),
929 Commands(
"TRANSACTION", 0, 0, 0,
""),
934 Commands(
"UNCOMMITTED", 0, 0, 0,
""),
935 Commands(
"UNDEFINED", 0, 0, 0,
""),
948 Commands(
"USER_RESOURCES", 0, 0, 0,
""),
951 Commands(
"UTC_TIMESTAMP", 0, 0, 0,
""),
954 Commands(
"VARBINARY", 0, 0, 0,
""),
956 Commands(
"VARCHARACTER", 0, 0, 0,
""),
957 Commands(
"VARIABLES", 0, 0, 0,
""),
971 Commands(
"YEAR_MONTH", 0, 0, 0,
""),
982 Commands(
"BENCHMARK", 0, 0, 0,
""),
991 Commands(
"CHAR_LENGTH", 0, 0, 0,
""),
992 Commands(
"CHARACTER_LENGTH", 0, 0, 0,
""),
994 Commands(
"COERCIBILITY", 0, 0, 0,
""),
997 Commands(
"CONCAT_WS", 0, 0, 0,
""),
998 Commands(
"CONNECTION_ID", 0, 0, 0,
""),
1000 Commands(
"CONVERT_TZ", 0, 0, 0,
""),
1007 Commands(
"DATE_ADD", 0, 0, 0,
""),
1008 Commands(
"DATEDIFF", 0, 0, 0,
""),
1009 Commands(
"DATE_FORMAT", 0, 0, 0,
""),
1010 Commands(
"DATE_SUB", 0, 0, 0,
""),
1012 Commands(
"DAYOFMONTH", 0, 0, 0,
""),
1013 Commands(
"DAYOFWEEK", 0, 0, 0,
""),
1014 Commands(
"DAYOFYEAR", 0, 0, 0,
""),
1017 Commands(
"DES_ENCRYPT", 0, 0, 0,
""),
1018 Commands(
"DES_DECRYPT", 0, 0, 0,
""),
1019 Commands(
"DIMENSION", 0, 0, 0,
""),
1020 Commands(
"DISJOINT", 0, 0, 0,
""),
1024 Commands(
"ENDPOINT", 0, 0, 0,
""),
1025 Commands(
"ENVELOPE", 0, 0, 0,
""),
1027 Commands(
"EXTERIORRING", 0, 0, 0,
""),
1030 Commands(
"EXPORT_SET", 0, 0, 0,
""),
1032 Commands(
"FIND_IN_SET", 0, 0, 0,
""),
1035 Commands(
"FOUND_ROWS", 0, 0, 0,
""),
1036 Commands(
"FROM_DAYS", 0, 0, 0,
""),
1037 Commands(
"FROM_UNIXTIME", 0, 0, 0,
""),
1038 Commands(
"GET_LOCK", 0, 0, 0,
""),
1040 Commands(
"GREATEST", 0, 0, 0,
""),
1041 Commands(
"GROUP_CONCAT", 0, 0, 0,
""),
1042 Commands(
"GROUP_UNIQUE_USERS", 0, 0, 0,
""),
1046 Commands(
"INTERIORRINGN", 0, 0, 0,
""),
1047 Commands(
"INTERSECTS", 0, 0, 0,
""),
1048 Commands(
"ISCLOSED", 0, 0, 0,
""),
1051 Commands(
"IS_FREE_LOCK", 0, 0, 0,
""),
1052 Commands(
"IS_USED_LOCK", 0, 0, 0,
""),
1053 Commands(
"LAST_INSERT_ID", 0, 0, 0,
""),
1054 Commands(
"ISSIMPLE", 0, 0, 0,
""),
1055 Commands(
"LAST_DAY", 0, 0, 0,
""),
1060 Commands(
"LOAD_FILE", 0, 0, 0,
""),
1068 Commands(
"MAKE_SET", 0, 0, 0,
""),
1069 Commands(
"MAKEDATE", 0, 0, 0,
""),
1070 Commands(
"MASTER_POS_WAIT", 0, 0, 0,
""),
1072 Commands(
"MBRCONTAINS", 0, 0, 0,
""),
1073 Commands(
"MBRDISJOINT", 0, 0, 0,
""),
1074 Commands(
"MBREQUAL", 0, 0, 0,
""),
1075 Commands(
"MBRINTERSECTS", 0, 0, 0,
""),
1076 Commands(
"MBROVERLAPS", 0, 0, 0,
""),
1077 Commands(
"MBRTOUCHES", 0, 0, 0,
""),
1078 Commands(
"MBRWITHIN", 0, 0, 0,
""),
1082 Commands(
"MONTHNAME", 0, 0, 0,
""),
1083 Commands(
"NAME_CONST", 0, 0, 0,
""),
1086 Commands(
"NUMPOINTS", 0, 0, 0,
""),
1087 Commands(
"OCTET_LENGTH", 0, 0, 0,
""),
1090 Commands(
"OVERLAPS", 0, 0, 0,
""),
1091 Commands(
"PERIOD_ADD", 0, 0, 0,
""),
1092 Commands(
"PERIOD_DIFF", 0, 0, 0,
""),
1095 Commands(
"POSITION", 0, 0, 0,
""),
1101 Commands(
"RELEASE_LOCK", 0, 0, 0,
""),
1104 Commands(
"ROW_COUNT", 0, 0, 0,
""),
1107 Commands(
"SESSION_USER", 0, 0, 0,
""),
1118 Commands(
"STARTPOINT", 0, 0, 0,
""),
1121 Commands(
"STDDEV_POP", 0, 0, 0,
""),
1122 Commands(
"STDDEV_SAMP", 0, 0, 0,
""),
1123 Commands(
"STR_TO_DATE", 0, 0, 0,
""),
1126 Commands(
"SUBSTRING", 0, 0, 0,
""),
1127 Commands(
"SUBSTRING_INDEX", 0, 0, 0,
""),
1130 Commands(
"SYSTEM_USER", 0, 0, 0,
""),
1132 Commands(
"TIME_FORMAT", 0, 0, 0,
""),
1137 Commands(
"UNCOMPRESS", 0, 0, 0,
""),
1138 Commands(
"UNCOMPRESSED_LENGTH", 0, 0, 0,
""),
1140 Commands(
"UNIQUE_USERS", 0, 0, 0,
""),
1141 Commands(
"UNIX_TIMESTAMP", 0, 0, 0,
""),
1144 Commands(
"VARIANCE", 0, 0, 0,
""),
1146 Commands(
"VAR_SAMP", 0, 0, 0,
""),
1149 Commands(
"WEEKOFYEAR", 0, 0, 0,
""),
1153 Commands(
"YEARWEEK", 0, 0, 0,
""),
1155 Commands((
char *)NULL, 0, 0, 0,
"")
1160 static int not_in_history(
const char *line);
1161 static void initialize_readline (
char *name);
1162 static void fix_history(
string *final_command);
1164 static Commands *find_command(
const char *name,
char cmd_name);
1165 static bool add_line(
string *buffer,
char *line,
char *in_string,
1167 static void remove_cntrl(
string *buffer);
1168 static void print_table_data(drizzle_result_st *result);
1169 static void print_tab_data(drizzle_result_st *result);
1170 static void print_table_data_vertically(drizzle_result_st *result);
1171 static void print_warnings(uint32_t error_code);
1172 static boost::posix_time::ptime start_timer(
void);
1173 static void end_timer(boost::posix_time::ptime,
string &buff);
1174 static void drizzle_end_timer(boost::posix_time::ptime,
string &buff);
1175 static void nice_time(boost::posix_time::time_duration duration,
string &buff);
1176 extern "C" void drizzle_end(
int sig);
1177 extern "C" void handle_sigint(
int sig);
1178 #if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1179 static void window_resize(
int sig);
1190 static bool server_shutdown(
void)
1192 drizzle_result_st result;
1196 printf(_(
"shutting down drizzled"));
1197 if (opt_drizzle_port > 0)
1199 printf(_(
" on port %d"), opt_drizzle_port);
1204 drizzle_return_t ret;
1205 if (drizzle_shutdown(con, &result, DRIZZLE_SHUTDOWN_DEFAULT, &ret) == NULL or
1206 ret != DRIZZLE_RETURN_OK)
1208 if (ret == DRIZZLE_RETURN_ERROR_CODE)
1210 fprintf(stderr, _(
"shutdown failed; error: '%s'"), drizzle_result_error(&result));
1211 drizzle_result_free(&result);
1215 fprintf(stderr, _(
"shutdown failed; error: '%s'"), drizzle_con_error(con));
1220 drizzle_result_free(&result);
1224 printf(_(
"done\n"));
1230 static bool kill_query(uint32_t query_id)
1232 drizzle_result_st result;
1233 drizzle_return_t ret;
1237 printf(_(
"killing query %u"), query_id);
1241 if (drizzle_kill(con, &result, query_id,
1242 &ret) == NULL || ret != DRIZZLE_RETURN_OK)
1244 if (ret == DRIZZLE_RETURN_ERROR_CODE)
1246 fprintf(stderr, _(
"kill failed; error: '%s'"),
1247 drizzle_result_error(&result));
1248 drizzle_result_free(&result);
1252 fprintf(stderr, _(
"kill failed; error: '%s'"), drizzle_con_error(con));
1257 drizzle_result_free(&result);
1260 printf(_(
"done\n"));
1273 static bool server_ping(
void)
1275 drizzle_result_st result;
1276 drizzle_return_t ret;
1278 if (drizzle_ping(con, &result, &ret) != NULL && ret == DRIZZLE_RETURN_OK)
1281 printf(_(
"drizzled is alive\n"));
1285 if (ret == DRIZZLE_RETURN_ERROR_CODE)
1287 fprintf(stderr, _(
"ping failed; error: '%s'"),
1288 drizzle_result_error(&result));
1289 drizzle_result_free(&result);
1293 fprintf(stderr, _(
"drizzled won't answer to ping, error: '%s'"), drizzle_con_error(con));
1297 drizzle_result_free(&result);
1315 static bool execute_commands(
int *error)
1317 bool executed=
false;
1322 if (server_ping() ==
false)
1329 if (server_shutdown() ==
false)
1336 if (kill_query(opt_kill) ==
false)
1346 static void check_timeout_value(uint32_t in_connect_timeout)
1348 opt_connect_timeout= 0;
1349 if (in_connect_timeout > 3600*12)
1351 cout << _(
"Error: Invalid Value for connect_timeout");
1354 opt_connect_timeout= in_connect_timeout;
1357 static void check_max_input_line(uint32_t in_max_input_line)
1359 opt_max_input_line= 0;
1360 if (in_max_input_line < 4096 || in_max_input_line > (int64_t)2*1024L*1024L*1024L)
1362 cout << _(
"Error: Invalid Value for max_input_line");
1365 opt_max_input_line= in_max_input_line - (in_max_input_line % 1024);
1368 int main(
int argc,
char *argv[])
1373 #if defined(ENABLE_NLS)
1374 # if defined(HAVE_LOCALE_H)
1375 setlocale(LC_ALL,
"");
1377 bindtextdomain(
"drizzle", LOCALEDIR);
1378 textdomain(
"drizzle");
1381 po::options_description commandline_options(_(
"Options used only in command line"));
1382 commandline_options.add_options()
1383 (
"help,?",_(
"Displays this help and exit."))
1384 (
"batch,B",_(
"Don't use history file. Disable interactive behavior. (Enables --silent)"))
1385 (
"column-type-info", po::value<bool>(&column_types_flag)->default_value(
false)->zero_tokens(),
1386 _(
"Display column type information."))
1387 (
"comments,c", po::value<bool>(&preserve_comments)->default_value(
false)->zero_tokens(),
1388 _(
"Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"))
1389 (
"vertical,E", po::value<bool>(&vertical)->default_value(
false)->zero_tokens(),
1390 _(
"Print the output of a query (rows) vertically."))
1391 (
"force,f", po::value<bool>(&ignore_errors)->default_value(
false)->zero_tokens(),
1392 _(
"Continue even if we get an sql error."))
1393 (
"named-commands,G", po::value<bool>(&named_cmds)->default_value(
false)->zero_tokens(),
1394 _(
"Enable named commands. Named commands mean this program's internal commands; see drizzle> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter."))
1395 (
"no-beep,b", po::value<bool>(&opt_nobeep)->default_value(
false)->zero_tokens(),
1396 _(
"Turn off beep on error."))
1397 (
"disable-line-numbers", _(
"Do not write line numbers for errors."))
1398 (
"disable-column-names", _(
"Do not write column names in results."))
1399 (
"skip-column-names,N",
1400 _(
"Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
1401 (
"set-variable,O", po::value<string>(),
1402 _(
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."))
1403 (
"table,t", po::value<bool>(&output_tables)->default_value(
false)->zero_tokens(),
1404 _(
"Output in table format."))
1405 (
"safe-updates,U", po::value<bool>(&safe_updates)->default_value(
false)->zero_tokens(),
1406 _(
"Only allow UPDATE and DELETE that uses keys."))
1407 (
"i-am-a-dummy,U", po::value<bool>(&safe_updates)->default_value(
false)->zero_tokens(),
1408 _(
"Synonym for option --safe-updates, -U."))
1409 (
"verbose,v", po::value<string>(&opt_verbose)->default_value(
""),
1410 _(
"-v vvv implies that verbose= 3, Used to specify verbose"))
1411 (
"version,V", _(
"Output version information and exit."))
1412 (
"secure-auth", po::value<bool>(&opt_secure_auth)->default_value(
false)->zero_tokens(),
1413 _(
"Refuse client connecting to server if it uses old (pre-4.1.1) protocol"))
1414 (
"show-warnings", po::value<bool>(&show_warnings)->default_value(
false)->zero_tokens(),
1415 _(
"Show warnings after every statement."))
1416 (
"show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(0),
1417 _(
"Number of lines before each import progress report."))
1418 (
"ping", po::value<bool>(&opt_ping)->default_value(
false)->zero_tokens(),
1419 _(
"Ping the server to check if it's alive."))
1420 (
"no-defaults", po::value<bool>()->default_value(
false)->zero_tokens(),
1421 _(
"Configuration file defaults are not used if no-defaults is set"))
1424 po::options_description drizzle_options(_(
"Options specific to the drizzle client"));
1425 drizzle_options.add_options()
1426 (
"disable-auto-rehash,A",
1427 _(
"Disable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time."))
1428 (
"auto-vertical-output", po::value<bool>(&auto_vertical_output)->default_value(
false)->zero_tokens(),
1429 _(
"Automatically switch to vertical output mode if the result is wider than the terminal width."))
1430 (
"database,D", po::value<string>(¤t_db)->default_value(
""),
1431 _(
"Database to use."))
1432 (
"default-character-set",po::value<string>(),
1434 (
"delimiter", po::value<string>(&delimiter_str)->default_value(
";"),
1435 _(
"Delimiter to be used."))
1436 (
"execute,e", po::value<string>(),
1437 _(
"Execute command and quit. (Disables --force and history file)"))
1438 (
"local-infile", po::value<bool>(&opt_local_infile)->default_value(
false)->zero_tokens(),
1439 _(
"Enable LOAD DATA LOCAL INFILE."))
1440 (
"unbuffered,n", po::value<bool>(&unbuffered)->default_value(
false)->zero_tokens(),
1441 _(
"Flush buffer after each query."))
1442 (
"sigint-ignore", po::value<bool>(&opt_sigint_ignore)->default_value(
false)->zero_tokens(),
1443 _(
"Ignore SIGINT (CTRL-C)"))
1444 (
"one-database,o", po::value<bool>(&one_database)->default_value(
false)->zero_tokens(),
1445 _(
"Only update the default database. This is useful for skipping updates to other database in the update log."))
1446 (
"pager", po::value<string>(),
1447 _(
"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."))
1448 (
"disable-pager", po::value<bool>(&opt_nopager)->default_value(
false)->zero_tokens(),
1449 _(
"Disable pager and print to stdout. See interactive help (\\h) also."))
1450 (
"prompt", po::value<string>(¤t_prompt)->default_value(
""),
1451 _(
"Set the drizzle prompt to this value."))
1452 (
"quick,q", po::value<bool>(&quick)->default_value(
false)->zero_tokens(),
1453 _(
"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."))
1454 (
"raw,r", po::value<bool>(&opt_raw_data)->default_value(
false)->zero_tokens(),
1455 _(
"Write fields without conversion. Used with --batch."))
1456 (
"disable-reconnect", _(
"Do not reconnect if the connection is lost."))
1457 (
"shutdown", po::value<bool>()->zero_tokens(),
1458 _(
"Shutdown the server"))
1459 (
"silent,s", _(
"Be more silent. Print results with a tab as separator, each row on new line."))
1460 (
"kill", po::value<uint32_t>(&opt_kill)->default_value(0),
1461 _(
"Kill a running query."))
1462 (
"tee", po::value<string>(),
1463 _(
"Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default."))
1464 (
"disable-tee", po::value<bool>()->default_value(
false)->zero_tokens(),
1465 _(
"Disable outfile. See interactive help (\\h) also."))
1466 (
"connect-timeout", po::value<uint32_t>(&opt_connect_timeout)->default_value(0)->notifier(&check_timeout_value),
1467 _(
"Number of seconds before connection timeout."))
1468 (
"max-input-line", po::value<uint32_t>(&opt_max_input_line)->default_value(16*1024L*1024L)->notifier(&check_max_input_line),
1469 _(
"Max length of input line"))
1470 (
"select-limit", po::value<uint32_t>(&select_limit)->default_value(1000L),
1471 _(
"Automatic limit for SELECT when using --safe-updates"))
1472 (
"max-join-size", po::value<uint32_t>(&max_join_size)->default_value(1000000L),
1473 _(
"Automatic limit for rows in a join when using --safe-updates"))
1476 po::options_description client_options(_(
"Options specific to the client"));
1477 client_options.add_options()
1478 (
"host,h", po::value<string>(¤t_host)->default_value(
"localhost"),
1479 _(
"Connect to host"))
1480 (
"password,P", po::value<string>(¤t_password)->default_value(PASSWORD_SENTINEL),
1481 _(
"Socket file to use when connecting to server."))
1482 (
"socket", po::value<string>(&socket_file),
1483 _(
"Password to use when connecting to server. If password is not given it's asked from the tty."))
1484 (
"port,p", po::value<uint32_t>()->default_value(0),
1485 _(
"Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, built-in default"))
1486 (
"user,u", po::value<string>(¤t_user)->default_value(
UserDetect().getUser()),
1487 _(
"User for login if not current user."))
1488 (
"protocol",po::value<string>(&opt_protocol)->default_value(
"mysql"),
1489 _(
"The protocol of connection (mysql, mysql-plugin-auth, or drizzle)."))
1491 po::options_description long_options(_(
"Allowed Options"));
1492 long_options.add(commandline_options).add(drizzle_options).add(client_options);
1494 std::string system_config_dir_drizzle(SYSCONFDIR);
1495 system_config_dir_drizzle.append(
"/drizzle/drizzle.cnf");
1497 std::string system_config_dir_client(SYSCONFDIR);
1498 system_config_dir_client.append(
"/drizzle/client.cnf");
1500 std::string user_config_dir((getenv(
"XDG_CONFIG_HOME")? getenv(
"XDG_CONFIG_HOME"):
"~/.config"));
1502 if (user_config_dir.compare(0, 2,
"~/") == 0)
1505 homedir= getenv(
"HOME");
1506 if (homedir != NULL)
1507 user_config_dir.replace(0, 1, homedir);
1510 po::variables_map vm;
1512 po::positional_options_description p;
1513 p.add(
"database", 1);
1516 int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1518 po::store(po::command_line_parser(argc, argv).options(long_options).
1519 style(style).positional(p).extra_parser(parse_password_arg).run(),
1522 if (! vm[
"no-defaults"].as<bool>())
1524 std::string user_config_dir_drizzle(user_config_dir);
1525 user_config_dir_drizzle.append(
"/drizzle/drizzle.cnf");
1527 std::string user_config_dir_client(user_config_dir);
1528 user_config_dir_client.append(
"/drizzle/client.cnf");
1530 ifstream user_drizzle_ifs(user_config_dir_drizzle.c_str());
1531 po::store(dpo::parse_config_file(user_drizzle_ifs, drizzle_options), vm);
1533 ifstream user_client_ifs(user_config_dir_client.c_str());
1534 po::store(dpo::parse_config_file(user_client_ifs, client_options), vm);
1536 ifstream system_drizzle_ifs(system_config_dir_drizzle.c_str());
1537 store(dpo::parse_config_file(system_drizzle_ifs, drizzle_options), vm);
1539 ifstream system_client_ifs(system_config_dir_client.c_str());
1540 po::store(dpo::parse_config_file(system_client_ifs, client_options), vm);
1545 default_prompt= strdup(getenv(
"DRIZZLE_PS1") ?
1546 getenv(
"DRIZZLE_PS1") :
1548 if (default_prompt == NULL)
1550 fprintf(stderr, _(
"Memory allocation error while constructing initial "
1551 "prompt. Aborting.\n"));
1555 if (current_prompt.empty())
1556 current_prompt= strdup(default_prompt);
1558 if (current_prompt.empty())
1560 fprintf(stderr, _(
"Memory allocation error while constructing initial "
1561 "prompt. Aborting.\n"));
1564 processed_prompt=
new string();
1565 processed_prompt->reserve(32);
1571 if (
const char* tmp= getenv(
"PAGER"))
1575 default_pager_set= 1;
1579 if (not isatty(0) || not isatty(1))
1585 status.setAddToHistory(1);
1586 status.setExitStatus(1);
1594 int stdout_fileno_copy;
1595 stdout_fileno_copy= dup(fileno(stdout));
1596 if (stdout_fileno_copy == -1)
1599 close(stdout_fileno_copy);
1604 line_numbers= not vm.count(
"disable-line-numbers");
1605 column_names= not vm.count(
"disable-column-names");
1606 opt_rehash= not vm.count(
"disable-auto-rehash");
1607 opt_reconnect= not vm.count(
"disable-reconnect");
1610 if (vm.count(
"shutdown"))
1616 if (vm.count(
"delimiter"))
1619 if (! strstr(delimiter_str.c_str(),
"\\"))
1621 delimiter= delimiter_str.c_str();
1625 put_info(_(
"DELIMITER cannot contain a backslash character"),
1630 delimiter_length= (uint32_t)strlen(delimiter);
1632 if (vm.count(
"tee"))
1634 if (vm[
"tee"].as<string>().empty())
1640 init_tee(vm[
"tee"].as<string>().c_str());
1642 if (vm[
"disable-tee"].as<bool>())
1647 if (vm.count(
"pager"))
1649 if (vm[
"pager"].as<string>().empty())
1654 if (vm[pager].as<string>().length())
1656 default_pager_set= 1;
1657 pager= vm[
"pager"].as<
string>();
1658 default_pager= pager;
1660 else if (default_pager_set)
1661 pager= default_pager;
1666 if (vm.count(
"disable-pager"))
1671 if (vm.count(
"no-auto-rehash"))
1674 if (vm.count(
"skip-column-names"))
1677 if (vm.count(
"execute"))
1680 status.setAddToHistory(1);
1681 if (status.getLineBuff() == NULL)
1682 status.setLineBuff(opt_max_input_line,NULL);
1683 if (status.getLineBuff() == NULL)
1687 status.getLineBuff()->addString(vm[
"execute"].as<string>().c_str());
1693 if (vm.count(
"protocol"))
1695 boost::to_lower(opt_protocol);
1696 if (not opt_protocol.compare(
"mysql"))
1698 global_con_options= (drizzle_con_options_t)(DRIZZLE_CON_MYSQL|DRIZZLE_CON_INTERACTIVE);
1699 use_drizzle_protocol=
false;
1701 else if (not opt_protocol.compare(
"mysql-plugin-auth"))
1703 global_con_options= (drizzle_con_options_t)(DRIZZLE_CON_MYSQL|DRIZZLE_CON_INTERACTIVE|DRIZZLE_CON_AUTH_PLUGIN);
1704 use_drizzle_protocol=
false;
1706 else if (not opt_protocol.compare(
"drizzle"))
1708 global_con_options= (drizzle_con_options_t)(DRIZZLE_CON_EXPERIMENTAL);
1709 use_drizzle_protocol=
true;
1713 cout << _(
"Error: Unknown protocol") <<
" '" << opt_protocol <<
"'" << endl;
1718 if (vm.count(
"port"))
1720 opt_drizzle_port= vm[
"port"].as<uint32_t>();
1725 if (opt_drizzle_port > 65535)
1727 printf(_(
"Error: Value of %" PRIu32
" supplied for port is not valid.\n"), opt_drizzle_port);
1732 if (vm.count(
"password"))
1734 if (!opt_password.empty())
1735 opt_password.erase();
1736 if (current_password == PASSWORD_SENTINEL)
1742 opt_password= current_password;
1743 tty_password=
false;
1752 if (!opt_verbose.empty())
1754 verbose= opt_verbose.length();
1757 if (vm.count(
"batch"))
1760 status.setAddToHistory(0);
1766 if (vm.count(
"silent"))
1771 if (vm.count(
"help") || vm.count(
"version"))
1773 printf(_(
"Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
1774 drizzle_version(), VERSION,
1775 HOST_VENDOR, HOST_OS, HOST_CPU,
1776 rl_library_version);
1777 if (vm.count(
"version"))
1779 printf(_(
"Copyright (C) 2008 Sun Microsystems\n"
1780 "This software comes with ABSOLUTELY NO WARRANTY. "
1781 "This is free software,\n"
1782 "and you are welcome to modify and redistribute it "
1783 "under the GPL license\n"));
1784 printf(_(
"Usage: drizzle [OPTIONS] [schema]\n"));
1785 cout << long_options;
1790 if (process_options())
1795 memset(&drizzle, 0,
sizeof(drizzle));
1796 if (sql_connect(current_host, current_db, current_user, opt_password))
1799 status.setExitStatus(1);
1804 if (execute_commands(&command_error) !=
false)
1807 exit(command_error);
1810 if (status.getBatch() && !status.getLineBuff())
1812 status.setLineBuff(opt_max_input_line, stdin);
1813 if (status.getLineBuff() == NULL)
1819 if (!status.getBatch())
1822 if (opt_sigint_ignore)
1823 signal(SIGINT, SIG_IGN);
1825 signal(SIGINT, handle_sigint);
1826 signal(SIGQUIT, drizzle_end);
1828 #if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1830 signal(SIGWINCH, window_resize);
1834 std::vector<char> output_buff;
1835 output_buff.resize(512);
1837 snprintf(&output_buff[0], output_buff.size(),
1838 _(
"Welcome to the Drizzle client.. Commands end with %s or \\g."),
1841 put_info(&output_buff[0], INFO_INFO, 0, 0);
1843 glob_buffer=
new string();
1844 glob_buffer->reserve(512);
1846 snprintf(&output_buff[0], output_buff.size(),
1847 _(
"Your Drizzle connection id is %u\nConnection protocol: %s\nServer version: %s\n"),
1848 drizzle_con_thread_id(con),
1849 opt_protocol.c_str(),
1850 server_version_string(con));
1851 put_info(&output_buff[0], INFO_INFO, 0, 0);
1854 initialize_readline((
char *)current_prompt.c_str());
1855 if (!status.getBatch() && !quick)
1858 if (getenv(
"DRIZZLE_HISTFILE"))
1859 histfile= strdup(getenv(
"DRIZZLE_HISTFILE"));
1860 else if (getenv(
"HOME"))
1862 histfile=(
char*) malloc(strlen(getenv(
"HOME")) + strlen(
"/.drizzle_history") + 2);
1864 sprintf(histfile,
"%s/.drizzle_history",getenv(
"HOME"));
1865 char link_name[FN_REFLEN];
1866 ssize_t sym_link_size= readlink(histfile,link_name,FN_REFLEN-1);
1867 if (sym_link_size >= 0)
1869 link_name[sym_link_size]=
'\0';
1870 if (strncmp(link_name,
"/dev/null", 10) == 0)
1881 tee_fprintf(stdout, _(
"Reading history-file %s\n"),histfile);
1882 read_history(histfile);
1883 histfile_tmp= (
char*) malloc((uint32_t) strlen(histfile) + 5);
1884 sprintf(histfile_tmp,
"%s.TMP", histfile);
1888 put_info(_(
"Type 'help;' or '\\h' for help. "
1889 "Type '\\c' to clear the buffer.\n"),INFO_INFO,0,0);
1890 status.setExitStatus(read_and_execute(!status.getBatch()));
1896 catch(exception &err)
1898 cerr << _(
"Error:") << err.what() << endl;
1903 void drizzle_end(
int sig)
1905 drizzle_con_free(con);
1906 drizzle_free(drizzle);
1907 if (!status.getBatch() && !quick && histfile)
1911 tee_fprintf(stdout, _(
"Writing history-file %s\n"),histfile);
1912 if (!write_history(histfile_tmp))
1913 rename(histfile_tmp, histfile);
1915 delete status.getLineBuff();
1916 status.setLineBuff(0);
1919 put_info(sig ? _(
"Aborted") : _(
"Bye"), INFO_RESULT,0,0);
1921 delete processed_prompt;
1922 opt_password.erase();
1926 current_host.erase();
1927 current_user.erase();
1928 free(full_username);
1929 free(part_username);
1930 free(default_prompt);
1931 current_prompt.erase();
1932 exit(status.getExitStatus());
1942 void handle_sigint(
int sig)
1945 if (executing_query ==
false or interrupted_query)
1949 drizzle_con_st *kill_drizzle_con;
1950 if ((kill_drizzle_con= drizzle_con_add_tcp(drizzle,
1951 current_host.c_str(), opt_drizzle_port,
1952 current_user.c_str(), opt_password.c_str(), NULL,
1953 use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL)))
1956 char kill_buffer[40];
1957 snprintf(kill_buffer,
sizeof(kill_buffer),
"KILL /*!50000 QUERY */ %u", drizzle_con_thread_id(kill_drizzle_con));
1959 drizzle_return_t ret;
1960 drizzle_result_st res;
1961 if ((drizzle_query_str(kill_drizzle_con, &res, kill_buffer, &ret)))
1963 drizzle_result_free(&res);
1966 drizzle_con_free(kill_drizzle_con);
1968 tee_fprintf(stdout, _(
"Query aborted by Ctrl+C\n"));
1970 interrupted_query=
true;
1980 #if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1981 void window_resize(
int)
1983 struct winsize window_size;
1985 if (ioctl(fileno(stdin), TIOCGWINSZ, &window_size) == 0)
1986 terminal_width= window_size.ws_col;
1992 static int process_options()
1994 if (
const char* tmp= getenv(
"DRIZZLE_HOST"))
1997 if (
const char* pagpoint= getenv(
"PAGER"))
2006 default_pager= pager;
2010 if (status.getBatch())
2012 default_pager=
"stdout";
2015 default_pager_set= 0;
2021 opt_password= client_get_tty_password(NULL);
2025 static int read_and_execute(
bool interactive)
2029 uint32_t line_number=0;
2032 status.setExitStatus(1);
2038 if (status.getLineBuff())
2039 line= status.getLineBuff()->readline();
2044 if (show_progress_size > 0)
2046 if ((line_number % show_progress_size) == 0)
2047 fprintf(stderr, _(
"Processing line: %"PRIu32
"\n"), line_number);
2049 if (!glob_buffer->empty())
2050 status.setQueryStartLine(line_number);
2054 string prompt(ml_comment
2056 : glob_buffer->empty()
2057 ? construct_prompt()
2065 if (opt_outfile && glob_buffer->empty())
2069 fputs(prompt.c_str(), OUTFILE);
2070 line= readline(prompt.c_str());
2075 if (opt_outfile && line)
2076 fprintf(OUTFILE,
"%s\n", line);
2081 status.setExitStatus(0);
2089 if ((named_cmds || (glob_buffer->empty()))
2090 && !ml_comment && !in_string && (com=find_command(line,0)))
2092 if ((*com->func)(glob_buffer,line) > 0)
2095 if (glob_buffer->empty())
2097 if (interactive && status.getAddToHistory() && not_in_history(line))
2101 if (add_line(glob_buffer,line,&in_string,&ml_comment))
2106 if (!interactive && !status.getExitStatus())
2108 remove_cntrl(glob_buffer);
2109 if (!glob_buffer->empty())
2111 status.setExitStatus(1);
2112 if (com_go(glob_buffer,line) <= 0)
2113 status.setExitStatus(0);
2117 return status.getExitStatus();
2121 static Commands *find_command(
const char *name,
char cmd_char)
2133 while (isspace(*name))
2140 if (strstr(name,
"\\g") || (strstr(name, delimiter) &&
2141 !(strlen(name) >= 9 &&
2142 !strcmp(name,
"delimiter"))))
2144 if ((end=strcont(name,
" \t")))
2146 len=(uint32_t) (end - name);
2147 while (isspace(*end))
2153 len=(uint32_t) strlen(name);
2156 for (uint32_t i= 0; commands[i].getName(); i++)
2158 if (commands[i].func &&
2159 ((name && !strncmp(name, commands[i].getName(), len)
2160 && !commands[i].getName()[len] && (!end || (end && commands[i].getTakesParams()))) || (!name && commands[i].getCmdChar() == cmd_char)))
2162 return(&commands[i]);
2169 static bool add_line(
string *buffer,
char *line,
char *in_string,
2172 unsigned char inchar;
2179 if (!line[0] && (buffer->empty()))
2181 if (status.getAddToHistory() && line[0] && not_in_history(line))
2184 for (pos=out=line ; (inchar= (
unsigned char) *pos) ; pos++)
2186 if (!preserve_comments)
2189 if (isspace(inchar) && (out == line) &&
2195 if (not drizzled::utf8::is_single(*pos))
2198 if ((length= drizzled::utf8::sequence_length(*pos)))
2200 if (!*ml_comment || preserve_comments)
2211 if (!*ml_comment && inchar ==
'\\' &&
2212 !(*in_string && (drizzle_con_status(con) & DRIZZLE_CON_STATUS_NO_BACKSLASH_ESCAPES)))
2216 if (!(inchar = (
unsigned char) *++pos))
2218 if (*in_string || inchar ==
'N')
2221 *out++= (char) inchar;
2224 if ((com=find_command(NULL,(
char) inchar)))
2229 buffer->append(line, (out-line));
2233 if ((*com->func)(buffer,pos-1) > 0)
2235 if (com->getTakesParams())
2244 for (pos++; *pos && (*pos !=
'*' || *(pos + 1) !=
'/'); pos++)
2251 *pos && (*pos != *delimiter ||
2252 strncmp(pos + 1, delimiter + 1,
2253 strlen(delimiter + 1))) ; pos++)
2258 pos+= delimiter_length - 1;
2264 string buff(_(
"Unknown command: "));
2265 buff.push_back(
'\'');
2266 buff.push_back(inchar);
2267 buff.push_back(
'\'');
2268 buff.push_back(
'.');
2269 if (put_info(buff.c_str(),INFO_ERROR,0,0) > 0)
2272 *out++=(char) inchar;
2276 else if (!*ml_comment && !*in_string && !strncmp(pos, delimiter,
2280 pos+= delimiter_length;
2282 if (preserve_comments)
2284 while (isspace(*pos))
2290 buffer->append(line, (out-line));
2294 if (preserve_comments && ((*pos ==
'#') ||
2300 buffer->append(pos);
2306 if ((com= find_command(buffer->c_str(), 0)))
2309 if ((*com->func)(buffer, buffer->c_str()) > 0)
2314 if (com_go(buffer, 0) > 0)
2319 else if (!*ml_comment
2324 && isspace(pos[2])))))
2329 buffer->append(line, (out - line));
2334 if (preserve_comments)
2336 bool started_with_nothing= !buffer->empty();
2337 buffer->append(pos);
2344 if (started_with_nothing)
2346 if (com_go(buffer, 0) > 0)
2354 else if (!*in_string && inchar ==
'/' && *(pos+1) ==
'*' &&
2357 if (preserve_comments)
2367 buffer->append(line, (out-line));
2371 else if (*ml_comment && !ss_comment && inchar ==
'*' && *(pos + 1) ==
'/')
2373 if (preserve_comments)
2383 buffer->append(line, (out - line));
2393 if (!*in_string && inchar ==
'/' && *(pos + 1) ==
'*' &&
2396 else if (!*in_string && ss_comment && inchar ==
'*' && *(pos + 1) ==
'/')
2398 if (inchar == *in_string)
2400 else if (!*ml_comment && !*in_string &&
2401 (inchar ==
'\'' || inchar ==
'"' || inchar ==
'`'))
2402 *in_string= (char) inchar;
2403 if (!*ml_comment || preserve_comments)
2405 if (need_space && !isspace((
char)inchar))
2408 *out++= (char) inchar;
2412 if (out != line || (buffer->length() > 0))
2415 uint32_t length=(uint32_t) (out-line);
2416 if ((buffer->length() + length) > opt_max_input_line)
2418 status.setExitStatus(1);
2419 put_info(_(
"Not found a delimiter within max_input_line of input"), INFO_ERROR, 0, 0);
2422 if ((!*ml_comment || preserve_comments))
2423 buffer->append(line, length);
2433 static char **mysql_completion (
const char *text,
int start,
int end);
2434 extern "C" char *new_command_generator(
const char *text,
int);
2441 static char *no_completion(
const char *,
int)
2449 static void fix_history(
string *final_command)
2451 int total_lines = 1;
2452 const char *ptr = final_command->c_str();
2453 char str_char =
'\0';
2456 string fixed_buffer;
2457 fixed_buffer.reserve(512);
2460 while (*ptr !=
'\0')
2468 if (str_char ==
'\0')
2470 else if (str_char == *ptr)
2472 fixed_buffer.append(ptr, 1);
2479 fixed_buffer.append((str_char ==
'\0') ?
" " :
"\n");
2483 fixed_buffer.append(
"\\");
2489 if (*ptr ==
'\'' || *ptr ==
'"' || *ptr ==
'\\')
2490 fixed_buffer.append(ptr, 1);
2496 fixed_buffer.append(ptr, 1);
2500 if (total_lines > 1)
2501 add_history(fixed_buffer.c_str());
2508 static int not_in_history(
const char *line)
2510 HIST_ENTRY *oldhist = history_get(history_length);
2514 if (strcmp(oldhist->line,line) == 0)
2519 static void initialize_readline (
char *name)
2522 rl_readline_name= name;
2525 rl_attempted_completion_function= (rl_completion_func_t*)&mysql_completion;
2536 char **mysql_completion (
const char *text,
int,
int)
2538 if (!status.getBatch() && !quick)
2539 return rl_completion_matches(text, new_command_generator);
2544 inline string lower_string(
const string& from)
2546 return boost::to_lower_copy(from);
2549 inline string lower_string(
const char* from)
2551 return boost::to_lower_copy(
string(from));
2556 public unary_function<const string&, bool>
2562 inline bool operator() (
const pair<string,string> &match_against)
const
2564 string sub_match= lower_string(match_against.first.substr(0,match_text.size()));
2565 return match_func(sub_match,match_text);
2572 char *new_command_generator(
const char *text,
int state)
2577 completion_string= lower_string(text);
2578 if (completion_string.size() == 0)
2580 completion_iter= completion_map.begin();
2581 completion_end= completion_map.end();
2585 completion_iter= find_if(completion_map.begin(), completion_map.end(),
2587 completion_end= find_if(completion_iter, completion_map.end(),
2591 if (completion_iter == completion_end || (
size_t)state > completion_map.size())
2593 char *result= (
char *)malloc((*completion_iter).second.size()+1);
2594 strcpy(result, (*completion_iter).second.c_str());
2601 static void build_completion_hash(
bool rehash,
bool write_info)
2604 drizzle_return_t ret;
2605 drizzle_result_st databases,tables,fields;
2606 drizzle_row_t database_row,table_row;
2607 string tmp_str, tmp_str_lower;
2610 if (status.getBatch() || quick || current_db.empty())
2615 completion_map.clear();
2618 while (cmd->getName()) {
2619 tmp_str= cmd->getName();
2620 tmp_str_lower= lower_string(tmp_str);
2621 completion_map[tmp_str_lower]= tmp_str;
2628 if (drizzle_query_str(con, &databases,
"select schema_name from information_schema.schemata", &ret) != NULL)
2630 if (ret == DRIZZLE_RETURN_OK)
2632 if (drizzle_result_buffer(&databases) != DRIZZLE_RETURN_OK)
2634 put_info(drizzle_error(drizzle),INFO_INFO,0,0);
2638 while ((database_row=drizzle_row_next(&databases)))
2640 tmp_str= database_row[0];
2641 tmp_str_lower= lower_string(tmp_str);
2642 completion_map[tmp_str_lower]= tmp_str;
2647 drizzle_result_free(&databases);
2650 query=
"select table_name, column_name from information_schema.columns where table_schema='";
2651 query.append(current_db);
2652 query.append(
"' order by table_name");
2654 if (drizzle_query(con, &fields, query.c_str(), query.length(), &ret) != NULL)
2656 if (ret == DRIZZLE_RETURN_OK &&
2657 drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
2659 if (drizzle_result_row_count(&tables) > 0 && !opt_silent && write_info)
2662 _(
"Reading table information for completion of "
2663 "table and column names\n"
2664 "You can turn off this feature to get a quicker "
2665 "startup with -A\n\n"));
2668 std::string table_name;
2669 while ((table_row=drizzle_row_next(&fields)))
2671 if (table_name.compare(table_row[0]) != 0)
2673 tmp_str= table_row[0];
2674 tmp_str_lower= lower_string(tmp_str);
2675 completion_map[tmp_str_lower]= tmp_str;
2676 table_name= table_row[0];
2678 tmp_str= table_row[0];
2679 tmp_str.append(
".");
2680 tmp_str.append(table_row[1]);
2681 tmp_str_lower= lower_string(tmp_str);
2682 completion_map[tmp_str_lower]= tmp_str;
2684 tmp_str= table_row[1];
2685 tmp_str_lower= lower_string(tmp_str);
2686 completion_map[tmp_str_lower]= tmp_str;
2690 drizzle_result_free(&fields);
2691 completion_iter= completion_map.begin();
2697 static int reconnect(
void)
2701 put_info(_(
"No connection. Trying to reconnect..."),INFO_INFO,0,0);
2702 (void) com_connect((
string *)0, 0);
2703 if (opt_rehash && connected)
2704 com_rehash(NULL, NULL);
2707 return put_info(_(
"Can't connect to the server\n"),INFO_ERROR,0,0);
2711 static void get_current_db(
void)
2713 drizzle_return_t ret;
2714 drizzle_result_st res;
2719 if (drizzle_query_str(con, &res,
"SELECT DATABASE()", &ret) != NULL)
2721 if (ret == DRIZZLE_RETURN_OK &&
2722 drizzle_result_buffer(&res) == DRIZZLE_RETURN_OK)
2724 drizzle_row_t row= drizzle_row_next(&res);
2727 drizzle_result_free(&res);
2736 int drizzleclient_real_query_for_lazy(
const char *buf,
size_t length,
2737 drizzle_result_st *result,
2738 uint32_t *error_code)
2740 drizzle_return_t ret;
2742 for (uint32_t retry=0;; retry++)
2745 if (drizzle_query(con, result, buf, length, &ret) != NULL and
2746 ret == DRIZZLE_RETURN_OK)
2750 error= put_error(con, result);
2752 if (ret == DRIZZLE_RETURN_ERROR_CODE)
2754 *error_code= drizzle_result_error_code(result);
2755 drizzle_result_free(result);
2758 if (ret != DRIZZLE_RETURN_LOST_CONNECTION || retry > 1 ||
2769 int drizzleclient_store_result_for_lazy(drizzle_result_st *result)
2771 if (drizzle_result_buffer(result) == DRIZZLE_RETURN_OK)
2776 if (drizzle_con_error(con)[0])
2778 int ret= put_error(con, result);
2779 drizzle_result_free(result);
2787 com_help(
string *buffer,
const char *)
2790 char buff[32], *end;
2791 std::vector<char> output_buff;
2792 output_buff.resize(512);
2794 put_info(_(
"List of all Drizzle commands:"), INFO_INFO,0,0);
2797 snprintf(&output_buff[0], output_buff.size(),
2798 _(
"Note that all text commands must be first on line and end with '%s' or \\g"),
2800 put_info(&output_buff[0], INFO_INFO, 0, 0);
2802 for (i = 0; commands[i].getName(); i++)
2804 end= strcpy(buff, commands[i].getName());
2805 end+= strlen(commands[i].getName());
2806 for (j= (
int)strlen(commands[i].getName()); j < 10; j++)
2807 end= strcpy(end,
" ")+1;
2808 if (commands[i].func)
2809 tee_fprintf(stdout,
"%s(\\%c) %s\n", buff,
2810 commands[i].getCmdChar(), _(commands[i].getDoc()));
2812 tee_fprintf(stdout,
"\n");
2819 com_clear(
string *buffer,
const char *)
2821 if (status.getAddToHistory())
2822 fix_history(buffer);
2835 com_go(
string *buffer,
const char *)
2838 drizzle_result_st result;
2839 drizzle_return_t ret;
2840 uint32_t warnings= 0;
2841 boost::posix_time::ptime timer;
2843 uint32_t error_code= 0;
2846 interrupted_query=
false;
2849 remove_cntrl(buffer);
2851 if (buffer->empty())
2854 if (status.getBatch())
2856 return put_info(_(
"No query specified\n"),INFO_ERROR,0,0);
2859 if (!connected && reconnect())
2863 return opt_reconnect ? -1 : 1;
2866 (void) com_print(buffer, 0);
2869 ((buffer->length() < 4) || (buffer->find(
"SET ") != 0)))
2871 (void) put_info(_(
"Ignoring query to other database"),INFO_INFO,0,0);
2875 timer=start_timer();
2876 executing_query=
true;
2877 error= drizzleclient_real_query_for_lazy(buffer->c_str(),buffer->length(),&result, &error_code);
2879 if (status.getAddToHistory())
2881 buffer->append(vertical ?
"\\G" : delimiter);
2883 fix_history(buffer);
2897 if (drizzle_column_buffer(&result) != DRIZZLE_RETURN_OK)
2899 error= put_error(con, &result);
2905 error= drizzleclient_store_result_for_lazy(&result);
2910 string time_buff(
"");
2911 if (verbose >= 3 || !opt_silent)
2912 drizzle_end_timer(timer,time_buff);
2915 if (drizzle_result_column_count(&result) > 0)
2917 if (!quick && drizzle_result_row_count(&result) == 0 &&
2920 strcpy(buff, _(
"Empty set"));
2925 if (vertical || (auto_vertical_output &&
2926 (terminal_width < get_result_width(&result))))
2927 print_table_data_vertically(&result);
2928 else if (opt_silent && verbose <= 2 && !output_tables)
2929 print_tab_data(&result);
2931 print_table_data(&result);
2933 ngettext(
"%ld row in set",
"%ld rows in set",
2934 (
long) drizzle_result_row_count(&result)),
2935 (
long) drizzle_result_row_count(&result));
2937 if (drizzle_result_error_code(&result))
2938 error= put_error(con, &result);
2941 else if (drizzle_result_affected_rows(&result) == ~(uint64_t) 0)
2942 strcpy(buff,_(
"Query OK"));
2944 sprintf(buff, ngettext(
"Query OK, %ld row affected",
2945 "Query OK, %ld rows affected",
2946 (
long) drizzle_result_affected_rows(&result)),
2947 (
long) drizzle_result_affected_rows(&result));
2949 pos= strchr(buff,
'\0');
2950 if ((warnings= drizzle_result_warning_count(&result)))
2954 char warnings_buff[20];
2955 memset(warnings_buff,0,20);
2956 sprintf(warnings_buff,
"%d", warnings);
2957 strcpy(pos, warnings_buff);
2958 pos+= strlen(warnings_buff);
2959 pos= strcpy(pos,
" warning")+8;
2963 strcpy(pos, time_buff.c_str());
2964 put_info(buff,INFO_RESULT,0,0);
2965 if (strcmp(drizzle_result_info(&result),
""))
2966 put_info(drizzle_result_info(&result),INFO_RESULT,0,0);
2967 put_info(
"",INFO_RESULT,0,0);
2971 drizzle_result_free(&result);
2973 if (drizzle_con_status(con) & DRIZZLE_CON_STATUS_MORE_RESULTS_EXISTS)
2975 if (drizzle_result_read(con, &result, &ret) == NULL ||
2976 ret != DRIZZLE_RETURN_OK)
2978 if (ret == DRIZZLE_RETURN_ERROR_CODE)
2980 error_code= drizzle_result_error_code(&result);
2981 drizzle_result_free(&result);
2984 error= put_error(con, NULL);
2989 }
while (drizzle_con_status(con) & DRIZZLE_CON_STATUS_MORE_RESULTS_EXISTS);
2992 error= put_error(con, NULL);
2998 if (show_warnings == 1 && (warnings >= 1 || error))
2999 print_warnings(error_code);
3001 if (!error && !status.getBatch() and
3002 drizzle_con_status(con) & DRIZZLE_CON_STATUS_DB_DROPPED)
3007 executing_query=
false;
3012 static void init_pager()
3014 if (opt_nopager ==
false)
3016 if (!(PAGER= popen(pager.c_str(),
"w")))
3018 tee_fprintf(stdout,_(
"popen() failed! defaulting PAGER to stdout!\n"));
3028 static void end_pager()
3035 static void init_tee(
const char *file_name)
3043 if ((new_outfile= fopen(file_name,
"a")) == NULL)
3045 tee_fprintf(stdout, _(
"Error logging to file '%s'\n"), file_name);
3048 OUTFILE = new_outfile;
3050 tee_fprintf(stdout, _(
"Logging to file '%s'\n"), file_name);
3057 static void end_tee()
3067 com_ego(
string *buffer,
const char *line)
3070 bool oldvertical=vertical;
3072 result=com_go(buffer,line);
3073 vertical=oldvertical;
3078 static const char *fieldtype2str(drizzle_column_type_t type)
3081 case DRIZZLE_COLUMN_TYPE_BLOB:
return "BLOB";
3082 case DRIZZLE_COLUMN_TYPE_DATE:
return "DATE";
3083 case DRIZZLE_COLUMN_TYPE_DATETIME:
return "DATETIME";
3084 case DRIZZLE_COLUMN_TYPE_NEWDECIMAL:
return "DECIMAL";
3085 case DRIZZLE_COLUMN_TYPE_DOUBLE:
return "DOUBLE";
3086 case DRIZZLE_COLUMN_TYPE_ENUM:
return "ENUM";
3087 case DRIZZLE_COLUMN_TYPE_LONG:
return "LONG";
3088 case DRIZZLE_COLUMN_TYPE_LONGLONG:
return "LONGLONG";
3089 case DRIZZLE_COLUMN_TYPE_NULL:
return "NULL";
3090 case DRIZZLE_COLUMN_TYPE_TIMESTAMP:
return "TIMESTAMP";
3091 default:
return "?-unknown-?";
3095 static char *fieldflags2str(uint32_t f) {
3096 static char buf[1024];
3099 #define ff2s_check_flag(X) \
3100 if (f & DRIZZLE_COLUMN_FLAGS_ ## X) { s=strcpy(s, # X " ")+strlen(# X " "); \
3101 f &= ~ DRIZZLE_COLUMN_FLAGS_ ## X; }
3102 ff2s_check_flag(NOT_NULL);
3103 ff2s_check_flag(PRI_KEY);
3104 ff2s_check_flag(UNIQUE_KEY);
3105 ff2s_check_flag(MULTIPLE_KEY);
3106 ff2s_check_flag(BLOB);
3107 ff2s_check_flag(UNSIGNED);
3108 ff2s_check_flag(BINARY);
3109 ff2s_check_flag(ENUM);
3110 ff2s_check_flag(AUTO_INCREMENT);
3111 ff2s_check_flag(TIMESTAMP);
3112 ff2s_check_flag(SET);
3113 ff2s_check_flag(NO_DEFAULT_VALUE);
3114 ff2s_check_flag(NUM);
3115 ff2s_check_flag(PART_KEY);
3116 ff2s_check_flag(GROUP);
3117 ff2s_check_flag(UNIQUE);
3118 ff2s_check_flag(BINCMP);
3119 ff2s_check_flag(ON_UPDATE_NOW);
3120 #undef ff2s_check_flag
3122 sprintf(s,
" unknows=0x%04x", f);
3127 print_field_types(drizzle_result_st *result)
3129 drizzle_column_st *field;
3132 while ((field = drizzle_column_next(result)))
3134 tee_fprintf(PAGER, _(
"Field %3u: `%s`\n"
3140 "Collation: %s (%u)\n"
3146 drizzle_column_name(field), drizzle_column_catalog(field),
3147 drizzle_column_db(field), drizzle_column_table(field),
3148 drizzle_column_orig_table(field),
3149 fieldtype2str(drizzle_column_type(field)),
3150 drizzle_column_charset(field), drizzle_column_size(field),
3151 drizzle_column_max_size(field), drizzle_column_decimals(field),
3152 fieldflags2str(drizzle_column_flags(field)));
3154 tee_puts(
"", PAGER);
3158 print_table_data(drizzle_result_st *result)
3161 drizzle_return_t ret;
3162 drizzle_column_st *field;
3163 std::vector<bool> num_flag;
3164 std::vector<bool> boolean_flag;
3165 std::vector<bool> ansi_boolean_flag;
3168 separator.reserve(256);
3170 num_flag.resize(drizzle_result_column_count(result));
3171 boolean_flag.resize(drizzle_result_column_count(result));
3172 ansi_boolean_flag.resize(drizzle_result_column_count(result));
3173 if (column_types_flag)
3175 print_field_types(result);
3176 if (!drizzle_result_row_count(result))
3178 drizzle_column_seek(result,0);
3180 separator.append(
"+");
3181 while ((field = drizzle_column_next(result)))
3183 uint32_t x, length= 0;
3187 uint32_t name_length= strlen(drizzle_column_name(field));
3192 length= drizzled::utf8::char_length(drizzle_column_name(field));
3194 if (name_length == drizzle_column_max_size(field))
3196 if (length < drizzle_column_max_size(field))
3197 drizzle_column_set_max_size(field, length);
3201 length= name_length;
3206 length=max(length,drizzle_column_size(field));
3208 length=max(length,(uint32_t)drizzle_column_max_size(field));
3210 !(drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_NOT_NULL))
3215 if ((length < 5) and
3216 (server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3217 (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY) and
3218 (drizzle_column_type(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3223 drizzle_column_set_max_size(field, length);
3225 for (x=0; x< (length+2); x++)
3226 separator.append(
"-");
3227 separator.append(
"+");
3230 tee_puts((
char*) separator.c_str(), PAGER);
3233 drizzle_column_seek(result,0);
3234 (void) tee_fputs(
"|", PAGER);
3235 for (uint32_t off=0; (field = drizzle_column_next(result)) ; off++)
3237 uint32_t name_length= (uint32_t) strlen(drizzle_column_name(field));
3238 uint32_t numcells= drizzled::utf8::char_length(drizzle_column_name(field));
3239 uint32_t display_length= drizzle_column_max_size(field) + name_length -
3241 tee_fprintf(PAGER,
" %-*s |",(
int) min(display_length,
3243 drizzle_column_name(field));
3244 num_flag[off]= ((drizzle_column_type(field) <= DRIZZLE_COLUMN_TYPE_LONGLONG) ||
3245 (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_NEWDECIMAL));
3246 if ((server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3247 (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY))
3249 if ((drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3251 ansi_boolean_flag[off]=
true;
3255 ansi_boolean_flag[off]=
false;
3257 boolean_flag[off]=
true;
3258 num_flag[off]=
false;
3262 boolean_flag[off]=
false;
3265 (void) tee_fputs(
"\n", PAGER);
3266 tee_puts((
char*) separator.c_str(), PAGER);
3273 cur= drizzle_row_buffer(result, &ret);
3274 if (ret != DRIZZLE_RETURN_OK)
3276 (void)put_error(con, result);
3281 cur= drizzle_row_next(result);
3283 if (cur == NULL || interrupted_query)
3286 size_t *lengths= drizzle_row_field_sizes(result);
3287 (void) tee_fputs(
"| ", PAGER);
3288 drizzle_column_seek(result, 0);
3289 for (uint32_t off= 0; off < drizzle_result_column_count(result); off++)
3292 uint32_t data_length;
3293 uint32_t field_max_length;
3294 uint32_t visible_length;
3295 uint32_t extra_padding;
3297 if (cur[off] == NULL)
3302 else if (boolean_flag[off])
3304 if (strncmp(cur[off],
"1", 1) == 0)
3306 if (ansi_boolean_flag[off])
3319 if (ansi_boolean_flag[off])
3334 data_length= (uint32_t) lengths[off];
3337 field= drizzle_column_next(result);
3338 field_max_length= drizzle_column_max_size(field);
3348 visible_length= drizzled::utf8::char_length(buffer);
3349 extra_padding= data_length - visible_length;
3351 if (field_max_length > MAX_COLUMN_LENGTH)
3352 tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding,
false);
3355 if (num_flag[off] != 0)
3356 tee_print_sized_data(buffer, data_length, field_max_length+extra_padding,
true);
3358 tee_print_sized_data(buffer, data_length,
3359 field_max_length+extra_padding,
false);
3361 tee_fputs(
" | ", PAGER);
3363 (void) tee_fputs(
"\n", PAGER);
3365 drizzle_row_free(result, cur);
3367 tee_puts(separator.c_str(), PAGER);
3386 static int get_field_disp_length(drizzle_column_st *field)
3388 uint32_t length= column_names ? strlen(drizzle_column_name(field)) : 0;
3391 length= max(length, drizzle_column_size(field));
3393 length= max(length, (uint32_t)drizzle_column_max_size(field));
3396 !(drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_NOT_NULL))
3412 static int get_result_width(drizzle_result_st *result)
3414 unsigned int len= 0;
3415 drizzle_column_st *field;
3418 offset= drizzle_column_current(result);
3419 assert(offset == 0);
3421 while ((field= drizzle_column_next(result)) != NULL)
3422 len+= get_field_disp_length(field) + 3;
3424 (void) drizzle_column_seek(result, offset);
3430 tee_print_sized_data(
const char *data,
unsigned int data_length,
unsigned int total_bytes_to_send,
bool right_justified)
3440 if (right_justified)
3441 for (i= data_length; i < total_bytes_to_send; i++)
3442 tee_putc((
int)
' ', PAGER);
3444 for (i= 0, p= data; i < data_length; i+= 1, p+= 1)
3447 tee_putc((
int)
' ', PAGER);
3449 tee_putc((
int)*p, PAGER);
3452 if (! right_justified)
3453 for (i= data_length; i < total_bytes_to_send; i++)
3454 tee_putc((
int)
' ', PAGER);
3460 print_table_data_vertically(drizzle_result_st *result)
3463 drizzle_return_t ret;
3464 uint32_t max_length=0;
3465 drizzle_column_st *field;
3467 while ((field = drizzle_column_next(result)))
3469 uint32_t length= strlen(drizzle_column_name(field));
3470 if (length > max_length)
3472 drizzle_column_set_max_size(field, length);
3475 for (uint32_t row_count=1;; row_count++)
3479 cur= drizzle_row_buffer(result, &ret);
3480 if (ret != DRIZZLE_RETURN_OK)
3482 (void)put_error(con, result);
3487 cur= drizzle_row_next(result);
3489 if (cur == NULL || interrupted_query)
3491 drizzle_column_seek(result,0);
3493 "*************************** %d. row ***************************\n", row_count);
3494 for (uint32_t off=0; off < drizzle_result_column_count(result); off++)
3496 field= drizzle_column_next(result);
3497 tee_fprintf(PAGER,
"%*s: ",(
int) max_length,drizzle_column_name(field));
3498 tee_fprintf(PAGER,
"%s\n",cur[off] ? (
char*) cur[off] :
"NULL");
3501 drizzle_row_free(result, cur);
3508 static void print_warnings(uint32_t error_code)
3511 drizzle_result_st result;
3514 uint32_t new_code= 0;
3518 query=
"show warnings";
3519 drizzleclient_real_query_for_lazy(query, strlen(query),&result,&new_code);
3520 drizzleclient_store_result_for_lazy(&result);
3523 if (!(num_rows= drizzle_result_row_count(&result)))
3526 cur= drizzle_row_next(&result);
3534 if (!cur || (num_rows == 1 &&
3535 error_code == (uint32_t) strtoul(cur[1], NULL, 10)))
3541 if (status.getBatch())
3552 tee_fprintf(out,
"%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
3553 }
while ((cur= drizzle_row_next(&result)));
3555 if (not status.getBatch())
3559 drizzle_result_free(&result);
3564 safe_put_field(
const char *pos,uint32_t length)
3567 tee_fputs(
"NULL", PAGER);
3571 tee_fputs(pos, PAGER);
3572 else for (
const char *end=pos+length ; pos != end ; pos++)
3575 if ((l = drizzled::utf8::sequence_length(*pos)))
3578 tee_putc(*pos++, PAGER);
3583 tee_fputs(
"\\0", PAGER);
3584 else if (*pos ==
'\t')
3585 tee_fputs(
"\\t", PAGER);
3586 else if (*pos ==
'\n')
3587 tee_fputs(
"\\n", PAGER);
3588 else if (*pos ==
'\\')
3589 tee_fputs(
"\\\\", PAGER);
3591 tee_putc(*pos, PAGER);
3598 print_tab_data(drizzle_result_st *result)
3601 drizzle_return_t ret;
3602 drizzle_column_st *field;
3604 std::vector<bool> boolean_flag;
3605 std::vector<bool> ansi_boolean_flag;
3607 boolean_flag.resize(drizzle_result_column_count(result));
3608 ansi_boolean_flag.resize(drizzle_result_column_count(result));
3611 for (uint32_t off= 0; (field = drizzle_column_next(result)); off++)
3613 if (opt_silent < 2 && column_names)
3616 (void) tee_fputs(
"\t", PAGER);
3617 (void) tee_fputs(drizzle_column_name(field), PAGER);
3619 if ((server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3620 (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY))
3622 if ((drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3624 ansi_boolean_flag[off]=
true;
3628 ansi_boolean_flag[off]=
false;
3630 boolean_flag[off]=
true;
3634 boolean_flag[off]=
false;
3637 if (opt_silent < 2 && column_names)
3639 (void) tee_fputs(
"\n", PAGER);
3645 cur= drizzle_row_buffer(result, &ret);
3646 if (ret != DRIZZLE_RETURN_OK)
3648 (void)put_error(con, result);
3653 cur= drizzle_row_next(result);
3658 lengths= drizzle_row_field_sizes(result);
3659 drizzle_column_seek(result, 0);
3660 for (uint32_t off=0 ; off < drizzle_result_column_count(result); off++)
3663 (void) tee_fputs(
"\t", PAGER);
3664 if (boolean_flag[off])
3666 if (strncmp(cur[off],
"1", 1) == 0)
3668 if (ansi_boolean_flag[off])
3670 safe_put_field(
"YES", 3);
3674 safe_put_field(
"TRUE", 4);
3679 if (ansi_boolean_flag[off])
3681 safe_put_field(
"NO", 2);
3685 safe_put_field(
"FALSE", 5);
3691 safe_put_field(cur[off], lengths[off]);
3694 (void) tee_fputs(
"\n", PAGER);
3696 drizzle_row_free(result, cur);
3701 com_tee(
string *,
const char *line )
3703 char file_name[FN_REFLEN], *end;
3706 if (status.getBatch())
3708 while (isspace(*line))
3710 if (!(param =strchr(line,
' ')))
3712 if (outfile.empty())
3714 printf(_(
"No previous outfile available, you must give a filename!\n"));
3717 else if (opt_outfile)
3719 tee_fprintf(stdout, _(
"Currently logging to file '%s'\n"), outfile.c_str());
3723 param= outfile.c_str();
3728 while (isspace(*param))
3730 strncpy(file_name, param,
sizeof(file_name) - 1);
3731 end= file_name + strlen(file_name);
3733 while (end > file_name && (isspace(end[-1]) ||
3737 if (end == file_name)
3739 printf(_(
"No outfile specified!\n"));
3742 init_tee(file_name);
3748 com_notee(
string *,
const char *)
3752 tee_fprintf(stdout, _(
"Outfile disabled.\n"));
3761 com_pager(
string *,
const char *line)
3765 if (status.getBatch())
3768 while (isspace(*line))
3771 param= strchr(line,
' ');
3773 while (param && isspace(*param))
3775 if (!param || (*param ==
'\0'))
3777 if (!default_pager_set)
3779 tee_fprintf(stdout, _(
"Default pager wasn't set, using stdout.\n"));
3785 pager= default_pager;
3789 string pager_name(param);
3790 string::iterator end= pager_name.end();
3791 while (end > pager_name.begin() &&
3792 (isspace(*(end-1)) || iscntrl(*(end-1))))
3794 pager_name.erase(end, pager_name.end());
3796 default_pager= pager_name;
3799 tee_fprintf(stdout, _(
"PAGER set to '%s'\n"), pager.c_str());
3805 com_nopager(
string *,
const char *)
3810 tee_fprintf(stdout, _(
"PAGER set to stdout\n"));
3817 com_quit(
string *,
const char *)
3820 status.setExitStatus(0);
3825 com_rehash(
string *,
const char *)
3827 build_completion_hash(1, 0);
3834 com_print(
string *buffer,
const char *)
3836 tee_puts(
"--------------", stdout);
3837 (void) tee_fputs(buffer->c_str(), stdout);
3838 if ( (buffer->length() == 0)
3839 || (buffer->c_str())[(buffer->length())-1] !=
'\n')
3840 tee_putc(
'\n', stdout);
3841 tee_puts(
"--------------\n", stdout);
3848 com_connect(
string *buffer,
const char *line)
3850 char *tmp, buff[256];
3851 bool save_rehash= opt_rehash;
3854 memset(buff, 0,
sizeof(buff));
3861 tmp= strncpy(buff, line,
sizeof(buff)-2);
3865 tmp= get_arg(buff, 0);
3869 tmp= get_arg(buff, 1);
3872 current_host.erase();
3873 current_host=strdup(tmp);
3882 assert(buffer!=NULL);
3887 error=sql_connect(current_host, current_db, current_user, opt_password);
3888 opt_rehash= save_rehash;
3892 sprintf(buff, _(
"Connection id: %u"), drizzle_con_thread_id(con));
3893 put_info(buff,INFO_INFO,0,0);
3894 sprintf(buff, _(
"Current schema: %.128s\n"),
3895 !current_db.empty() ? current_db.c_str() : _(
"*** NONE ***"));
3896 put_info(buff,INFO_INFO,0,0);
3902 static int com_source(
string *,
const char *line)
3904 char source_name[FN_REFLEN], *end;
3912 while (isspace(*line))
3914 if (!(param = strchr(line,
' ')))
3915 return put_info(_(
"Usage: \\. <filename> | source <filename>"),
3917 while (isspace(*param))
3919 end= strncpy(source_name,param,
sizeof(source_name)-1);
3920 end+= strlen(source_name);
3921 while (end > source_name && (isspace(end[-1]) ||
3927 if (!(sql_file = fopen(source_name,
"r")))
3929 char buff[FN_REFLEN+60];
3930 sprintf(buff, _(
"Failed to open file '%s', error: %d"), source_name,errno);
3931 return put_info(buff, INFO_ERROR, 0 ,0);
3934 line_buff=
new LineBuffer(opt_max_input_line,sql_file);
3938 memset(&status, 0,
sizeof(status));
3941 status.setBatch(old_status.getBatch());
3942 status.setLineBuff(line_buff);
3943 status.setFileName(source_name);
3945 assert(glob_buffer!=NULL);
3946 glob_buffer->clear();
3947 error= read_and_execute(
false);
3951 delete status.getLineBuff();
3953 status.setLineBuff(0);
3960 com_delimiter(
string *,
const char *line)
3964 strncpy(buff, line,
sizeof(buff) - 1);
3965 char* tmp= get_arg(buff, 0);
3969 put_info(_(
"DELIMITER must be followed by a 'delimiter' character or string"), INFO_ERROR, 0, 0);
3974 if (strstr(tmp,
"\\"))
3976 put_info(_(
"DELIMITER cannot contain a backslash character"), INFO_ERROR, 0, 0);
3980 delimiter= strdup(tmp);
3981 delimiter_length= (int)strlen(delimiter);
3982 delimiter_str= delimiter;
3988 com_use(
string *,
const char *line)
3990 char *tmp, buff[FN_REFLEN + 1];
3992 drizzle_result_st result;
3993 drizzle_return_t ret;
3995 memset(buff, 0,
sizeof(buff));
3996 strncpy(buff, line,
sizeof(buff) - 1);
3997 tmp= get_arg(buff, 0);
4000 put_info(_(
"USE must be followed by a schema name"), INFO_ERROR, 0, 0);
4010 if (current_db.empty() || strcmp(current_db.c_str(),tmp))
4039 if (!connected && reconnect())
4040 return opt_reconnect ? -1 : 1;
4041 for (
bool try_again=
true; try_again; try_again=
false)
4043 if (drizzle_select_db(con, &result, tmp, &ret) == NULL ||
4044 ret != DRIZZLE_RETURN_OK)
4046 if (ret == DRIZZLE_RETURN_ERROR_CODE)
4048 int error= put_error(con, &result);
4049 drizzle_result_free(&result);
4053 if (ret != DRIZZLE_RETURN_LOST_CONNECTION || !try_again)
4055 return put_error(con, NULL);
4060 return opt_reconnect ? -1 : 1;
4064 drizzle_result_free(&result);
4068 build_completion_hash(opt_rehash, 1);
4071 put_info(_(
"Schema changed"),INFO_INFO, 0, 0);
4075 static int com_shutdown(
string *,
const char *)
4077 drizzle_result_st result;
4078 drizzle_return_t ret;
4082 printf(_(
"shutting down drizzled"));
4083 if (opt_drizzle_port > 0)
4084 printf(_(
" on port %d"), opt_drizzle_port);
4088 if (drizzle_shutdown(con, &result, DRIZZLE_SHUTDOWN_DEFAULT,
4089 &ret) == NULL || ret != DRIZZLE_RETURN_OK)
4091 if (ret == DRIZZLE_RETURN_ERROR_CODE)
4093 fprintf(stderr, _(
"shutdown failed; error: '%s'"), drizzle_result_error(&result));
4094 drizzle_result_free(&result);
4098 fprintf(stderr, _(
"shutdown failed; error: '%s'"), drizzle_con_error(con));
4103 drizzle_result_free(&result);
4106 printf(_(
"done\n"));
4112 com_warnings(
string *,
const char *)
4115 put_info(_(
"Show warnings enabled."),INFO_INFO, 0, 0);
4120 com_nowarnings(
string *,
const char *)
4123 put_info(_(
"Show warnings disabled."),INFO_INFO, 0, 0);
4137 char *get_arg(
char *line,
bool get_next_arg)
4140 bool quoted= 0, valid_arg= 0;
4146 for (; *ptr; ptr++) ;
4153 while (isspace(*ptr))
4158 while (*ptr &&!isspace(*ptr))
4163 while (isspace(*ptr))
4165 if (*ptr ==
'\'' || *ptr ==
'\"' || *ptr ==
'`')
4171 for (start=ptr ; *ptr; ptr++)
4173 if (*ptr ==
'\\' && ptr[1])
4178 else if ((!quoted && *ptr ==
' ') || (quoted && *ptr == qtype))
4184 valid_arg= ptr != start;
4185 return valid_arg ? start : NULL;
4190 sql_connect(
const string &host,
const string &database,
const string &user,
const string &password)
4192 drizzle_return_t ret;
4196 drizzle_con_free(con);
4197 drizzle_free(drizzle);
4200 drizzle= drizzle_create();
4201 if (drizzle == NULL)
4206 if (socket_file.size())
4208 if ((con= drizzle_con_add_uds(drizzle, socket_file.c_str(),
4209 user.c_str(), password.c_str(),
4211 global_con_options)) == NULL)
4213 (void) put_error(con, NULL);
4214 (void) fflush(stdout);
4218 else if ((con= drizzle_con_add_tcp(drizzle, host.c_str(),
4219 opt_drizzle_port, user.c_str(),
4220 password.c_str(), database.c_str(),
4221 global_con_options)) == NULL)
4223 (void) put_error(con, NULL);
4224 (void) fflush(stdout);
4228 if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
4233 (void) put_error(con, NULL);
4234 (void) fflush(stdout);
4235 return ignore_errors ? -1 : 1;
4242 server_type= server_detect.getServerType();
4244 build_completion_hash(opt_rehash, 1);
4250 com_status(
string *,
const char *)
4256 drizzle_result_st result;
4257 drizzle_return_t ret;
4259 tee_puts(
"--------------", stdout);
4260 printf(_(
"Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
4261 drizzle_version(), VERSION,
4262 HOST_VENDOR, HOST_OS, HOST_CPU,
4263 rl_library_version);
4267 tee_fprintf(stdout, _(
"\nConnection id:\t\t%lu\n"),drizzle_con_thread_id(con));
4272 if (drizzle_query_str(con, &result,
"select DATABASE(), USER() limit 1",
4273 &ret) != NULL && ret == DRIZZLE_RETURN_OK &&
4274 drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
4276 drizzle_row_t cur=drizzle_row_next(&result);
4279 tee_fprintf(stdout, _(
"Current schema:\t%s\n"), cur[0] ? cur[0] :
"");
4280 tee_fprintf(stdout, _(
"Current user:\t\t%s\n"), cur[1]);
4282 drizzle_result_free(&result);
4284 else if (ret == DRIZZLE_RETURN_ERROR_CODE)
4285 drizzle_result_free(&result);
4286 tee_puts(_(
"SSL:\t\t\tNot in use"), stdout);
4291 tee_fprintf(stdout, _(
"\nNo connection\n"));
4298 tee_fprintf(stdout, _(
"\nAll updates ignored to this schema\n"));
4301 tee_fprintf(stdout, _(
"Current pager:\t\t%s\n"), pager.c_str());
4302 tee_fprintf(stdout, _(
"Using outfile:\t\t'%s'\n"), opt_outfile ? outfile.c_str() :
"");
4303 tee_fprintf(stdout, _(
"Using delimiter:\t%s\n"), delimiter);
4304 tee_fprintf(stdout, _(
"Server version:\t\t%s\n"), server_version_string(con));
4305 tee_fprintf(stdout, _(
"Protocol:\t\t%s\n"), opt_protocol.c_str());
4306 tee_fprintf(stdout, _(
"Protocol version:\t%d\n"), drizzle_con_protocol_version(con));
4307 tee_fprintf(stdout, _(
"Connection:\t\t%s\n"), drizzle_con_host(con));
4313 if (drizzle_con_uds(con))
4315 tee_fprintf(stdout, _(
"UNIX socket:\t\t%s\n"), drizzle_con_uds(con));
4319 tee_fprintf(stdout, _(
"TCP port:\t\t%d\n"), drizzle_con_port(con));
4325 tee_fprintf(stdout, _(
"\nNote that you are running in safe_update_mode:\n"));
4327 tee_fprintf(stdout, _(
"\
4328 UPDATEs and DELETEs that don't use a key in the WHERE clause are not allowed.\n\
4329 (One can force an UPDATE/DELETE by adding LIMIT # at the end of the command.)\n \
4330 SELECT has an automatic 'LIMIT %lu' if LIMIT is not used.\n \
4331 Max number of examined row combination in a join is set to: %lu\n\n"),
4332 select_limit, max_join_size);
4334 tee_puts(
"--------------\n", stdout);
4339 server_version_string(drizzle_con_st *local_con)
4341 static string buf(
"");
4342 static bool server_version_string_reserved=
false;
4344 if (!server_version_string_reserved)
4346 buf.reserve(MAX_SERVER_VERSION_LENGTH);
4347 server_version_string_reserved=
true;
4352 drizzle_result_st result;
4353 drizzle_return_t ret;
4355 buf.append(drizzle_con_server_version(local_con));
4358 (void)drizzle_query_str(local_con, &result,
4359 "select @@version_comment limit 1", &ret);
4360 if (ret == DRIZZLE_RETURN_OK &&
4361 drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
4363 drizzle_row_t cur = drizzle_row_next(&result);
4369 drizzle_result_free(&result);
4371 else if (ret == DRIZZLE_RETURN_ERROR_CODE)
4372 drizzle_result_free(&result);
4379 put_info(
const char *str,INFO_TYPE info_type, uint32_t error,
const char *sqlstate)
4381 FILE *file= (info_type == INFO_ERROR ? stderr : stdout);
4382 static int inited=0;
4384 if (status.getBatch())
4386 if (info_type == INFO_ERROR)
4388 (void) fflush(file);
4389 fprintf(file,_(
"ERROR"));
4393 (void) fprintf(file,
" %d (%s)",error, sqlstate);
4395 (
void) fprintf(file,
" %d",error);
4397 if (status.getQueryStartLine() && line_numbers)
4399 (void) fprintf(file,
" at line %"PRIu32,status.getQueryStartLine());
4400 if (status.getFileName())
4401 (
void) fprintf(file,
" in file: '%s'", status.getFileName());
4403 (void) fprintf(file,
": %s\n",str);
4404 (void) fflush(file);
4408 else if (info_type == INFO_RESULT && verbose > 1)
4409 tee_puts(str, file);
4412 return info_type == INFO_ERROR ? -1 : 0;
4414 if (!opt_silent || info_type == INFO_ERROR)
4419 #ifdef HAVE_SETUPTERM
4420 (void) setupterm((
char *)0, 1, (
int *) 0);
4423 if (info_type == INFO_ERROR)
4428 vidattr(A_STANDOUT);
4432 (void) tee_fprintf(file, _(
"ERROR %d (%s): "), error, sqlstate);
4434 (
void) tee_fprintf(file, _(
"ERROR %d: "), error);
4437 tee_puts(_(
"ERROR: "), file);
4441 (void) tee_puts(str, file);
4446 return info_type == INFO_ERROR ? -1 : 0;
4451 put_error(drizzle_con_st *local_con, drizzle_result_st *res)
4457 error= drizzle_result_error(res);
4458 if (!strcmp(error,
""))
4460 error= drizzle_con_error(local_con);
4465 error= drizzle_con_error(local_con);
4468 return put_info(error, INFO_ERROR,
4469 res == NULL ? drizzle_con_error_code(local_con) :
4470 drizzle_result_error_code(res),
4471 res == NULL ? drizzle_con_sqlstate(local_con) :
4472 drizzle_result_sqlstate(res));
4476 static void remove_cntrl(
string *buffer)
4478 const char *start= buffer->c_str();
4479 const char *end= start + (buffer->length());
4480 while (start < end && !isgraph(end[-1]))
4482 uint32_t pos_to_truncate= (end-start);
4483 if (buffer->length() > pos_to_truncate)
4484 buffer->erase(pos_to_truncate);
4488 void tee_fprintf(FILE *file,
const char *fmt, ...)
4492 va_start(args, fmt);
4493 (void) vfprintf(file, fmt, args);
4498 va_start(args, fmt);
4499 (void) vfprintf(OUTFILE, fmt, args);
4505 void tee_fputs(
const char *s, FILE *file)
4513 void tee_puts(
const char *s, FILE *file)
4520 fputc(
'\n', OUTFILE);
4524 void tee_putc(
int c, FILE *file)
4531 #include <sys/times.h>
4533 static boost::posix_time::ptime start_timer(
void)
4535 return boost::posix_time::microsec_clock::universal_time();
4538 static void nice_time(boost::posix_time::time_duration duration,
string &buff)
4540 ostringstream tmp_buff_str;
4542 if (duration.hours() > 0)
4544 tmp_buff_str << duration.hours();
4545 if (duration.hours() > 1)
4546 tmp_buff_str << _(
" hours ");
4548 tmp_buff_str << _(
" hour ");
4550 if (duration.hours() > 0 || duration.minutes() > 0)
4552 tmp_buff_str << duration.minutes() << _(
" min ");
4555 tmp_buff_str.precision(duration.num_fractional_digits());
4557 double seconds= duration.fractional_seconds();
4559 seconds/= pow(10.0,duration.num_fractional_digits());
4561 seconds+= duration.seconds();
4562 tmp_buff_str << seconds << _(
" sec");
4564 buff.append(tmp_buff_str.str());
4567 static void end_timer(boost::posix_time::ptime start_time,
string &buff)
4569 boost::posix_time::ptime end_time= start_timer();
4570 boost::posix_time::time_period duration(start_time, end_time);
4572 nice_time(duration.length(), buff);
4576 static void drizzle_end_timer(boost::posix_time::ptime start_time,
string &buff)
4579 end_timer(start_time,buff);
4583 static const char * construct_prompt()
4586 assert(processed_prompt!=NULL);
4587 processed_prompt->clear();
4590 time_t lclock = time(NULL);
4591 struct tm *t = localtime(&lclock);
4594 string::iterator c= current_prompt.begin();
4595 while (c != current_prompt.end())
4597 if (*c != PROMPT_CHAR)
4599 processed_prompt->push_back(*c);
4613 add_int_to_prompt(++prompt_counter);
4617 processed_prompt->append(drizzle_con_server_version(con));
4619 processed_prompt->append(
"not_connected");
4622 processed_prompt->append(not current_db.empty() ? current_db :
"(none)");
4626 const char *prompt= connected ? drizzle_con_host(con) :
"not_connected";
4627 if (strstr(prompt,
"Localhost"))
4628 processed_prompt->append(
"localhost");
4631 const char *end=strrchr(prompt,
' ');
4633 processed_prompt->append(prompt, (end-prompt));
4641 processed_prompt->append(
"not_connected");
4645 if (drizzle_con_uds(con))
4647 const char *pos=strrchr(drizzle_con_uds(con),
'/');
4648 processed_prompt->append(pos ? pos+1 : drizzle_con_uds(con));
4651 add_int_to_prompt(drizzle_con_port(con));
4657 processed_prompt->append(full_username ? full_username :
4658 (!current_user.empty() ? current_user :
"(unknown)"));
4663 processed_prompt->append(part_username ? part_username :
4664 (!current_user.empty() ? current_user : _(
"(unknown)")));
4668 processed_prompt->append(PROMPT_CHAR, 1);
4673 processed_prompt->append(
'\n', 1);
4679 processed_prompt->append(
' ', 1);
4683 if (t->tm_hour < 10)
4684 add_int_to_prompt(0);
4685 add_int_to_prompt(t->tm_hour);
4688 getHour = t->tm_hour % 12;
4692 add_int_to_prompt(0);
4693 add_int_to_prompt(getHour);
4697 add_int_to_prompt(0);
4698 add_int_to_prompt(t->tm_min);
4701 getYear = t->tm_year % 100;
4703 add_int_to_prompt(0);
4704 add_int_to_prompt(getYear);
4707 add_int_to_prompt(t->tm_year+1900);
4710 strftime(dateTime, 32,
"%a %b %d %H:%M:%S %Y", localtime(&lclock));
4711 processed_prompt->append(dateTime);
4715 add_int_to_prompt(0);
4716 add_int_to_prompt(t->tm_sec);
4719 processed_prompt->append(get_day_name(t->tm_wday));
4722 processed_prompt->append(t->tm_hour < 12 ?
"am" :
"pm");
4725 add_int_to_prompt(t->tm_mon+1);
4728 processed_prompt->append(get_month_name(t->tm_mon));
4731 processed_prompt->append(
"'");
4734 processed_prompt->append(
"\"");
4737 processed_prompt->append(
";");
4740 processed_prompt->append(
"\t");
4743 processed_prompt->append(delimiter_str);
4746 processed_prompt->push_back(*c);
4751 return processed_prompt->c_str();
4755 static void add_int_to_prompt(
int toadd)
4757 ostringstream buffer;
4759 processed_prompt->append(buffer.str().c_str());
4762 static void init_username()
4780 static int com_prompt(
string *,
const char *line)
4782 const char *ptr=strchr(line,
' ');
4784 tee_fprintf(stdout, _(
"Returning to default PROMPT of %s\n"),
4787 char * tmpptr= strdup(ptr ? ptr+1 : default_prompt);
4789 tee_fprintf(stdout, _(
"Memory allocation error. Not changing prompt\n"));
4792 current_prompt.erase();
4793 current_prompt= tmpptr;
4794 tee_fprintf(stdout, _(
"PROMPT set to '%s'\n"), current_prompt.c_str());
4805 static const char * strcont(
const char *str,
const char *set)
4807 const char * start = set;
uint32_t day_of_week(int64_t day_number, bool sunday_is_first_day_of_week)