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 / odbc.c < prev    next >
C/C++ Source or Header  |  1998-07-27  |  8KB  |  327 lines

  1. /* ODBCEX.C     General ODBC code for Odbcex example (all platforms)
  2. */
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <malloc.h>
  7. #include <ctype.h>
  8. #include <stdlib.h>
  9. #include "example.h"
  10.  
  11. #if defined( __DOS__ )
  12.   #if defined( __386__ )
  13.     #include "ds32odbc.h"
  14.   #else
  15.     #include "dosodbc.h"
  16.   #endif
  17. #elif defined( __QNX__ )
  18.   #include "qnxodbc.h"
  19. #elif defined( __OS2__ )
  20.   #include "os2odbc.h"
  21. #elif defined( __WINDOWS_386__ )
  22.     #include "winodbc.h"
  23. #elif defined( __NT__ )  ||  defined( __386__ )  ||  defined( _M_I386 )
  24.     #include "ntodbc.h"
  25. #elif defined( UNIX )
  26.     #include "unixodbc.h"
  27. #else 
  28.     #include "winodbc.h"
  29. #endif
  30.  
  31. typedef struct a_column {
  32.     char                *value;
  33.     SDWORD          size;   /* size of value fetched */
  34.     char            *colname;
  35.     int             width;
  36. } a_column;
  37.  
  38. extern int          PageSize;
  39. char                TableName[ NAME_LEN ];
  40. a_column            *Columns = NULL;
  41. SWORD                NumColumns;
  42. HENV                 Environment;
  43. HDBC                 Connection;
  44. HSTMT                Statement;
  45.  
  46. static int warning( char *msg )
  47. {
  48.     Displaytext( 0, "Not found - %s\n", msg );
  49.     return( TRUE );
  50. }
  51.  
  52. static int retcode( RETCODE rcode, HSTMT stmt )
  53. {
  54.     UCHAR        sqlstate[ 6 ];
  55.     UCHAR        error_msg[ 100 ];
  56.  
  57.     if( rcode == SQL_SUCCESS || rcode == SQL_SUCCESS_WITH_INFO ) {
  58.     return( TRUE );
  59.     } else if( rcode == SQL_NO_DATA_FOUND ) {
  60.     return( FALSE );
  61.     } else {
  62.     SQLError( Environment, Connection, stmt, sqlstate, NULL,
  63.           error_msg, sizeof( error_msg ), NULL );
  64.     Displaytext( 0, "SQL error %s -- %s\n", sqlstate, error_msg );
  65.     return( FALSE );
  66.     }
  67. }
  68.  
  69. static void make_columns( HSTMT statement )
  70. {
  71.     char                colname[ NAME_LEN + 1 ];
  72.     SWORD        namelen;
  73.     UWORD        col;
  74.     SDWORD        size;
  75.  
  76.     retcode( SQLNumResultCols( statement, &NumColumns ), statement );
  77.     Columns = (a_column *) calloc( NumColumns, sizeof( a_column ) );
  78.     for( col = 0; col < NumColumns; ++col ) {
  79.         retcode( SQLColAttributes( statement, (UWORD) (col + 1), SQL_COLUMN_DISPLAY_SIZE,
  80.         NULL, 0, NULL, &size ), statement );
  81.         if( size > MAX_FETCH_SIZE ) {
  82.         size = MAX_FETCH_SIZE;
  83.         }
  84.         Columns[ col ].width = (int) size;
  85.         Columns[ col ].value = (char *) malloc( (int)(size + 1) );
  86.         retcode( SQLBindCol( statement, (UWORD) (col + 1), SQL_C_CHAR,
  87.         Columns[ col ].value, Columns[ col ].width + 1,
  88.         &Columns[ col ].size ), statement );
  89.         retcode( SQLColAttributes( statement, (UWORD) (col + 1), SQL_COLUMN_NAME,
  90.         colname, NAME_LEN, &namelen, NULL ), statement );
  91.         Columns[ col ].colname = (char *) malloc( namelen + 1 );
  92.         strcpy( Columns[ col ].colname, colname );
  93.         if( Columns[ col ].width < namelen ) {
  94.         Columns[ col ].width = namelen;
  95.         }
  96.         if( Columns[ col ].width < NULL_TEXT_LEN ) {
  97.         Columns[ col ].width = NULL_TEXT_LEN;
  98.         }
  99.     }
  100. }
  101.  
  102. static void free_columns()
  103. {
  104.     int            col;
  105.  
  106.     for( col = 0; col < NumColumns; ++col ) {
  107.     free( Columns[ col ].value );
  108.     free( Columns[ col ].colname );
  109.     }
  110.     free( Columns );
  111.     Columns = NULL;
  112.     NumColumns = 0;
  113. }
  114.  
  115. static int open_cursor()
  116. {
  117.     char                buff[ 100 ];
  118.  
  119.     if( !retcode( SQLAllocStmt( Connection, &Statement ), NULL ) ) {
  120.     return( FALSE ); 
  121.     }
  122.     if( !retcode( SQLSetScrollOptions( Statement, SQL_CONCUR_VALUES, SQL_SCROLL_DYNAMIC, 1 ), Statement ) ) {
  123.     return( FALSE );
  124.     }
  125.  
  126.     sprintf( buff, "select * from %s", TableName );
  127.     if( !retcode( SQLPrepare( Statement, (UCHAR *)buff, SQL_NTS ), Statement ) ) {
  128.     return( FALSE );
  129.     }
  130.     SQLSetStmtOption( Statement, SQL_TXN_ISOLATION, 0 );
  131.     if( !retcode( SQLExecute( Statement ), Statement ) ) {
  132.     return( FALSE );
  133.     }
  134.     make_columns( Statement );
  135.     return( TRUE );
  136. }
  137.  
  138. static int close_cursor()
  139. {
  140.     free_columns();
  141.     SQLFreeStmt( Statement, SQL_DROP );
  142.     Statement = NULL;
  143.     return( TRUE );
  144. }
  145.  
  146. static int fetch_row()
  147. {
  148.     int            okay;
  149.     UDWORD        numfetch;
  150.  
  151.     okay = retcode( SQLExtendedFetch( Statement, SQL_FETCH_NEXT, 0,
  152.             &numfetch, NULL ), Statement );
  153.     if( !okay ) return( FALSE );
  154.     if( numfetch == 0 ) {
  155.     warning( "fetching" );
  156.     return( FALSE );
  157.     }
  158.     return( TRUE );
  159. }
  160.  
  161. static void move( long relpos )
  162. {
  163.     UDWORD        numfetch;
  164.     int            okay;
  165.  
  166.     if( relpos == 0 ) return;
  167.     okay = retcode( SQLExtendedFetch( Statement, SQL_FETCH_RELATIVE,
  168.             relpos, &numfetch, NULL ), Statement );
  169.     if( !okay ) return;
  170.     if( numfetch == 0 ) {
  171.     warning( "moving" );
  172.     }
  173. }
  174.  
  175. static int top()
  176. {
  177.     UDWORD        numfetch;
  178.     int            okay;
  179.  
  180.     okay = retcode( SQLExtendedFetch( Statement, SQL_FETCH_FIRST, 0,
  181.             &numfetch, NULL ), Statement );
  182.     if( okay ) {
  183.     okay = retcode( SQLExtendedFetch( Statement, SQL_FETCH_RELATIVE,
  184.                 -1, &numfetch, NULL ), Statement );
  185.     }
  186.     return( okay );
  187. }
  188.  
  189. static int bottom()
  190. {
  191.     UDWORD        numfetch;
  192.     int            okay;
  193.  
  194.     okay = retcode( SQLExtendedFetch( Statement, SQL_FETCH_LAST, 0,
  195.             &numfetch, NULL ), Statement );
  196.     return( okay );
  197. }
  198.  
  199. static void print_headings()
  200. {
  201.     int                 i;
  202.     int                 width;
  203.     int                 total;
  204.  
  205.     total = 0;
  206.     for( i = 0; i < NumColumns; ++i ) {
  207.     width = Columns[ i ].width;
  208.     Displaytext( total, "%-*.*s", width, width, Columns[ i ].colname );
  209.     total += width + 1;
  210.     }
  211.     Displaytext( 0, "\n" );
  212. }
  213.  
  214. static void print_data()
  215. {
  216.     int                 i;
  217.     int                 width;
  218.     int                 total;
  219.     char        *data;
  220.  
  221.     total = 0;
  222.     for( i = 0; i < NumColumns; ++i ) {
  223.     width = Columns[ i ].width;
  224.     if( Columns[ i ].size == SQL_NULL_DATA ) {
  225.         data = NULL_TEXT;
  226.     } else {
  227.         data = Columns[ i ].value;
  228.     }
  229.         Displaytext( total, "%-*.*s", width, width, data );
  230.     total += width + 1;
  231.     }
  232.     Displaytext( 0, "\n" );
  233. }
  234.  
  235. static void print()
  236. {
  237.     int                 i;
  238.  
  239.     if( Statement == NULL ) {
  240.         Displaytext( 0, "*** Error: Cursor not open." );
  241.     return;
  242.     }
  243.     print_headings();
  244.     for( i = 0; i < PageSize; ) {
  245.         ++i;
  246.         if( !fetch_row() ) {
  247.         break;
  248.     }
  249.     print_data();
  250.     }
  251.     move( -i );
  252. }
  253.  
  254. static void help()
  255. {
  256.     Displaytext( 0, "ODBC Cursor Demonstration Program Commands:\n" );
  257.     Displaytext( 0, "p - Print current page\n" );
  258.     Displaytext( 0, "u - Move up a page\n" );
  259.     Displaytext( 0, "d - Move down a page\n" );
  260.     Displaytext( 0, "b - Move to bottom page\n" );
  261.     Displaytext( 0, "t - Move to top page\n" );
  262.     Displaytext( 0, "n - New table\n" );
  263.     Displaytext( 0, "q - Quit\n" );
  264.     Displaytext( 0, "h - Help (this screen)\n" );
  265. }
  266.  
  267. extern int WSQLEX_Init()
  268. {
  269.     if( SQLAllocEnv( &Environment ) != SQL_SUCCESS ) return( FALSE );
  270.     if( SQLAllocConnect( Environment, &Connection ) != SQL_SUCCESS ) {
  271.         SQLFreeEnv( Environment );
  272.         return( FALSE );
  273.     }
  274.     retcode( SQLConnect( Connection, (UCHAR *)"ASA 6.0 Sample", SQL_NTS,
  275.                  (UCHAR *)"DBA", SQL_NTS, (UCHAR *)"SQL", SQL_NTS ), NULL );
  276.     GetTableName( TableName, MAX_TABLE_NAME );
  277.     open_cursor();
  278.     help(); 
  279.     return( TRUE );
  280. }
  281.  
  282. extern void WSQLEX_Process_Command( int selection )
  283. {
  284.     switch( tolower( selection ) ) {
  285.         case 'p':       print();
  286.             break;
  287.  
  288.     case 'u':    move( -PageSize );
  289.             print();
  290.             break;
  291.  
  292.     case 'd':    move( PageSize );
  293.             print();
  294.             break;
  295.  
  296.     case 't':    top();
  297.             print();
  298.             break;
  299.  
  300.     case 'b':    bottom();
  301.             move( -PageSize );
  302.             print();
  303.             break;
  304.  
  305.     case 'h':    help();
  306.             break;
  307.  
  308.     case 'n':    close_cursor();
  309.                         GetTableName( TableName, MAX_TABLE_NAME);
  310.                         open_cursor();
  311.             break;
  312.             
  313.     default:    Displaytext( 0, 
  314.                 "Invalid command, press 'h' for help\n" );
  315.     }
  316. }
  317.             
  318. extern int WSQLEX_Finish()
  319. {
  320.     close_cursor();
  321.     SQLTransact( Environment, Connection, SQL_ROLLBACK );
  322.     SQLDisconnect( Connection );
  323.     SQLFreeConnect( Connection );
  324.     SQLFreeEnv( Environment );
  325.     return( TRUE );
  326. }
  327.