summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormwesdorp <mwesdorp>2013-08-21 11:16:39 +0000
committermwesdorp <mwesdorp>2013-08-21 11:16:39 +0000
commit0b56a9543189fc4a6afcf8ce1d6b8fa0a12b16fe (patch)
treefbd9c62c9df5465fdeac0c45a2ef78b512ac09fd /src
parent8d808bb71f1a5d3d84f61fac724cd46c7495476e (diff)
sqsh-2.4 New features and bugfixes
Diffstat (limited to 'src')
-rw-r--r--src/cmd_connect.c30
-rw-r--r--src/cmd_do.c30
-rw-r--r--src/dsp_html.c12
-rw-r--r--src/sqsh_config.h5
-rw-r--r--src/sqsh_readline.c30
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 */