cleanup
[csql.git] / src / odbc / odbcDbc.cxx
blob87b978374ba1f24da2abc4f9dcf55188df591009
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 inputEnv->dbcList_.append(*outputHandle);
63 inputEnv->state_ = E2;
64 ((CSqlOdbcDbc*) *outputHandle)->parentEnv_ = inputEnv;
65 ((CSqlOdbcDbc*) *outputHandle)->state_ = C2;
67 return( SQL_SUCCESS );
70 SQLRETURN SQLFreeConnect(
71 SQLHDBC ConnectionHandle)
73 return( CSqlOdbcDbc::SQLFreeHandle( ConnectionHandle ) );
76 SQLRETURN CSqlOdbcDbc::SQLFreeHandle(
77 SQLHANDLE inputHandle) // IN
79 CSqlOdbcDbc *inputDbc = (CSqlOdbcDbc*) inputHandle;
81 // Validate handle
82 if( isValidHandle( inputDbc, SQL_HANDLE_DBC ) != SQL_SUCCESS )
83 return( SQL_INVALID_HANDLE );
85 // Check whether we can proceed.
86 if( inputDbc->chkStateForSQLFreeHandle() != SQL_SUCCESS )
87 return( SQL_ERROR );
89 // Remove Dbc from Parent Env.
90 ListIterator iter = inputDbc->parentEnv_->dbcList_.getIterator();
91 CSqlOdbcDbc *dbcElem = NULL;
92 while(iter.hasElement())
94 dbcElem = (CSqlOdbcDbc *) iter.nextElement();
95 if (dbcElem == inputDbc) {
96 iter.reset();
97 inputDbc->parentEnv_->dbcList_.remove(dbcElem);
98 break;
101 if( inputDbc->parentEnv_->dbcList_.size() == 0 )
102 inputDbc->parentEnv_->state_ = E1;
104 inputDbc->handleType_ = -1; // Make object invalid.
105 delete inputDbc; // Delete Dbc.
107 return( SQL_SUCCESS );
110 SQLRETURN SQLDriverConnect(
111 SQLHDBC ConnectionHandle,
112 SQLHWND WindowHandle,
113 SQLCHAR * InConnectionString,
114 SQLSMALLINT StringLength1,
115 SQLCHAR * OutConnectionString,
116 SQLSMALLINT BufferLength,
117 SQLSMALLINT * StringLength2Ptr,
118 SQLUSMALLINT DriverCompletion)
120 // Validate handle
121 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
122 return( SQL_INVALID_HANDLE );
124 return( ((CSqlOdbcDbc*) ConnectionHandle)->SQLConnect(InConnectionString,
125 SQL_NTS, (SQLCHAR*)"root", (SQLSMALLINT)strlen("root"),
126 (SQLCHAR*)"manager", (SQLSMALLINT)strlen("manager")) );
130 char * CSqlOdbcDbc::getFromUrl(char *url,char *name)
132 char *token=NULL, *subtoken=NULL;
133 char *saveptr1, *saveptr2,*str1,*str2;
134 for ( str1 = url; ; str1 = NULL) {
135 token = strtok_r(str1, ";" , &saveptr1);
136 if (token == NULL)
137 break;
138 // printf("TOKEN: %s\n",token);
139 str2 = token;
140 subtoken = strtok_r(str2, "=", &saveptr2);
141 //printf(" --> %s\n", subtoken);
142 if (subtoken != NULL){
143 if(strcasecmp(subtoken,name)==0)
145 return strtok_r(NULL,"=",&saveptr2);
149 return NULL;
152 SQLRETURN SQLConnect( // All param's are IN
153 SQLHDBC ConnectionHandle,
154 SQLCHAR *ServerName,
155 SQLSMALLINT NameLength1,
156 SQLCHAR *UserName,
157 SQLSMALLINT NameLength2,
158 SQLCHAR *Authentication,
159 SQLSMALLINT NameLength3)
161 // Validate handle
162 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
163 return( SQL_INVALID_HANDLE );
165 return( ((CSqlOdbcDbc*) ConnectionHandle)->SQLConnect( ServerName, NameLength1,
166 UserName, NameLength2, Authentication, NameLength3) );
169 SQLRETURN CSqlOdbcDbc::SQLConnect( // All param's are IN
170 SQLCHAR *serverName,
171 SQLSMALLINT len1,
172 SQLCHAR *user,
173 SQLSMALLINT len2,
174 SQLCHAR *pass,
175 SQLSMALLINT len3)
177 int rc;
178 char str[IDENTIFIER_LENGTH];
179 char *dsn=NULL;
180 char *hostName = NULL;
181 char *portNo = NULL;
182 char *connMode = NULL;
183 // Start with NO_ERR
184 err_.set( NO_ERR );
185 // Can we proceed ?
186 if( chkStateForSQLConnect() != SQL_SUCCESS )
187 return( SQL_ERROR );
189 // Invalid Buffer Length.
190 if( (len1 < 0 && len1 != SQL_NTS) || (len2 < 0 && len2 != SQL_NTS) || (len2 < 0 && len2 != SQL_NTS) )
192 err_.set( ERROR_BUFLEN );
193 return( SQL_ERROR );
195 if (fsqlConn_ != NULL)
197 err_.set( ERROR_CONNINUSE);
198 return ( SQL_ERROR );
201 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
202 dsn = getFromUrl(str,"DSN");
203 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
204 connMode = getFromUrl(str,"MODE");
205 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
206 hostName = getFromUrl(str,"SERVER");
207 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
208 portNo = getFromUrl(str,"PORT");
209 //printf("Mode=%s , hostName=%s port=%s\n",connMode,hostName,portNo);
210 if(NULL != connMode){
211 if (hostName == NULL || strcasecmp((char*)hostName, "localhost") == 0 ){
212 if (strcasecmp((char*)connMode, "Gateway") == 0){
213 fsqlConn_ = SqlFactory::createConnection(CSqlGateway);
214 mode_ = 3;
215 }else if (strcasecmp((char*)connMode, "Adapter") == 0){
216 fsqlConn_ = SqlFactory::createConnection(CSqlAdapter);
217 mode_ = 2;
218 }else if (strcasecmp((char*)connMode, "csql") == 0){
219 fsqlConn_ = SqlFactory::createConnection(CSql);
220 mode_ = 1;
221 }else return ( SQL_ERROR );
222 } else {
223 if (portNo == NULL) {
224 err_.set(ERROR_INVARGVAL);
225 return (SQL_ERROR);
227 if (strcasecmp((char*)connMode, "Gateway") == 0){
228 fsqlConn_ = SqlFactory::createConnection(CSqlNetworkGateway);
229 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
230 con->setHost(hostName, atoi(portNo));
231 mode_ = 6;
232 }else if (strcasecmp((char*)connMode, "Adapter") == 0){
233 fsqlConn_ = SqlFactory::createConnection(CSqlNetworkAdapter);
234 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
235 con->setHost(hostName, atoi(portNo));
236 mode_ = 5;
237 }else if (strcasecmp((char*)connMode, "csql") == 0){
238 fsqlConn_ = SqlFactory::createConnection(CSqlNetwork);
239 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
240 con->setHost(hostName, atoi(portNo));
241 mode_ = 4;
242 }else {
243 err_.set( ERROR_INVARGVAL );
244 return ( SQL_ERROR );
248 }else{
249 fsqlConn_ = SqlFactory::createConnection(CSql);
250 mode_ = 1;
252 rc = fsqlConn_->connect( (char*) user, (char*) pass );
253 if( rc != OK )
255 err_.set( ERROR_CONNREJCTD);
256 return( SQL_ERROR );
258 rc = fsqlConn_->beginTrans( isolationLevel_ );
259 if( rc != OK )
261 err_.set( ERROR_INVTRANSTATE );
262 return( SQL_ERROR );
264 curAccessMode_ = accessMode_;
265 curIsolationLevel_ = isolationLevel_;
267 // Update Dbc state
268 state_ = C4;
270 return( SQL_SUCCESS );
274 SQLRETURN SQLDisconnect(
275 SQLHDBC ConnectionHandle) // IN
277 // Validate Handle
278 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
279 return( SQL_INVALID_HANDLE );
280 SQLRETURN ret = ( ((CSqlOdbcDbc*) ConnectionHandle)->SQLDisconnect() );
281 return ret;
284 SQLRETURN CSqlOdbcDbc::SQLDisconnect( void )
286 SQLRETURN rc;
288 // Start with NO_ERR
289 err_.set( NO_ERR );
291 // Can we proceed ?
292 if( chkStateForSQLDisconnect() != SQL_SUCCESS )
293 return( SQL_ERROR );
295 ListIterator iter=stmtList_.getIterator();
296 while (iter.hasElement()) {
297 rc = CSqlOdbcStmt::SQLFreeHandle(iter.nextElement());
298 if( rc != OK )
299 return( SQL_ERROR );
302 // Rollback the transaction
303 if( fsqlConn_->rollback() != OK )
304 return( SQL_ERROR );
306 // Disconnect
307 if( fsqlConn_->disconnect() != OK )
308 return( SQL_ERROR );
310 delete fsqlConn_;
311 fsqlConn_ = NULL;
312 // Change the state of Dbc
313 state_ = C2;
315 return( SQL_SUCCESS );
318 SQLRETURN CSqlOdbcDbc::SQLEndTran(
319 SQLSMALLINT completionType) // IN
321 SQLRETURN rc;
323 // Start with NO_ERR
324 err_.set( NO_ERR );
326 // Can we proceed ?
327 if( chkStateForSQLEndTran() != SQL_SUCCESS )
328 return( SQL_ERROR );
330 // Stop if no transaction is started.
331 if( state_ != C6 )
332 return( SQL_SUCCESS );
334 // Close cursors of all the statements
335 ListIterator iter = stmtList_.getIterator();
336 CSqlOdbcStmt *stmtElem = NULL;
337 while (iter.hasElement()) {
338 stmtElem = (CSqlOdbcStmt *) iter.nextElement();
339 stmtElem->SQLFreeHandle( SQL_CLOSE );
341 // Finish transaction
342 switch( completionType )
344 case SQL_COMMIT:
346 if( fsqlConn_->commit() != OK )
347 return( SQL_ERROR );
349 if( fsqlConn_->beginTrans( curIsolationLevel_ ) != OK )
350 return( SQL_ERROR );
352 break;
354 case SQL_ROLLBACK:
355 if( fsqlConn_->rollback() != OK )
356 return( SQL_ERROR );
358 rc = fsqlConn_->beginTrans( curIsolationLevel_ );
359 break;
361 default: err_.set( ERROR_OPTRANGE );
362 return( SQL_ERROR );
365 // Had statements ?
366 if( stmtList_.size() == 0 )
367 state_ = C4;
368 else
369 state_ = C5;
371 return( SQL_SUCCESS );
374 SQLRETURN SQLSetConnectOption(
375 SQLHDBC ConnectionHandle,
376 SQLUSMALLINT Option,
377 SQLUINTEGER Value)
379 return( SQLSetConnectAttr( ConnectionHandle, Option, (SQLPOINTER) Value, 0) );
382 SQLRETURN SQLSetConnectAttr(
383 SQLHDBC ConnectionHandle,
384 SQLINTEGER Attribute,
385 SQLPOINTER Value,
386 SQLINTEGER StringLength)
388 // Validate handle
389 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
390 return( SQL_INVALID_HANDLE );
392 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLSetConnectAttr( Attribute, Value, StringLength ) );
395 SQLRETURN CSqlOdbcDbc::SQLSetConnectAttr(
396 SQLINTEGER attribute,
397 SQLPOINTER value,
398 SQLINTEGER stringLength)
400 // Start with NO_ERR
401 err_.set( NO_ERR );
403 switch( attribute )
405 case SQL_ATTR_ACCESS_MODE:
406 // validate 'value'
407 if( (SQLUINTEGER) value == SQL_MODE_READ_ONLY )
408 accessMode_ = ACCESSMODE_READ_ONLY;
409 else if( (SQLUINTEGER) value == SQL_MODE_READ_WRITE )
410 accessMode_ = ACCESSMODE_READ_WRITE;
411 else
412 return( SQL_ERROR );
414 break;
415 case SQL_DEFAULT_TXN_ISOLATION:
416 case SQL_ATTR_TXN_ISOLATION:
417 // validate 'value'
418 if( (SQLUINTEGER) value == SQL_TXN_READ_UNCOMMITTED )
419 isolationLevel_ = READ_UNCOMMITTED;
420 else if( (SQLUINTEGER) value == SQL_TXN_READ_COMMITTED )
421 isolationLevel_ = READ_COMMITTED;
422 else if( (SQLUINTEGER) value == SQL_TXN_REPEATABLE_READ )
423 isolationLevel_ = READ_REPEATABLE;
424 // else if( (SQLUINTEGER) value == SQL_TXN_SERIALIZABLE )
425 // isolationLevel_ = SERIALIZABLE;
426 else
427 return( SQL_ERROR );
429 break;
430 case SQL_ATTR_AUTOCOMMIT:
431 autoCommit_ = (SQLUINTEGER) value;
432 if( state_ == C6 )
433 SQLEndTran( SQL_COMMIT );
434 break;
436 default: err_.set( ERROR_OPTRANGE );
437 return( SQL_ERROR );
440 return( SQL_SUCCESS );
443 SQLRETURN SQLGetConnectOption(
444 SQLHDBC ConnectionHandle,
445 SQLUSMALLINT Option,
446 SQLPOINTER Value)
448 return( SQLGetConnectAttr( ConnectionHandle, Option, Value, 0, 0) );
451 SQLRETURN SQLGetConnectAttr(
452 SQLHDBC ConnectionHandle,
453 SQLINTEGER Attribute,
454 SQLPOINTER Value,
455 SQLINTEGER BufferLength,
456 SQLINTEGER *StringLength)
458 // Validate handle
459 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
460 return( SQL_INVALID_HANDLE );
462 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLGetConnectAttr( Attribute, Value, BufferLength, StringLength ) );
465 SQLRETURN CSqlOdbcDbc::SQLGetConnectAttr(
466 SQLINTEGER attribute,
467 SQLPOINTER value,
468 SQLINTEGER bufferLength,
469 SQLINTEGER *stringLength)
471 // Start with NO_ERR
472 err_.set( NO_ERR );
474 switch( attribute )
476 case SQL_ATTR_ACCESS_MODE:
477 // Get ODBC Access Mode
478 if( accessMode_ == ACCESSMODE_READ_ONLY )
479 *((SQLUINTEGER*) value) = SQL_MODE_READ_ONLY;
480 else if( accessMode_ == ACCESSMODE_READ_WRITE )
481 *((SQLUINTEGER*) value) = SQL_MODE_READ_WRITE;
482 else
483 return( SQL_ERROR );
485 break;
486 case SQL_DEFAULT_TXN_ISOLATION:
487 case SQL_ATTR_TXN_ISOLATION:
488 // validate 'value'
489 if( (SQLUINTEGER) isolationLevel_ == READ_UNCOMMITTED )
490 *((SQLUINTEGER*) value) = SQL_TXN_READ_UNCOMMITTED;
491 else if( (SQLUINTEGER) isolationLevel_ == READ_COMMITTED )
492 *((SQLUINTEGER*) value) = SQL_TXN_READ_COMMITTED;
493 else if( (SQLUINTEGER) isolationLevel_ == READ_REPEATABLE )
494 *((SQLUINTEGER*) value) = SQL_TXN_REPEATABLE_READ;
495 // else if( (SQLUINTEGER) isolationLevel_ == SERIALIZABLE )
496 // *((SQLUINTEGER*) value) = SQL_TXN_SERIALIZABLE;
497 else
498 return( SQL_ERROR );
500 break;
501 case SQL_ATTR_AUTOCOMMIT:
502 *((SQLUINTEGER*) value) = autoCommit_;
503 break;
505 default: err_.set( ERROR_OPTRANGE );
506 return( SQL_ERROR );
509 return( SQL_SUCCESS );
512 /*SQLRETURN SQLGetFunctions(
513 SQLHDBC ConnectionHandle,
514 SQLUSMALLINT FunctionId,
515 SQLUSMALLINT * SupportedPtr)
517 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
518 return( SQL_INVALID_HANDLE );
519 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLGetFunctions(FunctionId,SupportedPtr) );
522 SQLRETURN CSqlOdbcDbc::SQLGetFunctions(
523 SQLUSMALLINT FunctionId,
524 SQLUSMALLINT * SupportedPtr)
526 if(isFunctionSupports(FunctionId))
527 *SupportedPtr = SQL_TRUE ;
528 else
529 *SupportedPtr = SQL_FALSE;
530 return (SQL_SUCCESS);
535 SQLRETURN SQLGetInfo(
536 SQLHDBC ConnectionHandle,
537 SQLUSMALLINT InfoType,
538 SQLPOINTER InfoValuePtr,
539 SQLSMALLINT BufferLength,
540 SQLSMALLINT * StringLengthPtr)
542 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
543 return( SQL_INVALID_HANDLE );
545 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLGetInfo( InfoType,InfoValuePtr,BufferLength,StringLengthPtr ) );
549 SQLRETURN CSqlOdbcDbc::SQLGetInfo(
550 SQLUSMALLINT InfoType,
551 SQLPOINTER InfoValuePtr,
552 SQLSMALLINT BufferLength,
553 SQLSMALLINT * StringLengthPtr)
555 return (SQL_SUCCESS);