home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ool.zip / OOL / source / XTABLE.SQC < prev    next >
Text File  |  1997-04-07  |  19KB  |  744 lines

  1. /******************    XTABLE.SQC    **********************/
  2. /*********  (c)opyright Stefan von Brauk, 1996  ***********/
  3.  
  4. #include "xtable.h"
  5. #include "xtabex.h"
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <math.h>
  11.  
  12.  
  13. /*@ XTable
  14. @remarks XTable is a class to read/write data from/to a DB2/2 database. To use XTable a DB2/2 database
  15. manager must be installed on your system. XTable is reduced in functionality:
  16. <OL>
  17. <LI>Only one cursor can be open (so never forget to call CloseCursor())
  18. <LI>Some data-types like DECIMAL, TIMESTAMP are not supported
  19. </OL>
  20. (The authors distribute a library which works exactly like XTable without that restrictions, so send an email 
  21. if you are interested).<BR>
  22. The static methods like connect/disconnect etc are used for basic communication wth DB2/2, you do not need 
  23. to instanciate an object to use this function.<BR>
  24. Befor using this class you must bind the library to your database(s). To do so you find in the directory
  25. OOL\TOOLS a file named XTABLE.BND. Bind the file to your database in the following manner:<BR>
  26. sqlbind xtable.bnd database<BR>
  27. where <database> is the name of your database. Additionaly this file must be bind to all databases which are
  28. accessed by your application.<BR>
  29. Befor you create an object of XTable you must call Connect()!<BR>
  30. All functions of this class throw exceptions of the type XTableException if an error ocures.
  31. */
  32.  
  33.  
  34. /*@ XTable :: Connect ( char * dbName )
  35. @group connect
  36. @remarks Connect to a database. If your application terminates you must call DisConnect()
  37. otherwise DB2/2 will do a rollback.
  38. @parameters char * dbName   the name of the database
  39. @returns    int  errorCode  Errorcode
  40. */
  41. int XTable :: Connect ( char * dbName )
  42. {
  43.    struct sqlca sqlca;
  44.    sqlestrd_api( (unsigned char *) dbName, (unsigned char *) "",'S', &sqlca);  
  45.  
  46.    if( sqlca.sqlcode != 0)                                             
  47.    {
  48.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  49.       return sqlca.sqlcode;
  50.    }
  51.    return 0;
  52. }
  53.  
  54.  
  55. /*@ int XTable :: DisConnect()
  56. @group connect
  57. @remarks disconnect from a database. 
  58. @returns    int  errorCode  Errorcode
  59. */
  60. int XTable :: DisConnect()
  61. {
  62.    struct sqlca sqlca;
  63.    sqlestpd( &sqlca);
  64.    if( sqlca.sqlcode != 0)
  65.    {
  66.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  67.       return sqlca.sqlcode;
  68.    }
  69.    return 0;
  70. }
  71.  
  72.  
  73. /*@ XTable :: XTable ( const char * tab)
  74. @group constructors/destructors
  75. @remarks Create an instance of XTable. The structure of the table is read so you can
  76. use the QueryFiledName/QueryFieldType functions to get information about the opened table.
  77. @parameters char * tabName   the name of the table
  78. @returns    int  errorCode   Errorcode
  79. */
  80. XTable :: XTable ( const char * tab)
  81. {
  82.    EXEC SQL BEGIN DECLARE SECTION;
  83.       char sqlString[100];
  84.    EXEC SQL END DECLARE SECTION;
  85.    
  86.    cursorOpen = FALSE;
  87.    insertFlag = FALSE;
  88.  
  89.    sqlda sqlda;
  90.  
  91.    EXEC SQL WHENEVER SQLERROR GO TO error;
  92.    short int i;         
  93.  
  94.    tabName = (char*) malloc( strlen(tab) + 1);
  95.    strcpy( tabName, (const char*) tab);
  96.  
  97.    memset ( &sqlda, 0, sizeof(sqlda));
  98.  
  99.    strcpy( sqlString, "SELECT * FROM ");
  100.    strcat( sqlString, (const char*) tab);
  101.  
  102.    EXEC SQL PREPARE STMT INTO :sqlda FROM :sqlString;
  103.    if( sqlca.sqlcode != 0)
  104.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);  
  105.  
  106.    sql = (::sqlda*) malloc( sizeof(sqlda) + 44 * sqlda.sqld);
  107.    sql->sqln = sqlda.sqld;
  108.  
  109.    EXEC SQL DESCRIBE STMT INTO :*sql;
  110.  
  111.    fields = (Field*) malloc( sql->sqld * sizeof(Field));
  112.    for(i=0; i < sql->sqld; i++)
  113.    {
  114.       sql->sqlvar[i].sqlname.data[sql->sqlvar[i].sqlname.length]=0;
  115.       sql->sqlvar[i].sqllen = 1000;
  116.       fields[i].data = (unsigned char*) malloc( sql->sqlvar[i].sqllen);
  117.       sql->sqlvar[i].sqldata = fields[i].data;
  118.       sql->sqlvar[i].sqlind = &fields[i].ind;
  119.    }
  120.  
  121.    return;
  122.  
  123.    error:
  124.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  125.    EXEC SQL WHENEVER SQLERROR CONTINUE;
  126. }
  127.  
  128.  
  129. XTable :: ~XTable()
  130. {
  131.    short int i;
  132.  
  133.    if(cursorOpen)  
  134.       CloseCursor();
  135.  
  136.    for(i=0;i<sql->sqld; i++)
  137.    {
  138.       free (fields[i].data);
  139.    }
  140.    free(fields);
  141.    free( sql );
  142.    free( tabName );
  143. }
  144.  
  145.  
  146. void XTable :: AddSet()
  147. {
  148.    insertFlag = TRUE;
  149.    for(int i=0; i < sql->sqld; i++)
  150.       {
  151.          fields[i].ind = -1;
  152.          sql->sqlvar[i].sqllen=0;   
  153.       }
  154. }
  155.  
  156.  
  157. /*@ XTable :: Select(const char * whereList, char * order, char * group, BOOL update )
  158. @group table functions
  159. @remarks Perfor a select on the table and open a cursor. If successful the cursor is set to the first row of the result table.
  160. @parameters <t '°' c=2>
  161.                 °char * whereList   °The select. Instead of a full  SQL-Select like "SEECT * FROM....." you only need to specify the WHERE-clause like "FIELD1 > 0 AND FIELD2 > 20"
  162.            °char * orderList   °list to order the results of the query eg. "FIELD1, FIELD2"
  163.            °char * groupBy     °how to group the results
  164.            °BOOL forUpdate     °TRUE=get ready to update the data<BR>FALSE=results will not be updated.<BR>If set TRUE orderList and groupList must be NULL!
  165.                 </t>
  166. @returns    int  errorCode  Errorcode
  167. */
  168. int XTable :: Select(const char * whereList, char * order, char * group, BOOL update )
  169. {
  170.    EXEC SQL BEGIN DECLARE SECTION;
  171.       char * sqlSt;
  172.    EXEC SQL END DECLARE SECTION;
  173.  
  174.    insertFlag = FALSE;
  175.    int res, i;
  176.  
  177.    XString sqlStatement;
  178.    EXEC SQL WHENEVER SQLERROR GO TO error;
  179.  
  180.    eoFile = FALSE;
  181.  
  182.    sqlStatement = "SELECT * FROM ";
  183.    sqlStatement += GetName();
  184.  
  185.    if( whereList )
  186.    {
  187.       sqlStatement += " WHERE ";
  188.       sqlStatement += whereList;
  189.    }
  190.  
  191.    if(order)
  192.       {
  193.          sqlStatement += " ORDER BY ";
  194.          sqlStatement += order;
  195.       }
  196.  
  197.    if(group)
  198.       {
  199.          sqlStatement += " @group BY ";
  200.          sqlStatement += group;
  201.       }
  202.  
  203.    if(update)
  204.    {
  205.       sqlStatement += " FOR UPDATE OF ";
  206.       for(i=0; i < sql->sqld; i++)
  207.       {
  208.          sqlStatement += (char*) sql->sqlvar[i].sqlname.data;
  209.          if( i < sql->sqld - 1)
  210.             sqlStatement += ", ";
  211.       }
  212.    }
  213.  
  214.    sqlSt = sqlStatement;
  215.  
  216.    EXEC SQL PREPARE STMT INTO :*sql FROM :sqlSt; 
  217.  
  218.    for(i=0; i < sql->sqld; i++)
  219.    {
  220.       sql->sqlvar[i].sqldata = fields[i].data;
  221.       sql->sqlvar[i].sqlind = &fields[i].ind;
  222.       *sql->sqlvar[i].sqlind = 0;
  223.    }
  224.    EXEC SQL DECLARE c1 CURSOR FOR STMT;
  225.    EXEC SQL OPEN c1 USING DESCRIPTOR :*sql;
  226.  
  227.    cursorOpen = TRUE;
  228.  
  229.    EXEC SQL FETCH c1 USING DESCRIPTOR :*sql;
  230.  
  231.    if( sqlca.sqlcode == 100)
  232.       eoFile = TRUE;
  233.  
  234.    return 0;  
  235.  
  236.    error:
  237.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  238.       return sqlca.sqlcode;
  239.  
  240.    EXEC SQL WHENEVER SQLERROR CONTINUE;
  241. }
  242.  
  243.  
  244. /*@ XTable :: CloseCursor( void)
  245. @group cursor
  246. @remarks Close a cursor which was opend with a select. In this version of XTable only one cursor can be open at a time.
  247. @returns    int  errorCode  Errorcode
  248. */
  249. int XTable :: CloseCursor( void)
  250. {
  251.    if( cursorOpen )
  252.       {
  253.          EXEC SQL CLOSE c1;         
  254.          if( sqlca.sqlcode )
  255.          {
  256.             OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  257.             return sqlca.sqlcode;
  258.          }
  259.          cursorOpen = FALSE;
  260.       }
  261.   return 0;
  262. }
  263.  
  264.  
  265. /*@ XTable :: SaveSet( void)
  266. @group table functions
  267. @remarks Save the data of the row the cursor actualy shows to.
  268. @returns    int  errorCode  Errorcode
  269. */
  270. int XTable :: SaveSet( void)
  271. {
  272.    EXEC SQL BEGIN DECLARE SECTION;
  273.       char sqlSave[3000];
  274.    EXEC SQL END DECLARE SECTION;
  275.  
  276.    short int i;
  277.  
  278.    EXEC SQL WHENEVER SQLERROR GO TO error;
  279.    SHORT j;
  280.  
  281.    if(insertFlag)
  282.       {
  283.          strcpy( sqlSave, "INSERT INTO ");
  284.          strcat ( sqlSave, (const char*) GetName());
  285.          strcat(sqlSave, " (");
  286.          for(i=0; i < sql->sqld; i++)
  287.             {
  288.                strcat(sqlSave, " ");
  289.                strcat( sqlSave, (const char*) sql->sqlvar[i].sqlname.data);
  290.                if( i < sql->sqld - 1)
  291.                   strcat( sqlSave, ", ");
  292.             }
  293.          strcat( sqlSave, ") VALUES (");
  294.          for(i=0; i < sql->sqld; i++)
  295.             {
  296.                if( i < sql->sqld - 1)
  297.                   strcat( sqlSave, " ?, ");
  298.                else
  299.                   strcat( sqlSave, " ?");
  300.             }
  301.          strcat ( sqlSave, ")");
  302.       }
  303.    else
  304.       {
  305.          strcpy( sqlSave, "UPDATE ");
  306.          strcat ( sqlSave, (const char*) GetName());
  307.          strcat( sqlSave, " SET ");
  308.          for(i=0; i < sql->sqld; i++)
  309.             {
  310.                strcat( sqlSave, (const char*) sql->sqlvar[i].sqlname.data);
  311.  
  312.                if( i < sql->sqld - 1)
  313.                   strcat( sqlSave, "= ?, ");
  314.                else
  315.                   strcat( sqlSave, "= ?");
  316.             }
  317.          strcat ( sqlSave, " WHERE CURRENT OF c1");
  318.       }   
  319.  
  320.    EXEC SQL PREPARE c1 FROM :sqlSave;
  321.  
  322.    EXEC SQL EXECUTE c1 USING DESCRIPTOR : *sql;
  323.    insertFlag = FALSE;
  324.  
  325.    return 0;
  326.  
  327.    error:
  328.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  329.       return sqlca.sqlcode;
  330.    EXEC SQL WHENEVER SQLERROR CONTINUE;
  331. }
  332.  
  333.  
  334. /*@ XTable :: MoveNext ( void )
  335. @group table functions
  336. @remarks Set the cursor to the next row. Use IsEOF() to check if the end of the table is reached.
  337. @returns    int  errorCode  Errorcode.
  338. */
  339. int XTable :: MoveNext ( void )
  340. {
  341.    EXEC SQL WHENEVER SQLERROR GO TO error;
  342.  
  343.    EXEC SQL FETCH c1 USING DESCRIPTOR :*sql;
  344.  
  345.    if( sqlca.sqlcode == 100)
  346.       eoFile = TRUE;
  347.    return 0;
  348.  
  349.    error:
  350.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  351.       return sqlca.sqlcode;    
  352.    EXEC SQL WHENEVER SQLERROR CONTINUE;
  353. }
  354.  
  355.  
  356. /*@ XTable :: QueryFieldCount()
  357. @group table functions
  358. @remarks returns the count of fields in the table
  359. @returns    int  cunt of fields (-1 if an error ocured)
  360. */
  361. SHORT XTable :: QueryFieldCount()
  362. {
  363.    if(sql)
  364.       return sql->sqld;
  365.    else
  366.       return -1;
  367. }
  368.     
  369.  
  370. BOOL XTable :: QueryFieldName( XString * buffer, SHORT index)
  371. {
  372.    if(sql && index < sql->sqld)
  373.       {
  374.          memcpy( buffer->GetBuffer( sql->sqlvar[index].sqlname.length + 1), sql->sqlvar[index].sqlname.data, sql->sqlvar[index].sqlname.length);
  375.          buffer->ReleaseBuffer( sql->sqlvar[index].sqlname.length );
  376.          return TRUE;
  377.       }
  378.    else
  379.       return FALSE;
  380. }
  381.  
  382. /*
  383. LONG XTable :: QueryFieldLength( SHORT index, XString * buffer)
  384. {
  385.    if(sql && index < sql->sqld)
  386.       {
  387.          if( sql->sqlvar[index].sqltype == 484 || sql->sqlvar[index].sqltype == 485)
  388.             {
  389.                if(buffer)
  390.                   {
  391.                      *buffer =(LONG) sql->sqlvar[index].sqllen % 256;
  392.                      *buffer += ",";
  393.                      *buffer += (LONG) sql->sqlvar[index].sqllen / 256;
  394.                   }
  395.                return (sql->sqlvar[index].sqllen % 256) + 1 + (sql->sqlvar[index].sqllen / 256);
  396.             }
  397.          else
  398.             {
  399.                if(buffer)
  400.                   *buffer = (LONG)sql->sqlvar[index].sqllen;
  401.                return sql->sqlvar[index].sqllen;
  402.             }
  403.       }
  404.    else
  405.       return -1;
  406. }
  407. */
  408.  
  409. SHORT XTable :: QueryFieldType( SHORT index)
  410. {
  411.    if(sql && index < sql->sqld)
  412.       return sql->sqlvar[index].sqltype;
  413.    else
  414.       return -1;
  415. }
  416.  
  417.  
  418. int XTable :: GetFieldIndex( const char * fieldName )
  419. {
  420.    for(int i=0; i < sql->sqld; i++)
  421.    {
  422.       if( strcmp( (char*) sql->sqlvar[i].sqlname.data, fieldName) == 0)
  423.          return i;
  424.    }
  425.  
  426.    char string[100];
  427.    sprintf( string, "Field <%s> not found in table <%s>", fieldName, GetName());
  428.    OOLTableThrow((char*) string, 1);
  429.    return -1;
  430. }
  431.  
  432.  
  433. int XTable :: GetField( const char * fieldName, long int& value)
  434. {
  435.    int i;
  436.    if( (i = GetFieldIndex( fieldName)) < 0)
  437.       return -2;
  438.    return GetField(i, value);
  439. }
  440.  
  441.  
  442. int XTable :: GetField( SHORT i, long int& value)
  443. {
  444.    if( *sql->sqlvar[i].sqlind < 0)
  445.       return -1;
  446.    value = *sql->sqlvar[i].sqldata;
  447.    return  0;
  448. }
  449.  
  450.  
  451. int XTable :: GetField( const char * fieldName, double& value)
  452. {
  453.    int i;
  454.    if( (i = GetFieldIndex( fieldName)) < 0)
  455.       return -2;
  456.    return GetField(i, value);
  457. }
  458.  
  459.  
  460. int XTable :: GetField( SHORT i, double& value)
  461. {
  462.    if( *sql->sqlvar[i].sqlind < 0)
  463.       return -1;
  464.    if( sql->sqlvar[i].sqltype == 484 || sql->sqlvar[i].sqltype == 485)
  465.       {
  466.          SHORT lower, j=0;
  467.          XString r;
  468.          do   
  469.             {
  470.                lower = sql->sqlvar[i].sqldata[j] % 16;
  471.                r += (LONG) sql->sqlvar[i].sqldata[j] / 16;
  472.                if(lower < 9)
  473.                   r+=(LONG) lower;
  474.                j++;
  475.             }
  476.          while( lower < 9);
  477.          value = atol( r );
  478.          value = value / pow(10, sql->sqlvar[i].sqllen / 256);
  479.       }
  480.    else
  481.       value = *sql->sqlvar[i].sqldata;
  482.    return  0;
  483. }
  484.  
  485.  
  486. int XTable :: GetField( const char * fieldName, XTime * value)
  487. {
  488.    int i;
  489.    if( (i = GetFieldIndex( fieldName)) < 0)
  490.       return -2;
  491.    return GetField(i, value);
  492. }
  493.  
  494.  
  495. int XTable :: GetField( SHORT i, XTime * value)
  496. {
  497.    if( *sql->sqlvar[i].sqlind < 0)
  498.       {
  499.          value->SetHours( 0 );
  500.          value->SetMinutes( 0 );
  501.          value->SetSeconds( 0 );
  502.          return -1;
  503.       }
  504.    SHORT j=0;
  505.    if( sql->sqlvar[i].sqltype == 392 || sql->sqlvar[i].sqltype == 393)
  506.       j = 11;
  507.    char buffer[3];
  508.    buffer[0] = sql->sqlvar[i].sqldata[j];
  509.    buffer[1] = sql->sqlvar[i].sqldata[j+1];
  510.    buffer[2] = 0;
  511.    value->SetHours( atoi(buffer) );
  512.    buffer[0] = sql->sqlvar[i].sqldata[j+3];
  513.    buffer[1] = sql->sqlvar[i].sqldata[j+4];
  514.    buffer[2] = 0;
  515.    value->SetMinutes( atoi(buffer) );
  516.    buffer[0] = sql->sqlvar[i].sqldata[j+6];
  517.    buffer[1] = sql->sqlvar[i].sqldata[j+7];
  518.    buffer[2] = 0;
  519.    value->SetSeconds( atoi(buffer) );
  520.  
  521.    return  0;
  522. }
  523.  
  524.  
  525. int XTable :: GetField( const char * fieldName, XDate * value)
  526. {
  527.    int i;
  528.    if( (i = GetFieldIndex( fieldName)) < 0)
  529.       return -2;
  530.    return GetField(i, value);
  531. }
  532.  
  533.  
  534. int XTable :: GetField( SHORT i, XDate * value)
  535. {
  536.    if( *sql->sqlvar[i].sqlind < 0)
  537.       {
  538.          value->SetYears( 0);
  539.          value->SetMonths( 0);
  540.          value->SetDays( 0);
  541.          return -1;
  542.       }
  543.    char buffer[5];
  544.    buffer[0] = sql->sqlvar[i].sqldata[0];
  545.    buffer[1] = sql->sqlvar[i].sqldata[1];
  546.    buffer[2] = sql->sqlvar[i].sqldata[2];
  547.    buffer[3] = sql->sqlvar[i].sqldata[3];
  548.    buffer[4] = 0;
  549.    value->SetYears( atoi(buffer));
  550.  
  551.    buffer[0] = sql->sqlvar[i].sqldata[5];
  552.    buffer[1] = sql->sqlvar[i].sqldata[6];
  553.    buffer[2] = 0;
  554.    value->SetMonths( atoi(buffer) );
  555.  
  556.    buffer[0] = sql->sqlvar[i].sqldata[8];
  557.    buffer[1] = sql->sqlvar[i].sqldata[9];
  558.    buffer[2] = 0;
  559.    value->SetDays( atoi(buffer) );
  560.  
  561.    return  0;
  562. }
  563.  
  564.  
  565. int XTable :: GetField( const char * fieldName, XString * value)
  566. {
  567.    int i;
  568.    if( (i = GetFieldIndex( fieldName)) < 0)
  569.       return -2;
  570.    return GetField(i, value);
  571. }
  572.  
  573.  
  574. int XTable :: GetField( SHORT i, XString * value)
  575. {
  576.    if( *sql->sqlvar[i].sqlind < 0)
  577.       {
  578.          *value = "";
  579.          return -1;
  580.       }
  581.  
  582.    switch( sql->sqlvar[i].sqltype )
  583.       {  
  584.          case 452:
  585.          case 453:
  586.             {
  587.                if(sql->sqlvar[i].sqllen == 0)
  588.                   *value = "";
  589.                else
  590.                   {
  591.                      unsigned char *p = sql->sqlvar[i].sqldata + sql->sqlvar[i].sqllen;
  592.                      *p = 0;
  593.                      *value = (char*) sql->sqlvar[i].sqldata;
  594.                   }
  595.             }
  596.             break;
  597.          case 448:
  598.          case 449:
  599.             {
  600.                char len = (char) sql->sqlvar[i].sqldata[0];
  601.                if(len == 0)
  602.                   *value = "";
  603.                else                
  604.                   {
  605.                      unsigned char *p = sql->sqlvar[i].sqldata;
  606.                      p += 2;
  607.                      memcpy(value->GetBuffer(len+1), p, len);
  608.                      value->ReleaseBuffer(len);
  609.                   }
  610.             }
  611.             break;
  612.          case 456:
  613.          case 457:
  614.             {
  615.                unsigned char *p = sql->sqlvar[i].sqldata;              
  616.                USHORT len;
  617.                memcpy(&len, p, 2);
  618.                if(len ==0)
  619.                   *value = "";
  620.                else
  621.                   {
  622.                      p += 2;
  623.                      memcpy(value->GetBuffer(len+1), p, len);
  624.                      value->ReleaseBuffer(len);
  625.                   }
  626.             }
  627.             break;
  628.          case 460:
  629.          case 461:
  630.             *value = (char*) sql->sqlvar[i].sqldata;
  631.             break;
  632.       }
  633.    return 0;
  634. }
  635.  
  636.  
  637. int XTable :: SetField( const char * fieldName, long int value, BOOL isNull)
  638. {
  639.    int i;
  640.    if( (i = GetFieldIndex( fieldName)) < 0)
  641.       return -2;
  642.  
  643.     if( isNull)
  644.        *sql->sqlvar[i].sqlind = -1;
  645.     else
  646.     {
  647.        *sql->sqlvar[i].sqlind = 0;
  648.        memcpy( sql->sqlvar[i].sqldata, &value, sql->sqlvar[i].sqllen);
  649.     }
  650.     return 0;
  651. }
  652.  
  653.  
  654. int XTable :: SetField( const char * fieldName, char * value, BOOL isNull)
  655. {
  656.    int i;
  657.    if( (i = GetFieldIndex( fieldName)) < 0)
  658.       return -2;
  659.  
  660.    if( isNull)
  661.       *sql->sqlvar[i].sqlind = -1;
  662.    else
  663.    {
  664.       *sql->sqlvar[i].sqlind = 0;
  665.       strcpy( (char*) sql->sqlvar[i].sqldata, value);
  666.       sql->sqlvar[i].sqldata[strlen(value)] = 0;
  667.    }
  668.    return 0;
  669. }
  670.  
  671.  
  672. /*@ XTable :: Commit(void)
  673. @group misc
  674. @remarks let DB2/2 perfor a commit
  675. @returns    int  errorCode  Errorcode
  676. */
  677. int XTable :: Commit(void)
  678. {
  679.    struct sqlca sqlca;
  680.    EXEC SQL WHENEVER SQLERROR GO TO error;
  681.  
  682.    EXEC SQL COMMIT;
  683.  
  684.    return 0;
  685.  
  686.    error:
  687.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  688.       return sqlca.sqlcode;    
  689.    EXEC SQL WHENEVER SQLERROR CONTINUE;
  690. }
  691.  
  692.  
  693. /*@ XTable :: Rollback(void)
  694. @group misc
  695. @remarks let DB2/2 perfor a rollback
  696. @returns    int  errorCode  Errorcode
  697. */
  698. int XTable :: Rollback(void)
  699. {
  700.    struct sqlca sqlca;
  701.    EXEC SQL WHENEVER SQLERROR GO TO error;
  702.  
  703.    EXEC SQL ROLLBACK;
  704.  
  705.    return 0;
  706.  
  707.    error:
  708.       OOLTableThrow( (char*) sqlca.sqlerrmc, sqlca.sqlcode);
  709.       return sqlca.sqlcode;    
  710.    EXEC SQL WHENEVER SQLERROR CONTINUE;
  711. }
  712.  
  713.  
  714. /*@ XTable :: LockTable(BOOL ex)
  715. @group misc
  716. @remarks Lock the cvurrent table.
  717. @parameters BOOL exclusive  TRUE=eclusive lock, FALSE=shared lock
  718. @returns    int  errorCode  Errorcode
  719. */
  720. int XTable :: LockTable(BOOL ex)
  721. {
  722.    EXEC SQL WHENEVER SQLERROR GO TO error;
  723.  
  724.    EXEC SQL BEGIN DECLARE SECTION;
  725.       char sqlLock[300];
  726.    EXEC SQL END DECLARE SECTION;
  727.    
  728.    strcpy(sqlLock, "LOCK TABLE ");
  729.    strcat(sqlLock, tabName);
  730.    if( ex)
  731.       strcat( sqlLock, " IN EXCLUSIVE MODE");
  732.    else
  733.       strcat( sqlLock, " IN SHARE MODE");
  734.    EXEC SQL EXECUTE IMMEDIATE :sqlLock;
  735.  
  736.    return 0;
  737.  
  738.    error:
  739.       OOLTableThrow((char*) sqlca.sqlerrmc, sqlca.sqlcode);
  740.       return sqlca.sqlcode;    
  741.    EXEC SQL WHENEVER SQLERROR CONTINUE;
  742. }
  743.  
  744.