#pragma module "ISQL_VMS" "ISQL_VMS-1-053B" /* **++ ** FACILITY: ISQL/VMS ** ** MODULE DESCRIPTION: ** ** An Interactive SQL utility supposed to be used with Sybase or ** MicroSusck SQL server. Written by using the FreeTDS library. ** ** AUTHORS: ** ** Ruslan R. Laishev ** ** CREATION DATE: 19-NOV-2000 ** ** DESIGN ISSUES: ** ** This utility is supposed to be used as replacement the OpenRDA ISQL ** utility. A syntax of traditional ISQL/W utility is used. ** ** BUILD on VMS: ** ** $CC isql_vms.c,convert.c,login.c,mem.c,numeric.c,read.c,write.c,token.c,util.c - ** /nowarn/list/define=(TDS42,HW_LITTLE_ENDIAN)/inclu=[]/nomemb ** $LINK isql_vms.obj,convert.obj,login.obj,mem.obj,numeric.obj,read.obj,write.obj,token.obj,util.obj ** ** Set symbols before start ISQL_VMS.EXE ** ** $ISQL_CONNECT = "sa*dsfsdfsdfsdf@server.zztop.net" ** ** Optionaly: ** $ISQL_VERBOSE = 1 ** ** ** ** MODIFICATION HISTORY: ** ** 21-NOV-2000 RRL Replace REMUSERNAME,REMPASSWORD,REMSERVER by signle variable: ** ISQL_CONNECT = "sa*dsfsdfsdfsdf@server.zztop.net" ** 6-MAY-2001 RRL Modified TOKEN.C module to handle properly a PRINT '...' ** statement result. ** 12-JAN-2001 RRL Some cosmetic changes to use FreeTDS 0.53. ** 7-FEB-2003 RRL Added error message handling. ** ** {@tbs@}... **-- */ /* ** ** INCLUDE FILES ** */ #include #include #include #include #include /* ** ** FreeTDS LIBRARY INCLUDE FILES ** */ #include "tds.h" #include "tdsconvert.h" char space[256]; char minus[256]; int verbose; #define min(x,y) ((x > y)?y:x) #define max(x,y) ((x < y)?y:x) extern *g_tds_err_handler,g_tds_msg_handler; void msg_handler ( TDSSOCKET *tds ) { fprintf(stderr,"%L Msg %d, Level %d, State %d, Server %s, Line %d\n%s\n", tds->msg_info->msg_number, tds->msg_info->msg_level, tds->msg_info->msg_state, tds->msg_info->server, tds->msg_info->line_number, tds->msg_info->message); tds_free_msg(tds->msg_info); } void err_handler ( TDSSOCKET *tds ) { fprintf(stderr,"%s\n",tds->msg_info->message); tds_free_msg(tds->msg_info); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Print to SYS$OUTPUT columns name gotten from a server answer. ** ** FORMAL PARAMETERS: ** ** tds: a pointer to TDSSOCKET context structure ** ** RETURN VALUE: ** ** None ** **-- */ void out_col_names ( TDSSOCKET *tds ) { int col,spacelen; /* ** Print columns names with padding by space */ for ( col = 0;col < tds->res_info->num_cols;col++) { if ( 0 > (spacelen = tds->res_info->columns[col]->column_size - tds->res_info->columns[col]->column_namelen) ) spacelen = 0; fprintf(stdout,"%.*s%.*s ",tds->res_info->columns[col]->column_namelen, tds->res_info->columns[col]->column_name, spacelen,space); } fprintf(stdout,"\n"); /* ** Print the "----..." as separator */ for ( col = 0;col < tds->res_info->num_cols;col++) { spacelen = max(tds->res_info->columns[col]->column_size, tds->res_info->columns[col]->column_namelen); fprintf(stdout,"%.*s ",spacelen,minus); } fprintf(stdout,"\n"); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Print to SYS$OUTPUT a single row values gotten from a server answer. ** ** FORMAL PARAMETERS: ** ** tds: a pointer to TDSSOCKET context structure ** ** RETURN VALUE: ** ** None ** **-- */ void out_row_values ( TDSSOCKET *tds ) { int col,type,offset,size,null,spacelen,len; char * row; void * value; char buf [ 256 ]; TDS_INT status; row = tds->res_info->current_row; for ( col = 0;col < tds->res_info->num_cols;col++) { buf[0] = '\0'; type = tds->res_info->columns[col]->column_type; size = tds->res_info->columns[col]->column_size; offset = tds->res_info->columns[col]->column_offset; value = (row+offset); if ( tds_get_null(tds->res_info->current_row, col) ) { fprintf(stdout,"(Null) "); continue; } type = tds_get_conversion_type(type,size); tds_convert(type,value,size,SYBVARCHAR,buf,sizeof(buf)); switch (type) { case SYBVARCHAR: case SYBTEXT: case SYBNVARCHAR: len = fprintf(stdout,"%s ",buf); break; default: len = fprintf(stdout,"%s ",buf); } if ( 0 < (spacelen = size - len) ) fprintf(stdout,"%.*s ",spacelen,space); } fprintf(stdout,"\n"); } #define MAXLINES 128 #define MAXCHARS 1024 void main ( int argc, char ** argv ) { TDSLOGIN *login; TDSSOCKET *tds; int rc,i,lines,len,itty,otty; char sql_text[MAXLINES][MAXCHARS]; char buf[sizeof(sql_text)],*cp,user[32],pass[32],server[128]; /* ** Get a connect info string */ verbose = (NULL != getenv("ISQL_VERBOSE")); if ( !(cp = getenv("ISQL_CONNECT")) ) { fprintf(stderr,"ISQL_CONNECT is not defined\n"); exit (1); } if ( 3 != sscanf(cp,"%31[^*\n]*%31[^@\n]@%127[^\n]",user,pass,server) ) { fprintf(stderr,"ISQL_CONNECT is not defined\n"); exit (1); } if ( verbose ) fprintf(stderr,"Connect to '%s' with USERNAME = '%s',PASSWORD = '%s'.\n",server,user,pass); /* ** Is current output device is terminal ? */ otty = fileno(stdout); otty = isatty(otty); itty = fileno(stdin); itty = isatty(itty); /* ** Connect and login at server */ login = tds_alloc_login(); tds_set_user(login,user); tds_set_passwd(login,pass); tds_set_server(login,server); tds_set_app(login,"ISQL_VMS"); tds_set_host(login,"LocalHost"); tds_set_library(login,"Library"); tds_set_charset(login,"iso_1"); tds_set_language(login,"us_english"); tds_set_packet(login,512); if ( !(tds = tds_connect(login,NULL)) ) { fprintf(stderr,"Login failed.\n"); exit(1); } /* ** */ memset(space,' ',sizeof(space)); memset(minus,'-',sizeof(minus)); g_tds_err_handler = err_handler; g_tds_msg_handler = msg_handler; tds->parent = err_handler; /* ** Start processing a input stream of SQL expression */ while ( 1 ) { /* ** Input from the SYS$INPUT */ memset(sql_text,0,sizeof(sql_text)); if ( itty || verbose ) fprintf(stdout,"\nStart input a SQL expresion (%u maximum lines), GO to execute,^Z to exit\nISQL>",MAXLINES); /* ** Reading from the SYS$INPUT a portion of the SQL lines */ for(lines = 0;lines < MAXLINES;) { if ( !fgets(sql_text[lines],MAXCHARS,stdin) ) exit (0); if ( !strncmp(sql_text[lines],"GO",2) || (!strncmp(sql_text[lines],"go",2)) ) break; if ( itty || verbose ) fprintf(stderr,"\nCont> "); if ( !strlen(sql_text[lines]) ) continue; lines++; } /* ** Is there something to execute ? */ if ( !lines ) continue; /* ** Concatenate all lines into a single string */ for(len = i = 0; i < lines;i++) { if ( verbose ) fprintf(stderr,"%02.2u:%s",i+1,sql_text[i]); len += sprintf(buf+len," %s ",sql_text[i]); len--; } /* ** Submit a query */ tds_submit_query(tds,buf); /* ** Processing a result of the query processing */ while ( TDS_NO_MORE_RESULTS != (rc = tds_process_result_tokens(tds)) ) { if ( !tds->res_info ) continue; out_col_names(tds); while ( TDS_SUCCEED == (rc = tds_process_row_tokens(tds)) ) out_row_values(tds); } if ( tds->rows_affected && verbose ) fprintf(stdout,"\nSQL: %u row affected/selected\n",tds->rows_affected); } tds_free_socket(tds); tds_free_login(login); }