/***************************************************************************/ /* RESULTS.C */ /* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */ /***************************************************************************/ // Commenting #define out - causing compiler error - not sure if needed, compiles // okay without it. //#define WINVER 0x0400 #include "precomp.h" #include "wbemidl.h" #include //smart pointer _COM_SMARTPTR_TYPEDEF(IWbemServices, IID_IWbemServices); _COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, IID_IEnumWbemClassObject); //_COM_SMARTPTR_TYPEDEF(IWbemContext, IID_IWbemContext ); _COM_SMARTPTR_TYPEDEF(IWbemLocator, IID_IWbemLocator); #include "drdbdr.h" /***************************************************************************/ BOOL INTFUNC GetUnsignedAttribute(LPSTMT lpstmt, SWORD fSqlType) { UWORD i; for (i = 0; i < lpstmt->lpdbc->lpISAM->cSQLTypes; i++) { if (lpstmt->lpdbc->lpISAM->SQLTypes[i].type == fSqlType) { if (lpstmt->lpdbc->lpISAM->SQLTypes[i].unsignedAttribute == -1) return FALSE; else return lpstmt->lpdbc->lpISAM->SQLTypes[i].unsignedAttribute; } } return FALSE; } /***************************************************************************/ RETCODE SQL_API SQLNumResultCols( HSTMT hstmt, SWORD FAR *pccol) { RETCODE rc; SDWORD ccol; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; MyImpersonator im ( (LPSTMT)hstmt, "SQLNumResultCols" ); /* Find the number of columns */ rc = SQL_SUCCESS; if (pccol != NULL) { rc = SQLColAttributes(hstmt, 0, SQL_COLUMN_COUNT, NULL, 0, NULL, &ccol); if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) return rc; *pccol = (SWORD) ccol; } return rc; } /***************************************************************************/ RETCODE SQL_API SQLDescribeCol( HSTMT hstmt, UWORD icol, UCHAR FAR *szColName, SWORD cbColNameMax, SWORD FAR *pcbColName, SWORD FAR *pfSqlType, UDWORD FAR *pcbColDef, SWORD FAR *pibScale, SWORD FAR *pfNullable) { RETCODE rc; SDWORD fDesc; LPSTMT lpstmt; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; /* Get statement handle */ lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_SUCCESS; MyImpersonator im (lpstmt, "SQLDecribeCol"); /* Get each piece of information (get the column name last so that */ /* if there is a truncation warning it will not get lost). */ rc = SQL_SUCCESS; if (pfSqlType != NULL) { rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_TYPE, NULL, 0, NULL, &fDesc); if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) return rc; *pfSqlType = (SWORD) fDesc; } if (pcbColDef != NULL) { rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_PRECISION, NULL, 0, NULL, &fDesc); if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) return rc; *pcbColDef = (UDWORD) fDesc; //Added by Sai Wong if ( (SDWORD)fDesc == SQL_NO_TOTAL) { *pcbColDef = 0; } } if (pibScale != NULL) { rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_SCALE, NULL, 0, NULL, &fDesc); if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) return rc; *pibScale = (SWORD) fDesc; } if (pfNullable != NULL) { rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_NULLABLE, NULL, 0, NULL, &fDesc); if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) return rc; *pfNullable = (SWORD) fDesc; } if ((szColName != NULL) || (pcbColName)) { rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_NAME, szColName, cbColNameMax, pcbColName, NULL); if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) return rc; } return rc; } /***************************************************************************/ RETCODE SQL_API SQLColAttributes( HSTMT hstmt, UWORD icol, UWORD fDescType, PTR rgbDesc, SWORD cbDescMax, SWORD FAR *pcbDesc, SDWORD FAR *pfDesc) { LPSTMT lpstmt; UINT fStmtType; LPSQLNODE lpSqlNode; RETCODE rc; UWORD count; LPSQLTYPE lpSqlType; STRINGIDX idxAlias; UWORD i; LPSQLNODE lpSqlNodeTable; /* Get statement handle */ lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_SUCCESS; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; MyImpersonator im (lpstmt, "SQLColAttributes"); /* Get the statement type */ fStmtType = lpstmt->fStmtType; /* Is there a prepared statement? */ if (fStmtType == STMT_TYPE_NONE) { if (lpstmt->lpSqlStmt != NULL) { /* Yes. Determine the statement type */ lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE); lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql); switch (lpSqlNode->sqlNodeType) { case NODE_TYPE_SELECT: fStmtType = STMT_TYPE_SELECT; break; case NODE_TYPE_INSERT: case NODE_TYPE_DELETE: case NODE_TYPE_UPDATE: case NODE_TYPE_CREATE: case NODE_TYPE_DROP: case NODE_TYPE_CREATEINDEX: case NODE_TYPE_DROPINDEX: case NODE_TYPE_PASSTHROUGH: /* Update statements have no results */ if (fDescType != SQL_COLUMN_COUNT) { lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } if (pfDesc != NULL) *pfDesc = 0; return SQL_SUCCESS; default: lpstmt->errcode = ERR_INTERNAL; return SQL_ERROR; } } } /* Get the attribute */ switch (fStmtType) { case STMT_TYPE_NONE: if (fDescType != SQL_COLUMN_COUNT) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } if (pfDesc != NULL) *pfDesc = 0; break; /* Look these answer up in the colAttributes table */ case STMT_TYPE_TABLES: case STMT_TYPE_COLUMNS: case STMT_TYPE_STATISTICS: case STMT_TYPE_SPECIALCOLUMNS: case STMT_TYPE_TYPEINFO: case STMT_TYPE_PRIMARYKEYS: case STMT_TYPE_FOREIGNKEYS: /* Just want the number of columns? */ if (fDescType == SQL_COLUMN_COUNT) { if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][0].count; } else if (icol > colAttributes[lpstmt->fStmtType][0].count) { lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } else { switch (fDescType) { case SQL_COLUMN_COUNT: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].count; break; case SQL_COLUMN_AUTO_INCREMENT: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].autoIncrement; break; case SQL_COLUMN_CASE_SENSITIVE: if (pfDesc != NULL) { *pfDesc = colAttributes[lpstmt->fStmtType][icol].caseSensitive; if (*pfDesc == -2) *pfDesc = ISAMCaseSensitive(lpstmt->lpdbc->lpISAM); } break; case SQL_COLUMN_DISPLAY_SIZE: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].displaySize; break; case SQL_COLUMN_LABEL: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, colAttributes[lpstmt->fStmtType][icol].label); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; break; case SQL_COLUMN_LENGTH: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].length; break; case SQL_COLUMN_MONEY: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].money; break; case SQL_COLUMN_NAME: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, colAttributes[lpstmt->fStmtType][icol].name); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; break; case SQL_COLUMN_NULLABLE: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].nullable; break; case SQL_COLUMN_OWNER_NAME: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, colAttributes[lpstmt->fStmtType][icol].ownerName); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; break; case SQL_COLUMN_PRECISION: if (pfDesc != NULL) *pfDesc = (SDWORD) colAttributes[lpstmt->fStmtType][icol].precision; break; case SQL_COLUMN_QUALIFIER_NAME: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, colAttributes[lpstmt->fStmtType][icol].qualifierName); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; break; case SQL_COLUMN_SCALE: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].scale; break; case SQL_COLUMN_SEARCHABLE: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].columnSearchable; break; case SQL_COLUMN_TABLE_NAME: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, colAttributes[lpstmt->fStmtType][icol].tableName); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; break; case SQL_COLUMN_TYPE: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].type; break; case SQL_COLUMN_TYPE_NAME: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, (LPUSTR) colAttributes[lpstmt->fStmtType][icol].typeName); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; break; case SQL_COLUMN_UNSIGNED: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].unsignedAttribute; break; case SQL_COLUMN_UPDATABLE: if (pfDesc != NULL) *pfDesc = colAttributes[lpstmt->fStmtType][icol].updatable; break; default: lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } } break; case STMT_TYPE_SELECT: /* Get the list of columns */ lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE); lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql); /* Handle the special case when there are no columns */ if (lpSqlNode->node.select.Values == NO_SQLNODE) { if (fDescType != SQL_COLUMN_COUNT) { lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } else { if (pfDesc != NULL) *pfDesc = 0; return SQL_SUCCESS; } } /* Find the desired column */ lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.select.Values); for (count = 1; (count != icol) || (fDescType == SQL_COLUMN_COUNT); count++) { if (lpSqlNode->node.values.Next == NO_SQLNODE) { if (fDescType != SQL_COLUMN_COUNT) { lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } break; } lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.values.Next); } /* Column count? */ if (fDescType != SQL_COLUMN_COUNT) { /* No. Save alias (if any) for later */ idxAlias = lpSqlNode->node.values.Alias; /* No. Get the column node */ lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.values.Value); /* Column reference? */ if (lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) { /* Yes. Get the column definition */ lpSqlNodeTable = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.column.Table); ClassColumnInfoBase* cInfoBase = lpSqlNodeTable->node.table.Handle->pColumnInfo; if ( !cInfoBase->IsValid() ) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; } if ( !cInfoBase->GetDataTypeInfo(lpSqlNode->node.column.Id, lpSqlType) || (!lpSqlType) ) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; } } else { /* No. Get the descriptor of the datatype */ lpSqlType = NULL; for (i = 0; i < lpstmt->lpdbc->lpISAM->cSQLTypes; i++) { if (lpstmt->lpdbc->lpISAM->SQLTypes[i].type == lpSqlNode->sqlSqlType) { lpSqlType = &(lpstmt->lpdbc->lpISAM->SQLTypes[i]); break; } } if (lpSqlType == NULL) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; } } } /* Get the data */ switch (fDescType) { case SQL_COLUMN_AUTO_INCREMENT: if (pfDesc != NULL) { if (lpSqlType->autoincrement == -1) *pfDesc = FALSE; else *pfDesc = lpSqlType->autoincrement; } break; case SQL_COLUMN_CASE_SENSITIVE: if (pfDesc != NULL) *pfDesc = lpSqlType->caseSensitive; break; case SQL_COLUMN_COUNT: if (pfDesc != NULL) *pfDesc = count; break; case SQL_COLUMN_DISPLAY_SIZE: if (pfDesc == NULL) break; switch (lpSqlType->type) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: *pfDesc = lpSqlNode->sqlPrecision; break; case SQL_DECIMAL: case SQL_NUMERIC: *pfDesc = lpSqlNode->sqlPrecision + 2; break; case SQL_BIT: *pfDesc = 1; break; case SQL_TINYINT: if (lpSqlType->unsignedAttribute == TRUE) *pfDesc = 3; else *pfDesc = 4; break; case SQL_SMALLINT: if (lpSqlType->unsignedAttribute == TRUE) *pfDesc = 5; else *pfDesc = 6; break; case SQL_INTEGER: if (lpSqlType->unsignedAttribute == TRUE) *pfDesc = 10; else *pfDesc = 11; break; case SQL_BIGINT: if (lpSqlType->unsignedAttribute == TRUE) *pfDesc = lpSqlNode->sqlPrecision; else *pfDesc = lpSqlNode->sqlPrecision + 1; break; case SQL_REAL: *pfDesc = 13; break; case SQL_FLOAT: case SQL_DOUBLE: *pfDesc = 22; break; case SQL_DATE: *pfDesc = 10; break; case SQL_TIME: *pfDesc = 8; break; case SQL_TIMESTAMP: if (TIMESTAMP_SCALE > 0) *pfDesc = 20 + TIMESTAMP_SCALE; else *pfDesc = 19; break; case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: *pfDesc = lpSqlNode->sqlPrecision * 2; break; default: lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } break; case SQL_COLUMN_LABEL: rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_NAME, rgbDesc, cbDescMax, pcbDesc, pfDesc); if (rc != SQL_SUCCESS) return rc; break; case SQL_COLUMN_LENGTH: if (pfDesc == NULL) break; switch (lpSqlType->type) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: *pfDesc = lpSqlNode->sqlPrecision; break; case SQL_DECIMAL: case SQL_NUMERIC: *pfDesc = lpSqlNode->sqlPrecision + 2; break; case SQL_BIT: *pfDesc = 1; break; case SQL_TINYINT: *pfDesc = 1; break; case SQL_SMALLINT: *pfDesc = 2; break; case SQL_INTEGER: *pfDesc = 4; break; case SQL_BIGINT: if (lpSqlType->unsignedAttribute == TRUE) *pfDesc = lpSqlNode->sqlPrecision; else *pfDesc = lpSqlNode->sqlPrecision + 1; break; case SQL_REAL: *pfDesc = 4; break; case SQL_FLOAT: case SQL_DOUBLE: *pfDesc = 8; break; case SQL_DATE: *pfDesc = 6; break; case SQL_TIME: *pfDesc = 6; break; case SQL_TIMESTAMP: *pfDesc = 16; break; case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: *pfDesc = lpSqlNode->sqlPrecision; break; default: lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } break; case SQL_COLUMN_MONEY: if (pfDesc != NULL) *pfDesc = lpSqlType->money; break; case SQL_COLUMN_NAME: if (idxAlias != NO_STRING) { lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, ToString(lpstmt->lpSqlStmt, idxAlias)); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; } else if (lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) { lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, ToString(lpstmt->lpSqlStmt, lpSqlNode->node.column.Column)); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; } else { if ((rgbDesc != NULL) && (cbDescMax > 0)) s_lstrcpy(rgbDesc, ""); if (pcbDesc != NULL) *pcbDesc = 0; } break; case SQL_COLUMN_NULLABLE: if (pfDesc != NULL) { // if (lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) // *pfDesc = FALSE; // else *pfDesc = lpSqlType->nullable; } break; case SQL_COLUMN_OWNER_NAME: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, (LPUSTR) ""); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; case SQL_COLUMN_PRECISION: if (pfDesc == NULL) break; switch (lpSqlType->type) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_DECIMAL: case SQL_NUMERIC: case SQL_BIGINT: case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: *pfDesc = lpSqlNode->sqlPrecision; break; case SQL_BIT: *pfDesc = 1; break; case SQL_TINYINT: *pfDesc = 3; break; case SQL_SMALLINT: *pfDesc = 5; break; case SQL_INTEGER: *pfDesc = 10; break; case SQL_REAL: *pfDesc = 7; break; case SQL_FLOAT: case SQL_DOUBLE: *pfDesc = 15; break; case SQL_DATE: *pfDesc = 10; break; case SQL_TIME: *pfDesc = 8; break; case SQL_TIMESTAMP: if (TIMESTAMP_SCALE > 0) *pfDesc = 20 + TIMESTAMP_SCALE; else *pfDesc = 19; break; default: lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } break; case SQL_COLUMN_QUALIFIER_NAME: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, (LPUSTR) ""); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; case SQL_COLUMN_SCALE: if (pfDesc != NULL) { if (lpSqlNode->sqlScale != NO_SCALE) *pfDesc = lpSqlNode->sqlScale; else *pfDesc = 0; } break; case SQL_COLUMN_SEARCHABLE: if (pfDesc != NULL) *pfDesc = lpSqlType->searchable; break; case SQL_COLUMN_TABLE_NAME: if (lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) { lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, ToString(lpstmt->lpSqlStmt, lpSqlNode->node.column.Tablealias)); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; } else { if ((rgbDesc != NULL) && (cbDescMax > 0)) s_lstrcpy(rgbDesc, ""); if (pcbDesc != NULL) *pcbDesc = 0; } break; case SQL_COLUMN_TYPE: if (pfDesc != NULL) *pfDesc = lpSqlType->type; break; case SQL_COLUMN_TYPE_NAME: lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, lpSqlType->name); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; case SQL_COLUMN_UNSIGNED: if (pfDesc != NULL) { if (lpSqlType->unsignedAttribute == -1) *pfDesc = TRUE; else *pfDesc = lpSqlType->unsignedAttribute; } break; case SQL_COLUMN_UPDATABLE: if (pfDesc != NULL) *pfDesc = SQL_ATTR_READWRITE_UNKNOWN; break; default: lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } break; } return SQL_SUCCESS; } /***************************************************************************/ RETCODE SQL_API SQLBindCol( HSTMT hstmt, UWORD icol, SWORD fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD FAR *pcbValue) { LPSTMT lpstmt; LPBOUND lpBound; LPBOUND lpBoundPrev; HGLOBAL hBound; /* Get statement handle */ lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_SUCCESS; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; MyImpersonator im (lpstmt, "SQLBindCol"); /* Find the binding is on the list */ lpBoundPrev = NULL; lpBound = lpstmt->lpBound; while (lpBound != NULL) { if (lpBound->icol == icol) break; lpBoundPrev = lpBound; lpBound = lpBound->lpNext; } /* Removing the binding? */ if (rgbValue == NULL) { /* Yes. Was it on the list? */ if (lpBound != NULL) { /* Yes. Take it off the list */ if (lpBoundPrev != NULL) lpBoundPrev->lpNext = lpBound->lpNext; else lpstmt->lpBound = lpBound->lpNext; GlobalUnlock (GlobalPtrHandle(lpBound)); GlobalFree (GlobalPtrHandle(lpBound)); } } else { /* No. Was it on the list? */ if (lpBound == NULL) { /* No. Make an entry for it */ hBound = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (BOUND)); if (hBound == NULL || (lpBound = (LPBOUND)GlobalLock (hBound)) == NULL) { if (hBound) GlobalFree(hBound); lpstmt->errcode = ERR_MEMALLOCFAIL; return SQL_ERROR; } lpBound->lpNext = lpstmt->lpBound; lpstmt->lpBound = lpBound; lpBound->icol = icol; } /* Save the bound description */ lpBound->fCType = fCType; lpBound->rgbValue = rgbValue; lpBound->cbValueMax = cbValueMax; lpBound->pcbValue = pcbValue; } return SQL_SUCCESS; } /***************************************************************************/ RETCODE SQL_API SQLFetch( HSTMT hstmt) { LPSTMT lpstmt; LPBOUND lpBound; RETCODE rc; RETCODE errcode; LPSQLNODE lpSqlNode; SWORD err; UWORD index; SDWORD count; HGLOBAL hKeyInfo; /* Get statement handle */ lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_SUCCESS; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; MyImpersonator im (lpstmt, "SQLFetch"); /* Which table? */ switch (lpstmt->fStmtType) { case STMT_TYPE_NONE: lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; /* SQLTables() result... */ case STMT_TYPE_TABLES: { /* Error if after the last row */ if (lpstmt->irow == AFTER_LAST_ROW) return SQL_NO_DATA_FOUND; /* Point at next row */ if (lpstmt->irow == BEFORE_FIRST_ROW) lpstmt->irow = 0; else lpstmt->irow++; /* Does caller want all the tables or all the table types. */ switch (lpstmt->fStmtSubtype) { case STMT_SUBTYPE_TABLES_TABLES: { /* All the tables. If no qualifying tables, return EOT */ if (lpstmt->lpISAMTableList == NULL) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } //Find out if we should perform next command //synchronously or asynchronously UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF; SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode); /* Get next table name */ err = ISAMGetNextTableName(fSyncMode, lpstmt->lpISAMTableList, (LPUSTR)lpstmt->szTableName, (LPUSTR)lpstmt->szTableType); if (err == ISAM_EOF) { if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } else if (err == ISAM_STILL_EXECUTING) { return SQL_STILL_EXECUTING; } else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->szISAMError); lpstmt->irow = AFTER_LAST_ROW; return SQL_ERROR; } if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; } break; case STMT_SUBTYPE_TABLES_TYPES: { (lpstmt->szTableType)[0] = 0; switch (lpstmt->irow) { case 0: strcpy( (char*)lpstmt->szTableType, "TABLE"); break; case 1: strcpy( (char*)lpstmt->szTableType, "SYSTEM TABLE"); break; default: { //EOF lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } break; } } break; case STMT_SUBTYPE_TABLES_QUALIFIERS: { if (lpstmt->lpISAMQualifierList == NULL) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } //Find out if we should perform next command //synchronously or asynchronously UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF; SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode); /* Get next qualifier name */ err = ISAMGetNextQualifierName(fSyncMode, lpstmt->lpISAMQualifierList, (LPUSTR)lpstmt->szQualifierName); if (err == ISAM_EOF) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } else if (err == ISAM_STILL_EXECUTING) { return SQL_STILL_EXECUTING; } else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->szISAMError); lpstmt->irow = AFTER_LAST_ROW; return SQL_ERROR; } } break; case STMT_SUBTYPE_TABLES_OWNERS: { /* The table ownders. Has it been returned yet? */ if (lpstmt->irow != 0) { /* Yes. EOT */ lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } } break; } break; } /* SQLColumns() result... */ case STMT_TYPE_COLUMNS: { /* Error if after the last row */ if (lpstmt->irow == AFTER_LAST_ROW) return SQL_NO_DATA_FOUND; /* If no qualifying tables, EOT */ if (lpstmt->lpISAMTableList == NULL) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } /* Point at next row */ if (lpstmt->irow == BEFORE_FIRST_ROW) lpstmt->irow = 0; else lpstmt->irow++; /* Loop until a column is found */ while (TRUE) { /* If no more columns in the current table... */ //We need to find out the number of columns in table //Find out if we should perform next command //synchronously or asynchronously UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF; SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode); BOOL fTableDefChange = TRUE; UWORD cNumberOfColsInCurrentTable = 0; while ( (lpstmt->lpISAMTableDef == NULL) || ( fTableDefChange && (cNumberOfColsInCurrentTable = GetNumberOfColumnsInTable(lpstmt->lpISAMTableDef) ) && (UWORD)lpstmt->irow >= cNumberOfColsInCurrentTable ) || ( (UWORD)lpstmt->irow >= cNumberOfColsInCurrentTable) ) { /* Go to next table (if any) */ err = ISAMGetNextTableName(fSyncMode, lpstmt->lpISAMTableList, (LPUSTR)lpstmt->szTableName, (LPUSTR)lpstmt->szTableType); fTableDefChange = TRUE; if (err == ISAM_EOF) { if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } else if (err == ISAM_STILL_EXECUTING) { return SQL_STILL_EXECUTING; } else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->szISAMError); lpstmt->irow = AFTER_LAST_ROW; return SQL_ERROR; } if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; /* Get the definition of the table */ if (lpstmt->lpISAMTableDef != NULL) { ISAMCloseTable(lpstmt->lpISAMTableDef); lpstmt->lpISAMTableDef = NULL; } if (NO_ISAM_ERR != ISAMOpenTable(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->lpISAMTableList->lpQualifierName, lpstmt->lpISAMTableList->cbQualifierName, (LPUSTR)lpstmt->szTableName, TRUE, &(lpstmt->lpISAMTableDef))) lpstmt->lpISAMTableDef = NULL; else if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; /* Get first column of that table */ lpstmt->irow = 0; } //Out of While ..loop, so we must have check TABLEDEF at least once fTableDefChange = FALSE; /* Does this column name match the pattern supplied? */ //Remember, we may have a DIFFERENT TABLEDEF !!! ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } char pColumnName [MAX_COLUMN_NAME_LENGTH+1]; if ( FAILED(cInfoBase->GetColumnName(lpstmt->irow, pColumnName)) ) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } //Check if this column type is support //if not we skip this column if (ISAMGetColumnType(lpstmt->lpISAMTableDef, (UWORD) lpstmt->irow) ) { //Check that column name matches search pattern if ( (PatternMatch(TRUE, (LPUSTR)pColumnName, SQL_NTS, (LPUSTR)lpstmt->szColumnName, SQL_NTS, ISAMCaseSensitive(lpstmt->lpdbc->lpISAM)) ) ) { //Ignore any 'lazy' columns BOOL fIsLazy = FALSE; cInfoBase->IsLazy(lpstmt->irow, fIsLazy); //Check if we want to show system properties if (lpstmt->lpISAMTableDef->lpISAM->fSysProps && !fIsLazy) { //We want to show system properties, so continue /* Yes. Return this column */ break; } else { //We don't want to show system properties if (_strnicmp("__", pColumnName, 2) && !fIsLazy) { //Not a system property /* Yes. Return this column */ break; } } } } /* Try the next row */ lpstmt->irow++; } } break; /* SQLStatistics() result... */ case STMT_TYPE_STATISTICS: { /* Error if after the last row */ if (lpstmt->irow == AFTER_LAST_ROW) return SQL_NO_DATA_FOUND; /* Was a table found? */ if (lpstmt->lpISAMTableDef == NULL) { /* No. EOT */ lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } /* Point at next row */ if (lpstmt->irow == BEFORE_FIRST_ROW) lpstmt->irow = 0; else lpstmt->irow++; /* Get number of key columns */ count = 0; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns(); BOOL fIsKey = FALSE; for (index = 0; index < cNumberOfCols; index++) { if (SUCCEEDED(cInfoBase->GetKey(index, fIsKey)) && fIsKey) count++; } /* Has the table or key component been returned yet? */ if (lpstmt->irow > count) { /* Yes. EOT */ lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } } break; /* SQLSpecialColumns() result... */ case STMT_TYPE_SPECIALCOLUMNS: { /* Error if after the last row */ if (lpstmt->irow == AFTER_LAST_ROW) return SQL_NO_DATA_FOUND; /* Was a table found? */ if (lpstmt->lpISAMTableDef == NULL) { /* No. EOT */ lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } /* Point at next row */ if (lpstmt->irow == BEFORE_FIRST_ROW) lpstmt->irow = 0; else lpstmt->irow++; /* Get number of key columns */ count = 0; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns(); BOOL fIsKey = FALSE; for (index = 0; index < cNumberOfCols; index++) { if (SUCCEEDED(cInfoBase->GetKey(index, fIsKey)) && fIsKey) count++; } /* Has the key component been returned yet? */ if (lpstmt->irow >= count) { /* Yes. EOT */ lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } } break; /* SQLGetTypeInfo() */ case STMT_TYPE_TYPEINFO: { /* Error if after the last row */ if (lpstmt->irow == AFTER_LAST_ROW) return SQL_NO_DATA_FOUND; /* Find next qualifying type */ while (TRUE) { /* Point at next row */ if (lpstmt->irow == BEFORE_FIRST_ROW) lpstmt->irow = 0; else lpstmt->irow++; /* Error if no more */ if (lpstmt->irow >= (SDWORD) lpstmt->lpdbc->lpISAM->cSQLTypes) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } /* If this one is supported and matches it, use it */ if (lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].supported && ((lpstmt->fSqlType == SQL_ALL_TYPES) || (lpstmt->fSqlType == lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].type))) break; } } break; /* SQLPrimaryKeys() */ case STMT_TYPE_PRIMARYKEYS: { /* Error if after the last row */ if (lpstmt->irow == AFTER_LAST_ROW) return SQL_NO_DATA_FOUND; /* Was a table found? */ if (lpstmt->lpISAMTableDef == NULL) { /* No. EOT */ lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } /* Point at next row */ if (lpstmt->irow == BEFORE_FIRST_ROW) lpstmt->irow = 0; else lpstmt->irow++; /* Get number of key columns */ count = 0; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns(); BOOL fIsKey = FALSE; for (index = 0; index < cNumberOfCols; index++) { if (SUCCEEDED(cInfoBase->GetKey(index, fIsKey)) && fIsKey) count++; } /* Has the key component been returned yet? */ if (lpstmt->irow >= count) { /* Yes. EOT */ lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } } break; /* SQLForeignKeys() */ case STMT_TYPE_FOREIGNKEYS: { /* Error if after the last row */ if (lpstmt->irow == AFTER_LAST_ROW) return SQL_NO_DATA_FOUND; /* If before first row, allocate space for key information */ if (lpstmt->irow == BEFORE_FIRST_ROW) { hKeyInfo = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (KEYINFO)); if (hKeyInfo == NULL || (lpstmt->lpKeyInfo = (LPKEYINFO)GlobalLock (hKeyInfo)) == NULL) { if (hKeyInfo) GlobalFree(hKeyInfo); lpstmt->errcode = ERR_MEMALLOCFAIL; return SQL_ERROR; } s_lstrcpy(lpstmt->lpKeyInfo->szPrimaryKeyName, ""); s_lstrcpy(lpstmt->lpKeyInfo->szForeignKeyName, ""); lpstmt->lpKeyInfo->iKeyColumns = 0; lpstmt->lpKeyInfo->cKeyColumns = 0; lpstmt->lpKeyInfo->fForeignKeyUpdateRule = -1; lpstmt->lpKeyInfo->fForeignKeyDeleteRule = -1; } /* If need information for next foreign key, retrieve it */ while (lpstmt->lpKeyInfo->iKeyColumns == lpstmt->lpKeyInfo->cKeyColumns) { switch (lpstmt->fStmtSubtype) { case STMT_SUBTYPE_FOREIGNKEYS_SINGLE: if (lpstmt->irow != BEFORE_FIRST_ROW) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } break; case STMT_SUBTYPE_FOREIGNKEYS_MULTIPLE_FK_TABLES: { if (lpstmt->lpISAMTableList == NULL) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } //Find out if we should perform next command //synchronously or asynchronously UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF; SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode); err = ISAMGetNextTableName(fSyncMode, lpstmt->lpISAMTableList, (LPUSTR)lpstmt->szTableName, (LPUSTR)lpstmt->szTableType); if (err == ISAM_EOF) { if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, lpstmt->szISAMError); lpstmt->irow = AFTER_LAST_ROW; return SQL_ERROR; } if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; } break; case STMT_SUBTYPE_FOREIGNKEYS_MULTIPLE_PK_TABLES: { if (lpstmt->lpISAMTableList == NULL) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } //Find out if we should perform next command //synchronously or asynchronously UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF; SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode); err = ISAMGetNextTableName(fSyncMode, lpstmt->lpISAMTableList, lpstmt->szPkTableName, (LPUSTR)lpstmt->szTableType); if (err == ISAM_EOF) { if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, lpstmt->szISAMError); lpstmt->irow = AFTER_LAST_ROW; return SQL_ERROR; } if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; /* Get the foriegn key information */ err = ISAMForeignKey(lpstmt->lpdbc->lpISAM, lpstmt->szPkTableName, lpstmt->szTableName, lpstmt->lpKeyInfo->szPrimaryKeyName, lpstmt->lpKeyInfo->szForeignKeyName, &(lpstmt->lpKeyInfo->fForeignKeyUpdateRule), &(lpstmt->lpKeyInfo->fForeignKeyDeleteRule), &(lpstmt->lpKeyInfo->cKeyColumns), lpstmt->lpKeyInfo->PrimaryKeyColumns, lpstmt->lpKeyInfo->ForeignKeyColumns); if (err == ISAM_EOF) { if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; if (lpstmt->fStmtSubtype == STMT_SUBTYPE_FOREIGNKEYS_SINGLE) { lpstmt->irow = AFTER_LAST_ROW; return SQL_NO_DATA_FOUND; } lpstmt->lpKeyInfo->cKeyColumns = 0; } else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, lpstmt->szISAMError); lpstmt->irow = AFTER_LAST_ROW; return SQL_ERROR; } if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned) lpstmt->fISAMTxnStarted = TRUE; lpstmt->lpKeyInfo->iKeyColumns = 0; /* Point at next row of data to return */ (lpstmt->lpKeyInfo->iKeyColumns)++; if (lpstmt->irow == BEFORE_FIRST_ROW) lpstmt->irow = 0; else lpstmt->irow++; } break; } } } break; /* SELECT statement... */ case STMT_TYPE_SELECT: /* Get the select statement */ lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE); lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql); /* Error parameters are still needed */ if ((lpstmt->idxParameter != NO_SQLNODE) || lpstmt->fNeedData) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } /* Fetch the next row */ lpstmt->errcode = FetchRow(lpstmt, lpSqlNode); if (lpstmt->errcode == ERR_NODATAFOUND) return SQL_NO_DATA_FOUND; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; } /* Get the bound columns */ errcode = ERR_SUCCESS; for (lpBound = lpstmt->lpBound; lpBound != NULL; lpBound = lpBound->lpNext) { rc = SQLGetData(hstmt, lpBound->icol, lpBound->fCType, lpBound->rgbValue, lpBound->cbValueMax, lpBound->pcbValue); if (rc == SQL_SUCCESS_WITH_INFO) errcode = lpstmt->errcode; else if (rc != SQL_SUCCESS) return rc; } /* So far no column read */ lpstmt->icol = NO_COLUMN; lpstmt->cbOffset = 0; if (errcode != ERR_SUCCESS) { lpstmt->errcode = errcode; return SQL_SUCCESS_WITH_INFO; } return SQL_SUCCESS; } /***************************************************************************/ RETCODE SQL_API SQLGetData( HSTMT hstmt, UWORD icol, SWORD fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD FAR *pcbValue) { LPSTMT lpstmt; SWORD sValue; UDWORD udValue; SWORD fSqlTypeIn; PTR rgbValueIn; SDWORD cbValueIn; LPSQLTYPE lpSqlType; LPSQLNODE lpSqlNode; LPSQLNODE lpSqlNodeValues; SQLNODEIDX idxSqlNodeValues; UWORD column; SWORD err; SDWORD cbValue; UWORD index; long intval; // UWORD i; LPSQLNODE lpSqlNodeTable; BOOL fReturningDistinct; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; // ODBCTRACE(_T("\nWBEM ODBC Driver : ENTERING SQLGetData\n")); /* Get statement handle */ lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_SUCCESS; MyImpersonator im (lpstmt, "SQLGetData"); /* //SAI REPLACE // if ( (icol == 1) && (cbValueMax == 201) ) { char* pTemp = (char*) rgbValue; pTemp[0] = 0; lstrcpy(pTemp, "This is a long test dummy string to check for memory leaks"); // lstrcpy(pTemp, "This is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaks"); *pcbValue = 58; // *pcbValue = 580; ODBCTRACE("\n***** REACHED HERE *****\n"); return SQL_SUCCESS; } */ /* Which table? */ switch (lpstmt->fStmtType) { case STMT_TYPE_NONE: lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; /* SQLTables() result... */ case STMT_TYPE_TABLES: { /* Error if not on a row */ if ((lpstmt->irow == BEFORE_FIRST_ROW) || (lpstmt->irow == AFTER_LAST_ROW)) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } /* Return requested column */ switch (icol) { case TABLE_QUALIFIER: switch (lpstmt->fStmtSubtype) { case STMT_SUBTYPE_TABLES_QUALIFIERS: case STMT_SUBTYPE_TABLES_TABLES: fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) (lpstmt->szQualifierName); cbValueIn = SQL_NTS; break; default: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; } break; case TABLE_OWNER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case TABLE_NAME: /* Return either the table name or 'NULL' if just getting the */ /* table types */ switch (lpstmt->fStmtSubtype) { case STMT_SUBTYPE_TABLES_TABLES: fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) (lpstmt->szTableName); cbValueIn = SQL_NTS; break; default: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; } break; case TABLE_TYPE: fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) (lpstmt->szTableType); cbValueIn = SQL_NTS; break; case TABLE_REMARKS: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case TABLE_ATTRIBUTES: { fSqlTypeIn = SQL_CHAR; SDWORD cbBytesCopied = 0; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; /* No. Figure out how long szTableQualifier really is */ SWORD cbTableQualifier = (SWORD) TrueSize((LPUSTR)lpstmt->szQualifierName, SQL_NTS, MAX_QUALIFIER_NAME_LENGTH); LPSTR szConstqualifier = (LPSTR)lpstmt->szQualifierName; //If no table qualifier is specified then use the 'current' database if (!cbTableQualifier) { szConstqualifier = (char*) lpstmt->lpdbc->lpISAM->szDatabase; cbTableQualifier = (SWORD) TrueSize((LPUSTR)szConstqualifier, SQL_NTS, MAX_QUALIFIER_NAME_LENGTH); } if ( ISAMOpenTable(lpstmt->lpdbc->lpISAM, (LPUSTR)szConstqualifier, cbTableQualifier, (LPUSTR) lpstmt->szTableName, TRUE, &(lpstmt->lpISAMTableDef) ) == NO_ISAM_ERR) { ISAMGetTableAttr(lpstmt->lpISAMTableDef, (char*) rgbValue, cbValueMax, cbBytesCopied); rgbValueIn = (char*) rgbValue; cbValueIn = cbBytesCopied; ISAMCloseTable(lpstmt->lpISAMTableDef); lpstmt->lpISAMTableDef = NULL; } } break; default: lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } /* Reset offset if first read of this column */ if (lpstmt->icol != icol) { lpstmt->icol = icol; lpstmt->cbOffset = 0; } /* Convert the results to the requested type */ lpstmt->errcode = ConvertSqlToC(fSqlTypeIn, GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn, cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; } /* SQLColumns()... */ case STMT_TYPE_COLUMNS: { /* Error if not on a row */ if ((lpstmt->irow == BEFORE_FIRST_ROW) || (lpstmt->irow == AFTER_LAST_ROW)) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } /* Get pointer to definition of the type of the column */ lpSqlType = ISAMGetColumnType(lpstmt->lpISAMTableDef, (UWORD) lpstmt->irow); if (lpSqlType == NULL) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; } char szcolName [MAX_COLUMN_NAME_LENGTH + 1]; /* Return the requested column */ switch (icol) { case COLUMN_QUALIFIER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case COLUMN_OWNER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case COLUMN_TABLE: fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) (lpstmt->szTableName); cbValueIn = SQL_NTS; break; case COLUMN_NAME: { fSqlTypeIn = SQL_CHAR; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } rgbValueIn = szcolName; if ( FAILED(cInfoBase->GetColumnName(lpstmt->irow, (char*)rgbValueIn)) ) { return SQL_ERROR; } cbValueIn = SQL_NTS; } break; case COLUMN_TYPE: fSqlTypeIn = SQL_SMALLINT; rgbValueIn = &(lpSqlType->type); cbValueIn = 2; break; case COLUMN_TYPENAME: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpSqlType->name; cbValueIn = SQL_NTS; break; case COLUMN_PRECISION: fSqlTypeIn = SQL_INTEGER; switch (lpSqlType->type) { case SQL_DECIMAL: case SQL_NUMERIC: case SQL_BIGINT: case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: case SQL_DOUBLE: { ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } if ( !cInfoBase->GetPrecision(lpstmt->irow, udValue) ) { return SQL_ERROR; } } break; case SQL_TINYINT: udValue = 3; break; case SQL_SMALLINT: udValue = 5; break; case SQL_INTEGER: udValue = 10; break; case SQL_REAL: udValue = 7; break; case SQL_FLOAT: // case SQL_DOUBLE: udValue = 15; break; case SQL_BIT: udValue = 1; break; case SQL_DATE: udValue = 10; break; case SQL_TIME: udValue = 8; break; case SQL_TIMESTAMP: if (TIMESTAMP_SCALE > 0) udValue = 20 + TIMESTAMP_SCALE; else udValue = 19; break; default: udValue = 0; break; } rgbValueIn = &udValue; cbValueIn = 4; break; case COLUMN_LENGTH: fSqlTypeIn = SQL_INTEGER; switch (lpSqlType->type) { case SQL_DECIMAL: case SQL_NUMERIC: { ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } if ( !cInfoBase->GetPrecision(lpstmt->irow, udValue) ) { return SQL_ERROR; } udValue = udValue + 2; } break; case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: { ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } if ( !cInfoBase->GetPrecision(lpstmt->irow, udValue) ) { return SQL_ERROR; } } break; case SQL_TINYINT: udValue = 1; break; case SQL_SMALLINT: udValue = 2; break; case SQL_INTEGER: udValue = 4; break; case SQL_BIGINT: { ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } if ( !cInfoBase->GetPrecision(lpstmt->irow, udValue) ) { return SQL_ERROR; } if ( ! lpSqlType->unsignedAttribute) udValue = udValue + 1; } break; case SQL_REAL: udValue = 4; break; case SQL_FLOAT: case SQL_DOUBLE: udValue = 8; break; case SQL_BIT: udValue = 1; break; case SQL_DATE: udValue = 6; break; case SQL_TIME: udValue = 6; break; case SQL_TIMESTAMP: udValue = 16; break; default: udValue = 0; break; } rgbValueIn = &udValue; cbValueIn = 4; break; case COLUMN_SCALE: { fSqlTypeIn = SQL_SMALLINT; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } SWORD wScaleVal = 0; if ( !cInfoBase->GetScale(lpstmt->irow, wScaleVal) ) { return SQL_ERROR; } else { udValue = wScaleVal; } rgbValueIn = &udValue; cbValueIn = 2; } break; case COLUMN_RADIX: fSqlTypeIn = SQL_SMALLINT; switch (lpSqlType->type) { case SQL_DECIMAL: case SQL_NUMERIC: case SQL_TINYINT: case SQL_SMALLINT: case SQL_INTEGER: case SQL_BIGINT: case SQL_REAL: case SQL_FLOAT: case SQL_DOUBLE: sValue = 10; rgbValueIn = &sValue; cbValueIn = 2; break; case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_BIT: case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: case SQL_DATE: case SQL_TIME: case SQL_TIMESTAMP: default: rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; } break; case COLUMN_NULLABLE: { fSqlTypeIn = SQL_SMALLINT; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } if ( !cInfoBase->IsNullable(lpstmt->irow, sValue) ) { return SQL_ERROR; } rgbValueIn = &sValue; cbValueIn = 2; } break; case COLUMN_REMARKS: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case COLUMN_ATTRIBUTES: { rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; fSqlTypeIn = SQL_CHAR; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } if ( FAILED(cInfoBase->GetColumnAttr(lpstmt->irow, (char*)rgbValue, cbValueMax, cbValueIn)) ) { return SQL_ERROR; } rgbValueIn = rgbValue; } break; default: lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } /* Reset offset if first read of this column */ if (lpstmt->icol != icol) { lpstmt->icol = icol; lpstmt->cbOffset = 0; } /* Convert the results to the requested type */ lpstmt->errcode = ConvertSqlToC(fSqlTypeIn, GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn, cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; } /* SQLStatistics()... */ case STMT_TYPE_STATISTICS: { /* Error if not on a row */ if ((lpstmt->irow == BEFORE_FIRST_ROW) || (lpstmt->irow == AFTER_LAST_ROW)) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } /* Return the requested column */ switch (icol) { case STATISTIC_QUALIFIER: fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) (lpstmt->szQualifierName); cbValueIn = SQL_NTS; break; case STATISTIC_OWNER: fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) ""; cbValueIn = SQL_NTS; break; case STATISTIC_NAME: fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) (lpstmt->lpISAMTableDef->szTableName); cbValueIn = SQL_NTS; break; case STATISTIC_NONUNIQUE: if (lpstmt->irow == 0) { fSqlTypeIn = SQL_SMALLINT; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; } else { fSqlTypeIn = SQL_SMALLINT; sValue = FALSE; rgbValueIn = &sValue; cbValueIn = 2; } break; case STATISTIC_INDEXQUALIFIER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case STATISTIC_INDEXNAME: if (lpstmt->irow == 0) { fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; } else { fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) "KEY"; cbValueIn = SQL_NTS; } break; case STATISTIC_TYPE: if (lpstmt->irow == 0) { fSqlTypeIn = SQL_SMALLINT; sValue = SQL_TABLE_STAT; rgbValueIn = &sValue; cbValueIn = 2; } else { fSqlTypeIn = SQL_SMALLINT; sValue = SQL_INDEX_OTHER; rgbValueIn = &sValue; cbValueIn = 2; } break; case STATISTIC_SEQININDEX: if (lpstmt->irow == 0) { fSqlTypeIn = SQL_SMALLINT; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; } else { fSqlTypeIn = SQL_SMALLINT; sValue = (SWORD) lpstmt->irow; rgbValueIn = &sValue; cbValueIn = 2; } break; case STATISTIC_COLUMNNAME: if (lpstmt->irow == 0) { fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; } else { /* Find the description of the column. For each column... */ rgbValueIn = NULL; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns(); char pColumnName [MAX_COLUMN_NAME_LENGTH+1]; BOOL fIsKey = FALSE; for (index = 0;index < cNumberOfCols;index++) { if ( FAILED(cInfoBase->GetColumnName(index, pColumnName)) ) { return SQL_ERROR; } /* Is this column a component of the key? */ cInfoBase->GetKey(index, fIsKey); if (fIsKey) { /* Yes. Is this the component we want? */ /* Yes. Save pointer to column name */ fSqlTypeIn = SQL_CHAR; ((char*)rgbValue)[0] = 0; lstrcpy ((char*)rgbValue, pColumnName); rgbValueIn = (char*)rgbValue; cbValueIn = SQL_NTS; break; } } if (rgbValueIn == NULL) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; } } break; case STATISTIC_COLLATION: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case STATISTIC_CARDINALITY: fSqlTypeIn = SQL_INTEGER; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case STATISTIC_PAGES: fSqlTypeIn = SQL_INTEGER; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case STATISTIC_FILTERCONDITION: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; default: lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } /* Reset offset if first read of this column */ if (lpstmt->icol != icol) { lpstmt->icol = icol; lpstmt->cbOffset = 0; } /* Convert the results to the requested type */ lpstmt->errcode = ConvertSqlToC(fSqlTypeIn, GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn, cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; } break; /* SQLSpecialColumns()... */ case STMT_TYPE_SPECIALCOLUMNS: { /* Error if not on a row */ if ((lpstmt->irow == BEFORE_FIRST_ROW) || (lpstmt->irow == AFTER_LAST_ROW)) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } /* Find the description of the column. For each column... */ lpstmt->errcode = ERR_ISAM; ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo; if ( !cInfoBase->IsValid() ) { return SQL_ERROR; } UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns(); char pColumnName [MAX_COLUMN_NAME_LENGTH+1]; BOOL fIsKey = FALSE; for (index = 0; index < cNumberOfCols; index++) { if ( FAILED(cInfoBase->GetColumnName(index, pColumnName)) ) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; } /* Is this column a component of the key? */ cInfoBase->GetKey(index, fIsKey); if (fIsKey) { /* Yes. Save index to column */ lpstmt->errcode = ERR_SUCCESS; break; } } if (lpstmt->errcode == ERR_ISAM) return SQL_ERROR; /* Get pointer to definition of the type of the column */ if ( (!cInfoBase->GetDataTypeInfo(index, lpSqlType)) || (lpSqlType == NULL) ) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; } /* Return the requested column */ switch (icol) { case SPECIALCOLUMN_SCOPE: fSqlTypeIn = SQL_SMALLINT; sValue = SQL_SCOPE_SESSION; rgbValueIn = &sValue; cbValueIn = 2; break; case SPECIALCOLUMN_NAME: fSqlTypeIn = SQL_CHAR; ((char*)rgbValue)[0] = 0; lstrcpy((char*)rgbValue, pColumnName); rgbValueIn = (char*)rgbValue; cbValueIn = SQL_NTS; break; case SPECIALCOLUMN_TYPE: fSqlTypeIn = SQL_SMALLINT; rgbValueIn = &(lpSqlType->type); cbValueIn = 2; break; case SPECIALCOLUMN_TYPENAME: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpSqlType->name; cbValueIn = SQL_NTS; break; case SPECIALCOLUMN_PRECISION: fSqlTypeIn = SQL_INTEGER; switch (lpSqlType->type) { case SQL_DECIMAL: case SQL_NUMERIC: case SQL_BIGINT: case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: cInfoBase->GetPrecision(index, udValue); break; case SQL_TINYINT: udValue = 3; break; case SQL_SMALLINT: udValue = 5; break; case SQL_INTEGER: udValue = 10; break; case SQL_REAL: udValue = 7; break; case SQL_FLOAT: case SQL_DOUBLE: udValue = 15; break; case SQL_BIT: udValue = 1; break; case SQL_DATE: udValue = 10; break; case SQL_TIME: udValue = 8; break; case SQL_TIMESTAMP: if (TIMESTAMP_SCALE > 0) udValue = 20 + TIMESTAMP_SCALE; else udValue = 19; break; default: udValue = 0; break; } rgbValueIn = &udValue; cbValueIn = 4; break; case SPECIALCOLUMN_LENGTH: fSqlTypeIn = SQL_INTEGER; switch (lpSqlType->type) { case SQL_DECIMAL: case SQL_NUMERIC: { cInfoBase->GetPrecision(index, udValue); udValue = udValue + 2; } break; case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: cInfoBase->GetPrecision(index, udValue); break; case SQL_TINYINT: udValue = 1; break; case SQL_SMALLINT: udValue = 2; break; case SQL_INTEGER: udValue = 4; break; case SQL_BIGINT: { cInfoBase->GetPrecision(index, udValue); if ( !lpSqlType->unsignedAttribute ) udValue = udValue + 1; } break; case SQL_REAL: udValue = 4; break; case SQL_FLOAT: case SQL_DOUBLE: udValue = 8; break; case SQL_BIT: udValue = 1; break; case SQL_DATE: udValue = 6; break; case SQL_TIME: udValue = 6; break; case SQL_TIMESTAMP: udValue = 16; break; default: udValue = 0; break; } rgbValueIn = &udValue; cbValueIn = 4; break; case SPECIALCOLUMN_SCALE: { fSqlTypeIn = SQL_SMALLINT; cInfoBase->GetScale(index, sValue); rgbValueIn = &sValue; cbValueIn = 2; } break; case SPECIALCOLUMN_PSEUDOCOLUMN: fSqlTypeIn = SQL_SMALLINT; sValue = SQL_PC_UNKNOWN; rgbValueIn = &sValue; cbValueIn = 2; break; default: lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } /* Reset offset if first read of this column */ if (lpstmt->icol != icol) { lpstmt->icol = icol; lpstmt->cbOffset = 0; } /* Convert the results to the requested type */ lpstmt->errcode = ConvertSqlToC(fSqlTypeIn, GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn, cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; } /* SQLGetTypeInfo()... */ case STMT_TYPE_TYPEINFO: /* Error if not on a row */ if ((lpstmt->irow == BEFORE_FIRST_ROW) || (lpstmt->irow == AFTER_LAST_ROW)) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } /* Return the requested column */ switch (icol) { case TYPEINFO_NAME: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].name; cbValueIn = SQL_NTS; break; case TYPEINFO_TYPE: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].type; rgbValueIn = &sValue; cbValueIn = 2; break; case TYPEINFO_PRECISION: fSqlTypeIn = SQL_INTEGER; udValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].precision; rgbValueIn = &udValue; cbValueIn = 4; break; case TYPEINFO_PREFIX: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].prefix; if (rgbValueIn != NULL) cbValueIn = SQL_NTS; else cbValueIn = SQL_NULL_DATA; break; case TYPEINFO_SUFFIX: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].suffix; if (rgbValueIn != NULL) cbValueIn = SQL_NTS; else cbValueIn = SQL_NULL_DATA; break; case TYPEINFO_PARAMS: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].params; if (rgbValueIn != NULL) cbValueIn = SQL_NTS; else cbValueIn = SQL_NULL_DATA; break; case TYPEINFO_NULLABLE: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].nullable; rgbValueIn = &sValue; cbValueIn = 2; break; case TYPEINFO_CASESENSITIVE: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].caseSensitive; rgbValueIn = &sValue; cbValueIn = 2; break; case TYPEINFO_SEARCHABLE: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].searchable; rgbValueIn = &sValue; cbValueIn = 2; break; case TYPEINFO_UNSIGNED: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].unsignedAttribute; rgbValueIn = &sValue; if (sValue != -1) cbValueIn = 2; else cbValueIn = SQL_NULL_DATA; break; case TYPEINFO_MONEY: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].money; rgbValueIn = &sValue; cbValueIn = 2; break; case TYPEINFO_AUTOINCREMENT: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].autoincrement; rgbValueIn = &sValue; if (sValue != -1) cbValueIn = 2; else cbValueIn = SQL_NULL_DATA; break; case TYPEINFO_LOCALNAME: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].localName; if (rgbValueIn != NULL) cbValueIn = SQL_NTS; else cbValueIn = SQL_NULL_DATA; break; case TYPEINFO_MINSCALE: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].minscale; rgbValueIn = &sValue; if (sValue != -1) cbValueIn = 2; else cbValueIn = SQL_NULL_DATA; break; case TYPEINFO_MAXSCALE: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].maxscale; rgbValueIn = &sValue; if (sValue != -1) cbValueIn = 2; else cbValueIn = SQL_NULL_DATA; break; default: lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } /* Reset offset if first read of this column */ if (lpstmt->icol != icol) { lpstmt->icol = icol; lpstmt->cbOffset = 0; } /* Convert the results to the requested type */ lpstmt->errcode = ConvertSqlToC(fSqlTypeIn, GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn, cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; /* SQLPrimaryKeys()... */ case STMT_TYPE_PRIMARYKEYS: /* Error if not on a row */ if ((lpstmt->irow == BEFORE_FIRST_ROW) || (lpstmt->irow == AFTER_LAST_ROW)) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } /* Return the requested column */ switch (icol) { case PRIMARYKEY_QUALIFIER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case PRIMARYKEY_OWNER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case PRIMARYKEY_TABLE: fSqlTypeIn = SQL_CHAR; rgbValueIn = (LPSTR) (lpstmt->lpISAMTableDef->szTableName); cbValueIn = SQL_NTS; break; case PRIMARYKEY_COLUMN: /* Find the description of the column. For each column... */ return SQL_ERROR; break; case PRIMARYKEY_KEYSEQ: fSqlTypeIn = SQL_SMALLINT; sValue = (SWORD) (lpstmt->irow + 1); rgbValueIn = &sValue; cbValueIn = 2; break; case PRIMARYKEY_NAME: fSqlTypeIn = SQL_CHAR; if (s_lstrlen(lpstmt->lpISAMTableDef->szPrimaryKeyName) != 0) { rgbValueIn = lpstmt->lpISAMTableDef->szPrimaryKeyName; cbValueIn = SQL_NTS; } else { rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; } break; default: lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } /* Reset offset if first read of this column */ if (lpstmt->icol != icol) { lpstmt->icol = icol; lpstmt->cbOffset = 0; } /* Convert the results to the requested type */ lpstmt->errcode = ConvertSqlToC(fSqlTypeIn, GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn, cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; /* SQLForeignKeys()... */ case STMT_TYPE_FOREIGNKEYS: /* Error if not on a row */ if ((lpstmt->irow == BEFORE_FIRST_ROW) || (lpstmt->irow == AFTER_LAST_ROW)) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } /* Return the requested column */ switch (icol) { case FOREIGNKEY_PKQUALIFIER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case FOREIGNKEY_PKOWNER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case FOREIGNKEY_PKTABLE: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->szPkTableName; cbValueIn = SQL_NTS; break; case FOREIGNKEY_PKCOLUMN: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->lpKeyInfo->PrimaryKeyColumns[ lpstmt->lpKeyInfo->iKeyColumns-1]; cbValueIn = SQL_NTS; break; case FOREIGNKEY_FKQUALIFIER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case FOREIGNKEY_FKOWNER: fSqlTypeIn = SQL_CHAR; rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; break; case FOREIGNKEY_FKTABLE: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->szTableName; cbValueIn = SQL_NTS; break; case FOREIGNKEY_FKCOLUMN: fSqlTypeIn = SQL_CHAR; rgbValueIn = lpstmt->lpKeyInfo->ForeignKeyColumns[ lpstmt->lpKeyInfo->iKeyColumns-1]; cbValueIn = SQL_NTS; break; case FOREIGNKEY_KEYSEQ: fSqlTypeIn = SQL_SMALLINT; sValue = (SWORD) lpstmt->lpKeyInfo->iKeyColumns; rgbValueIn = &sValue; cbValueIn = 2; break; case FOREIGNKEY_UPDATERULE: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpKeyInfo->fForeignKeyUpdateRule; rgbValueIn = &sValue; if (lpstmt->lpKeyInfo->fForeignKeyUpdateRule != -1) cbValueIn = 2; else cbValueIn = SQL_NULL_DATA; break; case FOREIGNKEY_DELETERULE: fSqlTypeIn = SQL_SMALLINT; sValue = lpstmt->lpKeyInfo->fForeignKeyDeleteRule; rgbValueIn = &sValue; if (lpstmt->lpKeyInfo->fForeignKeyDeleteRule != -1) cbValueIn = 2; else cbValueIn = SQL_NULL_DATA; break; case FOREIGNKEY_FKNAME: fSqlTypeIn = SQL_CHAR; if (s_lstrlen(lpstmt->lpKeyInfo->szForeignKeyName) != 0) { rgbValueIn = lpstmt->lpKeyInfo->szForeignKeyName; cbValueIn = SQL_NTS; } else { rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; } break; case FOREIGNKEY_PKNAME: fSqlTypeIn = SQL_CHAR; if (s_lstrlen(lpstmt->lpKeyInfo->szPrimaryKeyName) != 0) { rgbValueIn = lpstmt->lpKeyInfo->szPrimaryKeyName; cbValueIn = SQL_NTS; } else { rgbValueIn = NULL; cbValueIn = SQL_NULL_DATA; } break; default: lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } /* Reset offset if first read of this column */ if (lpstmt->icol != icol) { lpstmt->icol = icol; lpstmt->cbOffset = 0; } /* Convert the results to the requested type */ lpstmt->errcode = ConvertSqlToC(fSqlTypeIn, GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn, cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; /* SELECT statement */ case STMT_TYPE_SELECT: { /* Error if not on a row */ lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE); lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql); if ((lpSqlNode->node.select.CurrentRow == BEFORE_FIRST_ROW) || (lpSqlNode->node.select.CurrentRow == AFTER_LAST_ROW)) { lpstmt->errcode = ERR_CURSORSTATE; return SQL_ERROR; } fReturningDistinct = lpSqlNode->node.select.ReturningDistinct; //This was added to fix an MS Access bug if ( (fCType == SQL_C_DEFAULT) || (fCType == SQL_C_LONG) || (fCType == SQL_C_SHORT) || (fCType == SQL_C_TINYINT) ) { SWORD pcbBytesRet = 0; SDWORD pfDummy = 0; UCHAR szColType [MAX_COLUMN_NAME_LENGTH+1]; szColType[0] = 0; SQLColAttributes(hstmt, icol, SQL_COLUMN_TYPE_NAME, szColType, MAX_COLUMN_NAME_LENGTH, &pcbBytesRet, &pfDummy); //test data // strcpy((char*)szColType, "SMALL_STRING"); // pcbBytesRet = 12; LPSQLTYPE lpSqlType = GetType2(szColType); if (lpSqlType == 0) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; }; if ( (lpSqlType->unsignedAttribute == -1) || (lpSqlType->unsignedAttribute == TRUE) ) { switch (fCType) { case SQL_C_DEFAULT: { switch (lpSqlType->type) { case SQL_TINYINT: fCType = SQL_C_UTINYINT; break; case SQL_SMALLINT: fCType = SQL_C_USHORT; break; case SQL_INTEGER: fCType = SQL_C_ULONG; break; default: break; } } break; case SQL_C_LONG: fCType = SQL_C_ULONG; break; case SQL_C_SHORT: fCType = SQL_C_USHORT; break; case SQL_C_TINYINT: fCType = SQL_C_UTINYINT; break; default: break; } } } /* Get the VALUE node corresponding to the column number. */ idxSqlNodeValues = lpSqlNode->node.select.Values; for (column = 1; column <= icol; column++) { if (idxSqlNodeValues == NO_SQLNODE) { lpstmt->errcode = ERR_INVALIDCOLUMNID; return SQL_ERROR; } lpSqlNodeValues = ToNode(lpstmt->lpSqlStmt, idxSqlNodeValues); idxSqlNodeValues = lpSqlNodeValues->node.values.Next; } lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNodeValues->node.values.Value); /* Reset offset if first read of this column */ if (lpstmt->icol != icol) { lpstmt->icol = icol; lpstmt->cbOffset = 0; } /* Is this a COLUMN node for a character (binary) column that is */ /* to be read into a character (binary) buffer? */ if ((lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) && (((lpSqlNode->sqlDataType == TYPE_CHAR) && (fCType == SQL_C_CHAR)) || ((lpSqlNode->sqlDataType == TYPE_BINARY) && (fCType == SQL_C_BINARY))) && (!(lpSqlNode->node.column.InSortRecord)) && (!(fReturningDistinct)) ) { /* Yes. Get the character data */ lpSqlNodeTable = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.column.Table); if (!(lpSqlNodeTable->node.table.AllNull)) { err = ISAMGetData(lpSqlNodeTable->node.table.Handle, lpSqlNode->node.column.Id, lpstmt->cbOffset, fCType, rgbValue, cbValueMax, &cbValue); if ((err == NO_ISAM_ERR) || (err == ISAM_TRUNCATION)) lpstmt->fISAMTxnStarted = TRUE; } else { if ((fCType == SQL_C_CHAR) && (rgbValue != NULL) && (cbValueMax > 0)) s_lstrcpy(rgbValue, ""); err = NO_ISAM_ERR; cbValue = SQL_NULL_DATA; } if (err == ISAM_TRUNCATION) lpstmt->errcode = ERR_DATATRUNCATED; else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->szISAMError); return SQL_ERROR; } /* Return the size */ if (pcbValue != NULL) *pcbValue = cbValue; // CString myOutput1; // myOutput1.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=1 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput1); /* Fix the offset */ if (cbValue >= cbValueMax) { if (fCType == SQL_C_CHAR) { if (cbValueMax > 0) lpstmt->cbOffset += (cbValueMax-1); } else lpstmt->cbOffset += (cbValueMax); } else if (cbValue > 0) lpstmt->cbOffset += (cbValue); /* Return warning if data was truncated */ if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; } /* Is this a COLUMN node for a character column that is */ /* to be read into a binary buffer? */ else if ((lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) && (lpSqlNode->sqlDataType == TYPE_CHAR) && (fCType == SQL_C_BINARY) && (!(lpSqlNode->node.column.InSortRecord)) && (!(fReturningDistinct)) ) { /* Yes. Get the character data */ lpSqlNodeTable = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.column.Table); if (!(lpSqlNodeTable->node.table.AllNull)) { err = ISAMGetData(lpSqlNodeTable->node.table.Handle, lpSqlNode->node.column.Id, lpstmt->cbOffset, SQL_C_CHAR, rgbValue, cbValueMax, &cbValue); if ((err == NO_ISAM_ERR) || (err == ISAM_TRUNCATION)) lpstmt->fISAMTxnStarted = TRUE; } else { err = NO_ISAM_ERR; cbValue = SQL_NULL_DATA; } if (err == ISAM_TRUNCATION) lpstmt->errcode = ERR_DATATRUNCATED; else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->szISAMError); return SQL_ERROR; } /* Return the size */ if (pcbValue != NULL) *pcbValue = cbValue; // CString myOutput2; // myOutput2.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=2 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput2); /* Fix the offset */ if (cbValue >= cbValueMax) lpstmt->cbOffset += (cbValueMax); else if (cbValue > 0) lpstmt->cbOffset += (cbValue); /* Return warning if data was truncated */ if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; } /* Is this a COLUMN node for a binary column that is */ /* to be read into a character buffer? */ else if ((lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) && (lpSqlNode->sqlDataType == TYPE_BINARY) && (fCType == SQL_C_CHAR) && (!(lpSqlNode->node.column.InSortRecord)) && (!(fReturningDistinct)) ) { /* Yes. Get the character data */ lpSqlNodeTable = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.column.Table); if (!(lpSqlNodeTable->node.table.AllNull)) { err = ISAMGetData(lpSqlNodeTable->node.table.Handle, lpSqlNode->node.column.Id, lpstmt->cbOffset, fCType, rgbValue, cbValueMax, &cbValue); if ((err == NO_ISAM_ERR) || (err == ISAM_TRUNCATION)) lpstmt->fISAMTxnStarted = TRUE; } else { if ((rgbValue != NULL) && (cbValueMax > 0)) s_lstrcpy(rgbValue, ""); err = NO_ISAM_ERR; cbValue = SQL_NULL_DATA; } if (err == ISAM_TRUNCATION) lpstmt->errcode = ERR_DATATRUNCATED; else if (err != NO_ISAM_ERR) { lpstmt->errcode = err; ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->szISAMError); return SQL_ERROR; } /* Return the size */ if (pcbValue != NULL) *pcbValue = cbValue; // CString myOutput3; // myOutput3.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=3 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput3); /* Fix the offset */ if (cbValue >= cbValueMax) { if (cbValueMax > 0) lpstmt->cbOffset += (cbValueMax-1); } else if (cbValue > 0) lpstmt->cbOffset += (cbValue); /* Return warning if data was truncated */ if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; } else { /* No. Evaluate the VALUE node. */ err = EvaluateExpression(lpstmt, lpSqlNode); if (err != ERR_SUCCESS) { lpstmt->errcode = err; return SQL_ERROR; } /* Is the value NULL? */ if (lpSqlNode->sqlIsNull) { /* Yes. Return NULL */ if (pcbValue != NULL) *pcbValue = SQL_NULL_DATA; } else { /* No. Copy the value from the node to the output buffer. */ switch (lpSqlNode->sqlDataType) { case TYPE_DOUBLE: case TYPE_NUMERIC: case TYPE_INTEGER: /* SQL_C_DEFAULT or SQL_C_BINARY specified? */ if ((fCType == SQL_C_DEFAULT)||(fCType == SQL_C_BINARY)) { /* Yes. Get the descriptor of datatype of value */ //Get type information about the column SWORD pcbBytesRet = 0; SDWORD pfDummy = 0; UCHAR szColType [MAX_COLUMN_NAME_LENGTH+1]; szColType[0] = 0; SQLColAttributes(hstmt, icol, SQL_COLUMN_TYPE_NAME, szColType, MAX_COLUMN_NAME_LENGTH, &pcbBytesRet, &pfDummy); lpSqlType = GetType2(szColType); // lpSqlType = GetType(lpSqlNode->sqlSqlType); if (lpSqlType == NULL) { lpstmt->errcode = ERR_ISAM; return SQL_ERROR; } /* Determine the C Type the value */ switch (lpSqlType->type) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: fCType = SQL_C_CHAR; break; case SQL_BIGINT: fCType = SQL_C_CHAR; break; case SQL_DECIMAL: case SQL_NUMERIC: fCType = SQL_C_CHAR; break; case SQL_DOUBLE: case SQL_FLOAT: fCType = SQL_C_DOUBLE; break; case SQL_BIT: fCType = SQL_C_BIT; break; case SQL_REAL: fCType = SQL_C_FLOAT; break; case SQL_INTEGER: if (lpSqlType->unsignedAttribute == TRUE) fCType = SQL_C_ULONG; else fCType = SQL_C_SLONG; break; case SQL_SMALLINT: if (lpSqlType->unsignedAttribute == TRUE) fCType = SQL_C_USHORT; else fCType = SQL_C_SSHORT; break; case SQL_TINYINT: if (lpSqlType->unsignedAttribute == TRUE) fCType = SQL_C_UTINYINT; else fCType = SQL_C_STINYINT; break; case SQL_DATE: case SQL_TIME: case SQL_TIMESTAMP: lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: fCType = SQL_C_BINARY; break; default: lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } } /* Get the value */ switch (lpSqlNode->sqlDataType) { case TYPE_DOUBLE: { lpstmt->errcode = ConvertSqlToC(SQL_DOUBLE, GetUnsignedAttribute(lpstmt, SQL_DOUBLE), &(lpSqlNode->value.Double), sizeof(double), &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); // CString myOutput4; // myOutput4.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=4 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput4); } break; case TYPE_INTEGER: { //We have already made sure value is stored in double //as the appropriate signed or un-signed value BOOL fIsUnsigned = (lpSqlNode->value.Double > 0) ? TRUE : FALSE; intval = (long) lpSqlNode->value.Double; lpstmt->errcode = ConvertSqlToC(SQL_INTEGER, // GetUnsignedAttribute(lpstmt, SQL_INTEGER), fIsUnsigned, &intval, sizeof(long), &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); // CString myOutput5; // myOutput5.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=5 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput5); } break; case TYPE_NUMERIC: { if (s_lstrlen(lpSqlNode->value.String) != 0) { lpstmt->errcode = ConvertSqlToC(SQL_CHAR, GetUnsignedAttribute(lpstmt, SQL_CHAR), lpSqlNode->value.String, s_lstrlen(lpSqlNode->value.String), &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); // CString myOutput6; // myOutput6.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=6 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput6); } else { lpstmt->errcode = ConvertSqlToC(SQL_CHAR, GetUnsignedAttribute(lpstmt, SQL_CHAR), "0", 1, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); // CString myOutput7; // myOutput7.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=7 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput7); } } break; case TYPE_CHAR: case TYPE_DATE: case TYPE_TIME: case TYPE_TIMESTAMP: case TYPE_BINARY: default: lpstmt->errcode = ERR_INTERNAL; break; } if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; case TYPE_CHAR: { lpstmt->errcode = ConvertSqlToC(SQL_CHAR, GetUnsignedAttribute(lpstmt, SQL_CHAR), lpSqlNode->value.String, s_lstrlen(lpSqlNode->value.String), &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); // CString myOutput8; // myOutput8.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=8 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput8); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; } break; case TYPE_DATE: lpstmt->errcode = ConvertSqlToC(SQL_DATE, GetUnsignedAttribute(lpstmt, SQL_DATE), &(lpSqlNode->value.Date), sizeof(DATE_STRUCT), &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; case TYPE_TIME: lpstmt->errcode = ConvertSqlToC(SQL_TIME, GetUnsignedAttribute(lpstmt, SQL_TIME), &(lpSqlNode->value.Time), sizeof(TIME_STRUCT), &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; case TYPE_TIMESTAMP: lpstmt->errcode = ConvertSqlToC(SQL_TIMESTAMP, GetUnsignedAttribute(lpstmt, SQL_TIMESTAMP), &(lpSqlNode->value.Timestamp), sizeof(TIMESTAMP_STRUCT), &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; break; case TYPE_BINARY: { lpstmt->errcode = ConvertSqlToC(SQL_BINARY, GetUnsignedAttribute(lpstmt, SQL_BINARY), BINARY_DATA(lpSqlNode->value.Binary), BINARY_LENGTH(lpSqlNode->value.Binary), &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax, pcbValue); // CString myOutput9; // myOutput9.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=9 pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput9); if (lpstmt->errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; else if (lpstmt->errcode != ERR_SUCCESS) return SQL_ERROR; } break; default: lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } } } } break; } // CString myOutput; // myOutput.Format(_T("\nWBEM ODBC Driver : EXITING SQLGetData pcbValue = %ld\n"), *pcbValue); // ODBCTRACE(myOutput); return SQL_SUCCESS; } /***************************************************************************/ RETCODE SQL_API SQLMoreResults( HSTMT hstmt) { LPSTMT lpstmt; RETCODE err; /* Get statement handle */ lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_SUCCESS; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; MyImpersonator im (lpstmt, "SQLMoreResults"); /* There is never a second result set */ err = SQLFreeStmt(hstmt, SQL_CLOSE); if ((err != SQL_SUCCESS) && (err != SQL_SUCCESS_WITH_INFO)) return err; return SQL_NO_DATA_FOUND; } /***************************************************************************/ RETCODE SQL_API SQLRowCount( HSTMT hstmt, SDWORD FAR *pcrow) { LPSTMT lpstmt; /* Get statement handle */ lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_SUCCESS; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; /* Return row count */ if (pcrow != NULL) *pcrow = lpstmt->cRowCount; return SQL_SUCCESS; } /***************************************************************************/ RETCODE SQL_API SQLSetPos( HSTMT hstmt, UWORD irow, UWORD fOption, UWORD fLock) { LPSTMT lpstmt; lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } /***************************************************************************/ RETCODE SQL_API SQLExtendedFetch( HSTMT hstmt, UWORD fFetchType, SDWORD irow, UDWORD FAR *pcrow, UWORD FAR *rgfRowStatus) { LPSTMT lpstmt; lpstmt = (LPSTMT) hstmt; lpstmt->errcode = ERR_NOTSUPPORTED; return SQL_ERROR; } /***************************************************************************/ RETCODE SQL_API SQLError( HENV henv, HDBC hdbc, HSTMT hstmt, UCHAR FAR *szSqlState, SDWORD FAR *pfNativeError, UCHAR FAR *szErrorMsg, SWORD cbErrorMsgMax, SWORD FAR *pcbErrorMsg) { LPENV lpenv; LPDBC lpdbc; LPSTMT lpstmt; RETCODE errcode; LPUSTR lpstr; UCHAR szTemplate[MAX_ERROR_LENGTH+1]; UCHAR szError[MAX_ERROR_LENGTH+1]; LPUSTR lpszISAMError; //To make guarentee Ole is initialized per thread COleInitializationManager myOleManager; //Initialize szTemplate[0] = 0; szError[0] = 0; /* If a HSTMT is specified, get error from HSTMT */ if (hstmt != SQL_NULL_HSTMT) { lpstmt = (LPSTMT) hstmt; errcode = lpstmt->errcode; lpszISAMError = (LPUSTR)lpstmt->szISAMError; lpstmt->errcode = ERR_SUCCESS; lpstr = (LPUSTR)lpstmt->szError; } /* Otherwise if a HDBC is specified, get error from HDBC */ else if (hdbc != SQL_NULL_HDBC) { lpdbc = (LPDBC) hdbc; errcode = lpdbc->errcode; lpszISAMError = (LPUSTR)lpdbc->szISAMError; lpdbc->errcode = ERR_SUCCESS; lpstr = NULL; } /* Otherwise if a HENV is specified, get error from HENV */ else if (henv != SQL_NULL_HENV) { lpenv = (LPENV) henv; errcode = lpenv->errcode; lpszISAMError = (LPUSTR)lpenv->szISAMError; lpenv->errcode = ERR_SUCCESS; lpstr = NULL; } /* Otherwise error */ else return SQL_INVALID_HANDLE; /* Return our internal error code */ if (pfNativeError != NULL) *pfNativeError = errcode; /* Success code? */ if (errcode == ERR_SUCCESS) { /* Yes. No message to return */ LoadString(s_hModule, errcode, (LPSTR)szError, MAX_ERROR_LENGTH+1); szError[SQL_SQLSTATE_SIZE] = '\0'; if (szSqlState != NULL) s_lstrcpy(szSqlState, szError); ReturnString(szErrorMsg, cbErrorMsgMax, pcbErrorMsg, (LPUSTR) (szError + SQL_SQLSTATE_SIZE + 1)); return SQL_NO_DATA_FOUND; } /* Load in error string */ if (errcode <= LAST_ISAM_ERROR_CODE) s_lstrcpy(szTemplate, lpszISAMError); else LoadString(s_hModule, errcode, (LPSTR)szTemplate, MAX_ERROR_LENGTH+1); szTemplate[SQL_SQLSTATE_SIZE] = '\0'; /* Return state */ if (szSqlState != NULL) { szSqlState[0] = 0; s_lstrcpy(szSqlState, szTemplate); } /* Return error message */ LPSTR lpTmp = (LPSTR)(szTemplate + SQL_SQLSTATE_SIZE + 1); wsprintf((LPSTR)szError, lpTmp, lpstr); errcode = ReturnString(szErrorMsg, cbErrorMsgMax, pcbErrorMsg, (LPUSTR)szError); if (errcode == ERR_DATATRUNCATED) return SQL_SUCCESS_WITH_INFO; return SQL_SUCCESS; } /***************************************************************************/