00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "icatLowLevelOdbc.h"
00034
00035 #include "eirods_tmp_string.h"
00036 #include "eirods_log.h"
00037
00038 int _cllFreeStatementColumns(icatSessionStruct *icss, int statementNumber);
00039
00040 int
00041 _cllExecSqlNoResult(icatSessionStruct *icss, const char *sql, int option);
00042
00043
00044 int cllBindVarCount=0;
00045 char *cllBindVars[MAX_BIND_VARS];
00046 int cllBindVarCountPrev=0;
00047
00048 SQLCHAR psgErrorMsg[SQL_MAX_MESSAGE_LENGTH + 10];
00049
00050 #ifdef ADDR_64BITS
00051
00052
00053
00054
00055
00056
00057
00058
00059 #define SQL_INT_OR_LEN SQLLEN
00060 #define SQL_UINT_OR_ULEN SQLULEN
00061 #else
00062 #define SQL_INT_OR_LEN SQLINTEGER
00063 #define SQL_UINT_OR_ULEN SQLUINTEGER
00064 #endif
00065
00066
00067 #define MAX_TOKEN 256
00068
00069 #define TMP_STR_LEN 1040
00070
00071 SQLINTEGER columnLength[MAX_TOKEN];
00072
00073 #include <stdio.h>
00074 #include <pwd.h>
00075 #include <ctype.h>
00076
00077 static int didBegin=0;
00078 static int noResultRowCount=0;
00079
00080
00081
00082
00083
00084 static const short MAX_NUMBER_ICAT_COLUMS = 32;
00085 static SQLLEN resultDataSizeArray[ MAX_NUMBER_ICAT_COLUMS ];
00086
00087
00088
00089
00090
00091 int
00092 logPsgError(int level, HENV henv, HDBC hdbc, HSTMT hstmt, int dbType)
00093 {
00094 SQLCHAR sqlstate[ SQL_SQLSTATE_SIZE + 10];
00095 SQLINTEGER sqlcode;
00096 SQLSMALLINT length;
00097 int errorVal=-2;
00098 while (SQLError(henv, hdbc, hstmt, sqlstate, &sqlcode, psgErrorMsg,
00099 SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS) {
00100 if (dbType == DB_TYPE_MYSQL) {
00101 if (strcmp((char *)sqlstate,"23000") == 0 &&
00102 strstr((char *)psgErrorMsg, "Duplicate entry")) {
00103 errorVal = CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME;
00104 }
00105 }
00106 else {
00107 if (strstr((char *)psgErrorMsg, "duplicate key")) {
00108 errorVal = CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME;
00109 }
00110 }
00111 rodsLog(level,"SQLSTATE: %s", sqlstate);
00112 rodsLog(level,"SQLCODE: %ld", sqlcode);
00113 rodsLog(level,"SQL Error message: %s", psgErrorMsg);
00114 }
00115 return(errorVal);
00116 }
00117
00118 int
00119 cllGetLastErrorMessage(char *msg, int maxChars) {
00120 strncpy(msg, (char *)&psgErrorMsg, maxChars);
00121 return(0);
00122 }
00123
00124
00125
00126
00127 int
00128 cllOpenEnv(icatSessionStruct *icss) {
00129 RETCODE stat;
00130
00131 HENV myHenv;
00132 stat = SQLAllocEnv(&myHenv);
00133
00134 if (stat != SQL_SUCCESS) {
00135 rodsLog(LOG_ERROR, "cllOpenEnv: SQLAllocEnv failed");
00136 return (-1);
00137 }
00138
00139 icss->environPtr=myHenv;
00140 return(0);
00141 }
00142
00143
00144
00145
00146
00147 int
00148 cllCloseEnv(icatSessionStruct *icss) {
00149 RETCODE stat;
00150 HENV myHenv;
00151
00152 myHenv = icss->environPtr;
00153 stat =SQLFreeEnv(myHenv);
00154
00155 if (stat != SQL_SUCCESS) {
00156 rodsLog(LOG_ERROR, "cllCloseEnv: SQLFreeEnv failed");
00157 }
00158 return(stat);
00159 }
00160
00161
00162
00163
00164 int
00165 cllConnect(icatSessionStruct *icss) {
00166 RETCODE stat;
00167
00168 SQLCHAR buffer[SQL_MAX_MESSAGE_LENGTH + 1];
00169 SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
00170 SQLINTEGER sqlcode;
00171 SQLSMALLINT length;
00172
00173 HDBC myHdbc;
00174
00175 stat = SQLAllocConnect(icss->environPtr,
00176 &myHdbc);
00177 if (stat != SQL_SUCCESS) {
00178 rodsLog(LOG_ERROR, "cllConnect: SQLAllocConnect failed: %d, stat");
00179 return (-1);
00180 }
00181
00182 stat = SQLConnect(myHdbc, (unsigned char *)CATALOG_ODBC_ENTRY_NAME, SQL_NTS,
00183 (unsigned char *)icss->databaseUsername, SQL_NTS,
00184 (unsigned char *)icss->databasePassword, SQL_NTS);
00185 if (stat != SQL_SUCCESS) {
00186 rodsLog(LOG_ERROR, "cllConnect: SQLConnect failed: %d", stat);
00187 rodsLog(LOG_ERROR,
00188 "cllConnect: SQLConnect failed:odbcEntry=%s,user=%s,pass=%s\n",
00189 CATALOG_ODBC_ENTRY_NAME,icss->databaseUsername,
00190 icss->databasePassword);
00191 while (SQLError(icss->environPtr,myHdbc , 0, sqlstate, &sqlcode, buffer,
00192 SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS) {
00193 rodsLog(LOG_ERROR, "cllConnect: SQLSTATE: %s\n", sqlstate);
00194 rodsLog(LOG_ERROR, "cllConnect: Native Error Code: %ld\n", sqlcode);
00195 rodsLog(LOG_ERROR, "cllConnect: %s \n", buffer);
00196 }
00197
00198 SQLDisconnect(myHdbc);
00199 SQLFreeConnect(myHdbc);
00200 return (-1);
00201 }
00202
00203 icss->connectPtr=myHdbc;
00204
00205 if (icss->databaseType == DB_TYPE_MYSQL) {
00206
00207
00208
00209
00210 cllExecSqlNoResult ( icss, "SET SESSION autocommit=0" ) ;
00211 cllExecSqlNoResult ( icss, "SET SESSION sql_mode='ANSI,STRICT_TRANS_TABLES'" ) ;
00212 cllExecSqlNoResult ( icss, "SET character_set_client = utf8" ) ;
00213 cllExecSqlNoResult ( icss, "SET character_set_results = utf8" ) ;
00214 cllExecSqlNoResult ( icss, "SET character_set_connection = utf8" ) ;
00215 }
00216
00217 return(0);
00218 }
00219
00220
00221
00222
00223 int
00224 cllConnectRda(icatSessionStruct *icss) {
00225 RETCODE stat;
00226
00227 SQLCHAR buffer[SQL_MAX_MESSAGE_LENGTH + 1];
00228 SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
00229 SQLINTEGER sqlcode;
00230 SQLSMALLINT length;
00231
00232 HDBC myHdbc;
00233
00234 stat = SQLAllocConnect(icss->environPtr,
00235 &myHdbc);
00236 if (stat != SQL_SUCCESS) {
00237 rodsLog(LOG_ERROR, "cllConnect: SQLAllocConnect failed: %d, stat");
00238 return (-1);
00239 }
00240
00241 stat = SQLSetConnectOption(myHdbc,
00242 SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF);
00243 if (stat != SQL_SUCCESS) {
00244 rodsLog(LOG_ERROR, "cllConnect: SQLSetConnectOption failed: %d", stat);
00245 return (-1);
00246 }
00247
00248 stat = SQLConnect(myHdbc, (unsigned char *)RDA_ODBC_ENTRY_NAME, SQL_NTS,
00249 (unsigned char *)icss->databaseUsername, SQL_NTS,
00250 (unsigned char *)icss->databasePassword, SQL_NTS);
00251 if (stat != SQL_SUCCESS) {
00252 rodsLog(LOG_ERROR, "cllConnect: SQLConnect failed: %d", stat);
00253 rodsLog(LOG_ERROR,
00254 "cllConnect: SQLConnect failed:odbcEntry=%s,user=%s,pass=%s\n",
00255 RDA_ODBC_ENTRY_NAME,icss->databaseUsername, icss->databasePassword);
00256 while (SQLError(icss->environPtr,myHdbc , 0, sqlstate, &sqlcode, buffer,
00257 SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS) {
00258 rodsLog(LOG_ERROR, "cllConnect: SQLSTATE: %s\n", sqlstate);
00259 rodsLog(LOG_ERROR, "cllConnect: Native Error Code: %ld\n", sqlcode);
00260 rodsLog(LOG_ERROR, "cllConnect: %s \n", buffer);
00261 }
00262
00263 SQLDisconnect(myHdbc);
00264 SQLFreeConnect(myHdbc);
00265 return (-1);
00266 }
00267
00268 icss->connectPtr=myHdbc;
00269
00270 if (icss->databaseType == DB_TYPE_MYSQL) {
00271
00272
00273
00274
00275
00276
00277 cllExecSqlNoResult ( icss, "SET SESSION autocommit=0" ) ;
00278 cllExecSqlNoResult ( icss,
00279 "SET SESSION sql_mode='ANSI,STRICT_TRANS_TABLES'" );
00280 }
00281 return(0);
00282 }
00283
00284
00285
00286
00287 int
00288 cllConnectDbr(icatSessionStruct *icss, char *odbcEntryName) {
00289 RETCODE stat;
00290
00291 SQLCHAR buffer[SQL_MAX_MESSAGE_LENGTH + 1];
00292 SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
00293 SQLINTEGER sqlcode;
00294 SQLSMALLINT length;
00295
00296 HDBC myHdbc;
00297
00298 stat = SQLAllocConnect(icss->environPtr,
00299 &myHdbc);
00300 if (stat != SQL_SUCCESS) {
00301 rodsLog(LOG_ERROR, "cllConnect: SQLAllocConnect failed: %d, stat");
00302 return (-1);
00303 }
00304
00305 stat = SQLSetConnectOption(myHdbc,
00306 SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF);
00307 if (stat != SQL_SUCCESS) {
00308 rodsLog(LOG_ERROR, "cllConnect: SQLSetConnectOption failed: %d", stat);
00309 return (-1);
00310 }
00311
00312 stat = SQLConnect(myHdbc, (unsigned char *)odbcEntryName, SQL_NTS,
00313 (unsigned char *)icss->databaseUsername, SQL_NTS,
00314 (unsigned char *)icss->databasePassword, SQL_NTS);
00315 if (stat != SQL_SUCCESS) {
00316 rodsLog(LOG_ERROR, "cllConnect: SQLConnect failed: %d", stat);
00317 rodsLog(LOG_ERROR,
00318 "cllConnect: SQLConnect failed:odbcEntry=%s,user=%s,pass=%s\n",
00319 odbcEntryName,icss->databaseUsername, icss->databasePassword);
00320 while (SQLError(icss->environPtr,myHdbc , 0, sqlstate, &sqlcode, buffer,
00321 SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS) {
00322 rodsLog(LOG_ERROR, "cllConnect: SQLSTATE: %s\n", sqlstate);
00323 rodsLog(LOG_ERROR, "cllConnect: Native Error Code: %ld\n", sqlcode);
00324 rodsLog(LOG_ERROR, "cllConnect: %s \n", buffer);
00325 }
00326
00327 SQLDisconnect(myHdbc);
00328 SQLFreeConnect(myHdbc);
00329 return (-1);
00330 }
00331
00332 icss->connectPtr=myHdbc;
00333
00334 if (icss->databaseType == DB_TYPE_MYSQL) {
00335
00336
00337
00338
00339
00340
00341 cllExecSqlNoResult ( icss, "SET SESSION autocommit=0" ) ;
00342 cllExecSqlNoResult ( icss,
00343 "SET SESSION sql_mode='ANSI,STRICT_TRANS_TABLES'" );
00344 }
00345 return(0);
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 #define maxPendingToRecord 5
00359 #define pendingRecordSize 30
00360 #define pBufferSize (maxPendingToRecord*pendingRecordSize)
00361 int
00362 cllCheckPending(const char *sql, int option, int dbType) {
00363 static int pendingCount=0;
00364 static int pendingIx=0;
00365 static int pendingAudits=0;
00366 static char pBuffer[pBufferSize+2];
00367 static int firstTime=1;
00368
00369 if (firstTime) {
00370 firstTime=0;
00371 memset(pBuffer, 0, pBufferSize);
00372 }
00373 if (option==0) {
00374 if (strncmp(sql,"commit", 6)==0 ||
00375 strncmp(sql,"rollback", 8)==0) {
00376 pendingIx=0;
00377 pendingCount=0;
00378 pendingAudits=0;
00379 memset(pBuffer, 0, pBufferSize);
00380 return(0);
00381 }
00382 if (pendingIx < maxPendingToRecord) {
00383 strncpy((char *)&pBuffer[pendingIx*pendingRecordSize], sql,
00384 pendingRecordSize-1);
00385 pendingIx++;
00386 }
00387 pendingCount++;
00388 return(0);
00389 }
00390 if (option==2) {
00391 pendingAudits++;
00392 return(0);
00393 }
00394
00395
00396 if (pendingCount > pendingAudits) {
00397 int i, max;
00398 int skip;
00399
00400 if (pendingIx == 1) {
00401 if (strncmp((char *)&pBuffer[0], "begin", 5)==0) {
00402 return(0);
00403 }
00404 }
00405 if (dbType == DB_TYPE_MYSQL) {
00406
00407
00408 skip=1;
00409 if (strncmp((char *)&pBuffer[0], "begin", 5)!=0) skip=0;
00410 max = maxPendingToRecord;
00411 if (pendingIx < max) max = pendingIx;
00412 for (i=1;i<max && skip==1;i++) {
00413 if (strncmp((char *)&pBuffer[i*pendingRecordSize],
00414 "SET SESSION",11) !=0) {
00415 skip=0;
00416 }
00417 }
00418 if (skip) return(0);
00419 }
00420
00421 rodsLog(LOG_NOTICE, "Warning, pending SQL at cllDisconnect, count: %d",
00422 pendingCount);
00423 max = maxPendingToRecord;
00424 if (pendingIx < max) max = pendingIx;
00425 for (i=0;i<max;i++) {
00426 rodsLog(LOG_NOTICE, "Warning, pending SQL: %s ...",
00427 (char *)&pBuffer[i*pendingRecordSize]);
00428 }
00429 if (pendingAudits > 0) {
00430 rodsLog(LOG_NOTICE, "Warning, SQL will be commited with audits");
00431 }
00432 }
00433
00434 if (pendingAudits > 0) {
00435 rodsLog(LOG_NOTICE,
00436 "Notice, pending Auditing SQL committed at cllDisconnect");
00437 return(1);
00438 }
00439 return(0);
00440 }
00441
00442
00443
00444
00445 int
00446 cllDisconnect(icatSessionStruct *icss) {
00447 RETCODE stat;
00448 HDBC myHdbc;
00449 int i;
00450
00451 myHdbc = icss->connectPtr;
00452
00453 i = cllCheckPending("", 1, icss->databaseType);
00454 if (i==1) {
00455 i = cllExecSqlNoResult(icss, "commit");
00456
00457
00458
00459 }
00460
00461 stat = SQLDisconnect(myHdbc);
00462 if (stat != SQL_SUCCESS) {
00463 rodsLog(LOG_ERROR, "cllDisconnect: SQLDisconnect failed: %d", stat);
00464 return(-1);
00465 }
00466
00467 stat = SQLFreeConnect(myHdbc);
00468 if (stat != SQL_SUCCESS) {
00469 rodsLog(LOG_ERROR, "cllDisconnect: SQLFreeConnect failed: %d", stat);
00470 return(-2);
00471 }
00472
00473 icss->connectPtr = myHdbc;
00474 return(0);
00475 }
00476
00477
00478
00479
00480
00481
00482 int
00483 cllExecSqlNoResult(icatSessionStruct *icss, const char *sql)
00484 {
00485 int status;
00486
00487 if (strncmp(sql,"commit", 6)==0 ||
00488 strncmp(sql,"rollback", 8)==0) {
00489 didBegin=0;
00490 }
00491 else {
00492 if (didBegin==0) {
00493 status = _cllExecSqlNoResult(icss, "begin", 1);
00494 if (status != SQL_SUCCESS) return(status);
00495 }
00496 didBegin=1;
00497 }
00498 return (_cllExecSqlNoResult(icss, sql, 0));
00499 }
00500
00501
00502
00503
00504 void
00505 logTheBindVariables(int level)
00506 {
00507 int i;
00508 char tmpStr[TMP_STR_LEN+2];
00509 for (i=0;i<cllBindVarCountPrev;i++) {
00510 snprintf(tmpStr, TMP_STR_LEN, "bindVar[%d]=%s", i+1, cllBindVars[i]);
00511 rodsLog(level, tmpStr);
00512 }
00513 }
00514
00515
00516
00517
00518 int
00519 bindTheVariables(HSTMT myHstmt, const char *sql) {
00520 int myBindVarCount;
00521 RETCODE stat;
00522 int i;
00523 char tmpStr[TMP_STR_LEN+2];
00524
00525 myBindVarCount = cllBindVarCount;
00526 cllBindVarCountPrev=cllBindVarCount;
00527 cllBindVarCount = 0;
00528
00529 if (myBindVarCount > 0) {
00530 rodsLogSql("SQLPrepare");
00531 stat = SQLPrepare(myHstmt, (unsigned char *)sql, SQL_NTS);
00532 if (stat != SQL_SUCCESS) {
00533 rodsLog(LOG_ERROR, "bindTheVariables: SQLPrepare failed: %d",
00534 stat);
00535 return(-1);
00536 }
00537
00538 for (i=0;i<myBindVarCount;i++) {
00539 stat = SQLBindParameter(myHstmt, i+1, SQL_PARAM_INPUT, SQL_C_CHAR,
00540 SQL_C_CHAR, 0, 0, cllBindVars[i], 0, 0);
00541 snprintf(tmpStr, TMP_STR_LEN, "bindVar[%d]=%s", i+1, cllBindVars[i]);
00542 rodsLogSql(tmpStr);
00543 if (stat != SQL_SUCCESS) {
00544 rodsLog(LOG_ERROR,
00545 "bindTheVariables: SQLBindParameter failed: %d", stat);
00546 return(-1);
00547 }
00548 }
00549
00550 if (stat != SQL_SUCCESS) {
00551 rodsLog(LOG_ERROR, "bindTheVariables: SQLAllocStmt failed: %d",
00552 stat);
00553 return(-1);
00554 }
00555 }
00556 return(0);
00557 }
00558
00559
00560
00561
00562
00563
00564 #ifdef NEW_ODBC
00565 static int cmp_stmt (const char *str1, const char *str2)
00566 {
00567
00568 while ( isspace(*str1) ) ++str1 ;
00569
00570
00571 for ( ; *str1 && *str2 ; ++str1, ++str2 ) {
00572 if ( tolower(*str1) != *str2 ) return 0 ;
00573 }
00574
00575
00576 while ( isspace(*str1) ) ++str1 ;
00577
00578
00579 return *str1 == *str2 ;
00580 }
00581 #endif
00582
00583
00584
00585
00586
00587
00588 int
00589 _cllExecSqlNoResult(icatSessionStruct *icss, const char *sql,
00590 int option) {
00591 RETCODE stat;
00592 HDBC myHdbc;
00593 HSTMT myHstmt;
00594 int result;
00595 char *status;
00596 SQL_INT_OR_LEN rowCount;
00597 #ifdef NEW_ODBC
00598 int i;
00599 #endif
00600 noResultRowCount=0;
00601 rowCount=0;
00602
00603 myHdbc = icss->connectPtr;
00604 rodsLog(LOG_DEBUG1, sql);
00605 stat = SQLAllocStmt(myHdbc, &myHstmt);
00606 if (stat != SQL_SUCCESS) {
00607 rodsLog(LOG_ERROR, "_cllExecSqlNoResult: SQLAllocStmt failed: %d", stat);
00608 return(-1);
00609 }
00610
00611 #if 0
00612 if (bindVar1 != 0 && *bindVar1 != '\0') {
00613 stat = SQLBindParameter(myHstmt, 1, SQL_PARAM_INPUT, SQL_C_SBIGINT,
00614 SQL_C_SBIGINT, 0, 0, 0, 0, 0);
00615 if (stat != SQL_SUCCESS) {
00616 rodsLog(LOG_ERROR, "_cllExecSqlNoResult: SQLAllocStmt failed: %d",
00617 stat);
00618 return(-1);
00619 }
00620 }
00621 #endif
00622
00623 if (option==0) {
00624 if (bindTheVariables(myHstmt, sql) != 0) return(-1);
00625 }
00626
00627 rodsLogSql(sql);
00628
00629 stat = SQLExecDirect(myHstmt, (unsigned char *)sql, SQL_NTS);
00630 status = "UNKNOWN";
00631 if (stat == SQL_SUCCESS) status= "SUCCESS";
00632 if (stat == SQL_SUCCESS_WITH_INFO) status="SUCCESS_WITH_INFO";
00633 if (stat == SQL_NO_DATA_FOUND) status="NO_DATA";
00634 if (stat == SQL_ERROR) status="SQL_ERROR";
00635 if (stat == SQL_INVALID_HANDLE) status="HANDLE_ERROR";
00636 rodsLogSqlResult(status);
00637
00638 if (stat == SQL_SUCCESS || stat == SQL_SUCCESS_WITH_INFO ||
00639 stat == SQL_NO_DATA_FOUND) {
00640 cllCheckPending(sql, 0, icss->databaseType);
00641 result = 0;
00642 if (stat == SQL_NO_DATA_FOUND) result = CAT_SUCCESS_BUT_WITH_NO_INFO;
00643 #ifdef NEW_ODBC
00644
00645
00646
00647
00648 if ( ! cmp_stmt(sql,"begin") && ! cmp_stmt(sql,"commit") && ! cmp_stmt(sql,"rollback") ) {
00649
00650 i = SQLRowCount (myHstmt, (SQL_INT_OR_LEN *)&rowCount);
00651 if (i) {
00652
00653 result = CAT_SUCCESS_BUT_WITH_NO_INFO;
00654 }
00655 if (rowCount==0) result = CAT_SUCCESS_BUT_WITH_NO_INFO;
00656 }
00657 #else
00658 rowCount=0;
00659 #endif
00660 }
00661 else {
00662 if (option==0) {
00663 logTheBindVariables(LOG_NOTICE);
00664 }
00665 rodsLog(LOG_NOTICE,"_cllExecSqlNoResult: SQLExecDirect error: %d sql:%s",
00666 stat, sql);
00667 result = logPsgError(LOG_NOTICE, icss->environPtr, myHdbc, myHstmt,
00668 icss->databaseType);
00669 }
00670
00671 stat = SQLFreeStmt(myHstmt, SQL_DROP);
00672 if (stat != SQL_SUCCESS) {
00673 rodsLog(LOG_ERROR, "_cllExecSqlNoResult: SQLFreeStmt error: %d", stat);
00674 }
00675
00676 noResultRowCount = rowCount;
00677
00678 return(result);
00679 }
00680
00681
00682
00683
00684
00685
00686 int
00687 cllExecSqlWithResult(icatSessionStruct *icss, int *stmtNum, char *sql) {
00688
00689 RETCODE stat;
00690 HDBC myHdbc;
00691 HSTMT hstmt;
00692 SQLSMALLINT numColumns;
00693
00694 SQLCHAR colName[MAX_TOKEN];
00695 SQLSMALLINT colType;
00696 SQLSMALLINT colNameLen;
00697 SQL_UINT_OR_ULEN precision;
00698 SQLSMALLINT scale;
00699 SQL_INT_OR_LEN displaysize;
00700 #ifndef NEW_ODBC
00701 static SQLINTEGER resultDataSize;
00702 #endif
00703
00704 icatStmtStrct *myStatement;
00705
00706 int i;
00707 int statementNumber;
00708 char *status;
00709
00710
00711
00712
00713
00714
00715
00716
00717 myHdbc = icss->connectPtr;
00718 rodsLog(LOG_DEBUG1, sql);
00719 stat = SQLAllocStmt(myHdbc, &hstmt);
00720 if (stat != SQL_SUCCESS) {
00721 rodsLog(LOG_ERROR, "cllExecSqlWithResult: SQLAllocStmt failed: %d",
00722 stat);
00723 return(-1);
00724 }
00725
00726 statementNumber=-1;
00727 for (i=0;i<MAX_NUM_OF_CONCURRENT_STMTS && statementNumber<0;i++) {
00728 if (icss->stmtPtr[i]==0) {
00729 statementNumber=i;
00730 }
00731 }
00732 if (statementNumber<0) {
00733 rodsLog(LOG_ERROR,
00734 "cllExecSqlWithResult: too many concurrent statements");
00735 return(-2);
00736 }
00737
00738 myStatement = (icatStmtStrct *)malloc(sizeof(icatStmtStrct));
00739 icss->stmtPtr[statementNumber]=myStatement;
00740
00741 myStatement->stmtPtr=hstmt;
00742
00743 if (bindTheVariables(hstmt, sql) != 0) return(-1);
00744
00745 rodsLogSql(sql);
00746 stat = SQLExecDirect(hstmt, (unsigned char *)sql, SQL_NTS);
00747
00748 status = "UNKNOWN";
00749 if (stat == SQL_SUCCESS) status= "SUCCESS";
00750 if (stat == SQL_SUCCESS_WITH_INFO) status="SUCCESS_WITH_INFO";
00751 if (stat == SQL_NO_DATA_FOUND) status="NO_DATA";
00752 if (stat == SQL_ERROR) status="SQL_ERROR";
00753 if (stat == SQL_INVALID_HANDLE) status="HANDLE_ERROR";
00754 rodsLogSqlResult(status);
00755
00756 if (stat == SQL_SUCCESS ||
00757 stat == SQL_SUCCESS_WITH_INFO ||
00758 stat == SQL_NO_DATA_FOUND) {
00759 }
00760 else {
00761 logTheBindVariables(LOG_NOTICE);
00762 rodsLog(LOG_NOTICE,
00763 "cllExecSqlWithResult: SQLExecDirect error: %d, sql:%s",
00764 stat, sql);
00765 logPsgError(LOG_NOTICE, icss->environPtr, myHdbc, hstmt,
00766 icss->databaseType);
00767 return(-1);
00768 }
00769
00770 stat = SQLNumResultCols(hstmt, &numColumns);
00771 if (stat != SQL_SUCCESS) {
00772 rodsLog(LOG_ERROR, "cllExecSqlWithResult: SQLNumResultCols failed: %d",
00773 stat);
00774 return(-2);
00775 }
00776 myStatement->numOfCols=numColumns;
00777 for (i = 0; i<numColumns; i++) {
00778 stat = SQLDescribeCol(hstmt, i+1, colName, sizeof(colName),
00779 &colNameLen, &colType, &precision, &scale, NULL);
00780 if (stat != SQL_SUCCESS) {
00781 rodsLog(LOG_ERROR, "cllExecSqlWithResult: SQLDescribeCol failed: %d",
00782 stat);
00783 return(-3);
00784 }
00785
00786 columnLength[i]=precision;
00787 stat = SQLColAttribute(hstmt, i+1, SQL_COLUMN_DISPLAY_SIZE,
00788 NULL, 0, NULL, &displaysize);
00789 if (stat != SQL_SUCCESS) {
00790 rodsLog(LOG_ERROR,
00791 "cllExecSqlWithResult: SQLColAttributes failed: %d",
00792 stat);
00793 return(-3);
00794 }
00795
00796 if (displaysize > ((int)strlen((char *) colName))) {
00797 columnLength[i] = displaysize + 1;
00798 }
00799 else {
00800 columnLength[i] = strlen((char *) colName) + 1;
00801 }
00802
00803
00804 myStatement->resultValue[i] = (char*)malloc((int)columnLength[i]);
00805
00806 strcpy((char *)myStatement->resultValue[i],"");
00807
00808 #if 1
00809
00810
00811 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i], columnLength[i], &resultDataSizeArray[ i ] );
00812 #else
00813 #if NEW_ODBC
00814 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i],
00815 columnLength[i], NULL);
00816
00817
00818
00819 #else
00820
00821 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i],
00822 columnLength[i], &resultDataSize);
00823 #endif
00824 #endif
00825 if (stat != SQL_SUCCESS) {
00826 rodsLog(LOG_ERROR,
00827 "cllExecSqlWithResult: SQLColAttributes failed: %d",
00828 stat);
00829 return(-4);
00830 }
00831
00832
00833 myStatement->resultColName[i] = (char*)malloc((int)columnLength[i]);
00834 strncpy(myStatement->resultColName[i], (char *)colName, columnLength[i]);
00835
00836 }
00837 *stmtNum = statementNumber;
00838 return(0);
00839 }
00840
00841
00842
00843
00844
00845 void
00846 logBindVars(
00847 int level,
00848 const char *bindVar1,
00849 const char *bindVar2,
00850 const char *bindVar3,
00851 const char *bindVar4,
00852 const char *bindVar5,
00853 const char *bindVar6) {
00854 if (bindVar1 != 0 && *bindVar1 != '\0') {
00855 rodsLog(level,"bindVar1=%s", bindVar1);
00856 }
00857 if (bindVar2 != 0 && *bindVar2 != '\0') {
00858 rodsLog(level,"bindVar2=%s", bindVar2);
00859 }
00860 if (bindVar3 != 0 && *bindVar3 != '\0') {
00861 rodsLog(level,"bindVar3=%s", bindVar3);
00862 }
00863 if (bindVar4 != 0 && *bindVar4 != '\0') {
00864 rodsLog(level,"bindVar4=%s", bindVar4);
00865 }
00866 }
00867
00868
00869
00870
00871
00872
00873 int
00874 cllExecSqlWithResultBV(
00875 icatSessionStruct *icss,
00876 int *stmtNum,
00877 char *sql,
00878 const char *bindVar1,
00879 const char *bindVar2,
00880 const char *bindVar3,
00881 const char *bindVar4,
00882 const char *bindVar5,
00883 const char *bindVar6) {
00884
00885 RETCODE stat;
00886 HDBC myHdbc;
00887 HSTMT hstmt;
00888 SQLSMALLINT numColumns;
00889
00890 SQLCHAR colName[MAX_TOKEN];
00891 SQLSMALLINT colType;
00892 SQLSMALLINT colNameLen;
00893 SQL_UINT_OR_ULEN precision;
00894 SQLSMALLINT scale;
00895 SQL_INT_OR_LEN displaysize;
00896 #ifndef NEW_ODBC
00897 static SQLINTEGER resultDataSize;
00898 #endif
00899
00900 icatStmtStrct *myStatement;
00901
00902 int i;
00903 int statementNumber;
00904 char *status;
00905 char tmpStr[TMP_STR_LEN+2];
00906
00907 eirods::tmp_string tmp_string1(bindVar1);
00908 eirods::tmp_string tmp_string2(bindVar2);
00909 eirods::tmp_string tmp_string3(bindVar3);
00910 eirods::tmp_string tmp_string4(bindVar4);
00911 eirods::tmp_string tmp_string5(bindVar5);
00912
00913 myHdbc = icss->connectPtr;
00914 rodsLog(LOG_DEBUG1, sql);
00915 stat = SQLAllocStmt(myHdbc, &hstmt);
00916 if (stat != SQL_SUCCESS) {
00917 rodsLog(LOG_ERROR, "cllExecSqlWithResultBV: SQLAllocStmt failed: %d",
00918 stat);
00919 return(-1);
00920 }
00921
00922 statementNumber=-1;
00923 for (i=0;i<MAX_NUM_OF_CONCURRENT_STMTS && statementNumber<0;i++) {
00924 if (icss->stmtPtr[i]==0) {
00925 statementNumber=i;
00926 }
00927 }
00928 if (statementNumber<0) {
00929 rodsLog(LOG_ERROR,
00930 "cllExecSqlWithResultBV: too many concurrent statements");
00931 return(-2);
00932 }
00933
00934 myStatement = (icatStmtStrct *)malloc(sizeof(icatStmtStrct));
00935 icss->stmtPtr[statementNumber]=myStatement;
00936
00937 myStatement->stmtPtr=hstmt;
00938
00939 if ((bindVar1 != 0 && *bindVar1 != '\0') ||
00940 (bindVar2 != 0 && *bindVar2 != '\0') ||
00941 (bindVar3 != 0 && *bindVar3 != '\0') ||
00942 (bindVar4 != 0 && *bindVar4 != '\0')) {
00943
00944 rodsLogSql("SQLPrepare");
00945 stat = SQLPrepare(hstmt, (unsigned char *)sql, SQL_NTS);
00946 if (stat != SQL_SUCCESS) {
00947 rodsLog(LOG_ERROR, "cllExecSqlNoResult: SQLPrepare failed: %d",
00948 stat);
00949 return(-1);
00950 }
00951
00952 if (bindVar1 != 0 && *bindVar1 != '\0') {
00953 stat = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,
00954 SQL_C_CHAR, 0, 0, tmp_string1.str(), 0, 0);
00955 snprintf(tmpStr, TMP_STR_LEN,
00956 "bindVar1=%s", bindVar1);
00957 rodsLogSql(tmpStr);
00958 if (stat != SQL_SUCCESS) {
00959 rodsLog(LOG_ERROR,
00960 "cllExecSqlNoResult: SQLBindParameter failed: %d", stat);
00961 return(-1);
00962 }
00963 }
00964 if (bindVar2 != 0 && *bindVar2 != '\0') {
00965 stat = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
00966 SQL_C_CHAR, 0, 0, tmp_string2.str(), 0, 0);
00967 snprintf(tmpStr, TMP_STR_LEN,
00968 "bindVar2=%s", bindVar2);
00969 rodsLogSql(tmpStr);
00970 if (stat != SQL_SUCCESS) {
00971 rodsLog(LOG_ERROR,
00972 "cllExecSqlNoResult: SQLBindParameter failed: %d", stat);
00973 return(-1);
00974 }
00975 }
00976 if (bindVar3 != 0 && *bindVar3 != '\0') {
00977 stat = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
00978 SQL_C_CHAR, 0, 0, tmp_string3.str(), 0, 0);
00979 snprintf(tmpStr, TMP_STR_LEN,
00980 "bindVar3=%s", bindVar3);
00981 rodsLogSql(tmpStr);
00982 if (stat != SQL_SUCCESS) {
00983 rodsLog(LOG_ERROR, "cllExecSqlNoResult: SQLBindParameter failed: %d",
00984 stat);
00985 return(-1);
00986 }
00987 }
00988 if (bindVar4 != 0 && *bindVar4 != '\0') {
00989 stat = SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR,
00990 SQL_C_CHAR, 0, 0, tmp_string4.str(), 0, 0);
00991 snprintf(tmpStr, TMP_STR_LEN,
00992 "bindVar4=%s", bindVar4);
00993 rodsLogSql(tmpStr);
00994 if (stat != SQL_SUCCESS) {
00995 rodsLog(LOG_ERROR, "cllExecSqlNoResult: SQLBindParameter failed: %d",
00996 stat);
00997 return(-1);
00998 }
00999 }
01000 if (bindVar5 != 0 && *bindVar5 != '\0') {
01001 stat = SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR,
01002 SQL_C_CHAR, 0, 0, tmp_string5.str(), 0, 0);
01003 snprintf(tmpStr, TMP_STR_LEN,
01004 "bindVar5=%s", bindVar5);
01005 rodsLogSql(tmpStr);
01006 if (stat != SQL_SUCCESS) {
01007 rodsLog(LOG_ERROR, "cllExecSqlNoResult: SQLBindParameter failed: %d",
01008 stat);
01009 return(-1);
01010 }
01011 }
01012 rodsLogSql(sql);
01013 stat = SQLExecute(hstmt);
01014 }
01015 else {
01016 rodsLogSql(sql);
01017 stat = SQLExecDirect(hstmt, (unsigned char *)sql, SQL_NTS);
01018 }
01019
01020 status = "UNKNOWN";
01021 if (stat == SQL_SUCCESS) status= "SUCCESS";
01022 if (stat == SQL_SUCCESS_WITH_INFO) status="SUCCESS_WITH_INFO";
01023 if (stat == SQL_NO_DATA_FOUND) status="NO_DATA";
01024 if (stat == SQL_ERROR) status="SQL_ERROR";
01025 if (stat == SQL_INVALID_HANDLE) status="HANDLE_ERROR";
01026 rodsLogSqlResult(status);
01027
01028 if (stat == SQL_SUCCESS ||
01029 stat == SQL_SUCCESS_WITH_INFO ||
01030 stat == SQL_NO_DATA_FOUND) {
01031 }
01032 else {
01033 logBindVars(LOG_NOTICE, bindVar1, bindVar2, bindVar3, bindVar4,
01034 bindVar5, bindVar6);
01035 rodsLog(LOG_NOTICE,
01036 "cllExecSqlWithResultBV: SQLExecDirect error: %d, sql:%s",
01037 stat, sql);
01038 logPsgError(LOG_NOTICE, icss->environPtr, myHdbc, hstmt,
01039 icss->databaseType);
01040 return(-1);
01041 }
01042
01043 stat = SQLNumResultCols(hstmt, &numColumns);
01044 if (stat != SQL_SUCCESS) {
01045 rodsLog(LOG_ERROR, "cllExecSqlWithResultBV: SQLNumResultCols failed: %d",
01046 stat);
01047 return(-2);
01048 }
01049 myStatement->numOfCols=numColumns;
01050
01051 for (i = 0; i<numColumns; i++) {
01052 stat = SQLDescribeCol(hstmt, i+1, colName, sizeof(colName),
01053 &colNameLen, &colType, &precision, &scale, NULL);
01054 if (stat != SQL_SUCCESS) {
01055 rodsLog(LOG_ERROR, "cllExecSqlWithResultBV: SQLDescribeCol failed: %d",
01056 stat);
01057 return(-3);
01058 }
01059
01060 columnLength[i]=precision;
01061 stat = SQLColAttribute(hstmt, i+1, SQL_COLUMN_DISPLAY_SIZE,
01062 NULL, 0, NULL, &displaysize);
01063 if (stat != SQL_SUCCESS) {
01064 rodsLog(LOG_ERROR,
01065 "cllExecSqlWithResultBV: SQLColAttributes failed: %d",
01066 stat);
01067 return(-3);
01068 }
01069
01070 if (displaysize > ((int)strlen((char *) colName))) {
01071 columnLength[i] = displaysize + 1;
01072 }
01073 else {
01074 columnLength[i] = strlen((char *) colName) + 1;
01075 }
01076
01077
01078 myStatement->resultValue[i] = (char*)malloc((int)columnLength[i]);
01079
01080 strcpy((char *)myStatement->resultValue[i],"");
01081 #if 1
01082
01083
01084 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i], columnLength[i], &resultDataSizeArray[i] );
01085 #else
01086 #ifdef NEW_ODBC
01087 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i],
01088 columnLength[i], NULL);
01089
01090
01091
01092 #else
01093
01094 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i],
01095 columnLength[i], &resultDataSize);
01096 #endif
01097 #endif
01098
01099 if (stat != SQL_SUCCESS) {
01100 rodsLog(LOG_ERROR,
01101 "cllExecSqlWithResultBV: SQLColAttributes failed: %d",
01102 stat);
01103 return(-4);
01104 }
01105
01106
01107 myStatement->resultColName[i] = (char*)malloc((int)columnLength[i]);
01108 strncpy(myStatement->resultColName[i], (char *)colName, columnLength[i]);
01109
01110 }
01111 *stmtNum = statementNumber;
01112 return(0);
01113 }
01114
01115
01116
01117
01118 int
01119 cllGetRow(icatSessionStruct *icss, int statementNumber) {
01120 HSTMT hstmt;
01121 RETCODE stat;
01122 int nCols, i;
01123 icatStmtStrct *myStatement;
01124 int logGetRows=0;
01125
01126
01127
01128
01129 myStatement=icss->stmtPtr[statementNumber];
01130 hstmt = myStatement->stmtPtr;
01131 nCols = myStatement->numOfCols;
01132
01133 for (i=0;i<nCols;i++) {
01134 strcpy((char *)myStatement->resultValue[i],"");
01135 }
01136 stat = SQLFetch(hstmt);
01137 if (stat != SQL_SUCCESS && stat != SQL_NO_DATA_FOUND) {
01138 rodsLog(LOG_ERROR, "cllGetRow: SQLFetch failed: %d", stat);
01139 return(-1);
01140 }
01141 if (stat == SQL_NO_DATA_FOUND) {
01142 if (logGetRows) {
01143 rodsLogSql("cllGetRow: NO DATA FOUND");
01144
01145 char tmpstr[210];
01146 snprintf(tmpstr, 200, "cllGetRow: NO DATA FOUND, statement:%d", statementNumber);
01147 }
01148 _cllFreeStatementColumns(icss,statementNumber);
01149 myStatement->numOfCols=0;
01150 }
01151 else {
01152 if (logGetRows) {
01153 char tmpstr[210];
01154
01155 snprintf(tmpstr, 200, "cllGetRow statement:%d columns:%d first column: %s", statementNumber, nCols, myStatement->resultValue[0]);
01156
01157 rodsLogSql(tmpstr);
01158 }
01159 }
01160 return(0);
01161 }
01162
01163
01164
01165
01166
01167 int
01168 cllNextValueString(char *itemName, char *outString, int maxSize) {
01169 #ifdef MY_ICAT
01170 snprintf(outString, maxSize, "%s_nextval()", itemName);
01171 #else
01172 snprintf(outString, maxSize, "nextval('%s')", itemName);
01173 #endif
01174 return 0;
01175 }
01176
01177 int
01178 cllGetRowCount(icatSessionStruct *icss, int statementNumber) {
01179 int i;
01180 HSTMT hstmt;
01181 icatStmtStrct *myStatement;
01182 SQL_INT_OR_LEN RowCount;
01183
01184 if (statementNumber < 0) return(noResultRowCount);
01185
01186 myStatement=icss->stmtPtr[statementNumber];
01187 hstmt = myStatement->stmtPtr;
01188
01189 i = SQLRowCount (hstmt, (SQL_INT_OR_LEN *)&RowCount);
01190 if (i) return(i);
01191 return(RowCount);
01192 }
01193
01194 int
01195 cllCurrentValueString(char *itemName, char *outString, int maxSize) {
01196 #ifdef MY_ICAT
01197 snprintf(outString, maxSize, "%s_currval()", itemName);
01198 #else
01199 snprintf(outString, maxSize, "currval('%s')", itemName);
01200 #endif
01201 return 0;
01202 }
01203
01204
01205
01206
01207
01208 int
01209 cllFreeStatement(icatSessionStruct *icss, int statementNumber) {
01210 HSTMT hstmt;
01211 RETCODE stat;
01212 int i;
01213
01214 icatStmtStrct *myStatement;
01215
01216 myStatement=icss->stmtPtr[statementNumber];
01217 if (myStatement==NULL) {
01218 return(0);
01219 }
01220 hstmt = myStatement->stmtPtr;
01221
01222 for (i=0;i<myStatement->numOfCols;i++) {
01223 free(myStatement->resultValue[i]);
01224 free(myStatement->resultColName[i]);
01225 }
01226
01227 stat = SQLFreeStmt(hstmt, SQL_DROP);
01228 if (stat != SQL_SUCCESS) {
01229 rodsLog(LOG_ERROR, "cllFreeStatement SQLFreeStmt error: %d", stat);
01230 }
01231
01232 free(myStatement);
01233
01234 icss->stmtPtr[statementNumber]=0;
01235
01236 return (0);
01237 }
01238
01239
01240
01241
01242
01243 int
01244 _cllFreeStatementColumns(icatSessionStruct *icss, int statementNumber) {
01245 int i;
01246
01247 icatStmtStrct *myStatement;
01248
01249 myStatement=icss->stmtPtr[statementNumber];
01250
01251 for (i=0;i<myStatement->numOfCols;i++) {
01252 free(myStatement->resultValue[i]);
01253 free(myStatement->resultColName[i]);
01254 }
01255 return (0);
01256 }
01257
01258
01259
01260
01261
01262 int cllTest(char *userArg, char *pwArg) {
01263 int i;
01264 int j, k;
01265 int OK;
01266 int stmt;
01267 int numOfCols;
01268 char userName[500];
01269
01270 struct passwd *ppasswd;
01271 icatSessionStruct icss;
01272
01273 icss.stmtPtr[0]=0;
01274 icss.databaseType = DB_TYPE_POSTGRES;
01275 #ifdef MY_ICAT
01276 icss.databaseType = DB_TYPE_MYSQL;
01277 #endif
01278
01279 rodsLogSqlReq(1);
01280 OK=1;
01281 i = cllOpenEnv(&icss);
01282 if (i != 0) OK=0;
01283
01284 if (userArg==0 || *userArg=='\0') {
01285 ppasswd = getpwuid(getuid());
01286 strcpy(userName,ppasswd->pw_name);
01287 }
01288 else {
01289 strncpy(userName, userArg, 500);
01290 }
01291 printf("userName=%s\n",userName);
01292 printf("password=%s\n",pwArg);
01293
01294 strncpy(icss.databaseUsername,userName, DB_USERNAME_LEN);
01295
01296 if (pwArg==0 || *pwArg=='\0') {
01297 strcpy(icss.databasePassword,"");
01298 }
01299 else {
01300 strncpy(icss.databasePassword,pwArg, DB_PASSWORD_LEN);
01301 }
01302
01303 i = cllConnect(&icss);
01304 if (i != 0) exit(-1);
01305
01306 i = cllExecSqlNoResult(&icss,"create table test (i integer, j integer, a varchar(32))");
01307 if (i != 0 && i != CAT_SUCCESS_BUT_WITH_NO_INFO) OK=0;
01308
01309 i = cllExecSqlNoResult(&icss, "insert into test values (2, 3, 'a')");
01310 if (i != 0) OK=0;
01311
01312 i = cllExecSqlNoResult(&icss, "commit");
01313 if (i != 0) OK=0;
01314
01315 i = cllExecSqlNoResult(&icss, "bad sql");
01316 if (i == 0) OK=0;
01317 i = cllExecSqlNoResult(&icss, "rollback");
01318
01319 i = cllExecSqlNoResult(&icss, "delete from test where i = 1");
01320 if (i != 0 && i != CAT_SUCCESS_BUT_WITH_NO_INFO) OK=0;
01321
01322 i = cllExecSqlNoResult(&icss, "commit");
01323 if (i != 0) OK=0;
01324
01325 i = cllExecSqlWithResultBV(&icss, &stmt,
01326 "select * from test where a = ?",
01327 "a",0 ,0,0,0,0);
01328 if (i != 0) OK=0;
01329
01330 if (i == 0) {
01331 numOfCols = 1;
01332 for (j=0;j<10 && numOfCols>0;j++) {
01333 i = cllGetRow(&icss, stmt);
01334 if (i != 0) {
01335 OK=0;
01336 }
01337 else {
01338 numOfCols = icss.stmtPtr[stmt]->numOfCols;
01339 if (numOfCols == 0) {
01340 printf("No more rows returned\n");
01341 i = cllFreeStatement(&icss,stmt);
01342 }
01343 else {
01344 for (k=0; k<numOfCols || k < icss.stmtPtr[stmt]->numOfCols; k++){
01345 printf("resultValue[%d]=%s\n",k,
01346 icss.stmtPtr[stmt]->resultValue[k]);
01347 }
01348 }
01349 }
01350 }
01351 }
01352
01353 i = cllExecSqlWithResultBV(&icss, &stmt,
01354 "select * from test where i = ?",
01355 "2",0,0,0,0,0);
01356 if (i != 0) OK=0;
01357
01358 if (i == 0) {
01359 numOfCols = 1;
01360 for (j=0;j<10 && numOfCols>0;j++) {
01361 i = cllGetRow(&icss, stmt);
01362 if (i != 0) {
01363 OK=0;
01364 }
01365 else {
01366 numOfCols = icss.stmtPtr[stmt]->numOfCols;
01367 if (numOfCols == 0) {
01368 printf("No more rows returned\n");
01369 i = cllFreeStatement(&icss,stmt);
01370 }
01371 else {
01372 for (k=0; k<numOfCols || k < icss.stmtPtr[stmt]->numOfCols; k++){
01373 printf("resultValue[%d]=%s\n",k,
01374 icss.stmtPtr[stmt]->resultValue[k]);
01375 }
01376 }
01377 }
01378 }
01379 }
01380
01381 i = cllExecSqlNoResult(&icss,"drop table test;");
01382 if (i != 0 && i != CAT_SUCCESS_BUT_WITH_NO_INFO) OK=0;
01383
01384 i = cllExecSqlNoResult(&icss, "commit");
01385 if (i != 0) OK=0;
01386
01387 i = cllDisconnect(&icss);
01388 if (i != 0) OK=0;
01389
01390 i = cllCloseEnv(&icss);
01391 if (i != 0) OK=0;
01392
01393 if (OK) {
01394 printf("The tests all completed normally\n");
01395 return(0);
01396 }
01397 else {
01398 printf("One or more tests DID NOT complete normally\n");
01399 return(-1);
01400 }
01401 }