ODBC GetData: Add support for a few fCType codes

This commit is contained in:
Nirgal Vourgère
2013-07-08 17:06:06 +02:00
parent 06ea2517e9
commit 3bdff87b9a
2 changed files with 99 additions and 18 deletions

View File

@@ -58,9 +58,9 @@ struct _hstmt {
struct _sql_bind_info { struct _sql_bind_info {
int column_number; int column_number;
int column_bindtype; int column_bindtype; /* type/conversion required */
int column_bindlen; int column_bindlen; /* size of varaddr buffer */
int *column_lenbind; int *column_lenbind; /* where to store length of varaddr used */
char *varaddr; char *varaddr;
struct _sql_bind_info *next; struct _sql_bind_info *next;
}; };

View File

@@ -1595,7 +1595,7 @@ static SQLRETURN SQL_API _SQLGetData(
MdbSQLColumn *sqlcol; MdbSQLColumn *sqlcol;
MdbColumn *col; MdbColumn *col;
MdbTableDef *table; MdbTableDef *table;
int i; int i, intValue;
TRACE("_SQLGetData"); TRACE("_SQLGetData");
stmt = (struct _hstmt *) hstmt; stmt = (struct _hstmt *) hstmt;
@@ -1648,21 +1648,96 @@ static SQLRETURN SQL_API _SQLGetData(
return SQL_SUCCESS; return SQL_SUCCESS;
} }
if (fCType==SQL_ARD_TYPE) {
// Get _sql_bind_info
struct _sql_bind_info *cur;
for (cur = stmt->bind_head; cur; cur=cur->next) {
if (cur->column_number == icol) {
fCType = cur->column_bindtype;
goto found_bound_type;
}
}
strcpy(sqlState, "07009");
return SQL_ERROR;
}
found_bound_type:
if (fCType==SQL_C_DEFAULT)
fCType = _odbc_get_client_type(col);
if (fCType == SQL_C_CHAR)
goto to_c_char;
switch(col->col_type) { switch(col->col_type) {
case MDB_BYTE: case MDB_BYTE:
*(SQLSMALLINT*)rgbValue = mdb_get_byte(mdb->pg_buf, col->cur_value_start); intValue = (int)mdb_get_byte(mdb->pg_buf, col->cur_value_start);
if (pcbValue) goto to_integer_type;
*pcbValue = sizeof(SQLSMALLINT);
break;
case MDB_INT: case MDB_INT:
*(SQLSMALLINT*)rgbValue = (SQLSMALLINT)mdb_get_int16(mdb->pg_buf, col->cur_value_start); intValue = mdb_get_int16(mdb->pg_buf, col->cur_value_start);
if (pcbValue) goto to_integer_type;
*pcbValue = sizeof(SQLSMALLINT);
break;
case MDB_LONGINT: case MDB_LONGINT:
*(SQLINTEGER*)rgbValue = mdb_get_int32(mdb->pg_buf, col->cur_value_start); intValue = mdb_get_int32(mdb->pg_buf, col->cur_value_start);
if (pcbValue) goto to_integer_type;
*pcbValue = sizeof(SQLINTEGER); to_integer_type:
switch (fCType) {
case SQL_C_UTINYINT:
if (intValue<0 || intValue>UCHAR_MAX) {
strcpy(sqlState, "22003"); // Numeric value out of range
return SQL_ERROR;
}
*(SQLCHAR*)rgbValue = (SQLCHAR)intValue;
if (pcbValue)
*pcbValue = sizeof(SQLCHAR);
break;
case SQL_C_TINYINT:
case SQL_C_STINYINT:
if (intValue<SCHAR_MIN || intValue>SCHAR_MAX) {
strcpy(sqlState, "22003"); // Numeric value out of range
return SQL_ERROR;
}
*(SQLSCHAR*)rgbValue = (SQLSCHAR)intValue;
if (pcbValue)
*pcbValue = sizeof(SQLSCHAR);
break;
case SQL_C_USHORT:
case SQL_C_SHORT:
if (intValue<0 || intValue>USHRT_MAX) {
strcpy(sqlState, "22003"); // Numeric value out of range
return SQL_ERROR;
}
*(SQLSMALLINT*)rgbValue = (SQLSMALLINT)intValue;
if (pcbValue)
*pcbValue = sizeof(SQLSMALLINT);
break;
case SQL_C_SSHORT:
if (intValue<SHRT_MIN || intValue>SHRT_MAX) {
strcpy(sqlState, "22003"); // Numeric value out of range
return SQL_ERROR;
}
*(SQLSMALLINT*)rgbValue = (SQLSMALLINT)intValue;
if (pcbValue)
*pcbValue = sizeof(SQLSMALLINT);
break;
case SQL_C_ULONG:
if (intValue<0 || intValue>UINT_MAX) {
strcpy(sqlState, "22003"); // Numeric value out of range
return SQL_ERROR;
}
*(SQLUINTEGER*)rgbValue = (SQLINTEGER)intValue;
if (pcbValue)
*pcbValue = sizeof(SQLINTEGER);
break;
case SQL_C_LONG:
case SQL_C_SLONG:
if (intValue<LONG_MIN || intValue>LONG_MAX) {
strcpy(sqlState, "22003"); // Numeric value out of range
return SQL_ERROR;
}
*(SQLINTEGER*)rgbValue = intValue;
if (pcbValue)
*pcbValue = sizeof(SQLINTEGER);
break;
default:
strcpy(sqlState, "HYC00"); // Not implemented
return SQL_ERROR;
}
break; break;
// case MDB_MONEY: TODO // case MDB_MONEY: TODO
case MDB_FLOAT: case MDB_FLOAT:
@@ -1675,8 +1750,10 @@ static SQLRETURN SQL_API _SQLGetData(
if (pcbValue) if (pcbValue)
*pcbValue = sizeof(double); *pcbValue = sizeof(double);
break; break;
case MDB_DATETIME: ;
#if ODBCVER >= 0x0300 #if ODBCVER >= 0x0300
// returns text if old odbc
case MDB_DATETIME:
{
struct tm tmp_t; struct tm tmp_t;
mdb_date_to_tm(mdb_get_double(mdb->pg_buf, col->cur_value_start), &tmp_t); mdb_date_to_tm(mdb_get_double(mdb->pg_buf, col->cur_value_start), &tmp_t);
@@ -1704,8 +1781,11 @@ static SQLRETURN SQL_API _SQLGetData(
*pcbValue = sizeof(TIMESTAMP_STRUCT); *pcbValue = sizeof(TIMESTAMP_STRUCT);
} }
break; break;
#endif // returns text if old odbc }
default: ; #endif
default: /* FIXME here we assume fCType == SQL_C_CHAR */
to_c_char:
{
char *str = mdb_col_to_string(mdb, mdb->pg_buf, char *str = mdb_col_to_string(mdb, mdb->pg_buf,
col->cur_value_start, col->col_type, col->cur_value_len); col->cur_value_start, col->col_type, col->cur_value_len);
int len = strlen(str); int len = strlen(str);
@@ -1736,6 +1816,7 @@ static SQLRETURN SQL_API _SQLGetData(
stmt->pos += len - stmt->pos; stmt->pos += len - stmt->pos;
free(str); free(str);
break; break;
}
} }
return SQL_SUCCESS; return SQL_SUCCESS;
} }