📄 mysql.cc
字号:
/* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* mysql command tool * Commands compatible with mSQL by David J. Hughes * * Written by: * Michael 'Monty' Widenius * Andi Gutmans <andi@zend.com> * Zeev Suraski <zeev@zend.com> * Jani Tolonen <jani@mysql.com> * Matt Wagner <matt@mysql.com> * Jeremy Cole <jcole@mysql.com> * Tonu Samuel <tonu@mysql.com> * Harrison Fisk <harrison@mysql.com> * **/#include "client_priv.h"#include <m_ctype.h>#include <stdarg.h>#include <my_dir.h>#ifndef __GNU_LIBRARY__#define __GNU_LIBRARY__ // Skip warnings in getopt.h#endif#include "my_readline.h"#include <signal.h>#include <violite.h>#if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)#include <locale.h>#endifconst char *VER= "14.12";/* Don't try to make a nice table if the data is too big */#define MAX_COLUMN_LENGTH 1024gptr sql_alloc(unsigned size); // Don't use mysqld alloc for thesevoid sql_element_free(void *ptr);#include "sql_string.h"extern "C" {#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)#include <curses.h>#include <term.h>#else#if defined(HAVE_TERMIOS_H)#include <termios.h>#include <unistd.h>#elif defined(HAVE_TERMBITS_H)#include <termbits.h>#elif defined(HAVE_ASM_TERMBITS_H) && (!defined __GLIBC__ || !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ > 0))#include <asm/termbits.h> // Standard linux#endif#undef VOID#if defined(HAVE_TERMCAP_H)#include <termcap.h>#else#ifdef HAVE_CURSES_H#include <curses.h>#endif#undef SYSV // hack to avoid syntax error#ifdef HAVE_TERM_H#include <term.h>#endif#endif#endif#undef bcmp // Fix problem with new readline#if defined( __WIN__) || defined(OS2)#include <conio.h>#elif !defined(__NETWARE__)#include <readline/readline.h>#define HAVE_READLINE#endif //int vidattr(long unsigned int attrs); // Was missing in sun curses}#if !defined(HAVE_VIDATTR)#undef vidattr#define vidattr(A) {} // Can't get this to work#endif#ifdef FN_NO_CASE_SENCE#define cmp_database(cs,A,B) my_strcasecmp((cs), (A), (B))#else#define cmp_database(cs,A,B) strcmp((A),(B))#endif#if !defined( __WIN__) && !defined( OS2) && !defined(__NETWARE__) && (!defined(HAVE_mit_thread) || !defined(THREAD))#define USE_POPEN#endif#include "completion_hash.h"#define PROMPT_CHAR '\\'#define DEFAULT_DELIMITER ";"typedef struct st_status{ int exit_status; ulong query_start_line; char *file_name; LINE_BUFFER *line_buff; bool batch,add_to_history;} STATUS;static HashTable ht;static char **defaults_argv;enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};typedef enum enum_info_type INFO_TYPE;static MYSQL mysql; /* The connection */static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, connected=0,opt_raw_data=0,unbuffered=0,output_tables=0, rehash=1,skip_updates=0,safe_updates=0,one_database=0, opt_compress=0, using_opt_local_infile=0, vertical=0, line_numbers=1, column_names=1,opt_html=0, opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, default_charset_used= 0, opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, show_warnings = 0;static ulong opt_max_allowed_packet, opt_net_buffer_length;static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;static my_string opt_mysql_unix_port=0;static int connect_flag=CLIENT_INTERACTIVE;static char *current_host,*current_db,*current_user=0,*opt_password=0, *current_prompt=0, *delimiter_str= 0, *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;static char *histfile;static char *histfile_tmp;static String glob_buffer,old_buffer;static String processed_prompt;static char *full_username=0,*part_username=0,*default_prompt=0;static int wait_time = 5;static STATUS status;static ulong select_limit,max_join_size,opt_connect_timeout=0;static char mysql_charsets_dir[FN_REFLEN+1];static const char *xmlmeta[] = { "&", "&", "<", "<", ">", ">", "\"", """, 0, 0};static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul", "Aug","Sep","Oct","Nov","Dec"};static char default_pager[FN_REFLEN];static char pager[FN_REFLEN], outfile[FN_REFLEN];static FILE *PAGER, *OUTFILE;static MEM_ROOT hash_mem_root;static uint prompt_counter;static char delimiter[16]= DEFAULT_DELIMITER;static uint delimiter_length= 1;#ifdef HAVE_SMEMstatic char *shared_memory_base_name=0;#endifstatic uint opt_protocol=0;static CHARSET_INFO *charset_info= &my_charset_latin1;#include "sslopt-vars.h"const char *default_dbug_option="d:t:o,/tmp/mysql.trace";void tee_fprintf(FILE *file, const char *fmt, ...);void tee_fputs(const char *s, FILE *file);void tee_puts(const char *s, FILE *file);void tee_putc(int c, FILE *file);static void tee_print_sized_data(const char *data, unsigned int length, unsigned int width);/* The names of functions that actually do the manipulation. */static int get_options(int argc,char **argv);static int com_quit(String *str,char*), com_go(String *str,char*), com_ego(String *str,char*), com_print(String *str,char*), com_help(String *str,char*), com_clear(String *str,char*), com_connect(String *str,char*), com_status(String *str,char*), com_use(String *str,char*), com_source(String *str, char*), com_rehash(String *str, char*), com_tee(String *str, char*), com_notee(String *str, char*), com_charset(String *str,char*), com_prompt(String *str, char*), com_delimiter(String *str, char*), com_warnings(String *str, char*), com_nowarnings(String *str, char*);#ifdef USE_POPENstatic int com_nopager(String *str, char*), com_pager(String *str, char*), com_edit(String *str,char*), com_shell(String *str, char *);#endifstatic int read_and_execute(bool interactive);static int sql_connect(char *host,char *database,char *user,char *password, uint silent);static int put_info(const char *str,INFO_TYPE info,uint error=0, const char *sql_state=0);static int put_error(MYSQL *mysql);static void safe_put_field(const char *pos,ulong length);static void xmlencode_print(const char *src, uint length);static void init_pager();static void end_pager();static void init_tee(const char *);static void end_tee();static const char* construct_prompt();static char *get_arg(char *line, my_bool get_next_arg);static void init_username();static void add_int_to_prompt(int toadd);/* A structure which contains information on the commands this program can understand. */typedef struct { const char *name; /* User printable name of the function. */ char cmd_char; /* msql command character */ int (*func)(String *str,char *); /* Function to call to do the job. */ bool takes_params; /* Max parameters for command */ const char *doc; /* Documentation for this function. */} COMMANDS;static COMMANDS commands[] = { { "?", '?', com_help, 1, "Synonym for `help'." }, { "clear", 'c', com_clear, 0, "Clear command."}, { "connect",'r', com_connect,1, "Reconnect to the server. Optional arguments are db and host." }, { "delimiter", 'd', com_delimiter, 1, "Set statement delimiter. NOTE: Takes the rest of the line as new delimiter." },#ifdef USE_POPEN { "edit", 'e', com_edit, 0, "Edit command with $EDITOR."},#endif { "ego", 'G', com_ego, 0, "Send command to mysql server, display result vertically."}, { "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."}, { "go", 'g', com_go, 0, "Send command to mysql server." }, { "help", 'h', com_help, 1, "Display this help." },#ifdef USE_POPEN { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },#endif { "notee", 't', com_notee, 0, "Don't write into outfile." },#ifdef USE_POPEN { "pager", 'P', com_pager, 1, "Set PAGER [to_pager]. Print the query results via PAGER." },#endif { "print", 'p', com_print, 0, "Print current command." }, { "prompt", 'R', com_prompt, 1, "Change your mysql prompt."}, { "quit", 'q', com_quit, 0, "Quit mysql." }, { "rehash", '#', com_rehash, 0, "Rebuild completion hash." }, { "source", '.', com_source, 1, "Execute an SQL script file. Takes a file name as an argument."}, { "status", 's', com_status, 0, "Get status information from the server."},#ifdef USE_POPEN { "system", '!', com_shell, 1, "Execute a system shell command."},#endif { "tee", 'T', com_tee, 1, "Set outfile [to_outfile]. Append everything into given outfile." }, { "use", 'u', com_use, 1, "Use another database. Takes database name as argument." }, { "charset", 'C', com_charset, 1, "Switch to another charset. Might be needed for processing binlog with multi-byte charsets." }, { "warnings", 'W', com_warnings, 0, "Show warnings after every statement." }, { "nowarning", 'w', com_nowarnings, 0, "Don't show warnings after every statement." }, /* Get bash-like expansion for some commands */ { "create table", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""}, { "drop", 0, 0, 0, ""}, { "select", 0, 0, 0, ""}, { "insert", 0, 0, 0, ""}, { "replace", 0, 0, 0, ""}, { "update", 0, 0, 0, ""}, { "delete", 0, 0, 0, ""}, { "explain", 0, 0, 0, ""}, { "show databases", 0, 0, 0, ""}, { "show fields from", 0, 0, 0, ""}, { "show keys from", 0, 0, 0, ""}, { "show tables", 0, 0, 0, ""}, { "load data from", 0, 0, 0, ""}, { "alter table", 0, 0, 0, ""}, { "set option", 0, 0, 0, ""}, { "lock tables", 0, 0, 0, ""}, { "unlock tables", 0, 0, 0, ""}, { (char *)NULL, 0, 0, 0, ""}};static const char *load_default_groups[]= { "mysql","client",0 };static const char *server_default_groups[]={ "server", "embedded", "mysql_SERVER", 0 };#ifdef HAVE_READLINE/* HIST_ENTRY is defined for libedit, but not for the real readline Need to redefine it for real readline to find it*/#if !defined(HAVE_HIST_ENTRY)typedef struct _hist_entry { const char *line; const char *data;} HIST_ENTRY; #endifextern "C" int add_history(const char *command); /* From readline directory */extern "C" int read_history(const char *command);extern "C" int write_history(const char *command);extern "C" HIST_ENTRY *history_get(int num);extern "C" int history_length;static int not_in_history(const char *line);static void initialize_readline (char *name);static void fix_history(String *final_command);#endifstatic COMMANDS *find_command(char *name,char cmd_name);static bool add_line(String &buffer,char *line,char *in_string, bool *ml_comment);static void remove_cntrl(String &buffer);static void print_table_data(MYSQL_RES *result);static void print_table_data_html(MYSQL_RES *result);static void print_table_data_xml(MYSQL_RES *result);static void print_tab_data(MYSQL_RES *result);static void print_table_data_vertically(MYSQL_RES *result);static void print_warnings(void);static ulong start_timer(void);static void end_timer(ulong start_time,char *buff);static void mysql_end_timer(ulong start_time,char *buff);static void nice_time(double sec,char *buff,bool part_second);static sig_handler mysql_end(int sig);int main(int argc,char *argv[]){ char buff[80]; char *defaults, *extra_defaults, *group_suffix; char *emb_argv[4]; int emb_argc; /* Get --defaults-xxx args for mysql_server_init() */ emb_argc= get_defaults_options(argc, argv, &defaults, &extra_defaults, &group_suffix)+1; memcpy((char*) emb_argv, (char*) argv, emb_argc * sizeof(*argv)); emb_argv[emb_argc]= 0; MY_INIT(argv[0]); DBUG_ENTER("main"); DBUG_PROCESS(argv[0]); delimiter_str= delimiter; default_prompt = my_strdup(getenv("MYSQL_PS1") ? getenv("MYSQL_PS1") : "mysql> ",MYF(MY_WME)); current_prompt = my_strdup(default_prompt,MYF(MY_WME)); prompt_counter=0; outfile[0]=0; // no (default) outfile strmov(pager, "stdout"); // the default, if --pager wasn't given { char *tmp=getenv("PAGER"); if (tmp && strlen(tmp)) { default_pager_set= 1; strmov(default_pager, tmp); } } if (!isatty(0) || !isatty(1)) { status.batch=1; opt_silent=1; ignore_errors=0; } else status.add_to_history=1; status.exit_status=1; load_defaults("my",load_default_groups,&argc,&argv); defaults_argv=argv; if (get_options(argc, (char **) argv)) { free_defaults(defaults_argv); my_end(0); exit(1); } if (status.batch && !status.line_buff && !(status.line_buff=batch_readline_init(opt_max_allowed_packet+512,stdin))) { free_defaults(defaults_argv); my_end(0); exit(1); } if (mysql_server_init(emb_argc, emb_argv, (char**) server_default_groups)) { free_defaults(defaults_argv); my_end(0); exit(1); } glob_buffer.realloc(512); completion_hash_init(&ht, 128); init_alloc_root(&hash_mem_root, 16384, 0); bzero((char*) &mysql, sizeof(mysql)); if (sql_connect(current_host,current_db,current_user,opt_password, opt_silent)) { quick=1; // Avoid history status.exit_status=1; mysql_end(-1); } if (!status.batch) ignore_errors=1; // Don't abort monitor if (opt_sigint_ignore) signal(SIGINT, SIG_IGN); else signal(SIGINT, mysql_end); // Catch SIGINT to clean up signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up /* Run in interactive mode like the ingres/postgres monitor */ put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.", INFO_INFO); sprintf((char*) glob_buffer.ptr(), "Your MySQL connection id is %lu to server version: %s\n", mysql_thread_id(&mysql),mysql_get_server_info(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -