src/odbc/odbcDbc.cxx

Go to the documentation of this file.
00001 /*  Class CSqlOdbcDbc
00002     Description: Connection Handle manager. 
00003 
00004     ODBC API's:
00005                 CSqlOdbcDbc::SQLAllocDbc();
00006                 CSqlOdbcDbc::SQLFreeDbc();
00007                 CSqlOdbcDbc::SQLConnect();
00008 */
00009 
00010 #include "odbcCommon.h"
00011 
00012 // Constructor
00013 CSqlOdbcDbc::CSqlOdbcDbc( void ) :
00014         handleType_( SQL_HANDLE_DBC ),
00015         parentEnv_( 0 ),
00016         state_( C1 ),
00017         err_( SQL_HANDLE_DBC ),
00018         mode_ (1), 
00019         curAccessMode_( ACCESSMODE_READ_WRITE ),
00020         curIsolationLevel_( READ_REPEATABLE ),
00021         accessMode_( ACCESSMODE_READ_WRITE ),
00022         isolationLevel_( READ_COMMITTED ),
00023         autoCommit_( SQL_AUTOCOMMIT_ON )
00024 {}
00025 
00026 SQLRETURN SQLAllocConnect(
00027     SQLHENV EnvironmentHandle,
00028     SQLHDBC *ConnectionHandle)
00029 {
00030     return( CSqlOdbcDbc::SQLAllocHandle( EnvironmentHandle, ConnectionHandle ) );
00031 }
00032 
00033 // All ODBC API's below.
00034 SQLRETURN CSqlOdbcDbc::SQLAllocHandle(
00035     SQLHANDLE   inputHandle,    // IN
00036     SQLHANDLE   *outputHandle ) // OUT
00037 {
00038 
00039     CSqlOdbcEnv *inputEnv = (CSqlOdbcEnv*) inputHandle;
00040 
00041     if( isValidHandle( inputEnv, SQL_HANDLE_ENV ) != SQL_SUCCESS )
00042         return( SQL_INVALID_HANDLE );
00043 
00044     // Stop if odbcVersion not set.
00045     if( inputEnv->odbcVersion_ == 0 )
00046     {
00047         inputEnv->err_.set( ERROR_FUNCSEQ );
00048         return( SQL_ERROR );
00049     }
00050 
00051     // Allocate Connection object.
00052     *outputHandle = (SQLHANDLE*) new CSqlOdbcDbc;
00053     if( *outputHandle == NULL )
00054     {
00055         globalError.set( ERROR_MEMALLOC );
00056         globalError.printStr( SQL_OV_ODBC3 );
00057         return( SQL_ERROR );
00058     }
00059 
00060     // Initialize relation b/w Env and Dbc
00061     inputEnv->dbcList_.insert( inputEnv->dbcList_.begin(), (CSqlOdbcDbc*) *outputHandle );
00062     inputEnv->state_ = E2;
00063     ((CSqlOdbcDbc*) *outputHandle)->parentEnv_ = inputEnv;
00064     ((CSqlOdbcDbc*) *outputHandle)->state_ = C2;
00065 
00066     return( SQL_SUCCESS );
00067 }
00068 
00069 SQLRETURN SQLFreeConnect(
00070     SQLHDBC ConnectionHandle)
00071 {
00072     return( CSqlOdbcDbc::SQLFreeHandle( ConnectionHandle ) );
00073 }
00074 
00075 SQLRETURN CSqlOdbcDbc::SQLFreeHandle(
00076     SQLHANDLE inputHandle)      // IN
00077 {
00078     CSqlOdbcDbc *inputDbc = (CSqlOdbcDbc*) inputHandle;
00079 
00080     // Validate handle
00081     if( isValidHandle( inputDbc, SQL_HANDLE_DBC ) != SQL_SUCCESS )
00082         return( SQL_INVALID_HANDLE );
00083 
00084     // Check whether we can proceed.
00085     if( inputDbc->chkStateForSQLFreeHandle() != SQL_SUCCESS )
00086         return( SQL_ERROR );
00087 
00088     // Remove Dbc from Parent Env.
00089     std::vector<CSqlOdbcDbc*>::iterator iter;
00090     iter = inputDbc->parentEnv_->dbcList_.begin();
00091     while( iter != inputDbc->parentEnv_->dbcList_.end() )
00092     {
00093         if( *iter == inputDbc )
00094         {
00095             inputDbc->parentEnv_->dbcList_.erase( iter );
00096             break;
00097         }
00098         iter++;
00099     }
00100     if( inputDbc->parentEnv_->dbcList_.size() == 0 )
00101         inputDbc->parentEnv_->state_ = E1;
00102 
00103     inputDbc->handleType_ = -1; // Make object invalid.
00104     delete inputDbc;            // Delete Dbc.
00105 
00106     return( SQL_SUCCESS );
00107 }
00108 
00109 SQLRETURN SQLDriverConnect(
00110      SQLHDBC     ConnectionHandle,
00111      SQLHWND     WindowHandle,
00112      SQLCHAR *     InConnectionString,
00113      SQLSMALLINT     StringLength1,
00114      SQLCHAR *     OutConnectionString,
00115      SQLSMALLINT     BufferLength,
00116      SQLSMALLINT *     StringLength2Ptr,
00117      SQLUSMALLINT     DriverCompletion)
00118 {
00119     printf("Connection string is %s\n", InConnectionString);
00120     // Validate handle
00121     if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
00122                  return( SQL_INVALID_HANDLE );
00123     
00124     return( ((CSqlOdbcDbc*) ConnectionHandle)->SQLConnect((SQLCHAR*)"a", 
00125                       (SQLSMALLINT)strlen("a"), (SQLCHAR*)"root", (SQLSMALLINT)strlen("root"), 
00126                       (SQLCHAR*)"manager", (SQLSMALLINT)strlen("manager")) );
00127    
00128 }
00129 
00130 SQLRETURN SQLConnect(           // All param's are IN
00131     SQLHDBC ConnectionHandle,
00132     SQLCHAR *ServerName,
00133     SQLSMALLINT NameLength1,
00134     SQLCHAR *UserName,
00135     SQLSMALLINT NameLength2,
00136     SQLCHAR *Authentication, 
00137     SQLSMALLINT NameLength3)
00138 {
00139     // Validate handle
00140     if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
00141         return( SQL_INVALID_HANDLE );
00142 
00143     return( ((CSqlOdbcDbc*) ConnectionHandle)->SQLConnect( ServerName, NameLength1, 
00144         UserName, NameLength2, Authentication, NameLength3) );
00145 }
00146 
00147 SQLRETURN CSqlOdbcDbc::SQLConnect(           // All param's are IN
00148     SQLCHAR *serverName,
00149     SQLSMALLINT len1,
00150     SQLCHAR *user,
00151     SQLSMALLINT len2,
00152     SQLCHAR *pass, 
00153     SQLSMALLINT len3)
00154 {
00155     int rc;
00156     char *hostName,*portNo;
00157     // Start with NO_ERR
00158     err_.set( NO_ERR );
00159 
00160     // Can we proceed ?
00161     if( chkStateForSQLConnect() != SQL_SUCCESS )
00162         return( SQL_ERROR );
00163     
00164     // Invalid Buffer Length.
00165     if( (len1 < 0 && len1 != SQL_NTS) || (len2 < 0 && len2 != SQL_NTS) || (len2 < 0 && len2 != SQL_NTS) )
00166     {
00167         err_.set( ERROR_BUFLEN );
00168         return( SQL_ERROR );
00169     }
00170     if (fsqlConn_ != NULL)
00171     {
00172         err_.set( ERROR_CONNINUSE);
00173         return ( SQL_ERROR );
00174     }
00175     if (strcasecmp((char*)serverName, "gateway") == 0)
00176     {
00177         fsqlConn_ = SqlFactory::createConnection(CSqlGateway);
00178         mode_ = 2;
00179     }else if (strcasecmp((char*)serverName, "adapter") == 0){
00180         fsqlConn_ = SqlFactory::createConnection(CSqlAdapter);
00181         mode_ = 3;
00182     }else{
00183         fsqlConn_ = SqlFactory::createConnection(CSql);
00184         mode_ = 1;
00185     }
00186 
00187     rc = fsqlConn_->connect( (char*) user, (char*) pass );
00188     if( rc != OK )
00189     {
00190         err_.set( ERROR_CONNREJCTD);
00191         return( SQL_ERROR );
00192     }
00193     rc = fsqlConn_->beginTrans( isolationLevel_ );
00194     if( rc != OK )
00195     {
00196         err_.set( ERROR_INVTRANSTATE );
00197         return( SQL_ERROR );
00198     }
00199     curAccessMode_ = accessMode_;
00200     curIsolationLevel_ = isolationLevel_;
00201 
00202     // Update Dbc state
00203     state_ = C4;
00204 
00205     return( SQL_SUCCESS );
00206 }
00207 
00208 SQLRETURN SQLDisconnect(
00209     SQLHDBC ConnectionHandle)   // IN
00210 {
00211     // Validate Handle
00212     if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
00213         return( SQL_INVALID_HANDLE );
00214     SQLRETURN ret = ( ((CSqlOdbcDbc*) ConnectionHandle)->SQLDisconnect() );
00215     return ret;
00216 }
00217 
00218 SQLRETURN CSqlOdbcDbc::SQLDisconnect( void )
00219 {
00220     SQLRETURN rc;
00221 
00222     // Start with NO_ERR
00223     err_.set( NO_ERR );
00224 
00225     // Can we proceed ?
00226     if( chkStateForSQLDisconnect() != SQL_SUCCESS )
00227         return( SQL_ERROR );
00228 
00229     // Free all stmts
00230     while( stmtList_.size() != 0 )
00231     {
00232         rc = CSqlOdbcStmt::SQLFreeHandle( stmtList_[0] );
00233         // This free's the stmt and removes element from stmtList_.
00234         if( rc != OK )
00235             return( SQL_ERROR );
00236     }
00237 
00238     // Commit the transaction
00239     if( fsqlConn_->commit() != OK )
00240         return( SQL_ERROR );
00241         
00242     // Disconnect
00243     if( fsqlConn_->disconnect() != OK )
00244         return( SQL_ERROR );
00245 
00246     delete fsqlConn_;
00247     fsqlConn_ = NULL;
00248     // Change the state of Dbc
00249     state_ = C2;
00250 
00251     return( SQL_SUCCESS );
00252 }
00253 
00254 SQLRETURN CSqlOdbcDbc::SQLEndTran(
00255     SQLSMALLINT completionType) // IN
00256 {
00257     SQLRETURN rc;
00258 
00259     // Start with NO_ERR
00260     err_.set( NO_ERR );
00261 
00262     // Can we proceed ?
00263     if( chkStateForSQLEndTran() != SQL_SUCCESS )
00264         return( SQL_ERROR );
00265 
00266     // Stop if no transaction is started.
00267     if( state_ != C6 )
00268         return( SQL_SUCCESS );
00269 
00270     // Close cursors of all the statements
00271     std::vector<CSqlOdbcStmt*>::iterator iter;
00272     iter = stmtList_.begin();
00273     while( iter != stmtList_.end() )
00274     {
00275         (*iter)->SQLFreeHandle( SQL_CLOSE );
00276         iter++;
00277     }
00278 
00279     // Finish transaction
00280     switch( completionType )
00281     {
00282         case SQL_COMMIT:
00283 
00284                     if( fsqlConn_->commit() != OK )
00285                         return( SQL_ERROR );
00286 
00287                     if( fsqlConn_->beginTrans( curIsolationLevel_ ) != OK )
00288                         return( SQL_ERROR );
00289 
00290                     break;
00291 
00292         case SQL_ROLLBACK:
00293                     if( fsqlConn_->rollback() != OK )
00294                         return( SQL_ERROR );
00295 
00296                     rc = fsqlConn_->beginTrans( curIsolationLevel_ );
00297                     break;
00298 
00299         default:    err_.set( ERROR_OPTRANGE );
00300                     return( SQL_ERROR );
00301     }
00302 
00303     // Had statements ?
00304     if( stmtList_.size() == 0 )
00305         state_ = C4;
00306     else
00307         state_ = C5;
00308 
00309     return( SQL_SUCCESS );
00310 }
00311 
00312 SQLRETURN SQLSetConnectOption(
00313     SQLHDBC ConnectionHandle,
00314     SQLUSMALLINT Option,
00315     SQLUINTEGER Value)
00316 {
00317     return( SQLSetConnectAttr( ConnectionHandle, Option, (SQLPOINTER) Value, 0) );
00318 }
00319 
00320 SQLRETURN SQLSetConnectAttr(
00321     SQLHDBC ConnectionHandle,
00322     SQLINTEGER Attribute,
00323     SQLPOINTER Value,
00324     SQLINTEGER StringLength)
00325 {
00326    // Validate handle
00327    if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
00328         return( SQL_INVALID_HANDLE );
00329 
00330    return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLSetConnectAttr( Attribute, Value, StringLength ) );
00331 }
00332 
00333 SQLRETURN CSqlOdbcDbc::SQLSetConnectAttr(
00334     SQLINTEGER attribute,
00335     SQLPOINTER value,
00336     SQLINTEGER stringLength)
00337 {
00338     // Start with NO_ERR
00339     err_.set( NO_ERR );
00340 
00341     switch( attribute )
00342     {
00343         case SQL_ATTR_ACCESS_MODE:
00344             // validate 'value'
00345             if( (SQLUINTEGER) value == SQL_MODE_READ_ONLY )
00346                 accessMode_ = ACCESSMODE_READ_ONLY;
00347             else if( (SQLUINTEGER) value == SQL_MODE_READ_WRITE )
00348                 accessMode_ = ACCESSMODE_READ_WRITE;
00349             else
00350                 return( SQL_ERROR );
00351 
00352             break;
00353         case SQL_DEFAULT_TXN_ISOLATION:
00354         case SQL_ATTR_TXN_ISOLATION:
00355             // validate 'value'
00356             if( (SQLUINTEGER) value == SQL_TXN_READ_UNCOMMITTED )
00357                 isolationLevel_ = READ_UNCOMMITTED;
00358             else if( (SQLUINTEGER) value == SQL_TXN_READ_COMMITTED )
00359                 isolationLevel_ = READ_COMMITTED;
00360             else if( (SQLUINTEGER) value == SQL_TXN_REPEATABLE_READ )
00361                 isolationLevel_ = READ_REPEATABLE;
00362 //            else if( (SQLUINTEGER) value == SQL_TXN_SERIALIZABLE )
00363 //                isolationLevel_ = SERIALIZABLE;
00364             else
00365                 return( SQL_ERROR );
00366 
00367             break;
00368         case SQL_ATTR_AUTOCOMMIT:
00369             autoCommit_ = (SQLUINTEGER) value;
00370             if( state_ == C6 )
00371                 SQLEndTran( SQL_COMMIT );
00372             break;
00373 
00374         default: err_.set( ERROR_OPTRANGE );
00375                  return( SQL_ERROR );
00376     }
00377 
00378     return( SQL_SUCCESS );
00379 }
00380 
00381 SQLRETURN SQLGetConnectOption(
00382     SQLHDBC ConnectionHandle,
00383     SQLUSMALLINT Option,
00384     SQLPOINTER Value)
00385 {
00386     return( SQLGetConnectAttr( ConnectionHandle, Option, Value, 0, 0) );
00387 }
00388 
00389 SQLRETURN SQLGetConnectAttr(
00390     SQLHDBC ConnectionHandle,
00391     SQLINTEGER Attribute,
00392     SQLPOINTER Value,
00393     SQLINTEGER BufferLength,
00394     SQLINTEGER *StringLength)
00395 {
00396    // Validate handle
00397    if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
00398         return( SQL_INVALID_HANDLE );
00399 
00400    return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLGetConnectAttr( Attribute, Value, BufferLength, StringLength ) );
00401 }
00402 
00403 SQLRETURN CSqlOdbcDbc::SQLGetConnectAttr(
00404     SQLINTEGER attribute,
00405     SQLPOINTER value,
00406     SQLINTEGER bufferLength,
00407     SQLINTEGER *stringLength)
00408 {
00409     // Start with NO_ERR
00410     err_.set( NO_ERR );
00411 
00412     switch( attribute )
00413     {
00414         case SQL_ATTR_ACCESS_MODE:
00415             // Get ODBC Access Mode
00416             if( accessMode_ == ACCESSMODE_READ_ONLY )
00417                 *((SQLUINTEGER*) value) = SQL_MODE_READ_ONLY;
00418             else if( accessMode_ == ACCESSMODE_READ_WRITE )
00419                 *((SQLUINTEGER*) value) = SQL_MODE_READ_WRITE;
00420             else
00421                 return( SQL_ERROR );
00422 
00423             break;
00424         case SQL_DEFAULT_TXN_ISOLATION:
00425         case SQL_ATTR_TXN_ISOLATION:
00426             // validate 'value'
00427             if( (SQLUINTEGER) isolationLevel_ == READ_UNCOMMITTED )
00428                 *((SQLUINTEGER*) value) = SQL_TXN_READ_UNCOMMITTED;
00429             else if( (SQLUINTEGER) isolationLevel_ == READ_COMMITTED )
00430                 *((SQLUINTEGER*) value) = SQL_TXN_READ_COMMITTED;
00431             else if( (SQLUINTEGER) isolationLevel_ == READ_REPEATABLE )
00432                 *((SQLUINTEGER*) value) = SQL_TXN_REPEATABLE_READ;
00433 //            else if( (SQLUINTEGER) isolationLevel_ == SERIALIZABLE )
00434 //                *((SQLUINTEGER*) value) = SQL_TXN_SERIALIZABLE;
00435             else
00436                 return( SQL_ERROR );
00437 
00438             break;
00439         case SQL_ATTR_AUTOCOMMIT:
00440             *((SQLUINTEGER*) value) = autoCommit_;
00441             break;
00442 
00443         default: err_.set( ERROR_OPTRANGE );
00444                  return( SQL_ERROR );
00445     }
00446 
00447     return( SQL_SUCCESS );
00448 }

Generated on Mon Jun 9 22:37:14 2008 for csql by  doxygen 1.4.7