adding cacheloader library
[csql.git] / src / odbc / odbcDbc.cxx
blobbcf444de06932d66636059ba8f01db9721f3bc3e
1 /* Class CSqlOdbcDbc
2 Description: Connection Handle manager.
4 ODBC API's:
5 CSqlOdbcDbc::SQLAllocDbc();
6 CSqlOdbcDbc::SQLFreeDbc();
7 CSqlOdbcDbc::SQLConnect();
8 */
10 #include "odbcCommon.h"
11 #include <SqlNwConnection.h>
13 // Constructor
14 CSqlOdbcDbc::CSqlOdbcDbc( void ) :
15 handleType_( SQL_HANDLE_DBC ),
16 parentEnv_( 0 ),
17 state_( C1 ),
18 err_( SQL_HANDLE_DBC ),
19 mode_ (1),
20 curAccessMode_( ACCESSMODE_READ_WRITE ),
21 curIsolationLevel_( READ_REPEATABLE ),
22 accessMode_( ACCESSMODE_READ_WRITE ),
23 isolationLevel_( READ_COMMITTED ),
24 autoCommit_( SQL_AUTOCOMMIT_ON ),
25 fsqlConn_( NULL )
28 SQLRETURN SQLAllocConnect(
29 SQLHENV EnvironmentHandle,
30 SQLHDBC *ConnectionHandle)
32 return( CSqlOdbcDbc::SQLAllocHandle( EnvironmentHandle, ConnectionHandle ) );
35 // All ODBC API's below.
36 SQLRETURN CSqlOdbcDbc::SQLAllocHandle(
37 SQLHANDLE inputHandle, // IN
38 SQLHANDLE *outputHandle ) // OUT
41 CSqlOdbcEnv *inputEnv = (CSqlOdbcEnv*) inputHandle;
43 if( isValidHandle( inputEnv, SQL_HANDLE_ENV ) != SQL_SUCCESS )
44 return( SQL_INVALID_HANDLE );
46 // Stop if odbcVersion not set.
47 if( inputEnv->odbcVersion_ == 0 )
49 inputEnv->err_.set( ERROR_FUNCSEQ );
50 return( SQL_ERROR );
53 // Allocate Connection object.
54 *outputHandle = (SQLHANDLE*) new CSqlOdbcDbc;
55 if( *outputHandle == NULL )
57 globalError.set( ERROR_MEMALLOC );
58 globalError.printStr( SQL_OV_ODBC3 );
59 return( SQL_ERROR );
62 // Initialize relation b/w Env and Dbc
63 inputEnv->dbcList_.insert( inputEnv->dbcList_.begin(), (CSqlOdbcDbc*) *outputHandle );
64 inputEnv->state_ = E2;
65 ((CSqlOdbcDbc*) *outputHandle)->parentEnv_ = inputEnv;
66 ((CSqlOdbcDbc*) *outputHandle)->state_ = C2;
68 return( SQL_SUCCESS );
71 SQLRETURN SQLFreeConnect(
72 SQLHDBC ConnectionHandle)
74 return( CSqlOdbcDbc::SQLFreeHandle( ConnectionHandle ) );
77 SQLRETURN CSqlOdbcDbc::SQLFreeHandle(
78 SQLHANDLE inputHandle) // IN
80 CSqlOdbcDbc *inputDbc = (CSqlOdbcDbc*) inputHandle;
82 // Validate handle
83 if( isValidHandle( inputDbc, SQL_HANDLE_DBC ) != SQL_SUCCESS )
84 return( SQL_INVALID_HANDLE );
86 // Check whether we can proceed.
87 if( inputDbc->chkStateForSQLFreeHandle() != SQL_SUCCESS )
88 return( SQL_ERROR );
90 // Remove Dbc from Parent Env.
91 std::vector<CSqlOdbcDbc*>::iterator iter;
92 iter = inputDbc->parentEnv_->dbcList_.begin();
93 while( iter != inputDbc->parentEnv_->dbcList_.end() )
95 if( *iter == inputDbc )
97 inputDbc->parentEnv_->dbcList_.erase( iter );
98 break;
100 iter++;
102 if( inputDbc->parentEnv_->dbcList_.size() == 0 )
103 inputDbc->parentEnv_->state_ = E1;
105 inputDbc->handleType_ = -1; // Make object invalid.
106 delete inputDbc; // Delete Dbc.
108 return( SQL_SUCCESS );
111 SQLRETURN SQLDriverConnect(
112 SQLHDBC ConnectionHandle,
113 SQLHWND WindowHandle,
114 SQLCHAR * InConnectionString,
115 SQLSMALLINT StringLength1,
116 SQLCHAR * OutConnectionString,
117 SQLSMALLINT BufferLength,
118 SQLSMALLINT * StringLength2Ptr,
119 SQLUSMALLINT DriverCompletion)
121 printf("Connection string is %s\n", InConnectionString);
122 // Validate handle
123 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
124 return( SQL_INVALID_HANDLE );
126 return( ((CSqlOdbcDbc*) ConnectionHandle)->SQLConnect((SQLCHAR*)"a",
127 (SQLSMALLINT)strlen("a"), (SQLCHAR*)"root", (SQLSMALLINT)strlen("root"),
128 (SQLCHAR*)"manager", (SQLSMALLINT)strlen("manager")) );
132 SQLRETURN SQLConnect( // All param's are IN
133 SQLHDBC ConnectionHandle,
134 SQLCHAR *ServerName,
135 SQLSMALLINT NameLength1,
136 SQLCHAR *UserName,
137 SQLSMALLINT NameLength2,
138 SQLCHAR *Authentication,
139 SQLSMALLINT NameLength3)
141 // Validate handle
142 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
143 return( SQL_INVALID_HANDLE );
145 return( ((CSqlOdbcDbc*) ConnectionHandle)->SQLConnect( ServerName, NameLength1,
146 UserName, NameLength2, Authentication, NameLength3) );
149 SQLRETURN CSqlOdbcDbc::SQLConnect( // All param's are IN
150 SQLCHAR *serverName,
151 SQLSMALLINT len1,
152 SQLCHAR *user,
153 SQLSMALLINT len2,
154 SQLCHAR *pass,
155 SQLSMALLINT len3)
157 int rc;
158 char str[IDENTIFIER_LENGTH];
159 char *hostName = NULL;
160 char *portNo = NULL;
161 char *connMode = NULL;
162 // Start with NO_ERR
163 err_.set( NO_ERR );
164 // Can we proceed ?
165 if( chkStateForSQLConnect() != SQL_SUCCESS )
166 return( SQL_ERROR );
168 // Invalid Buffer Length.
169 if( (len1 < 0 && len1 != SQL_NTS) || (len2 < 0 && len2 != SQL_NTS) || (len2 < 0 && len2 != SQL_NTS) )
171 err_.set( ERROR_BUFLEN );
172 return( SQL_ERROR );
174 if (fsqlConn_ != NULL)
176 err_.set( ERROR_CONNINUSE);
177 return ( SQL_ERROR );
180 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
181 connMode = strtok(str, ";");
182 hostName = strtok(NULL, ";");
183 portNo = strtok(NULL, ";");
184 if ((strcasecmp((char*)connMode, "Network") == 0) && (hostName == NULL || portNo == NULL)) return ( SQL_ERROR );
185 if (strcasecmp((char*)connMode, "Adapter") == 0)
187 fsqlConn_ = SqlFactory::createConnection(CSqlAdapter);
188 mode_ = 2;
189 }else if (strcasecmp((char*)connMode, "Gateway") == 0){
190 fsqlConn_ = SqlFactory::createConnection(CSqlGateway);
191 mode_ = 3;
192 } else if (strcasecmp((char*)connMode, "Network") == 0) {
193 fsqlConn_ = SqlFactory::createConnection(CSqlNetwork);
194 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
195 con->setHost(hostName, atoi(portNo));
196 mode_ = 4;
197 } else if (strcasecmp((char*)connMode, "NetworkAdapter") == 0) {
198 fsqlConn_ = SqlFactory::createConnection(CSqlNetworkAdapter);
199 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
200 con->setHost(hostName, atoi(portNo));
201 mode_ = 5;
202 } else if (strcasecmp((char*)connMode, "NetworkGateway") == 0) {
203 fsqlConn_ = SqlFactory::createConnection(CSqlNetworkGateway);
204 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
205 con->setHost(hostName, atoi(portNo));
206 mode_ = 6;
207 }else{
208 fsqlConn_ = SqlFactory::createConnection(CSql);
209 mode_ = 1;
212 rc = fsqlConn_->connect( (char*) user, (char*) pass );
213 if( rc != OK )
215 err_.set( ERROR_CONNREJCTD);
216 return( SQL_ERROR );
218 rc = fsqlConn_->beginTrans( isolationLevel_ );
219 if( rc != OK )
221 err_.set( ERROR_INVTRANSTATE );
222 return( SQL_ERROR );
224 curAccessMode_ = accessMode_;
225 curIsolationLevel_ = isolationLevel_;
227 // Update Dbc state
228 state_ = C4;
230 return( SQL_SUCCESS );
233 SQLRETURN SQLDisconnect(
234 SQLHDBC ConnectionHandle) // IN
236 // Validate Handle
237 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
238 return( SQL_INVALID_HANDLE );
239 SQLRETURN ret = ( ((CSqlOdbcDbc*) ConnectionHandle)->SQLDisconnect() );
240 return ret;
243 SQLRETURN CSqlOdbcDbc::SQLDisconnect( void )
245 SQLRETURN rc;
247 // Start with NO_ERR
248 err_.set( NO_ERR );
250 // Can we proceed ?
251 if( chkStateForSQLDisconnect() != SQL_SUCCESS )
252 return( SQL_ERROR );
254 // Free all stmts
255 while( stmtList_.size() != 0 )
257 rc = CSqlOdbcStmt::SQLFreeHandle( stmtList_[0] );
258 // This free's the stmt and removes element from stmtList_.
259 if( rc != OK )
260 return( SQL_ERROR );
263 // Commit the transaction
264 if( fsqlConn_->commit() != OK )
265 return( SQL_ERROR );
267 // Disconnect
268 if( fsqlConn_->disconnect() != OK )
269 return( SQL_ERROR );
271 delete fsqlConn_;
272 fsqlConn_ = NULL;
273 // Change the state of Dbc
274 state_ = C2;
276 return( SQL_SUCCESS );
279 SQLRETURN CSqlOdbcDbc::SQLEndTran(
280 SQLSMALLINT completionType) // IN
282 SQLRETURN rc;
284 // Start with NO_ERR
285 err_.set( NO_ERR );
287 // Can we proceed ?
288 if( chkStateForSQLEndTran() != SQL_SUCCESS )
289 return( SQL_ERROR );
291 // Stop if no transaction is started.
292 if( state_ != C6 )
293 return( SQL_SUCCESS );
295 // Close cursors of all the statements
296 std::vector<CSqlOdbcStmt*>::iterator iter;
297 iter = stmtList_.begin();
298 while( iter != stmtList_.end() )
300 (*iter)->SQLFreeHandle( SQL_CLOSE );
301 iter++;
304 // Finish transaction
305 switch( completionType )
307 case SQL_COMMIT:
309 if( fsqlConn_->commit() != OK )
310 return( SQL_ERROR );
312 if( fsqlConn_->beginTrans( curIsolationLevel_ ) != OK )
313 return( SQL_ERROR );
315 break;
317 case SQL_ROLLBACK:
318 if( fsqlConn_->rollback() != OK )
319 return( SQL_ERROR );
321 rc = fsqlConn_->beginTrans( curIsolationLevel_ );
322 break;
324 default: err_.set( ERROR_OPTRANGE );
325 return( SQL_ERROR );
328 // Had statements ?
329 if( stmtList_.size() == 0 )
330 state_ = C4;
331 else
332 state_ = C5;
334 return( SQL_SUCCESS );
337 SQLRETURN SQLSetConnectOption(
338 SQLHDBC ConnectionHandle,
339 SQLUSMALLINT Option,
340 SQLUINTEGER Value)
342 return( SQLSetConnectAttr( ConnectionHandle, Option, (SQLPOINTER) Value, 0) );
345 SQLRETURN SQLSetConnectAttr(
346 SQLHDBC ConnectionHandle,
347 SQLINTEGER Attribute,
348 SQLPOINTER Value,
349 SQLINTEGER StringLength)
351 // Validate handle
352 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
353 return( SQL_INVALID_HANDLE );
355 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLSetConnectAttr( Attribute, Value, StringLength ) );
358 SQLRETURN CSqlOdbcDbc::SQLSetConnectAttr(
359 SQLINTEGER attribute,
360 SQLPOINTER value,
361 SQLINTEGER stringLength)
363 // Start with NO_ERR
364 err_.set( NO_ERR );
366 switch( attribute )
368 case SQL_ATTR_ACCESS_MODE:
369 // validate 'value'
370 if( (SQLUINTEGER) value == SQL_MODE_READ_ONLY )
371 accessMode_ = ACCESSMODE_READ_ONLY;
372 else if( (SQLUINTEGER) value == SQL_MODE_READ_WRITE )
373 accessMode_ = ACCESSMODE_READ_WRITE;
374 else
375 return( SQL_ERROR );
377 break;
378 case SQL_DEFAULT_TXN_ISOLATION:
379 case SQL_ATTR_TXN_ISOLATION:
380 // validate 'value'
381 if( (SQLUINTEGER) value == SQL_TXN_READ_UNCOMMITTED )
382 isolationLevel_ = READ_UNCOMMITTED;
383 else if( (SQLUINTEGER) value == SQL_TXN_READ_COMMITTED )
384 isolationLevel_ = READ_COMMITTED;
385 else if( (SQLUINTEGER) value == SQL_TXN_REPEATABLE_READ )
386 isolationLevel_ = READ_REPEATABLE;
387 // else if( (SQLUINTEGER) value == SQL_TXN_SERIALIZABLE )
388 // isolationLevel_ = SERIALIZABLE;
389 else
390 return( SQL_ERROR );
392 break;
393 case SQL_ATTR_AUTOCOMMIT:
394 autoCommit_ = (SQLUINTEGER) value;
395 if( state_ == C6 )
396 SQLEndTran( SQL_COMMIT );
397 break;
399 default: err_.set( ERROR_OPTRANGE );
400 return( SQL_ERROR );
403 return( SQL_SUCCESS );
406 SQLRETURN SQLGetConnectOption(
407 SQLHDBC ConnectionHandle,
408 SQLUSMALLINT Option,
409 SQLPOINTER Value)
411 return( SQLGetConnectAttr( ConnectionHandle, Option, Value, 0, 0) );
414 SQLRETURN SQLGetConnectAttr(
415 SQLHDBC ConnectionHandle,
416 SQLINTEGER Attribute,
417 SQLPOINTER Value,
418 SQLINTEGER BufferLength,
419 SQLINTEGER *StringLength)
421 // Validate handle
422 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
423 return( SQL_INVALID_HANDLE );
425 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLGetConnectAttr( Attribute, Value, BufferLength, StringLength ) );
428 SQLRETURN CSqlOdbcDbc::SQLGetConnectAttr(
429 SQLINTEGER attribute,
430 SQLPOINTER value,
431 SQLINTEGER bufferLength,
432 SQLINTEGER *stringLength)
434 // Start with NO_ERR
435 err_.set( NO_ERR );
437 switch( attribute )
439 case SQL_ATTR_ACCESS_MODE:
440 // Get ODBC Access Mode
441 if( accessMode_ == ACCESSMODE_READ_ONLY )
442 *((SQLUINTEGER*) value) = SQL_MODE_READ_ONLY;
443 else if( accessMode_ == ACCESSMODE_READ_WRITE )
444 *((SQLUINTEGER*) value) = SQL_MODE_READ_WRITE;
445 else
446 return( SQL_ERROR );
448 break;
449 case SQL_DEFAULT_TXN_ISOLATION:
450 case SQL_ATTR_TXN_ISOLATION:
451 // validate 'value'
452 if( (SQLUINTEGER) isolationLevel_ == READ_UNCOMMITTED )
453 *((SQLUINTEGER*) value) = SQL_TXN_READ_UNCOMMITTED;
454 else if( (SQLUINTEGER) isolationLevel_ == READ_COMMITTED )
455 *((SQLUINTEGER*) value) = SQL_TXN_READ_COMMITTED;
456 else if( (SQLUINTEGER) isolationLevel_ == READ_REPEATABLE )
457 *((SQLUINTEGER*) value) = SQL_TXN_REPEATABLE_READ;
458 // else if( (SQLUINTEGER) isolationLevel_ == SERIALIZABLE )
459 // *((SQLUINTEGER*) value) = SQL_TXN_SERIALIZABLE;
460 else
461 return( SQL_ERROR );
463 break;
464 case SQL_ATTR_AUTOCOMMIT:
465 *((SQLUINTEGER*) value) = autoCommit_;
466 break;
468 default: err_.set( ERROR_OPTRANGE );
469 return( SQL_ERROR );
472 return( SQL_SUCCESS );