windows-nt/Source/XPSP1/NT/admin/wmi/wbem/adapters/odbc/results.cpp
2020-09-26 16:20:57 +08:00

3498 lines
109 KiB
C++

/***************************************************************************/
/* 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 <comdef.h>
//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;
}
/***************************************************************************/