diff options
author | mwesdorp <mwesdorp> | 2013-08-21 11:16:39 +0000 |
---|---|---|
committer | mwesdorp <mwesdorp> | 2013-08-21 11:16:39 +0000 |
commit | 0b56a9543189fc4a6afcf8ce1d6b8fa0a12b16fe (patch) | |
tree | fbd9c62c9df5465fdeac0c45a2ef78b512ac09fd /src | |
parent | 8d808bb71f1a5d3d84f61fac724cd46c7495476e (diff) |
sqsh-2.4 New features and bugfixes
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd_connect.c | 30 | ||||
-rw-r--r-- | src/cmd_do.c | 30 | ||||
-rw-r--r-- | src/dsp_html.c | 12 | ||||
-rw-r--r-- | src/sqsh_config.h | 5 | ||||
-rw-r--r-- | src/sqsh_readline.c | 30 |
5 files changed, 83 insertions, 24 deletions
diff --git a/src/cmd_connect.c b/src/cmd_connect.c index 681e754..5b4d1b4 100644 --- a/src/cmd_connect.c +++ b/src/cmd_connect.c @@ -42,7 +42,7 @@ /*-- Current Version --*/ #if !defined(lint) && !defined(__LINT__) -static char RCS_Id[] = "$Id: cmd_connect.c,v 1.32 2013/07/20 16:18:35 mwesdorp Exp $"; +static char RCS_Id[] = "$Id: cmd_connect.c,v 1.33 2013/08/21 11:16:39 mwesdorp Exp $"; USE(RCS_Id) #endif /* !defined(lint) */ @@ -165,11 +165,10 @@ int cmd_connect( argc, argv ) char *cp; extern char *sqsh_optarg ; extern int sqsh_optind ; - char use_database[128] ; int c ; int have_error = False ; int preserve_context = True ; - char orig_password[64]; + char orig_password[SQSH_PASSLEN+1]; int password_changed = False; char sqlbuf[64]; char passbuf[64]; @@ -536,7 +535,7 @@ int cmd_connect( argc, argv ) * If we don't have a password to use (i.e. the $password isn't set * or -P was not supplied), then ask the user for one. */ - else if (g_password_set == False) + else if (g_password_set == False) { len = sqsh_getinput( "Password: ", passbuf, sizeof(passbuf), 0); @@ -563,9 +562,8 @@ int cmd_connect( argc, argv ) */ if( preserve_context && database != NULL && *database != '\0' ) { - strncpy( use_database, database, sizeof(use_database)-1 ) ; - use_database[sizeof(use_database)-1] = '\0'; - autouse = use_database ; + env_put ( g_env, "autouse", database, ENV_F_TRAN ) ; + env_get ( g_env, "autouse", &autouse ) ; } /* @@ -1143,6 +1141,7 @@ int cmd_connect( argc, argv ) } } while (sg_login_failed == True); + sg_login = False; /* XXX */ /* ct_cancel(g_connection, NULL, CS_CANCEL_ALL); */ @@ -1260,17 +1259,29 @@ int cmd_connect( argc, argv ) ) != CS_SUCCEED) { ct_cmd_drop( cmd ); - goto connect_succeed; + goto connect_fail; } if (ct_send( cmd ) != CS_SUCCEED) { ct_cmd_drop( cmd ); - goto connect_succeed; + goto connect_fail; } while (ct_results( cmd, &result_type ) != CS_END_RESULTS); ct_cmd_drop( cmd ); + + /* + * sqsh-2.4 - Check in batch mode if the -D <database> is correctly set. + * Otherwise, abort to prevent script execution in wrong default + * database. + */ + env_get ( g_env, "database", &database ) ; + if (g_interactive != True && strcmp (autouse, database) != 0) + { + fprintf (stderr, "sqsh: ERROR: Unable to use database %s in batch mode\n", autouse); + sqsh_exit(254); + } } connect_succeed: @@ -1380,7 +1391,6 @@ connect_leave: varbuf_destroy( exp_buf ); sig_restore(); - sg_login = False; return return_code; } diff --git a/src/cmd_do.c b/src/cmd_do.c index c7a5ccf..2717240 100644 --- a/src/cmd_do.c +++ b/src/cmd_do.c @@ -74,6 +74,8 @@ int cmd_do( argc, argv ) varbuf_t *do_buf; varbuf_t *orig_sqlbuf; /* SQL Buffer upon entry */ CS_CONNECTION *orig_conn; /* Connection upon entry */ + CS_CONTEXT *orig_ctxt; /* Context upon entry */ + char orig_password[SQSH_PASSLEN+1]; /* Current session password */ int ret = False; int have_error = False; int exit_status; @@ -86,6 +88,19 @@ int cmd_do( argc, argv ) */ env_tran( g_env ); + /* + * sqsh-2.4 modification. + * This is totally utterly ugly, but the \do block may call \reconnect with a lot of + * parameter changes that will be committed in the global environment upon a successfull + * connection. If we put some of the original values on the logsave chain first, then the + * env_rollback call at the end of this function will eventually restore these parameter + * values back to the values of the current session. + */ + env_get( g_env, "DSQUERY", &expand); env_put( g_env, "DSQUERY", expand, ENV_F_TRAN ); + env_get( g_env, "database", &expand); env_put( g_env, "database", expand, ENV_F_TRAN ); + env_get( g_env, "username", &expand); env_put( g_env, "username", expand, ENV_F_TRAN ); + strcpy ( orig_password, g_password); + while ((ch = sqsh_getopt( argc, argv, "S:U:P:D:n" )) != EOF) { switch (ch) @@ -166,7 +181,7 @@ int cmd_do( argc, argv ) } /* - ** Before we go any further, read the reaminder of the input + ** Before we go any further, read the remainder of the input ** from the user (up to \done). */ do_buf = varbuf_create( 512 ); @@ -221,6 +236,7 @@ int cmd_do( argc, argv ) */ orig_sqlbuf = g_sqlbuf; orig_conn = g_connection; + orig_ctxt = g_context; /* ** And replace then with new copies. Note that setting @@ -240,6 +256,7 @@ int cmd_do( argc, argv ) if (do_connection == True) { g_connection = NULL; + g_context = NULL; if (jobset_run( g_jobset, "\\connect", &exit_status ) == -1) { fprintf( stderr, "\\do: Connect failed\n" ); @@ -261,9 +278,19 @@ int cmd_do( argc, argv ) g_connection = NULL; } + if (do_connection == True && + g_context != NULL) + { + if (ct_exit ( g_context, CS_UNUSED) != CS_SUCCEED) + ct_exit ( g_context, CS_FORCE_EXIT ); + cs_ctx_drop ( g_context ); + g_context = NULL; + } + varbuf_destroy( g_sqlbuf ); varbuf_destroy( do_buf ); + g_context = orig_ctxt; g_connection = orig_conn; g_sqlbuf = orig_sqlbuf; @@ -271,6 +298,7 @@ int cmd_do( argc, argv ) varbuf_destroy( expand_buf ); env_rollback( g_env ); + env_set( g_env, "password", orig_password ); return(ret); } diff --git a/src/dsp_html.c b/src/dsp_html.c index 6513d07..1a051fb 100644 --- a/src/dsp_html.c +++ b/src/dsp_html.c @@ -34,7 +34,7 @@ extern int errno; /*-- Current Version --*/ #if !defined(lint) && !defined(__LINT__) -static char RCS_Id[] = "$Id: dsp_html.c,v 1.3 2013/07/20 16:18:35 mwesdorp Exp $"; +static char RCS_Id[] = "$Id: dsp_html.c,v 1.4 2013/08/21 11:16:39 mwesdorp Exp $"; USE(RCS_Id) #endif /* !defined(lint) */ @@ -257,7 +257,7 @@ int dsp_html( output, cmd, flags ) } dsp_fputs( "</th>\n", output ); } - dsp_fputs( "</tr>\n</thead>\n", output ); + dsp_fputs( "</tr>\n</thead><tbody>\n", output ); } if (g_dsp_interrupted) @@ -272,7 +272,7 @@ int dsp_html( output, cmd, flags ) if (g_dsp_interrupted) goto dsp_interrupted; - dsp_fputs( "<tbody>\n<tr>\n", output ); + dsp_fputs( "<tr>\n", output ); for (i = 0; i < select_desc->d_ncols; i++) { col = &select_desc->d_cols[i]; @@ -297,7 +297,7 @@ int dsp_html( output, cmd, flags ) dsp_fputs( "</td>\n", output ); } - dsp_fputs( "</tr>\n</tbody>\n", output ); + dsp_fputs( "</tr>\n", output ); if (g_dsp_interrupted) goto dsp_interrupted; @@ -358,7 +358,7 @@ int dsp_html( output, cmd, flags ) if (in_table == CS_TRUE) { - dsp_fputs( "</table>\n", output ); + dsp_fputs( "</tbody></table>\n", output ); } if (last_row_result != CS_STATUS_RESULT && rows_affected != CS_NO_COUNT && @@ -462,7 +462,7 @@ static CS_INT dsp_comp_prrow_one( output, sel_desc, com_desc ) dsp_fputs( "</th>", output ); } - dsp_fputs( "</tr>\n</thead>\n", output ); + dsp_fputs( "</tr>\n</thead><tbody>\n", output ); dsp_fputs( "<tbody>\n<tr>\n", output ); for (i = 0; i < sel_desc->d_ncols; i++) diff --git a/src/sqsh_config.h b/src/sqsh_config.h index a4af922..91fbcc2 100644 --- a/src/sqsh_config.h +++ b/src/sqsh_config.h @@ -34,9 +34,10 @@ * The maximum length of a password. I just pulled this one out of * the air. * sqsh-2.1.6 - Increased value from 12 to 30 + * sqsh-2.4 - Increased value from 30 to 64 */ #ifndef SQSH_PASSLEN -#define SQSH_PASSLEN 30 +#define SQSH_PASSLEN 64 #endif /* @@ -148,7 +149,7 @@ /* * Current version number. */ -#define SQSH_VERSION "sqsh-2.3" +#define SQSH_VERSION "sqsh-2.4" #if !defined(__ansi__) # if defined(__STDC__) || defined(STDC_HEADERS) || defined(PROTOTYPES) diff --git a/src/sqsh_readline.c b/src/sqsh_readline.c index 98c8c13..8d7d788 100644 --- a/src/sqsh_readline.c +++ b/src/sqsh_readline.c @@ -34,10 +34,11 @@ #include "sqsh_readline.h" #include "sqsh_stdin.h" #include "sqsh_varbuf.h" +#include "sqsh_parser/sqsh_parser.h" /*-- Current Version --*/ #if !defined(lint) && !defined(__LINT__) -static char RCS_Id[] = "$Id: sqsh_readline.c,v 1.11 2013/07/20 16:18:35 mwesdorp Exp $" ; +static char RCS_Id[] = "$Id: sqsh_readline.c,v 1.12 2013/08/21 11:16:39 mwesdorp Exp $" ; USE(RCS_Id) #endif /* !defined(lint) */ @@ -56,7 +57,7 @@ static char* sqsh_generator _ANSI_ARGS(( char*, int )) ; */ static int sqsh_readline_addcol _ANSI_ARGS(( char* )) ; static int sqsh_readline_clearcol _ANSI_ARGS(( void )) ; -static int DynColnameLoad _ANSI_ARGS(( char* )) ; +static int DynColnameLoad _ANSI_ARGS(( char*, char* )) ; /* * sqsh-2.2.0 - Function prototypes for new feature readline_histignore. @@ -885,6 +886,8 @@ static char* sqsh_generator( text, state ) char *word; char *keyword_dynamic; char objname[256]; + varbuf_t *vb; + char *tn; len = strlen(text); nitems = sizeof(sqsh_statements) / sizeof(char*); @@ -915,13 +918,29 @@ static char* sqsh_generator( text, state ) * name we want to autocomplete. Obtain the objname from the text * and query all the column/parameter names for this object and * store them in a linked list. + * sqsh-2.4 : Added code to generate a completion list for aliased + * objectnames as well. Code contributed by K.-M. Hansche. */ for ( idx = 0; text[idx] != '\0' && text[idx] != '.'; idx++ ); if ( text[idx] == '.' ) { strncpy ( objname, text, idx ); objname[idx] = '\0'; - (void) DynColnameLoad ( objname ); + vb = varbuf_create ( varbuf_getlen(g_sqlbuf) + strlen(rl_line_buffer) ); + if (vb == NULL) + { + fprintf (stderr, "sqsh: %s\n", sqsh_get_errstr()); + sqsh_exit (255); + } + varbuf_strcpy ( vb, varbuf_getstr(g_sqlbuf) ); + varbuf_strcat ( vb, rl_line_buffer ); + + parseSql ( varbuf_getstr(vb) ); + tn = getTableForAlias ( objname ); + (void) DynColnameLoad ( (tn != NULL) ? tn : objname, objname ); + + varbuf_destroy(vb); + delTableDefs(); } else if (sg_colname_start != NULL) sqsh_readline_clearcol (); @@ -1226,8 +1245,9 @@ static int sqsh_readline_clearcol() * an existing table, view or stored procedure. * */ -static int DynColnameLoad (objname) +static int DynColnameLoad (objname, alias) char *objname; + char *alias; { CS_COMMAND *cmd; CS_DATAFMT columns[1]; @@ -1257,7 +1277,7 @@ static int DynColnameLoad (objname) return (CS_FAIL); } sprintf (query, "select \'%s.\' + name from syscolumns where id=object_id(\'%s\') order by name" - ,objname, objname); + ,alias, objname); if (ct_command( cmd, /* Command Structure */ CS_LANG_CMD, /* Command Type */ query, /* Query Buffer */ |