adding more debug messages to odbc
[csql.git] / src / odbc / odbcDbc.cxx
blobac94672078dfe863d28e0396429faa63e3b426b2
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;
66 return( SQL_SUCCESS );
69 SQLRETURN SQLFreeConnect(
70 SQLHDBC ConnectionHandle)
72 return( CSqlOdbcDbc::SQLFreeHandle( ConnectionHandle ) );
75 SQLRETURN CSqlOdbcDbc::SQLFreeHandle(
76 SQLHANDLE inputHandle) // IN
78 CSqlOdbcDbc *inputDbc = (CSqlOdbcDbc*) inputHandle;
80 // Validate handle
81 if( isValidHandle( inputDbc, SQL_HANDLE_DBC ) != SQL_SUCCESS )
82 return( SQL_INVALID_HANDLE );
84 // Check whether we can proceed.
85 if( inputDbc->chkStateForSQLFreeHandle() != SQL_SUCCESS )
86 return( SQL_ERROR );
88 // Remove Dbc from Parent Env.
89 ListIterator iter = inputDbc->parentEnv_->dbcList_.getIterator();
90 CSqlOdbcDbc *dbcElem = NULL;
91 while(iter.hasElement())
93 dbcElem = (CSqlOdbcDbc *) iter.nextElement();
94 if (dbcElem == inputDbc) {
95 iter.reset();
96 inputDbc->parentEnv_->dbcList_.remove(dbcElem);
97 break;
100 if( inputDbc->parentEnv_->dbcList_.size() == 0 )
101 inputDbc->parentEnv_->state_ = E1;
103 inputDbc->handleType_ = -1; // Make object invalid.
104 delete inputDbc; // Delete Dbc.
106 return( SQL_SUCCESS );
109 SQLRETURN SQLDriverConnect(
110 SQLHDBC ConnectionHandle,
111 SQLHWND WindowHandle,
112 SQLCHAR * InConnectionString,
113 SQLSMALLINT StringLength1,
114 SQLCHAR * OutConnectionString,
115 SQLSMALLINT BufferLength,
116 SQLSMALLINT * StringLength2Ptr,
117 SQLUSMALLINT DriverCompletion)
119 #ifdef DEBUG
120 printError(ErrWarning, "SQLDriverConnect");
121 #endif
123 // Validate handle
124 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
125 return( SQL_INVALID_HANDLE );
127 return( ((CSqlOdbcDbc*) ConnectionHandle)->SQLConnect(InConnectionString,
128 SQL_NTS, (SQLCHAR*)"root", (SQLSMALLINT)strlen("root"),
129 (SQLCHAR*)"manager", (SQLSMALLINT)strlen("manager")) );
133 char * CSqlOdbcDbc::getFromUrl(char *url,char *name)
135 char *token=NULL, *subtoken=NULL;
136 char *saveptr1, *saveptr2,*str1,*str2;
137 for ( str1 = url; ; str1 = NULL) {
138 token = strtok_r(str1, ";" , &saveptr1);
139 if (token == NULL)
140 break;
141 // printf("TOKEN: %s\n",token);
142 str2 = token;
143 subtoken = strtok_r(str2, "=", &saveptr2);
144 //printf(" --> %s\n", subtoken);
145 if (subtoken != NULL){
146 if(strcasecmp(subtoken,name)==0)
148 return strtok_r(NULL,"=",&saveptr2);
152 return NULL;
155 SQLRETURN SQLConnect( // All param's are IN
156 SQLHDBC ConnectionHandle,
157 SQLCHAR *ServerName,
158 SQLSMALLINT NameLength1,
159 SQLCHAR *UserName,
160 SQLSMALLINT NameLength2,
161 SQLCHAR *Authentication,
162 SQLSMALLINT NameLength3)
164 #ifdef DEBUG
165 printError(ErrWarning, "SQLConnect");
166 #endif
168 // Validate handle
169 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
170 return( SQL_INVALID_HANDLE );
172 return( ((CSqlOdbcDbc*) ConnectionHandle)->SQLConnect( ServerName, NameLength1,
173 UserName, NameLength2, Authentication, NameLength3) );
176 SQLRETURN CSqlOdbcDbc::SQLConnect( // All param's are IN
177 SQLCHAR *serverName,
178 SQLSMALLINT len1,
179 SQLCHAR *user,
180 SQLSMALLINT len2,
181 SQLCHAR *pass,
182 SQLSMALLINT len3)
184 int rc;
185 char str[IDENTIFIER_LENGTH];
186 char *dsn=NULL;
187 char *hostName = NULL;
188 char *portNo = NULL;
189 char *connMode = NULL;
190 // Start with NO_ERR
191 err_.set( NO_ERR );
192 // Can we proceed ?
193 if( chkStateForSQLConnect() != SQL_SUCCESS )
194 return( SQL_ERROR );
196 // Invalid Buffer Length.
197 if( (len1 < 0 && len1 != SQL_NTS) || (len2 < 0 && len2 != SQL_NTS) || (len2 < 0 && len2 != SQL_NTS) )
199 err_.set( ERROR_BUFLEN );
200 return( SQL_ERROR );
202 if (fsqlConn_ != NULL)
204 err_.set( ERROR_CONNINUSE);
205 return ( SQL_ERROR );
208 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
209 dsn = getFromUrl(str,"DSN");
210 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
211 connMode = getFromUrl(str,"MODE");
212 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
213 hostName = getFromUrl(str,"SERVER");
214 strncpy(str,(char *) serverName, IDENTIFIER_LENGTH);
215 portNo = getFromUrl(str,"PORT");
216 //printf("Mode=%s , hostName=%s port=%s\n",connMode,hostName,portNo);
217 if(NULL != connMode){
218 if (hostName == NULL || strcasecmp((char*)hostName, "localhost") == 0 ){
219 if (strcasecmp((char*)connMode, "Gateway") == 0){
220 fsqlConn_ = SqlFactory::createConnection(CSqlGateway);
221 mode_ = 3;
222 }else if (strcasecmp((char*)connMode, "Adapter") == 0){
223 fsqlConn_ = SqlFactory::createConnection(CSqlAdapter);
224 mode_ = 2;
225 }else if (strcasecmp((char*)connMode, "csql") == 0){
226 fsqlConn_ = SqlFactory::createConnection(CSql);
227 mode_ = 1;
228 }else return ( SQL_ERROR );
229 } else {
230 if (portNo == NULL) {
231 err_.set(ERROR_INVARGVAL);
232 return (SQL_ERROR);
234 if (strcasecmp((char*)connMode, "Gateway") == 0){
235 fsqlConn_ = SqlFactory::createConnection(CSqlNetworkGateway);
236 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
237 con->setHost(hostName, atoi(portNo));
238 mode_ = 6;
239 }else if (strcasecmp((char*)connMode, "Adapter") == 0){
240 fsqlConn_ = SqlFactory::createConnection(CSqlNetworkAdapter);
241 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
242 con->setHost(hostName, atoi(portNo));
243 mode_ = 5;
244 }else if (strcasecmp((char*)connMode, "csql") == 0){
245 fsqlConn_ = SqlFactory::createConnection(CSqlNetwork);
246 SqlNwConnection *con = (SqlNwConnection *)fsqlConn_;
247 con->setHost(hostName, atoi(portNo));
248 mode_ = 4;
249 }else {
250 err_.set( ERROR_INVARGVAL );
251 return ( SQL_ERROR );
255 }else{
256 fsqlConn_ = SqlFactory::createConnection(CSql);
257 mode_ = 1;
259 rc = fsqlConn_->connect( (char*) user, (char*) pass );
260 if( rc != OK )
262 err_.set( ERROR_CONNREJCTD);
263 return( SQL_ERROR );
265 rc = fsqlConn_->beginTrans( isolationLevel_ );
266 if( rc != OK )
268 err_.set( ERROR_INVTRANSTATE );
269 return( SQL_ERROR );
271 curAccessMode_ = accessMode_;
272 curIsolationLevel_ = isolationLevel_;
274 // Update Dbc state
275 state_ = C4;
277 return( SQL_SUCCESS );
281 SQLRETURN SQLDisconnect(
282 SQLHDBC ConnectionHandle) // IN
284 #ifdef DEBUG
285 printError(ErrWarning, "SQLDisConnect");
286 #endif
287 // Validate Handle
288 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
289 return( SQL_INVALID_HANDLE );
290 SQLRETURN ret = ( ((CSqlOdbcDbc*) ConnectionHandle)->SQLDisconnect() );
291 return ret;
294 SQLRETURN CSqlOdbcDbc::SQLDisconnect( void )
296 SQLRETURN rc;
298 // Start with NO_ERR
299 err_.set( NO_ERR );
301 // Can we proceed ?
302 if( chkStateForSQLDisconnect() != SQL_SUCCESS )
303 return( SQL_ERROR );
305 ListIterator iter=stmtList_.getIterator();
306 while (iter.hasElement()) {
307 rc = CSqlOdbcStmt::SQLFreeHandle(iter.nextElement());
308 if( rc != OK )
309 return( SQL_ERROR );
312 // Rollback the transaction
313 if( fsqlConn_->rollback() != OK )
314 return( SQL_ERROR );
316 // Disconnect
317 if( fsqlConn_->disconnect() != OK )
318 return( SQL_ERROR );
320 delete fsqlConn_;
321 fsqlConn_ = NULL;
322 // Change the state of Dbc
323 state_ = C2;
325 return( SQL_SUCCESS );
328 SQLRETURN CSqlOdbcDbc::SQLEndTran(
329 SQLSMALLINT completionType) // IN
331 #ifdef DEBUG
332 printError(ErrWarning, "SQLEndTran: %hd", completionType);
333 #endif
335 SQLRETURN rc;
337 // Start with NO_ERR
338 err_.set( NO_ERR );
340 // Can we proceed ?
341 if( chkStateForSQLEndTran() != SQL_SUCCESS )
342 return( SQL_ERROR );
344 // Stop if no transaction is started.
345 if( state_ != C6 )
346 return( SQL_SUCCESS );
348 // Close cursors of all the statements
349 ListIterator iter = stmtList_.getIterator();
350 CSqlOdbcStmt *stmtElem = NULL;
351 while (iter.hasElement()) {
352 stmtElem = (CSqlOdbcStmt *) iter.nextElement();
353 stmtElem->SQLFreeHandle( SQL_CLOSE );
355 // Finish transaction
356 switch( completionType )
358 case SQL_COMMIT:
360 if( fsqlConn_->commit() != OK )
361 return( SQL_ERROR );
363 if( fsqlConn_->beginTrans( curIsolationLevel_ ) != OK )
364 return( SQL_ERROR );
366 break;
368 case SQL_ROLLBACK:
369 if( fsqlConn_->rollback() != OK )
370 return( SQL_ERROR );
372 rc = fsqlConn_->beginTrans( curIsolationLevel_ );
373 break;
375 default: err_.set( ERROR_OPTRANGE );
376 return( SQL_ERROR );
379 // Had statements ?
380 if( stmtList_.size() == 0 )
381 state_ = C4;
382 else
383 state_ = C5;
385 return( SQL_SUCCESS );
388 SQLRETURN SQLSetConnectOption(
389 SQLHDBC ConnectionHandle,
390 SQLUSMALLINT Option,
391 SQLUINTEGER Value)
393 return( SQLSetConnectAttr( ConnectionHandle, Option, (SQLPOINTER) Value, 0) );
396 SQLRETURN SQLSetConnectAttr(
397 SQLHDBC ConnectionHandle,
398 SQLINTEGER Attribute,
399 SQLPOINTER Value,
400 SQLINTEGER StringLength)
402 // Validate handle
403 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
404 return( SQL_INVALID_HANDLE );
406 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLSetConnectAttr( Attribute, Value, StringLength ) );
409 SQLRETURN CSqlOdbcDbc::SQLSetConnectAttr(
410 SQLINTEGER attribute,
411 SQLPOINTER value,
412 SQLINTEGER stringLength)
414 // Start with NO_ERR
415 err_.set( NO_ERR );
417 switch( attribute )
419 case SQL_ATTR_ACCESS_MODE:
420 // validate 'value'
421 if( (SQLUINTEGER) value == SQL_MODE_READ_ONLY )
422 accessMode_ = ACCESSMODE_READ_ONLY;
423 else if( (SQLUINTEGER) value == SQL_MODE_READ_WRITE )
424 accessMode_ = ACCESSMODE_READ_WRITE;
425 else
426 return( SQL_ERROR );
428 break;
429 case SQL_DEFAULT_TXN_ISOLATION:
430 case SQL_ATTR_TXN_ISOLATION:
431 // validate 'value'
432 if( (SQLUINTEGER) value == SQL_TXN_READ_UNCOMMITTED )
433 isolationLevel_ = READ_UNCOMMITTED;
434 else if( (SQLUINTEGER) value == SQL_TXN_READ_COMMITTED )
435 isolationLevel_ = READ_COMMITTED;
436 else if( (SQLUINTEGER) value == SQL_TXN_REPEATABLE_READ )
437 isolationLevel_ = READ_REPEATABLE;
438 // else if( (SQLUINTEGER) value == SQL_TXN_SERIALIZABLE )
439 // isolationLevel_ = SERIALIZABLE;
440 else
441 return( SQL_ERROR );
443 break;
444 case SQL_ATTR_AUTOCOMMIT:
445 autoCommit_ = (SQLUINTEGER) value;
446 if( state_ == C6 )
447 SQLEndTran( SQL_COMMIT );
448 break;
450 default: err_.set( ERROR_OPTRANGE );
451 return( SQL_ERROR );
454 return( SQL_SUCCESS );
457 SQLRETURN SQLGetConnectOption(
458 SQLHDBC ConnectionHandle,
459 SQLUSMALLINT Option,
460 SQLPOINTER Value)
462 return( SQLGetConnectAttr( ConnectionHandle, Option, Value, 0, 0) );
465 SQLRETURN SQLGetConnectAttr(
466 SQLHDBC ConnectionHandle,
467 SQLINTEGER Attribute,
468 SQLPOINTER Value,
469 SQLINTEGER BufferLength,
470 SQLINTEGER *StringLength)
472 // Validate handle
473 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
474 return( SQL_INVALID_HANDLE );
476 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLGetConnectAttr( Attribute, Value, BufferLength, StringLength ) );
479 SQLRETURN CSqlOdbcDbc::SQLGetConnectAttr(
480 SQLINTEGER attribute,
481 SQLPOINTER value,
482 SQLINTEGER bufferLength,
483 SQLINTEGER *stringLength)
485 // Start with NO_ERR
486 err_.set( NO_ERR );
488 switch( attribute )
490 case SQL_ATTR_ACCESS_MODE:
491 // Get ODBC Access Mode
492 if( accessMode_ == ACCESSMODE_READ_ONLY )
493 *((SQLUINTEGER*) value) = SQL_MODE_READ_ONLY;
494 else if( accessMode_ == ACCESSMODE_READ_WRITE )
495 *((SQLUINTEGER*) value) = SQL_MODE_READ_WRITE;
496 else
497 return( SQL_ERROR );
499 break;
500 case SQL_DEFAULT_TXN_ISOLATION:
501 case SQL_ATTR_TXN_ISOLATION:
502 // validate 'value'
503 if( (SQLUINTEGER) isolationLevel_ == READ_UNCOMMITTED )
504 *((SQLUINTEGER*) value) = SQL_TXN_READ_UNCOMMITTED;
505 else if( (SQLUINTEGER) isolationLevel_ == READ_COMMITTED )
506 *((SQLUINTEGER*) value) = SQL_TXN_READ_COMMITTED;
507 else if( (SQLUINTEGER) isolationLevel_ == READ_REPEATABLE )
508 *((SQLUINTEGER*) value) = SQL_TXN_REPEATABLE_READ;
509 // else if( (SQLUINTEGER) isolationLevel_ == SERIALIZABLE )
510 // *((SQLUINTEGER*) value) = SQL_TXN_SERIALIZABLE;
511 else
512 return( SQL_ERROR );
514 break;
515 case SQL_ATTR_AUTOCOMMIT:
516 *((SQLUINTEGER*) value) = autoCommit_;
517 break;
519 default: err_.set( ERROR_OPTRANGE );
520 return( SQL_ERROR );
523 return( SQL_SUCCESS );
526 /*SQLRETURN SQLGetFunctions(
527 SQLHDBC ConnectionHandle,
528 SQLUSMALLINT FunctionId,
529 SQLUSMALLINT * SupportedPtr)
531 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
532 return( SQL_INVALID_HANDLE );
533 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLGetFunctions(FunctionId,SupportedPtr) );
536 SQLRETURN CSqlOdbcDbc::SQLGetFunctions(
537 SQLUSMALLINT FunctionId,
538 SQLUSMALLINT * SupportedPtr)
540 if(isFunctionSupports(FunctionId))
541 *SupportedPtr = SQL_TRUE ;
542 else
543 *SupportedPtr = SQL_FALSE;
544 return (SQL_SUCCESS);
549 SQLRETURN SQLGetInfo(
550 SQLHDBC ConnectionHandle,
551 SQLUSMALLINT InfoType,
552 SQLPOINTER InfoValuePtr,
553 SQLSMALLINT BufferLength,
554 SQLSMALLINT * StringLengthPtr)
556 if( isValidHandle( ConnectionHandle, SQL_HANDLE_DBC ) != SQL_SUCCESS )
557 return( SQL_INVALID_HANDLE );
559 return( ((CSqlOdbcDbc*)ConnectionHandle)->SQLGetInfo( InfoType,InfoValuePtr,BufferLength,StringLengthPtr ) );
563 SQLRETURN CSqlOdbcDbc::SQLGetInfo(
564 SQLUSMALLINT InfoType,
565 SQLPOINTER InfoValuePtr,
566 SQLSMALLINT BufferLength,
567 SQLSMALLINT * StringLengthPtr)
569 return (SQL_SUCCESS);