home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cppsql.zip / SQLSRC.ZIP / SQLC.SQC < prev    next >
Text File  |  1992-09-18  |  23KB  |  808 lines

  1. /* :H1 SQLC: START OF SPECIFICATIONS
  2. //----------------------------------------------------------------------
  3. //
  4. //  Module Name: SQLC
  5. //
  6. //  Description: This module interfaces to the SQL database.
  7. //
  8. //  Product Classification:
  9. //    IBM Internal Use Only
  10. //    (C) Copyright IBM Corp. 1992
  11. //
  12. //  Status: New
  13. //
  14. //  Initial Author: George L. Havens
  15. //
  16. //  Function: This module provides a C interface to the SQL routines
  17. //            required by the SQL object.
  18. //
  19. //  Notes: This module must be compiled into a C module using SQLPREP.
  20. //
  21. //  Dependencies: Description of any dependency this module
  22. //                has on any other module
  23. //
  24. //  Restrictions: *************************WARNING************************
  25. //                DO NOT MAKE MODIFICATIONS IN THE SQLC.C FILE.
  26. //                MAKE MODIFICATIONS IN THE SQLC.SQC FILE AND RUN SQLPREP TO
  27. //                CREATE THE SQLC.C FILE.
  28. //
  29. //  Compiler: Zortech C++
  30. //
  31. // Change Activity -----------------------------------------------------
  32. //
  33. // $MOD(SQLC) COMP(XREFGEN) PROD(WRTSVILL): Interface to SQL database.
  34. //
  35. // FLAG  REASON  VERS  DATE  WHO   DESCRIPTION
  36. // ---- -------- ---- ------ ---   -----------
  37. // $D0   XXXXXX  V100 920224 GLH : Initial level
  38. //
  39. // END-OF-SPECIFICATIONS -----------------------------------------------*/
  40.  
  41. #include "stdio.h"
  42. #include "sqlenv.h"
  43. #include "sqlutil.h"
  44.  
  45.  
  46. #include "portable.h"
  47.  
  48. static cursor_open = FALSE;
  49.  
  50. EXEC SQL INCLUDE SQLCA;
  51.  
  52. EXEC SQL BEGIN DECLARE SECTION;
  53. char host_string[200];
  54. EXEC SQL END DECLARE SECTION;
  55.  
  56. EXEC SQL DECLARE C1 CURSOR FOR S1;
  57.  
  58. struct sqlda *host_var;
  59.  
  60. /* :H1 sql_create: Create SQL Database
  61. //----------------------------------------------------------------------
  62. //
  63. //  Function Name: Create database
  64. //
  65. //  Purpose: This function will create an SQL database.
  66. //
  67. //  Description: This function will create an SQL database using the
  68. //               SQL API.
  69. //
  70. //  Input:
  71. //    name       Database name to be created
  72. //    comment    Comment to be inserted into the database
  73. //    bind_path  Bind file path name
  74. //    drive      Drive to build database on
  75. //
  76. //  Output:
  77. //    return     returns SQL return code
  78. //
  79. //----------------------------------------------------------------------*/
  80.  
  81. SHORT sql_create (CHAR *name, CHAR *comment, CHAR *bind_path, CHAR drive)
  82.   {
  83.     /* create database */
  84.     sqlecred (name,             /* database name */
  85.               drive,            /* database drive */
  86.               comment,          /* comment string */
  87.               0,                /* codepage */
  88.               &sqlca);          /* sqlca */
  89.  
  90.     /* if create error */
  91.     if (sqlca.sqlcode != 0)
  92.         return (sqlca.sqlcode);
  93.  
  94.     /* bind database to program */
  95.     sqlabind (bind_path, name, (char *)0, "NUL:", "DEF", &sqlca);
  96.  
  97.     return (sqlca.sqlcode);
  98.   }
  99.  
  100. /* :H1 sql_delete: Delete SQL Database
  101. //----------------------------------------------------------------------
  102. //
  103. //  Function Name: Delete database
  104. //
  105. //  Purpose: This function will delete an SQL database.
  106. //
  107. //  Description: This function deletes an SQL database using the SQL
  108. //               API.
  109. //
  110. //  Input:
  111. //    name       Database name to be deleted
  112. //
  113. //  Output:
  114. //    return     returns SQL return code
  115. //
  116. //----------------------------------------------------------------------*/
  117.  
  118. SHORT sql_delete (CHAR *name)
  119.   {
  120.     /* delete database */
  121.     sqledrpd (name, &sqlca);
  122.  
  123.     return (sqlca.sqlcode);
  124.   }
  125.  
  126. /* :H1 sql_start: Start SQL Database Manager
  127. //----------------------------------------------------------------------
  128. //
  129. //  Function Name: Start database manager
  130. //
  131. //  Purpose: This function will start the database manager.
  132. //
  133. //  Description: This function starts the database manager using the SQL
  134. //               API. It does not return an error if the database manager has
  135. //               already been started.
  136. //
  137. //  Input:
  138. //    none
  139. //
  140. //  Output:
  141. //    return     returns SQL return code
  142. //
  143. //----------------------------------------------------------------------*/
  144.  
  145. SHORT sql_start ()
  146.   {
  147.    SHORT rc;
  148.  
  149.     /* start database manager  */
  150.     rc = sqlestar ();
  151.  
  152.     /* if database manager already active */
  153.     if (rc == SQLE_RC_INVSTRT)
  154.         /* set to return OK */
  155.         rc = 0;
  156.  
  157.     return (rc);
  158.   }
  159.  
  160. /* :H1 sql_stop: Stop SQL Database Manager
  161. //----------------------------------------------------------------------
  162. //
  163. //  Function Name: Stop database manager
  164. //
  165. //  Purpose: This function will stop the database manager.
  166. //
  167. //  Description: This function stops the database manager using the SQL
  168. //               API.
  169. //
  170. //  Input:
  171. //    none
  172. //
  173. //  Output:
  174. //    return     returns SQL return code
  175. //
  176. //----------------------------------------------------------------------*/
  177.  
  178. SHORT sql_stop ()
  179.   {
  180.     /* stop database manager */
  181.     sqlestop (&sqlca);
  182.  
  183.     return (sqlca.sqlcode);
  184.   }
  185.  
  186. /* :H1 sql_open: Open Database
  187. //----------------------------------------------------------------------
  188. //
  189. //  Function Name: Open a database
  190. //
  191. //  Purpose: This function will connect a database to the application.
  192. //
  193. //  Description: This function binds and connects to the database using
  194. //               the SQL API.
  195. //
  196. //  Input:
  197. //    name       Database name to be opened.
  198. //    use        use database access, shared or exclusive
  199. //
  200. //  Output:
  201. //    return     returns SQL return code
  202. //
  203. //----------------------------------------------------------------------*/
  204.  
  205. SHORT sql_open (CHAR *name, CHAR use)
  206.   {
  207.     /* start using database */
  208.     sqlestrd (name, use, &sqlca);
  209.  
  210.     return (sqlca.sqlcode);
  211.   }
  212.  
  213. /* :H1 sql_close: Close Database
  214. //----------------------------------------------------------------------
  215. //
  216. //  Function Name: Close a database
  217. //
  218. //  Purpose: This function will disconnect a database from the application.
  219. //
  220. //  Description: This function disconnects from the database using
  221. //               the SQL API. It will also close the cursor if it is open.
  222. //
  223. //  Input:
  224. //    none
  225. //
  226. //  Output:
  227. //    return     returns SQL return code
  228. //
  229. //----------------------------------------------------------------------*/
  230.  
  231. SHORT sql_close ()
  232.   {
  233.     /* if cursor is open */
  234.     if (cursor_open == TRUE)
  235.       {
  236.         /* close cursor */
  237.         EXEC SQL CLOSE C1;
  238.         /* if close cursor error */
  239.         if (sqlca.sqlcode != 0)
  240.             return (sqlca.sqlcode);
  241.  
  242.         /* set cursor is not open */
  243.         cursor_open = FALSE;
  244.       }
  245.  
  246.     /* stop using database */
  247.     sqlestpd (&sqlca);
  248.  
  249.     return (sqlca.sqlcode);
  250.   }
  251.  
  252. /* :H1 sql_dynamic: Dynamic SQL Statements
  253. //----------------------------------------------------------------------
  254. //
  255. //  Function Name: sql_dynamic
  256. //
  257. //  Purpose: This function will perform dynamic SQL statements.
  258. //
  259. //  Description: This function executes a dynamic SQL statement.
  260. //
  261. //  Input:
  262. //    statement  dynamic SQL statement to be executed
  263. //
  264. //  Output:
  265. //    return     returns SQL return code
  266. //
  267. //----------------------------------------------------------------------*/
  268.  
  269. SHORT sql_dynamic (CHAR *statement)
  270.   {
  271.     /* move statement to host variable */
  272.     strcpy (host_string, statement);
  273.  
  274.     EXEC SQL EXECUTE IMMEDIATE :host_string;
  275.  
  276.     return (sqlca.sqlcode);
  277.   }
  278.  
  279. /* :H1 sql_desc: Dynamic SQL Statements Using Descriptors
  280. //----------------------------------------------------------------------
  281. //
  282. //  Function Name: sql_desc
  283. //
  284. //  Purpose: This function will perform dynamic SQL statements
  285. //           using descriptors.
  286. //
  287. //  Description: This function executes a dynamic SQL statement using
  288. //               descriptors.
  289. //
  290. //  Input:
  291. //    statement  dynamic SQL statement to be executed
  292. //    var        pointer to SQLDA
  293. //
  294. //  Output:
  295. //    return     returns SQL return code
  296. //
  297. //----------------------------------------------------------------------*/
  298.  
  299. SHORT sql_desc (CHAR *statement, struct sqlda *var)
  300.   {
  301.     /* move statement to host variable */
  302.     strcpy (host_string, statement);
  303.     host_var = var;
  304.  
  305.     EXEC SQL PREPARE S2 FROM :host_string;
  306.     /* if prepare error */
  307.     if (sqlca.sqlcode != 0)
  308.         return (sqlca.sqlcode);
  309.  
  310.     EXEC SQL EXECUTE S2 USING DESCRIPTOR :*host_var;
  311.  
  312.     return (sqlca.sqlcode);
  313.   }
  314.  
  315. /* :H1 sql_fetch: Dynamic SQL Fetch Statement Using Descriptors
  316. //----------------------------------------------------------------------
  317. //
  318. //  Function Name: sql_fetch
  319. //
  320. //  Purpose: This function will perform dynamic SQL fetch statement
  321. //           using descriptors.
  322. //
  323. //  Description: This function executes a fetch SQL statement using
  324. //               descriptors.
  325. //
  326. //  Input:
  327. //    initial    initial search?
  328. //    statement  statement to run
  329. //    var        pointer to SQLDA
  330. //
  331. //  Output:
  332. //    return     returns SQL return code
  333. //
  334. //----------------------------------------------------------------------*/
  335.  
  336. SHORT sql_fetch (BOOLEAN initial, CHAR *statement, struct sqlda *var)
  337.   {
  338.     if (initial == TRUE)
  339.       {
  340.         /* move statement to host variable */
  341.         strcpy (host_string, statement);
  342.         host_var = var;
  343.  
  344.         /* if cursor already open */
  345.         if (cursor_open == TRUE)
  346.           {
  347.             /* close cursor */
  348.             EXEC SQL CLOSE C1;
  349.             /* if close cursor error */
  350.             if (sqlca.sqlcode != 0)
  351.                 return (sqlca.sqlcode);
  352.  
  353.             /* set cursor is not open */
  354.             cursor_open = FALSE;
  355.           }
  356.  
  357.         EXEC SQL PREPARE S1 FROM :host_string;
  358.         /* if prepare error */
  359.         if (sqlca.sqlcode != 0)
  360.             return (sqlca.sqlcode);
  361.  
  362.         EXEC SQL OPEN C1;
  363.         /* if open cursor error */
  364.         if (sqlca.sqlcode != 0)
  365.             return (sqlca.sqlcode);
  366.  
  367.         /* set cursor is open */
  368.         cursor_open = TRUE;
  369.       }
  370.  
  371.     EXEC SQL FETCH C1 USING DESCRIPTOR :*host_var;
  372.  
  373.     return (sqlca.sqlcode);
  374.   }
  375.  
  376. /* :H1 sql_close_cur: Close SQL Cursor
  377. //----------------------------------------------------------------------
  378. //
  379. //  Function Name: sql_close_cur
  380. //
  381. //  Purpose: This function will close the SQL cursor.
  382. //
  383. //  Description: This function closes the cursor.
  384. //
  385. //  Input:
  386. //    none
  387. //
  388. //  Output:
  389. //    return     0 = successful
  390. //
  391. //----------------------------------------------------------------------*/
  392.  
  393. SHORT sql_close_cur (VOID)
  394.   {
  395.  
  396.     /* if cursor already open */
  397.     if (cursor_open == TRUE)
  398.       {
  399.         /* close cursor */
  400.         EXEC SQL CLOSE C1;
  401.  
  402.         /* set cursor not open */
  403.         cursor_open = FALSE;
  404.       }
  405.     return (0);
  406.   }
  407.  
  408. /* :H1 sql_delete_row: Delete Current Row
  409. //----------------------------------------------------------------------
  410. //
  411. //  Function Name: sql_delete_row
  412. //
  413. //  Purpose: This function will delete the current row.
  414. //
  415. //  Description: This function deletes the row described by the
  416. //               current cursor.
  417. //
  418. //  Input:
  419. //    statement  dynamic SQL delete statement to be executed
  420. //
  421. //  Output:
  422. //    return     returns SQL return code
  423. //
  424. //----------------------------------------------------------------------*/
  425.  
  426. SHORT sql_delete_row (CHAR *statement)
  427.   {
  428.     /* move statement to host variable */
  429.     strcpy (host_string, statement);
  430.  
  431.     /* add cursor name for search to statement */
  432.     strcat (host_string, " C1");
  433.  
  434.     EXEC SQL EXECUTE IMMEDIATE :host_string;
  435.  
  436.     return (sqlca.sqlcode);
  437.   }
  438.  
  439. /* :H1 sql_commit: Commit data to database
  440. //----------------------------------------------------------------------
  441. //
  442. //  Function Name: sql_commit
  443. //
  444. //  Purpose: This function will commit the data to the database
  445. //
  446. //  Description: This function will commit the outstanding data
  447. //               to the database.
  448. //
  449. //  Input:
  450. //    none
  451. //
  452. //  Output:
  453. //    return     returns SQL return code
  454. //
  455. //----------------------------------------------------------------------*/
  456.  
  457. SHORT sql_commit (VOID)
  458.   {
  459.     /* if cursor is open */
  460.     if (cursor_open == TRUE)
  461.       {
  462.         /* close cursor */
  463.         EXEC SQL CLOSE C1;
  464.         /* if close cursor error */
  465.         if (sqlca.sqlcode != 0)
  466.             return (sqlca.sqlcode);
  467.  
  468.         /* set cursor is not open */
  469.         cursor_open = FALSE;
  470.       }
  471.  
  472.     /* commit data to database */
  473.     EXEC SQL COMMIT;
  474.  
  475.     return (sqlca.sqlcode);
  476.   }
  477.  
  478. /* :H1 sql_get_buffer_size: Get buffer pool size
  479. //----------------------------------------------------------------------
  480. //
  481. //  Function Name: sql_get_buffer_size
  482. //
  483. //  Purpose: This function will get the buffer pool size for the database.
  484. //
  485. //  Description: This function will get the buffer pool size for the
  486. //               database.
  487. //
  488. //  Input:
  489. //    name       database name to query
  490. //    size       pointer to where to return size
  491. //
  492. //  Output:
  493. //    return     returns SQL return code
  494. //
  495. //----------------------------------------------------------------------*/
  496.  
  497. SHORT sql_get_pool_size (CHAR *name, USHORT *size)
  498.   {
  499.    struct sqlfupd request;
  500.  
  501.     /* build request */
  502.     request.token = SQLF_DBTN_BUFFPAGE;
  503.     request.ptrvalue = (CHAR *)size;
  504.  
  505.     /* get buffer pool size */
  506.     sqlfxdbc (name,             /* database name */
  507.               "",               /* password */
  508.               1,                /* count */
  509.               &request,         /* list of items */
  510.               &sqlca);          /* sqlca */
  511.  
  512.     return (sqlca.sqlcode);
  513.   }
  514.  
  515. /* :H1 sql_set_buffer_size: Set buffer pool size
  516. //----------------------------------------------------------------------
  517. //
  518. //  Function Name: sql_set_buffer_size
  519. //
  520. //  Purpose: This function will set the buffer pool size for the database.
  521. //
  522. //  Description: This function will set the buffer pool size for the
  523. //               database. It will update the sqlenseg for database
  524. //               manager if necessary.
  525. //
  526. //  Input:
  527. //    name       database name to update
  528. //    size       size to set
  529. //
  530. //  Output:
  531. //    return     returns SQL return code
  532. //
  533. //----------------------------------------------------------------------*/
  534.  
  535. SHORT sql_set_pool_size (CHAR *name, USHORT size)
  536.   {
  537.    struct sqlfupd request [2];
  538.    USHORT sqlenseg;
  539.    USHORT numdb;
  540.    USHORT dbheap;
  541.    USHORT locklist;
  542.    USHORT min_len;
  543.    SHORT  rc;
  544.  
  545.     /* build get sqlenseg and numdb request */
  546.     request[0].token = SQLF_KTN_SQLENSEG;
  547.     request[0].ptrvalue = (CHAR *)&sqlenseg;
  548.     request[1].token = SQLF_KTN_NUMDB;
  549.     request[1].ptrvalue = (CHAR *)&numdb;
  550.  
  551.     /* get sqlenseg and numdb for database manager */
  552.     sqlfxsys (2,                /* count */
  553.               &request[0],      /* list of items */
  554.               &sqlca);          /* sqlca */
  555.  
  556.     /* if get sqlenseg and numdb error */
  557.     if (sqlca.sqlcode != 0)
  558.         return (sqlca.sqlcode);
  559.  
  560.     /* build get dbheap and locklist request */
  561.     request[0].token = SQLF_DBTN_DBHEAP;
  562.     request[0].ptrvalue = (CHAR *)&dbheap;
  563.     request[1].token = SQLF_DBTN_LOCKLIST;
  564.     request[1].ptrvalue = (CHAR *)&locklist;
  565.  
  566.     /* get dbheap and locklist for database */
  567.     sqlfxdbc (name,             /* database name */
  568.               "",               /* password */
  569.               2,                /* count */
  570.               &request[0],         /* list of items */
  571.               &sqlca);          /* sqlca */
  572.  
  573.     /* compute minimum sqlenseg required */
  574.     min_len = ((numdb - 1) * 7) + dbheap + ((size + 15) / 16) +
  575.               ((locklist + 15) / 16) + 3;
  576.  
  577.     /* add for roundoff errors */
  578.     min_len += 5;
  579.  
  580.     /* if sqlenseg is less than the minimum required */
  581.     if (sqlenseg < min_len)
  582.       {
  583.         /* stop database manager */
  584.         sql_stop ();
  585.  
  586.         /* build set sqlenseg request */
  587.         request[0].token = SQLF_KTN_SQLENSEG;
  588.         request[0].ptrvalue = (CHAR *)&min_len;
  589.  
  590.         /* set sqlenseg for database manager */
  591.         sqlfusys (1,                /* count */
  592.                   &request[0],      /* list of items */
  593.                   &sqlca);          /* sqlca */
  594.  
  595.         /* if set sqlenseg error */
  596.         if (sqlca.sqlcode != 0)
  597.             return (sqlca.sqlcode);
  598.  
  599.         /* if error starting database manager so changes will
  600.            take effect */
  601.         if ( (rc = sql_start ()) != 0)
  602.             return (rc);
  603.       }
  604.  
  605.     /* build set size request */
  606.     request[0].token = SQLF_DBTN_BUFFPAGE;
  607.     request[0].ptrvalue = (CHAR *)&size;
  608.  
  609.     /* set buffer pool size */
  610.     sqlfeudb (name,             /* database name */
  611.               "",               /* password */
  612.               1,                /* count */
  613.               &request[0],      /* list of items */
  614.               &sqlca);          /* sqlca */
  615.  
  616.     return (sqlca.sqlcode);
  617.   }
  618. /* :H1 sql_get_log_size: Get log file size
  619. //----------------------------------------------------------------------
  620. //
  621. //  Function Name: sql_get_log_size
  622. //
  623. //  Purpose: This function will get the log size for the database.
  624. //
  625. //  Description: This function will use the SQL API to get the log file
  626. //               size of the specified database.
  627. //
  628. //  Input:
  629. //    name       database name to query
  630. //    size       pointer to where to return size
  631. //
  632. //  Output:
  633. //    return     returns SQL return code
  634. //
  635. //----------------------------------------------------------------------*/
  636.  
  637. SHORT sql_get_log_size (CHAR *name, USHORT *size)
  638.   {
  639.    struct sqlfupd request;
  640.  
  641.     /* build request */
  642.     request.token = SQLF_DBTN_LOGFILSIZ;
  643.     request.ptrvalue = (CHAR *)size;
  644.  
  645.     /* get log file size */
  646.     sqlfxdbc (name,             /* database name */
  647.               "",               /* password */
  648.               1,                /* count */
  649.               &request,         /* list of items */
  650.               &sqlca);          /* sqlca */
  651.  
  652.     return (sqlca.sqlcode);
  653.   }
  654.  
  655. /* :H1 sql_set_log_size: Set log file size
  656. //----------------------------------------------------------------------
  657. //
  658. //  Function Name: sql_set_log_size
  659. //
  660. //  Purpose: This function will set the log file size for the database.
  661. //
  662. //  Description: This function will use the SQL API to set the log
  663. //               file size for the specified database.
  664. //
  665. //  Input:
  666. //    name       database name to update
  667. //    size       size to set
  668. //
  669. //  Output:
  670. //    return     returns SQL return code
  671. //
  672. //----------------------------------------------------------------------*/
  673.  
  674. SHORT sql_set_log_size (CHAR *name, USHORT size)
  675.   {
  676.    struct sqlfupd request;
  677.  
  678.     /* build set size request */
  679.     request.token = SQLF_DBTN_LOGFILSIZ;
  680.     request.ptrvalue = (CHAR *)&size;
  681.  
  682.     /* set log file size */
  683.     sqlfeudb (name,             /* database name */
  684.               "",               /* password */
  685.               1,                /* count */
  686.               &request,         /* list of items */
  687.               &sqlca);          /* sqlca */
  688.  
  689.     return (sqlca.sqlcode);
  690.   }
  691. /* :H1 sql_get_log_number: Get number of log files for database
  692. //----------------------------------------------------------------------
  693. //
  694. //  Function Name: sql_get_log_number
  695. //
  696. //  Purpose: This function will get the number of logs for the database.
  697. //
  698. //  Description: This function will use the SQL API to get the number of
  699. //               log files for specified database.
  700. //
  701. //  Input:
  702. //    name       database name to query
  703. //    primary    pointer to where to return number of primary log files
  704. //    secondary  pointer to where to return number of secondary log files
  705. //
  706. //  Output:
  707. //    return     returns SQL return code
  708. //
  709. //----------------------------------------------------------------------*/
  710.  
  711. SHORT sql_get_log_number (CHAR *name, USHORT *primary, USHORT *secondary)
  712.   {
  713.    struct sqlfupd request[2];
  714.  
  715.     /* build request */
  716.     request[0].token = SQLF_DBTN_LOGPRIMARY;
  717.     request[0].ptrvalue = (CHAR *)primary;
  718.     request[1].token = SQLF_DBTN_LOGSECOND;
  719.     request[1].ptrvalue = (CHAR *)secondary;
  720.  
  721.     /* get number of log files */
  722.     sqlfxdbc (name,             /* database name */
  723.               "",               /* password */
  724.               2,                /* count */
  725.               &request[0],      /* list of items */
  726.               &sqlca);          /* sqlca */
  727.  
  728.     return (sqlca.sqlcode);
  729.   }
  730. /* :H1 sql_set_log_number: Set number of log files for database
  731. //----------------------------------------------------------------------
  732. //
  733. //  Function Name: sql_set_log_number
  734. //
  735. //  Purpose: This function will set the number of logs for the database.
  736. //
  737. //  Description: This function will use the SQL API to set the number of
  738. //               log files for specified database.
  739. //
  740. //  Input:
  741. //    name       database name to query
  742. //    primary    number of primary log files
  743. //    secondary  number of secondary log files
  744. //
  745. //  Output:
  746. //    return     returns SQL return code
  747. //
  748. //----------------------------------------------------------------------*/
  749.  
  750. SHORT sql_set_log_number (CHAR *name, USHORT primary, USHORT secondary)
  751.   {
  752.    struct sqlfupd request[2];
  753.  
  754.     /* build request */
  755.     request[0].token = SQLF_DBTN_LOGPRIMARY;
  756.     request[0].ptrvalue = (CHAR *)&primary;
  757.     request[1].token = SQLF_DBTN_LOGSECOND;
  758.     request[1].ptrvalue = (CHAR *)&secondary;
  759.  
  760.     /* set number of log files */
  761.     sqlfeudb (name,             /* database name */
  762.               "",               /* password */
  763.               2,                /* count */
  764.               &request[0],      /* list of items */
  765.               &sqlca);          /* sqlca */
  766.  
  767.     return (sqlca.sqlcode);
  768.   }
  769.  
  770. /* :H1 sql_rollback: Rollback data from database
  771. //----------------------------------------------------------------------
  772. //
  773. //  Function Name: sql_rollback
  774. //
  775. //  Purpose: This function will rollback the data from the database
  776. //
  777. //  Description: This function will rollback the outstanding data
  778. //               from the database.
  779. //
  780. //  Input:
  781. //    none
  782. //
  783. //  Output:
  784. //    return     returns SQL return code
  785. //
  786. //----------------------------------------------------------------------*/
  787.  
  788. SHORT sql_rollback (VOID)
  789.   {
  790.     /* if cursor is open */
  791.     if (cursor_open == TRUE)
  792.       {
  793.         /* close cursor */
  794.         EXEC SQL CLOSE C1;
  795.         /* if close cursor error */
  796.         if (sqlca.sqlcode != 0)
  797.             return (sqlca.sqlcode);
  798.  
  799.         /* set cursor is not open */
  800.         cursor_open = FALSE;
  801.       }
  802.  
  803.     /* rollback data from database */
  804.     EXEC SQL ROLLBACK;
  805.  
  806.     return (sqlca.sqlcode);
  807.   }
  808.