mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-18 18:22:07 +08:00
ODBC GetData: Add support for a few fCType codes
This commit is contained in:
@@ -58,9 +58,9 @@ struct _hstmt {
|
||||
|
||||
struct _sql_bind_info {
|
||||
int column_number;
|
||||
int column_bindtype;
|
||||
int column_bindlen;
|
||||
int *column_lenbind;
|
||||
int column_bindtype; /* type/conversion required */
|
||||
int column_bindlen; /* size of varaddr buffer */
|
||||
int *column_lenbind; /* where to store length of varaddr used */
|
||||
char *varaddr;
|
||||
struct _sql_bind_info *next;
|
||||
};
|
||||
|
103
src/odbc/odbc.c
103
src/odbc/odbc.c
@@ -1595,7 +1595,7 @@ static SQLRETURN SQL_API _SQLGetData(
|
||||
MdbSQLColumn *sqlcol;
|
||||
MdbColumn *col;
|
||||
MdbTableDef *table;
|
||||
int i;
|
||||
int i, intValue;
|
||||
|
||||
TRACE("_SQLGetData");
|
||||
stmt = (struct _hstmt *) hstmt;
|
||||
@@ -1648,22 +1648,97 @@ static SQLRETURN SQL_API _SQLGetData(
|
||||
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) {
|
||||
case MDB_BYTE:
|
||||
*(SQLSMALLINT*)rgbValue = mdb_get_byte(mdb->pg_buf, col->cur_value_start);
|
||||
if (pcbValue)
|
||||
*pcbValue = sizeof(SQLSMALLINT);
|
||||
break;
|
||||
intValue = (int)mdb_get_byte(mdb->pg_buf, col->cur_value_start);
|
||||
goto to_integer_type;
|
||||
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);
|
||||
goto to_integer_type;
|
||||
case MDB_LONGINT:
|
||||
intValue = mdb_get_int32(mdb->pg_buf, col->cur_value_start);
|
||||
goto to_integer_type;
|
||||
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 MDB_LONGINT:
|
||||
*(SQLINTEGER*)rgbValue = mdb_get_int32(mdb->pg_buf, col->cur_value_start);
|
||||
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;
|
||||
// case MDB_MONEY: TODO
|
||||
case MDB_FLOAT:
|
||||
*(float*)rgbValue = mdb_get_single(mdb->pg_buf, col->cur_value_start);
|
||||
@@ -1675,8 +1750,10 @@ static SQLRETURN SQL_API _SQLGetData(
|
||||
if (pcbValue)
|
||||
*pcbValue = sizeof(double);
|
||||
break;
|
||||
case MDB_DATETIME: ;
|
||||
#if ODBCVER >= 0x0300
|
||||
// returns text if old odbc
|
||||
case MDB_DATETIME:
|
||||
{
|
||||
struct tm 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);
|
||||
}
|
||||
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,
|
||||
col->cur_value_start, col->col_type, col->cur_value_len);
|
||||
int len = strlen(str);
|
||||
@@ -1737,6 +1817,7 @@ static SQLRETURN SQL_API _SQLGetData(
|
||||
free(str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user