home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 December / PCWorld_1998-12_cd.iso / software / sybase / ASA / asa60.exe / data1.cab / cxmp_files / dcur.sqc < prev    next >
Text File  |  1998-07-27  |  9KB  |  357 lines

  1. /* DCUR.SQC    General SQL code for Dcursex example (all platforms)
  2. */
  3.  
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. EXEC SQL INCLUDE SQLCA;
  9. EXEC SQL INCLUDE SQLDA;
  10. #include "sqldef.h"
  11. #include "example.h"
  12.  
  13. #define MAX_COL_WIDTH    50
  14.  
  15. extern int             PageSize;
  16. static char        TableName[MAX_TABLE_NAME];
  17. static SQLDA            _fd_ *SqlDA;
  18.  
  19. #ifdef _SQL_OS_NETWARE
  20.     #define Stringncopy(x,y,z)        strncpy(x,y,z)
  21.     #define Stringcat(x,y)        strcat(x,y)
  22. #else
  23.     #ifdef __SMALLDATA__
  24.     #define Stringncopy(x,y,z)        _fstrncpy(x,y,z)
  25.     #define Stringcat(x,y)        _fstrcat(x,y)
  26.     #else
  27.     #define Stringncopy(x,y,z)        strncpy(x,y,z)
  28.     #define Stringcat(x,y)        strcat(x,y)
  29.     #endif
  30. #endif
  31.  
  32. EXEC SQL BEGIN DECLARE SECTION;
  33. static char                   CursName[ 20 ];
  34. static a_sql_statement_number stat;
  35. EXEC SQL END DECLARE SECTION;
  36.  
  37. static void printSQLError()
  38. {
  39.     char                buffer[ 200 ];
  40.  
  41.     Displaytext( 0, "SQL error -- %s" MY_NEWLINE_STR,
  42.     sqlerror_message( &sqlca, buffer, sizeof( buffer ) ) );
  43. }
  44.  
  45. static int warning( char *msg )
  46. {
  47.     if( SQLCODE == SQLE_NOTFOUND ) {
  48.         if( SQLCOUNT >= 0 ) {
  49.         Displaytext( 0, "Not found - past bottom of table" MY_NEWLINE_STR );
  50.     } else {
  51.         Displaytext( 0, "Not found - past top of table" MY_NEWLINE_STR );
  52.     }
  53.     } else {
  54.     Displaytext( 0, 
  55.         "Unexpected warning %ld -- %s" MY_NEWLINE_STR, SQLCODE, msg );
  56.     }
  57.     return( TRUE );
  58. }
  59.  
  60. EXEC SQL WHENEVER SQLERROR { printSQLError(); return( FALSE ); };
  61.  
  62. static int open_cursor()
  63. {
  64.     EXEC SQL BEGIN DECLARE SECTION;
  65.     char                    buff[ 100 ];
  66.     EXEC SQL END DECLARE SECTION;
  67.     int                 n;
  68.  
  69.     sprintf( buff, "select * from %s", TableName );
  70.  
  71.     /* Note that database fills in statement number on prepare */
  72.     EXEC SQL PREPARE :stat FROM :buff;
  73.  
  74.     /* Note that we must initialize the cursor name */
  75.     strcpy( CursName, "table_cursor" );
  76.     EXEC SQL DECLARE :CursName CURSOR FOR :stat;
  77.  
  78.     EXEC SQL OPEN :CursName;
  79.  
  80.     SqlDA = alloc_sqlda( 3 );
  81.     EXEC SQL DESCRIBE :stat INTO SqlDA;
  82.     if( SqlDA->sqld > SqlDA->sqln ) {
  83.     n = SqlDA->sqld;
  84.     free_sqlda( SqlDA );
  85.     SqlDA = alloc_sqlda( n );
  86.     EXEC SQL DESCRIBE :stat INTO SqlDA;
  87.     }
  88.     fill_s_sqlda( SqlDA, 1000 );
  89.     return( TRUE );
  90. }
  91.  
  92. static int close_cursor()
  93. {
  94.     EXEC SQL CLOSE :CursName;
  95.     free_filled_sqlda( SqlDA );
  96.     SqlDA = NULL;
  97.     EXEC SQL DROP STATEMENT :stat;
  98.     return( TRUE );
  99. }
  100.  
  101. static int fetch_row()
  102. {
  103.     EXEC SQL FETCH RELATIVE 1 :CursName USING DESCRIPTOR SqlDA;
  104.  
  105.     if( SQLCODE < 0  ||  SQLCODE == SQLE_NOTFOUND ) {
  106.     warning( "Fetching" );
  107.     return( FALSE );
  108.     } else if( SQLCODE != 0 ) {
  109.     warning( "Fetching" );
  110.     return( TRUE );
  111.     } else {
  112.     return( TRUE );
  113.     }
  114. }
  115.  
  116. static int move(
  117.     EXEC SQL BEGIN DECLARE SECTION;
  118.     int                 relpos
  119.     EXEC SQL END DECLARE SECTION;
  120.     )
  121. {
  122.     EXEC SQL FETCH RELATIVE :relpos :CursName;
  123.     if( SQLCODE == SQLE_NOTFOUND && SQLCOUNT == 0 ) {
  124.     } else if( SQLCODE ) {
  125.     warning( "Moving" );
  126.     return( FALSE );
  127.     }
  128.     return( TRUE );
  129. }
  130.  
  131. static int top()
  132. {
  133.     EXEC SQL FETCH ABSOLUTE 0 :CursName;
  134.     return( TRUE );
  135. }
  136.  
  137. static int bottom()
  138. {
  139.     EXEC SQL FETCH ABSOLUTE -1 :CursName;
  140.     return( TRUE );
  141. }
  142.  
  143. static void help()
  144. {
  145.     Displaytext( 0, "DCursex Demonstration Program Commands:" MY_NEWLINE_STR );
  146.     Displaytext( 0, "p - Print current page" MY_NEWLINE_STR );
  147.     Displaytext( 0, "u - Move up a page" MY_NEWLINE_STR );
  148.     Displaytext( 0, "d - Move down a page" MY_NEWLINE_STR );
  149.     Displaytext( 0, "b - Move to bottom page" MY_NEWLINE_STR );
  150.     Displaytext( 0, "t - Move to top page" MY_NEWLINE_STR );
  151.     Displaytext( 0, "i - Insert a new row" MY_NEWLINE_STR );
  152.     Displaytext( 0, "n - New table" MY_NEWLINE_STR );
  153.     Displaytext( 0, "c - Commit changes and close cursor" MY_NEWLINE_STR );
  154.     Displaytext( 0, "q - Quit" MY_NEWLINE_STR );
  155.     Displaytext( 0, "h - Help (this screen)" MY_NEWLINE_STR );
  156. }
  157.  
  158. static int col_width( SQLDA _fd_ *da, int col )
  159. {
  160.     int                 col_name_len;
  161.     int                 data_len;
  162.     SQLDA_VARIABLE      _fd_ *sqlvar;
  163.  
  164.     sqlvar = &da->sqlvar[ col ];
  165.     col_name_len = sqlvar->sqlname.length;
  166.     data_len = sqlvar->sqllen;
  167.     if( data_len > col_name_len ) {
  168.     col_name_len = data_len;
  169.     }
  170.     if( strlen( NULL_TEXT ) > col_name_len ) {
  171.     col_name_len = strlen( NULL_TEXT );
  172.     }
  173.     if( col_name_len > MAX_COL_WIDTH ) {
  174.         return( MAX_COL_WIDTH );
  175.     }
  176.     return( col_name_len );
  177. }
  178.  
  179. static void print_headings( SQLDA _fd_ *da )
  180. {
  181.     int                 i;
  182.     int                 width;
  183.     int                 total;
  184.     char                colname[ SQL_MAX_NAME_LEN + 1 ];
  185.     char _fd_           *sqlname;
  186.  
  187.     total = 0;
  188.     for( i = 0; i < da->sqld; ++i ) {
  189.         width = col_width( da, i );
  190.         sqlname = da->sqlvar[ i ].sqlname.data;
  191.     Stringncopy( colname, sqlname, 
  192.         da->sqlvar[ i ].sqlname.length );
  193.         colname[ da->sqlvar[ i ].sqlname.length ] = '\0';
  194.         Displaytext( total, "%-*.*s", width, width, colname );
  195.         total += width+1;
  196.     }
  197.     Displaytext( 0, MY_NEWLINE_STR );
  198. }
  199.  
  200. static void print_data( SQLDA _fd_ *da )
  201. {
  202.     int                 i;
  203.     int                 width;
  204.     int                 total;
  205.     SQLDA_VARIABLE _fd_ *sqlvar;
  206.     char _sqldafar      *data;
  207.  
  208.     total = 0;
  209.     for( i = 0; i < da->sqld; ++i ) {
  210.     width = col_width( da, i );
  211.     sqlvar = &da->sqlvar[ i ];
  212.     if( *( sqlvar->sqlind ) < 0 ) {
  213.         data = NULL_TEXT;
  214.     } else {
  215.         data = (char _sqldafar *)sqlvar->sqldata;
  216.     }
  217.     #if _sqlfar_isfar
  218.         Displaytext( total, "%-*.*Fs", width, width, 
  219.             (char far *)data );
  220.     #else
  221.         Displaytext( total, "%-*.*s", width, width, data );
  222.     #endif
  223.     total += width+1;
  224.     }
  225.     Displaytext( 0, MY_NEWLINE_STR );
  226. }
  227.  
  228. static void print()
  229. {
  230.     int                 i;
  231.  
  232.     if( SqlDA == NULL ) {
  233.         Displaytext( 0, "*** Error: Cursor not open" MY_NEWLINE_STR );
  234.         return;
  235.     }
  236.     print_headings( SqlDA );
  237.     for( i = 0; i < PageSize; ) {
  238.         ++i;
  239.         if( fetch_row() ) {
  240.         print_data( SqlDA );
  241.         } else {
  242.         break;
  243.         }
  244.     }
  245.     move( -i );
  246. }
  247.  
  248. static int insert()
  249. {
  250.     char        prompt[ 80 ];
  251.     char        newvalue[ 80 ];
  252.     char _sqldafar      *data;
  253.     int            i;
  254.  
  255.     for( i = 0; i < SqlDA->sqld; i++ ) {
  256.     strcpy( prompt, "Enter a value for '" );
  257.     Stringcat( prompt, SqlDA->sqlvar[i].sqlname.data);
  258.     strcat( prompt, "'" );
  259.     data = (char _sqldafar *) SqlDA->sqlvar[i].sqldata;
  260.     GetValue( prompt, newvalue, 80 );
  261.     if( newvalue[0] == '\0'
  262.             && (SqlDA->sqlvar[i].sqltype & DT_NULLS_ALLOWED) != 0 ) {
  263.             *SqlDA->sqlvar[i].sqlind = -1;
  264.     } else {
  265.             *SqlDA->sqlvar[i].sqlind = 0;
  266.         Stringncopy( data, newvalue, SqlDA->sqlvar[i].sqllen );
  267.     }
  268.     }
  269.     EXEC SQL PUT :CursName USING DESCRIPTOR SqlDA;
  270.     return( TRUE );
  271. }
  272.  
  273. extern int WSQLEX_Init()
  274. {
  275.     char        parmstr[ 251 ];
  276.     
  277.     if( !db_init( &sqlca ) ) {
  278.         Display_systemerror( 
  279.         "Unable to initialize database interface" MY_NEWLINE_STR );
  280.         return( FALSE );
  281.     }
  282.     GetValue( "Enter connection string", parmstr, 250 );
  283.     if( strlen( parmstr ) == 0 ) {
  284.     strcpy( parmstr, 
  285.         "UID=dba;PWD=sql;DBF=c:\\sybase\\asa6\\asademo.db;ENG=asademo" );
  286.     }
  287.     db_string_connect( &sqlca, parmstr );
  288.     if( SQLCODE != SQLE_NOERROR ) {
  289.         printSQLError();
  290.     db_fini( &sqlca );
  291.         return( FALSE );
  292.     }
  293.     GetTableName( TableName, MAX_TABLE_NAME );
  294.     open_cursor();
  295.     help();
  296.     return( TRUE );
  297. }
  298.  
  299. static int commit_and_close( void )
  300. /*********************************/
  301. {
  302.     EXEC SQL COMMIT;
  303.     close_cursor();
  304.     return( TRUE );
  305. }
  306.  
  307. extern void WSQLEX_Process_Command( int selection )
  308. {
  309.     switch( tolower( selection ) ) {
  310.     case 'c':    commit_and_close();
  311.             break;
  312.  
  313.     case 'p':    print();
  314.             break;
  315.  
  316.     case 'u':    move( -PageSize );
  317.             print();
  318.             break;
  319.  
  320.     case 'd':    move( PageSize );
  321.             print();
  322.             break;
  323.  
  324.     case 't':    top();
  325.             print();
  326.             break;
  327.  
  328.     case 'b':    bottom();
  329.             move( -PageSize );
  330.             print();
  331.             break;
  332.  
  333.     case 'h':    help();
  334.             break;
  335.  
  336.     case 'n':    close_cursor();
  337.                     GetTableName( TableName, MAX_TABLE_NAME );
  338.                     open_cursor();
  339.             break;
  340.  
  341.         case 'i':       insert();
  342.             break;
  343.  
  344.     default:    Displaytext( 0, 
  345.                 "Invalid command, press 'h' for help" MY_NEWLINE_STR );
  346.     }
  347. }
  348.  
  349. extern int WSQLEX_Finish()
  350. {
  351.     close_cursor();
  352.     EXEC SQL ROLLBACK WORK;
  353.     EXEC SQL DISCONNECT;
  354.     db_fini( &sqlca );
  355.     return( TRUE );
  356. }
  357.