diff options
author | harrison@corona.lordblink.com <> | 2004-03-03 15:54:37 -0500 |
---|---|---|
committer | harrison@corona.lordblink.com <> | 2004-03-03 15:54:37 -0500 |
commit | ab1786129cdfbaedcdf947d0e24594a41fa28e42 (patch) | |
tree | 9081ee0166cb2fa018eec48c5d889ef974d7550e /client/mysql.cc | |
parent | 5e360685c15127c353d80cc46f78d818e271239f (diff) | |
download | mariadb-git-ab1786129cdfbaedcdf947d0e24594a41fa28e42.tar.gz |
Fix up history in readline implementation.
Two things changed:
1. Repeated queries are only stored once in the history.
2. Multiline queries are stored in a concated format in the history,
in addition to pieces.
(Push approved by serg)
Diffstat (limited to 'client/mysql.cc')
-rw-r--r-- | client/mysql.cc | 104 |
1 files changed, 101 insertions, 3 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index eb466a86c91..5d69d3838ee 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -25,7 +25,7 @@ * Matt Wagner <matt@mysql.com> * Jeremy Cole <jcole@mysql.com> * Tonu Samuel <tonu@mysql.com> - * Harrison Fisk <hcfisk@buffalo.edu> + * Harrison Fisk <harrison@mysql.com> * **/ @@ -289,10 +289,25 @@ 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(USE_LIBEDIT_INTERFACE) +typedef struct _hist_entry { + const char *line; + const char *data; +} HIST_ENTRY; +#endif + extern "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); #endif static COMMANDS *find_command (char *name,char cmd_name); @@ -937,7 +952,7 @@ static int read_lines(bool execute_commands) if (glob_buffer.is_empty()) // If buffer was emptied in_string=0; #ifdef HAVE_READLINE - if (status.add_to_history) + if (status.add_to_history && not_in_history(line)) add_history(line); #endif continue; @@ -1014,7 +1029,7 @@ static bool add_line(String &buffer,char *line,char *in_string, if (!line[0] && buffer.is_empty()) return 0; #ifdef HAVE_READLINE - if (status.add_to_history && line[0]) + if (status.add_to_history && line[0] && not_in_history(line)) add_history(line); #endif #ifdef USE_MB @@ -1169,6 +1184,75 @@ int no_completion() return 0; /* No filename completion */ } +/* glues pieces of history back together if in pieces */ +static void fix_history(String *final_command) +{ + int total_lines = 1; + char *ptr = final_command->c_ptr(); + String fixed_buffer; /* Converted buffer */ + char str_char = '\0'; /* Character if we are in a string or not */ + + /* find out how many lines we have and remove newlines */ + while (*ptr != '\0') + { + switch (*ptr) { + /* string character */ + case '"': + case '\'': + case '`': + if (str_char == '\0') /* open string */ + str_char = *ptr; + else if (str_char == *ptr) /* close string */ + str_char = '\0'; + fixed_buffer.append(ptr,1); + break; + case '\n': + /* + not in string, change to space + if in string, leave it alone + */ + fixed_buffer.append(str_char == '\0' ? " " : "\n"); + total_lines++; + break; + case '\\': + fixed_buffer.append('\\'); + /* need to see if the backslash is escaping anything */ + if (str_char) + { + ptr++; + /* special characters that need escaping */ + if (*ptr == '\'' || *ptr == '"' || *ptr == '\\') + fixed_buffer.append(ptr,1); + else + ptr--; + } + break; + + default: + fixed_buffer.append(ptr,1); + } + ptr++; + } + if (total_lines > 1) + add_history(fixed_buffer.ptr()); +} + +/* + returns 0 if line matches the previous history entry + returns 1 if the line doesn't match the previous history entry +*/ +static int not_in_history(const char *line) +{ + HIST_ENTRY *oldhist = history_get(history_length); + int num; + + if (oldhist == 0) + return 1; + if (strcmp(oldhist->line,line) == 0) + return 0; + return 1; +} + static void initialize_readline (char *name) { /* Allow conditional parsing of the ~/.inputrc file. */ @@ -1631,6 +1715,10 @@ com_help(String *buffer __attribute__((unused)), static int com_clear(String *buffer,char *line __attribute__((unused))) { +#ifdef HAVE_READLINE + if (status.add_to_history) + fix_history(buffer); +#endif buffer->length(0); return 0; } @@ -1690,6 +1778,16 @@ com_go(String *buffer,char *line __attribute__((unused))) timer=start_timer(); error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length()); + +#ifdef HAVE_READLINE + if (status.add_to_history) + { + buffer->append(vertical ? "\\G" : delimiter); + /* Append final command onto history */ + fix_history(buffer); + } +#endif + if (error) { buffer->length(0); // Remove query on error |