diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bc7b81..91d3edc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ ENDIF() MESSAGE(STATUS "Running cmake version ${CMAKE_VERSION}") +file(STRINGS ./rpm/obclient-VER.txt OBCLIENT_VERSION LIMIT_COUNT 1) + SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_SOURCE_DIR}/cmake/Internal/CPack) diff --git a/build.sh b/build.sh index 872a27c..64af136 100755 --- a/build.sh +++ b/build.sh @@ -26,12 +26,12 @@ cmake . \ -DOPENSSL_SSL_LIBRARY=$DEP_DIR/lib/libssl.a \ -DOPENSSL_CRYPTO_LIBRARY=$DEP_DIR/lib/libcrypto.a \ -DCURSES_CURSES_H_PATH=$DEP_DIR/include \ --DCURSES_CURSES_LIBRARY=$DEP_DIR/lib/libcurses.a \ --DCURSES_FORM_LIBRARY=$DEP_DIR/lib/libform.a \ +-DCURSES_CURSES_LIBRARY=$DEP_DIR/lib/libcurses.so \ -DCURSES_HAVE_CURSES_H=$DEP_DIR/include/curses.h \ -DCURSES_INCLUDE_PATH=$DEP_DIR/include \ --DCURSES_LIBRARY=$DEP_DIR/lib/libcurses.a \ --DCURSES_NCURSES_LIBRARY=$DEP_DIR/lib/libncurses.a \ +-DCURSES_LIBRARY=$DEP_DIR/lib/libcurses.so \ +-DCURSES_NCURSES_LIBRARY=$DEP_DIR/lib/libncurses.so \ +-DCURSES_FORM_LIBRARY=$DEP_DIR/lib/libform.so \ -DWITH_ZLIB=system \ -DWITH_LIBWRAP=0 \ -DENABLED_LOCAL_INFILE=1 \ diff --git a/client/client_priv.h b/client/client_priv.h index f336941..a38ae90 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -104,6 +104,10 @@ enum options_client OPT_SHUTDOWN_WAIT_FOR_SLAVES, OPT_PROXY_MODE, OPT_INIT_SQL, + OPT_OB_DISABLE_COMMANDS, + OPT_OB_SERVICE_NAME, + OPT_OB_PROXY_USER, + OPT_OB_SOCKET5_PROXY, OPT_MAX_CLIENT_OPTION /* should be always the last */ }; diff --git a/client/mysql.cc b/client/mysql.cc index 25887ed..256bf82 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -49,6 +49,9 @@ #include #endif +#include +#include + const char *VER = OBCLIENT_VERSION; /* Don't try to make a nice table if the data is too big */ @@ -126,6 +129,7 @@ static void my_vidattr(chtype attrs) #define PROMPT_CHAR '\\' #define DEFAULT_DELIMITER ";" +#define MAX_BUFFER_SIZE 1024 #define MAX_BATCH_BUFFER_SIZE (1024L * 1024L * 1024L) typedef struct st_status @@ -148,8 +152,6 @@ static my_bool dbms_serveroutput = 0; static my_bool dbms_prepared = 0; static regex_t dbms_enable_re; static regex_t dbms_disable_re; -static regex_t num_width_re; -static regex_t num_format_re; static regex_t column_format_re; MYSQL_STMT *dbms_stmt = NULL; static const char *dbms_enable_sql = "call dbms_output.enable()"; @@ -162,6 +164,7 @@ static MYSQL_BIND dbms_rs_bind[2]; static char dbms_line_buffer[32767]; static char dbms_status; static int put_stmt_error(MYSQL *con, MYSQL_STMT *stmt); +static void call_dbms_get_line(MYSQL *mysql, uint error); #define NS 13 static regex_t pl_create_sql_re; @@ -183,12 +186,17 @@ static uint show_object_offset = 12; bool is_pl_escape_sql = 0; static regex_t pl_escape_sql_re; +static regex_t pl_alter_sql_re; +static uint alter_type_offset = 2; +static uint alter_schema_offset = 4; +static uint alter_schema_quote_offset = 5; +static uint alter_object_offset = 7; +static uint alter_object_quote_offset = 8; + static char *pl_last_object = 0, *pl_last_type = 0, *pl_last_schema = 0; static char *pl_type = 0, *pl_object = 0, *pl_schema = 0; static uint pl_type_len = 0, pl_object_len = 0, pl_schema_len = 0; -static uint obclient_num_width = 0; -static bool force_set_num_width_close = 1; //default support as oracle - +static int handle_oracle_sql(MYSQL *mysql, String *buffer); static MYSQL mysql; /* The connection */ static my_bool ignore_errors=0,wait_flag=0,quick=0, @@ -221,6 +229,8 @@ static char *current_host,*current_db,*current_user=0,*opt_password=0, *current_prompt=0, *delimiter_str= 0, *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME, *opt_init_command= 0; +static char *current_host_success = 0; +static int current_port_success = 0; static char *histfile; static char *histfile_tmp; static String glob_buffer,old_buffer; @@ -292,8 +302,7 @@ static int com_nopager(String *str, char*), com_pager(String *str, char*), #endif static int read_and_execute(bool interactive); -static int sql_connect(char *host,char *database,char *user,char *password, - uint silent); +static int sql_connect(char *host,char *database,char *user,char *password, uint silent); static const char *server_version_string(MYSQL *mysql); static int put_info(const char *str,INFO_TYPE info,uint error=0, const char *sql_state = 0, my_bool oracle_mode = FALSE); @@ -323,7 +332,49 @@ static void report_progress_end(); static void get_current_db(); +/*ON:1, OFF:0*/ +static my_bool is_define_oracle = 1; +static char define_char_oracle = '&'; +static my_bool is_feedback_oracle = 1; +static int feedback_int_oracle = -1; +static my_bool is_sqlblanklines_oracle = 1; +static my_bool is_echo_oracle = 0; +static my_bool is_termout_oracle = 1; +static int pagesize_int_oracle = -1; +static my_bool is_trimspool_oracle = 1; +static my_bool is_exitcommit_oracle = 1; +static uint obclient_num_width = 10; +static bool force_set_num_width_close = 1; //default support as oracle static my_bool prompt_cmd_oracle(const char *str, char **text); +static my_bool is_global_comment(String *globbuffer); +static my_bool set_cmd_oracle(const char *str); +static my_bool set_param_oracle(const char *str); +static my_bool scan_define_oracle(String *buffer, String *newbuffer); +static my_bool exec_cmd_oracle(String *buffer, String *newbuffer); +static my_bool is_termout_oracle_enable(MYSQL *mysql); + + +static char obclient_login[MAX_BUFFER_SIZE] = { 0 }; +static char* get_login_sql_path(); +static void start_login_sql(MYSQL *mysql, String *buffer, const char *path); + +#define IS_CMD_SLASH 1 //oracle / +#define IS_CMD_LINE 2 //\s,\h... +static int is_cmd_line(char *pos, size_t len); + +#define COMMAND_MAX 50 +#define COMMAND_NAME_LEN 32 +static char *ob_disable_commands_str = 0; +static char disable_comands[COMMAND_MAX][COMMAND_NAME_LEN] = { 0 }; +static int disable_command_count = 0; +static my_bool is_command_valid(const char* name); + +static my_bool is_source_oracle = 0; +static std::map map_global; +static void free_map_global(); + +static char* ob_proxy_user_str = 0; +static char* ob_socket5_proxy_str = 0; /* A structure which contains information on the commands this program can understand. */ @@ -1157,6 +1208,7 @@ extern "C" sig_handler handle_sigint(int sig); static sig_handler window_resize(int sig); #endif +static char* ob_service_name_str = NULL; const char DELIMITER_NAME[]= "delimiter"; const uint DELIMITER_NAME_LEN= sizeof(DELIMITER_NAME) - 1; @@ -1257,24 +1309,14 @@ void init_width_and_format_for_result_value(void) /* SET NUMF format / SET NUMFORMAT format */ /* COLUMN c1 FORMAT format*/ - const char *num_width_re_str = - "^(" - "[[:space:]]*SET[[:space:]]+(NUMWIDTH|NUM)[[:space:]]+)"; - const char *num_format_re_str = - "^(" - "[[:space:]]*SET[[:space:]]+(NUMFORMAT|NUMF)[[:space:]]+)"; const char *column_format_re_str = "^(" "[[:space:]]*COLUMN[[:space:]]+([[:alnum:]_])[[:space:]]+" - "FORMAT[[:space:]]+)"; - init_re_comp(&num_width_re, num_width_re_str); - init_re_comp(&num_format_re, num_format_re_str); + "FORMAT[[:space:]]+([[:alnum:]_])[[:space:]]*)"; init_re_comp(&column_format_re, column_format_re_str); } void free_width_and_format_for_result_value() { - regfree(&num_width_re); - regfree(&num_format_re); regfree(&column_format_re); } @@ -1282,39 +1324,58 @@ void init_pl_sql(void) { const char *pl_create_sql_re_str = "^(" - //ǰ׺ create [or replace] + //prefix create [or replace] "[[:space:]]*CREATE[[:space:]]+(OR[[:space:]]+REPLACE[[:space:]]+)?" - // package( ���� 3 ~ 6 ) + // package( brackets 3 ~ 6 ) "(VIEW|PROCEDURE|FUNCTION|PACKAGE([[:space:]]+BODY)?|TRIGGER|TYPE([[:space:]]+BODY)?|LIBRARY|QUEUE|JAVA[[:space:]]+(SOURCE|CLASS)|DIMENSION|ASSEMBLY|HIERARCHY|ATTRIBUTE[[:space:]]+DIMENSION|ANALYTIC VIEW)[[:space:]]+" - // schema ( ���� 7 ~ 9) + // schema ( brackets 7 ~ 9) + //"((\\\")?([[:alnum:]_]+)\\\"?\\.)?" + "(([[:alnum:]$_]+)\\.|\\\"([^\"]*)\\\"\\.)?[[:space:]]*" + // object ( brackets 10 ~ 12) + //"(\\\")?([[:alnum:]_]+)\\\"?[[:space:]]*" + "(([[:alnum:]$_]+)|\\\"([^\"]*)\\\")?[[:space:]]*" + ")"; + + //alter procedure TEST.proc_test2 compile; + const char *pl_alter_sql_re_str = + "^(" + //prefix alter, + "[[:space:]]*ALTER[[:space:]]+" + // package( brackets 2 ) + "(VIEW|PROCEDURE|FUNCTION|PACKAGE)[[:space:]]+" + // schema ( brackets 3 ~ 5) //"((\\\")?([[:alnum:]_]+)\\\"?\\.)?" "(([[:alnum:]$_]+)\\.|\\\"([^\"]*)\\\"\\.)?[[:space:]]*" - // object ( ���� 10 ~ 12) + // object ( brackets 6 ~ 8) //"(\\\")?([[:alnum:]_]+)\\\"?[[:space:]]*" "(([[:alnum:]$_]+)|\\\"([^\"]*)\\\")?[[:space:]]*" ")"; const char *pl_show_errors_sql_re_str = "^(" - //ǰ׺ show err[ors] - "[[:space:]]*SHOW[[:space:]]+ERR(ORS)?" - //package( ���� 4 ~ 7 ) + //prefix show err[ors] + "[[:space:]]*SHOW[[:space:]]+ERR(OR|ORS)?" + //package( brackets 4 ~ 7 ) "([[:space:]]+(VIEW|PROCEDURE|FUNCTION|PACKAGE([[:space:]]+BODY)?|TRIGGER|TYPE([[:space:]]+BODY)?|LIBRARY|QUEUE|JAVA[[:space:]]+(SOURCE|CLASS)|DIMENSION|ASSEMBLY|HIERARCHY|ATTRIBUTE[[:space:]]+DIMENSION|ANALYTIC VIEW)[[:space:]]+" - //schema( ���� 8 ~ 10 ) + //schema( brackets 8 ~ 10 ) "((\\\")?([[:alnum:]_]+)\\\"?\\.)?" - //object( ���� 11 ~ 12 ) + //object( brackets 11 ~ 12 ) "(\\\")?([[:alnum:]_]+)\\\"?)?" "[[:space:]]*" "$)"; const char *pl_escape_sql_re_str = "^(" + // begin/declare support <