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
00747 stat = SQLExecDirect(hstmt, (unsigned char *)sql, SQL_NTS);
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
00778 for (i = 0; i<numColumns; i++) {
00779 stat = SQLDescribeCol(hstmt, i+1, colName, sizeof(colName),
00780 &colNameLen, &colType, &precision, &scale, NULL);
00781 if (stat != SQL_SUCCESS) {
00782 rodsLog(LOG_ERROR, "cllExecSqlWithResult: SQLDescribeCol failed: %d",
00783 stat);
00784 return(-3);
00785 }
00786
00787 columnLength[i]=precision;
00788 stat = SQLColAttribute(hstmt, i+1, SQL_COLUMN_DISPLAY_SIZE,
00789 NULL, 0, NULL, &displaysize);
00790 if (stat != SQL_SUCCESS) {
00791 rodsLog(LOG_ERROR,
00792 "cllExecSqlWithResult: SQLColAttributes failed: %d",
00793 stat);
00794 return(-3);
00795 }
00796
00797 if (displaysize > ((int)strlen((char *) colName))) {
00798 columnLength[i] = displaysize + 1;
00799 }
00800 else {
00801 columnLength[i] = strlen((char *) colName) + 1;
00802 }
00803
00804
00805 myStatement->resultValue[i] = (char*)malloc((int)columnLength[i]);
00806
00807 strcpy((char *)myStatement->resultValue[i],"");
00808
00809 #if 1
00810
00811
00812 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i], columnLength[i], &resultDataSizeArray[ i ] );
00813 #else
00814 #if NEW_ODBC
00815 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i],
00816 columnLength[i], NULL);
00817
00818
00819
00820 #else
00821
00822 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i],
00823 columnLength[i], &resultDataSize);
00824 #endif
00825 #endif
00826 if (stat != SQL_SUCCESS) {
00827 rodsLog(LOG_ERROR,
00828 "cllExecSqlWithResult: SQLColAttributes failed: %d",
00829 stat);
00830 return(-4);
00831 }
00832
00833
00834 myStatement->resultColName[i] = (char*)malloc((int)columnLength[i]);
00835 strncpy(myStatement->resultColName[i], (char *)colName, columnLength[i]);
00836
00837 }
00838 *stmtNum = statementNumber;
00839 return(0);
00840 }
00841
00842
00843
00844
00845
00846 void
00847 logBindVars(
00848 int level,
00849 const char *bindVar1,
00850 const char *bindVar2,
00851 const char *bindVar3,
00852 const char *bindVar4,
00853 const char *bindVar5,
00854 const char *bindVar6) {
00855 if (bindVar1 != 0 && *bindVar1 != '\0') {
00856 rodsLog(level,"bindVar1=%s", bindVar1);
00857 }
00858 if (bindVar2 != 0 && *bindVar2 != '\0') {
00859 rodsLog(level,"bindVar2=%s", bindVar2);
00860 }
00861 if (bindVar3 != 0 && *bindVar3 != '\0') {
00862 rodsLog(level,"bindVar3=%s", bindVar3);
00863 }
00864 if (bindVar4 != 0 && *bindVar4 != '\0') {
00865 rodsLog(level,"bindVar4=%s", bindVar4);
00866 }
00867 }
00868
00869
00870
00871
00872
00873
00874 int
00875 cllExecSqlWithResultBV(
00876 icatSessionStruct *icss,
00877 int *stmtNum,
00878 char *sql,
00879 const char *bindVar1,
00880 const char *bindVar2,
00881 const char *bindVar3,
00882 const char *bindVar4,
00883 const char *bindVar5,
00884 const char *bindVar6) {
00885
00886 RETCODE stat;
00887 HDBC myHdbc;
00888 HSTMT hstmt;
00889 SQLSMALLINT numColumns;
00890
00891 SQLCHAR colName[MAX_TOKEN];
00892 SQLSMALLINT colType;
00893 SQLSMALLINT colNameLen;
00894 SQL_UINT_OR_ULEN precision;
00895 SQLSMALLINT scale;
00896 SQL_INT_OR_LEN displaysize;
00897 #ifndef NEW_ODBC
00898 static SQLINTEGER resultDataSize;
00899 #endif
00900
00901 icatStmtStrct *myStatement;
00902
00903 int i;
00904 int statementNumber;
00905 char *status;
00906 char tmpStr[TMP_STR_LEN+2];
00907
00908 eirods::tmp_string tmp_string1(bindVar1);
00909 eirods::tmp_string tmp_string2(bindVar2);
00910 eirods::tmp_string tmp_string3(bindVar3);
00911 eirods::tmp_string tmp_string4(bindVar4);
00912 eirods::tmp_string tmp_string5(bindVar5);
00913
00914 myHdbc = icss->connectPtr;
00915 rodsLog(LOG_DEBUG1, sql);
00916 stat = SQLAllocStmt(myHdbc, &hstmt);
00917 if (stat != SQL_SUCCESS) {
00918 rodsLog(LOG_ERROR, "cllExecSqlWithResultBV: SQLAllocStmt failed: %d",
00919 stat);
00920 return(-1);
00921 }
00922
00923 statementNumber=-1;
00924 for (i=0;i<MAX_NUM_OF_CONCURRENT_STMTS && statementNumber<0;i++) {
00925 if (icss->stmtPtr[i]==0) {
00926 statementNumber=i;
00927 }
00928 }
00929 if (statementNumber<0) {
00930 rodsLog(LOG_ERROR,
00931 "cllExecSqlWithResultBV: too many concurrent statements");
00932 return(-2);
00933 }
00934
00935 myStatement = (icatStmtStrct *)malloc(sizeof(icatStmtStrct));
00936 icss->stmtPtr[statementNumber]=myStatement;
00937
00938 myStatement->stmtPtr=hstmt;
00939
00940 if ((bindVar1 != 0 && *bindVar1 != '\0') ||
00941 (bindVar2 != 0 && *bindVar2 != '\0') ||
00942 (bindVar3 != 0 && *bindVar3 != '\0') ||
00943 (bindVar4 != 0 && *bindVar4 != '\0')) {
00944
00945 rodsLogSql("SQLPrepare");
00946 stat = SQLPrepare(hstmt, (unsigned char *)sql, SQL_NTS);
00947 if (stat != SQL_SUCCESS) {
00948 rodsLog(LOG_ERROR, "cllExecSqlNoResult: SQLPrepare failed: %d",
00949 stat);
00950 return(-1);
00951 }
00952
00953 if (bindVar1 != 0 && *bindVar1 != '\0') {
00954 stat = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,
00955 SQL_C_CHAR, 0, 0, tmp_string1.str(), 0, 0);
00956 snprintf(tmpStr, TMP_STR_LEN,
00957 "bindVar1=%s", bindVar1);
00958 rodsLogSql(tmpStr);
00959 if (stat != SQL_SUCCESS) {
00960 rodsLog(LOG_ERROR,
00961 "cllExecSqlNoResult: SQLBindParameter failed: %d", stat);
00962 return(-1);
00963 }
00964 }
00965 if (bindVar2 != 0 && *bindVar2 != '\0') {
00966 stat = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
00967 SQL_C_CHAR, 0, 0, tmp_string2.str(), 0, 0);
00968 snprintf(tmpStr, TMP_STR_LEN,
00969 "bindVar2=%s", bindVar2);
00970 rodsLogSql(tmpStr);
00971 if (stat != SQL_SUCCESS) {
00972 rodsLog(LOG_ERROR,
00973 "cllExecSqlNoResult: SQLBindParameter failed: %d", stat);
00974 return(-1);
00975 }
00976 }
00977 if (bindVar3 != 0 && *bindVar3 != '\0') {
00978 stat = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
00979 SQL_C_CHAR, 0, 0, tmp_string3.str(), 0, 0);
00980 snprintf(tmpStr, TMP_STR_LEN,
00981 "bindVar3=%s", bindVar3);
00982 rodsLogSql(tmpStr);
00983 if (stat != SQL_SUCCESS) {
00984 rodsLog(LOG_ERROR, "cllExecSqlNoResult: SQLBindParameter failed: %d",
00985 stat);
00986 return(-1);
00987 }
00988 }
00989 if (bindVar4 != 0 && *bindVar4 != '\0') {
00990 stat = SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR,
00991 SQL_C_CHAR, 0, 0, tmp_string4.str(), 0, 0);
00992 snprintf(tmpStr, TMP_STR_LEN,
00993 "bindVar4=%s", bindVar4);
00994 rodsLogSql(tmpStr);
00995 if (stat != SQL_SUCCESS) {
00996 rodsLog(LOG_ERROR, "cllExecSqlNoResult: SQLBindParameter failed: %d",
00997 stat);
00998 return(-1);
00999 }
01000 }
01001 if (bindVar5 != 0 && *bindVar5 != '\0') {
01002 stat = SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR,
01003 SQL_C_CHAR, 0, 0, tmp_string5.str(), 0, 0);
01004 snprintf(tmpStr, TMP_STR_LEN,
01005 "bindVar5=%s", bindVar5);
01006 rodsLogSql(tmpStr);
01007 if (stat != SQL_SUCCESS) {
01008 rodsLog(LOG_ERROR, "cllExecSqlNoResult: SQLBindParameter failed: %d",
01009 stat);
01010 return(-1);
01011 }
01012 }
01013 rodsLogSql(sql);
01014 stat = SQLExecute(hstmt);
01015 }
01016 else {
01017 rodsLogSql(sql);
01018 stat = SQLExecDirect(hstmt, (unsigned char *)sql, SQL_NTS);
01019 }
01020
01021 status = "UNKNOWN";
01022 if (stat == SQL_SUCCESS) status= "SUCCESS";
01023 if (stat == SQL_SUCCESS_WITH_INFO) status="SUCCESS_WITH_INFO";
01024 if (stat == SQL_NO_DATA_FOUND) status="NO_DATA";
01025 if (stat == SQL_ERROR) status="SQL_ERROR";
01026 if (stat == SQL_INVALID_HANDLE) status="HANDLE_ERROR";
01027 rodsLogSqlResult(status);
01028
01029 if (stat == SQL_SUCCESS ||
01030 stat == SQL_SUCCESS_WITH_INFO ||
01031 stat == SQL_NO_DATA_FOUND) {
01032 }
01033 else {
01034 logBindVars(LOG_NOTICE, bindVar1, bindVar2, bindVar3, bindVar4,
01035 bindVar5, bindVar6);
01036 rodsLog(LOG_NOTICE,
01037 "cllExecSqlWithResultBV: SQLExecDirect error: %d, sql:%s",
01038 stat, sql);
01039 logPsgError(LOG_NOTICE, icss->environPtr, myHdbc, hstmt,
01040 icss->databaseType);
01041 return(-1);
01042 }
01043
01044 stat = SQLNumResultCols(hstmt, &numColumns);
01045 if (stat != SQL_SUCCESS) {
01046 rodsLog(LOG_ERROR, "cllExecSqlWithResultBV: SQLNumResultCols failed: %d",
01047 stat);
01048 return(-2);
01049 }
01050 myStatement->numOfCols=numColumns;
01051
01052 for (i = 0; i<numColumns; i++) {
01053 stat = SQLDescribeCol(hstmt, i+1, colName, sizeof(colName),
01054 &colNameLen, &colType, &precision, &scale, NULL);
01055 if (stat != SQL_SUCCESS) {
01056 rodsLog(LOG_ERROR, "cllExecSqlWithResultBV: SQLDescribeCol failed: %d",
01057 stat);
01058 return(-3);
01059 }
01060
01061 columnLength[i]=precision;
01062 stat = SQLColAttribute(hstmt, i+1, SQL_COLUMN_DISPLAY_SIZE,
01063 NULL, 0, NULL, &displaysize);
01064 if (stat != SQL_SUCCESS) {
01065 rodsLog(LOG_ERROR,
01066 "cllExecSqlWithResultBV: SQLColAttributes failed: %d",
01067 stat);
01068 return(-3);
01069 }
01070
01071 if (displaysize > ((int)strlen((char *) colName))) {
01072 columnLength[i] = displaysize + 1;
01073 }
01074 else {
01075 columnLength[i] = strlen((char *) colName) + 1;
01076 }
01077
01078
01079 myStatement->resultValue[i] = (char*)malloc((int)columnLength[i]);
01080
01081 strcpy((char *)myStatement->resultValue[i],"");
01082 #if 1
01083
01084
01085 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i], columnLength[i], &resultDataSizeArray[i] );
01086 #else
01087 #ifdef NEW_ODBC
01088 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i],
01089 columnLength[i], NULL);
01090
01091
01092
01093 #else
01094
01095 stat = SQLBindCol(hstmt, i+1, SQL_C_CHAR, myStatement->resultValue[i],
01096 columnLength[i], &resultDataSize);
01097 #endif
01098 #endif
01099
01100 if (stat != SQL_SUCCESS) {
01101 rodsLog(LOG_ERROR,
01102 "cllExecSqlWithResultBV: SQLColAttributes failed: %d",
01103 stat);
01104 return(-4);
01105 }
01106
01107
01108 myStatement->resultColName[i] = (char*)malloc((int)columnLength[i]);
01109 strncpy(myStatement->resultColName[i], (char *)colName, columnLength[i]);
01110
01111 }
01112 *stmtNum = statementNumber;
01113 return(0);
01114 }
01115
01116
01117
01118
01119 int
01120 cllGetRow(icatSessionStruct *icss, int statementNumber) {
01121 HSTMT hstmt;
01122 RETCODE stat;
01123 int nCols, i;
01124 icatStmtStrct *myStatement;
01125 int logGetRows=0;
01126
01127
01128
01129
01130 myStatement=icss->stmtPtr[statementNumber];
01131 hstmt = myStatement->stmtPtr;
01132 nCols = myStatement->numOfCols;
01133
01134 for (i=0;i<nCols;i++) {
01135 strcpy((char *)myStatement->resultValue[i],"");
01136 }
01137 stat = SQLFetch(hstmt);
01138 if (stat != SQL_SUCCESS && stat != SQL_NO_DATA_FOUND) {
01139 rodsLog(LOG_ERROR, "cllGetRow: SQLFetch failed: %d", stat);
01140 return(-1);
01141 }
01142 if (stat == SQL_NO_DATA_FOUND) {
01143 if (logGetRows) {
01144 rodsLogSql("cllGetRow: NO DATA FOUND");
01145
01146 char tmpstr[210];
01147 snprintf(tmpstr, 200, "cllGetRow: NO DATA FOUND, statement:%d", statementNumber);
01148 }
01149 _cllFreeStatementColumns(icss,statementNumber);
01150 myStatement->numOfCols=0;
01151 }
01152 else {
01153 if (logGetRows) {
01154 char tmpstr[210];
01155
01156 snprintf(tmpstr, 200, "cllGetRow statement:%d columns:%d first column: %s", statementNumber, nCols, myStatement->resultValue[0]);
01157
01158 rodsLogSql(tmpstr);
01159 }
01160 }
01161 return(0);
01162 }
01163
01164
01165
01166
01167
01168 int
01169 cllNextValueString(char *itemName, char *outString, int maxSize) {
01170 #ifdef MY_ICAT
01171 snprintf(outString, maxSize, "%s_nextval()", itemName);
01172 #else
01173 snprintf(outString, maxSize, "nextval('%s')", itemName);
01174 #endif
01175 return 0;
01176 }
01177
01178 int
01179 cllGetRowCount(icatSessionStruct *icss, int statementNumber) {
01180 int i;
01181 HSTMT hstmt;
01182 icatStmtStrct *myStatement;
01183 SQL_INT_OR_LEN RowCount;
01184
01185 if (statementNumber < 0) return(noResultRowCount);
01186
01187 myStatement=icss->stmtPtr[statementNumber];
01188 hstmt = myStatement->stmtPtr;
01189
01190 i = SQLRowCount (hstmt, (SQL_INT_OR_LEN *)&RowCount);
01191 if (i) return(i);
01192 return(RowCount);
01193 }
01194
01195 int
01196 cllCurrentValueString(char *itemName, char *outString, int maxSize) {
01197 #ifdef MY_ICAT
01198 snprintf(outString, maxSize, "%s_currval()", itemName);
01199 #else
01200 snprintf(outString, maxSize, "currval('%s')", itemName);
01201 #endif
01202 return 0;
01203 }
01204
01205
01206
01207
01208
01209 int
01210 cllFreeStatement(icatSessionStruct *icss, int statementNumber) {
01211 HSTMT hstmt;
01212 RETCODE stat;
01213 int i;
01214
01215 icatStmtStrct *myStatement;
01216
01217 myStatement=icss->stmtPtr[statementNumber];
01218 if (myStatement==NULL) {
01219 return(0);
01220 }
01221 hstmt = myStatement->stmtPtr;
01222
01223 for (i=0;i<myStatement->numOfCols;i++) {
01224 free(myStatement->resultValue[i]);
01225 free(myStatement->resultColName[i]);
01226 }
01227
01228 stat = SQLFreeStmt(hstmt, SQL_DROP);
01229 if (stat != SQL_SUCCESS) {
01230 rodsLog(LOG_ERROR, "cllFreeStatement SQLFreeStmt error: %d", stat);
01231 }
01232
01233 free(myStatement);
01234
01235 icss->stmtPtr[statementNumber]=0;
01236
01237 return (0);
01238 }
01239
01240
01241
01242
01243
01244 int
01245 _cllFreeStatementColumns(icatSessionStruct *icss, int statementNumber) {
01246 int i;
01247
01248 icatStmtStrct *myStatement;
01249
01250 myStatement=icss->stmtPtr[statementNumber];
01251
01252 for (i=0;i<myStatement->numOfCols;i++) {
01253 free(myStatement->resultValue[i]);
01254 free(myStatement->resultColName[i]);
01255 }
01256 return (0);
01257 }
01258
01259
01260
01261
01262
01263 int cllTest(char *userArg, char *pwArg) {
01264 int i;
01265 int j, k;
01266 int OK;
01267 int stmt;
01268 int numOfCols;
01269 char userName[500];
01270
01271 struct passwd *ppasswd;
01272 icatSessionStruct icss;
01273
01274 icss.stmtPtr[0]=0;
01275 icss.databaseType = DB_TYPE_POSTGRES;
01276 #ifdef MY_ICAT
01277 icss.databaseType = DB_TYPE_MYSQL;
01278 #endif
01279
01280 rodsLogSqlReq(1);
01281 OK=1;
01282 i = cllOpenEnv(&icss);
01283 if (i != 0) OK=0;
01284
01285 if (userArg==0 || *userArg=='\0') {
01286 ppasswd = getpwuid(getuid());
01287 strcpy(userName,ppasswd->pw_name);
01288 }
01289 else {
01290 strncpy(userName, userArg, 500);
01291 }
01292 printf("userName=%s\n",userName);
01293 printf("password=%s\n",pwArg);
01294
01295 strncpy(icss.databaseUsername,userName, DB_USERNAME_LEN);
01296
01297 if (pwArg==0 || *pwArg=='\0') {
01298 strcpy(icss.databasePassword,"");
01299 }
01300 else {
01301 strncpy(icss.databasePassword,pwArg, DB_PASSWORD_LEN);
01302 }
01303
01304 i = cllConnect(&icss);
01305 if (i != 0) exit(-1);
01306
01307 i = cllExecSqlNoResult(&icss,"create table test (i integer, j integer, a varchar(32))");
01308 if (i != 0 && i != CAT_SUCCESS_BUT_WITH_NO_INFO) OK=0;
01309
01310 i = cllExecSqlNoResult(&icss, "insert into test values (2, 3, 'a')");
01311 if (i != 0) OK=0;
01312
01313 i = cllExecSqlNoResult(&icss, "commit");
01314 if (i != 0) OK=0;
01315
01316 i = cllExecSqlNoResult(&icss, "bad sql");
01317 if (i == 0) OK=0;
01318 i = cllExecSqlNoResult(&icss, "rollback");
01319
01320 i = cllExecSqlNoResult(&icss, "delete from test where i = 1");
01321 if (i != 0 && i != CAT_SUCCESS_BUT_WITH_NO_INFO) OK=0;
01322
01323 i = cllExecSqlNoResult(&icss, "commit");
01324 if (i != 0) OK=0;
01325
01326 i = cllExecSqlWithResultBV(&icss, &stmt,
01327 "select * from test where a = ?",
01328 "a",0 ,0,0,0,0);
01329 if (i != 0) OK=0;
01330
01331 if (i == 0) {
01332 numOfCols = 1;
01333 for (j=0;j<10 && numOfCols>0;j++) {
01334 i = cllGetRow(&icss, stmt);
01335 if (i != 0) {
01336 OK=0;
01337 }
01338 else {
01339 numOfCols = icss.stmtPtr[stmt]->numOfCols;
01340 if (numOfCols == 0) {
01341 printf("No more rows returned\n");
01342 i = cllFreeStatement(&icss,stmt);
01343 }
01344 else {
01345 for (k=0; k<numOfCols || k < icss.stmtPtr[stmt]->numOfCols; k++){
01346 printf("resultValue[%d]=%s\n",k,
01347 icss.stmtPtr[stmt]->resultValue[k]);
01348 }
01349 }
01350 }
01351 }
01352 }
01353
01354 i = cllExecSqlWithResultBV(&icss, &stmt,
01355 "select * from test where i = ?",
01356 "2",0,0,0,0,0);
01357 if (i != 0) OK=0;
01358
01359 if (i == 0) {
01360 numOfCols = 1;
01361 for (j=0;j<10 && numOfCols>0;j++) {
01362 i = cllGetRow(&icss, stmt);
01363 if (i != 0) {
01364 OK=0;
01365 }
01366 else {
01367 numOfCols = icss.stmtPtr[stmt]->numOfCols;
01368 if (numOfCols == 0) {
01369 printf("No more rows returned\n");
01370 i = cllFreeStatement(&icss,stmt);
01371 }
01372 else {
01373 for (k=0; k<numOfCols || k < icss.stmtPtr[stmt]->numOfCols; k++){
01374 printf("resultValue[%d]=%s\n",k,
01375 icss.stmtPtr[stmt]->resultValue[k]);
01376 }
01377 }
01378 }
01379 }
01380 }
01381
01382 i = cllExecSqlNoResult(&icss,"drop table test;");
01383 if (i != 0 && i != CAT_SUCCESS_BUT_WITH_NO_INFO) OK=0;
01384
01385 i = cllExecSqlNoResult(&icss, "commit");
01386 if (i != 0) OK=0;
01387
01388 i = cllDisconnect(&icss);
01389 if (i != 0) OK=0;
01390
01391 i = cllCloseEnv(&icss);
01392 if (i != 0) OK=0;
01393
01394 if (OK) {
01395 printf("The tests all completed normally\n");
01396 return(0);
01397 }
01398 else {
01399 printf("One or more tests DID NOT complete normally\n");
01400 return(-1);
01401 }
01402 }