- Support for SQLGetDescField() (odbc-sql-get-desc-field-int and

odbc-sql-get-desc-field-string)

- Support for SQLNativeSql() (odbc-sql-native-sql)
This commit is contained in:
eknauel 2002-09-05 14:23:52 +00:00
parent 2e4ac7c244
commit 97744da0da
3 changed files with 303 additions and 32 deletions

View File

@ -240,6 +240,13 @@ s48_value odbc_sql_data_sources(s48_value env_handle)
(first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT),
server_name, SQL_MAX_DSN_LENGTH+1, &server_name_len,
driver_descr, ODBC_MAX_DRIVER_NAME_LEN, &driver_descr_len);
/* FIXME */
if (driver_descr_len > ODBC_MAX_DRIVER_NAME_LEN - 1)
{
ODBC_RAISE_EXCEPTION("SQLDataSources(): string driver_descr to long");
return S48_UNSPECIFIC;
}
first = 0;
switch (retval)
@ -927,12 +934,121 @@ s48_value odbc_sql_get_stmt_attr_string(s48_value stmt_handle,
/*
*
* part 4
* PART 4
*
* Setting and retrieving descriptor fields
*
*/
/* Returns the value of a single descriptor field (for integers) */
s48_value odbc_sql_get_desc_field_int(s48_value desc_handle, s48_value rec_number,
s48_value field_id)
{
SQLHDESC dh;
SQLSMALLINT rn, fi;
SQLINTEGER value, buffer_len;
SQLRETURN retval;
ODBC_DEBUG_PRINTF("odbc_sql_get_desc_field_int\n");
dh = (SQLHDESC) s48_extract_integer(desc_handle);
rn = (SQLSMALLINT) s48_extract_integer(rec_number);
fi = (SQLSMALLINT) s48_extract_integer(field_id);
retval = SQLGetDescField(dh, rn, fi, (SQLPOINTER) &value,
sizeof(SQLINTEGER), &buffer_len);
switch (retval)
{
case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO:
{
switch (buffer_len)
{
case SQL_IS_INTEGER:
return s48_enter_integer((SQLINTEGER) value);
case SQL_IS_UINTEGER:
return s48_enter_integer((SQLUINTEGER) value);
case SQL_IS_SMALLINT:
return s48_enter_integer((SQLSMALLINT) value);
case SQL_IS_USMALLINT:
return s48_enter_integer((SQLUSMALLINT) value);
default:
{
ODBC_RAISE_EXCEPTION("SQLGetDescField returned unknown integer type");
break;
}
}
}
case SQL_NO_DATA:
{
return S48_FALSE;
}
case SQL_ERROR:
{
ODBC_RAISE_EXCEPTION("SQLGetDescField returned SQL_ERROR");
break;
}
case SQL_INVALID_HANDLE:
{
ODBC_RAISE_EXCEPTION("SQLGetDescField got invalid handle");
break;
}
default:
{
ODBC_RAISE_EXCEPTION("SQLGetDescField returned unknown error code");
break;
}
}
}
/* Returns the value of a single descriptor field (for strings/binary data) */
s48_value odbc_sql_get_desc_field_string(s48_value desc_handle, s48_value rec_number,
s48_value field_id)
{
SQLHDESC dh;
SQLSMALLINT rn, fi;
SQLCHAR value[ODBC_MAX_GET_DESC_FIELD_STR_LEN];
SQLINTEGER buffer_len;
SQLRETURN retval;
ODBC_DEBUG_PRINTF("odbc_sql_get_desc_field_string\n");
dh = (SQLHDESC) s48_extract_integer(desc_handle);
rn = (SQLSMALLINT) s48_extract_integer(rec_number);
fi = (SQLSMALLINT) s48_extract_integer(field_id);
retval = SQLGetDescField(dh, rn, fi, (SQLPOINTER) value,
(ODBC_MAX_GET_DESC_FIELD_STR_LEN - 1),
&buffer_len);
switch (retval)
{
case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO:
{
return s48_enter_string(value);
}
case SQL_NO_DATA:
{
return S48_FALSE;
}
case SQL_ERROR:
{
ODBC_RAISE_EXCEPTION("SQLGetDescField returned SQL_ERROR");
break;
}
case SQL_INVALID_HANDLE:
{
ODBC_RAISE_EXCEPTION("SQLGetDescField got invalid handle");
break;
}
default:
{
ODBC_RAISE_EXCEPTION("SQLGetDescField returned unknown error code");
break;
}
}
}
/*
*
* PART 5
@ -1394,6 +1510,102 @@ s48_value odbc_sql_execute_direct(s48_value stmt_handle,
}
}
/* Returns the text of an SQL statement as translated by the driver. */
s48_value odbc_sql_native_sql(s48_value conn_handle, s48_value stmt_txt)
{
SQLHDBC ch;
SQLCHAR *stmt_in, stmt_out[ODBC_MAX_NATIVE_SQL_STR_LEN];
SQLINTEGER buffer_len;
SQLRETURN retval;
ch = (SQLHDBC) s48_extract_integer(conn_handle);
stmt_in = (SQLCHAR *) s48_extract_string(stmt_txt);
ODBC_DEBUG_PRINTF("odbc_sql_native_sql\n");
retval = SQLNativeSql(ch, stmt_in, S48_STRING_LENGTH(stmt_txt),
stmt_out, ODBC_MAX_NATIVE_SQL_STR_LEN - 1,
&buffer_len);
switch (retval)
{
case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO:
{
return s48_enter_string(stmt_out);
}
case SQL_ERROR:
{
ODBC_RAISE_EXCEPTION("SQLNativeSql returned SQL_ERROR");
break;
}
case SQL_INVALID_HANDLE:
{
ODBC_RAISE_EXCEPTION("SQLNativeSql got invalid handle");
break;
}
default:
{
ODBC_RAISE_EXCEPTION("SQLNativeSql returned unknoen error code");
break;
}
}
}
/* Returns the description for a specific parameter in a statement */
s48_value odbc_sql_describe_param(s48_value stmt_handle, s48_value parameter_no)
{
SQLHSTMT sh;
SQLUSMALLINT pn;
SQLUINTEGER ps;
SQLSMALLINT dt, dd, n;
SQLRETURN retval;
s48_value result = S48_UNSPECIFIC;
S48_DECLARE_GC_PROTECT(1);
S48_GC_PROTECT_1(result);
ODBC_DEBUG_PRINTF("odbc_sql_describe_param\n");
sh = (SQLHSTMT) s48_extract_integer(stmt_handle);
pn = (SQLUSMALLINT) s48_extract_integer(parameter_no);
retval = SQLDescribeParam(sh, pn, &dt, &ps, &dd, &n);
switch (retval)
{
case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO:
{
result = s48_make_record(odbc_parameter_record_type);
S48_RECORD_SET(result, SR_ODBC_PARAMETER_TYPE, s48_enter_integer(dt));
S48_RECORD_SET(result, SR_ODBC_PARAMETER_SIZE, s48_enter_integer(ps));
S48_RECORD_SET(result, SR_ODBC_PARAMETER_DIGITS, s48_enter_integer(dd));
S48_RECORD_SET(result, SR_ODBC_PARAMETER_NULLABLE, s48_enter_integer(n));
return result;
}
case SQL_ERROR:
{
ODBC_RAISE_EXCEPTION("SQLDescribeParam returned SQL_ERROR");
break;
}
case SQL_INVALID_HANDLE:
{
ODBC_RAISE_EXCEPTION("SQLDescribeParam got invalid handle");
break;
}
case SQL_STILL_EXECUTING:
{
ODBC_RAISE_EXCEPTION("SQLDescribeParam returned SQL_STILL_EXECUTING. Not implemented");
break;
}
default:
{
ODBC_RAISE_EXCEPTION("SQLDescribeParam returned unknown error code");
break;
}
}
}
/*
*
* PART 7
@ -2847,6 +3059,9 @@ void s48_init_odbc(void)
S48_GC_PROTECT_GLOBAL(odbc_column_record_type);
odbc_column_record_type = s48_get_imported_binding("odbc-column");
S48_GC_PROTECT_GLOBAL(odbc_parameter_record_type);
odbc_column_record_type = s48_get_imported_binding("odbc-parameter");
/* PART 1 */
S48_EXPORT_FUNCTION(odbc_alloc_environment_handle);
S48_EXPORT_FUNCTION(odbc_alloc_connection_handle);
@ -2873,17 +3088,20 @@ void s48_init_odbc(void)
S48_EXPORT_FUNCTION(odbc_sql_get_stmt_attr_int);
S48_EXPORT_FUNCTION(odbc_sql_get_stmt_attr_string);
/* PART 4 */
/* PART 5 */
S48_EXPORT_FUNCTION(odbc_sql_prepare);
S48_EXPORT_FUNCTION(odbc_sql_bind_parameter_exec_out);
S48_EXPORT_FUNCTION(odbc_sql_get_cursor_name);
S48_EXPORT_FUNCTION(odbc_sql_set_cursor_name);
/* PART 4 */
S48_EXPORT_FUNCTION(odbc_sql_get_desc_field_int);
S48_EXPORT_FUNCTION(odbc_sql_get_desc_field_string);
/* PART 5 */
S48_EXPORT_FUNCTION(odbc_sql_prepare);
S48_EXPORT_FUNCTION(odbc_sql_bind_parameter_exec_out);
S48_EXPORT_FUNCTION(odbc_sql_get_cursor_name);
S48_EXPORT_FUNCTION(odbc_sql_set_cursor_name);
/* PART 6 */
S48_EXPORT_FUNCTION(odbc_sql_execute);
S48_EXPORT_FUNCTION(odbc_sql_execute_direct);
S48_EXPORT_FUNCTION(odbc_sql_native_sql);
/* PART 7 */
S48_EXPORT_FUNCTION(odbc_sql_row_count);

View File

@ -7,13 +7,17 @@
#include <sqlext.h>
#define ERROR_MSG_BUFFER_LEN 255
#define ODBC_MAX_DRIVER_NAME_LEN 255
#define ODBC_GET_INFO_MAX_LEN 255
#define ODBC_GET_CONNECT_ATTR_MAX_LEN 255
#define ODBC_GET_STMT_ATTR_MAX_LEN 255
#define ODBC_GET_DATA_MAX_STR_LEN 255
#define ODBC_DESCRIBE_COL_MAX_STR_LEN 255
#define ODBC_MAX_CURSOR_NAME_STR_LEN 255
#define ODBC_MAX_STR_LEN 255
#define ODBC_MAX_DRIVER_NAME_LEN ODBC_MAX_STR_LEN
#define ODBC_GET_INFO_MAX_LEN ODBC_MAX_STR_LEN
#define ODBC_GET_CONNECT_ATTR_MAX_LEN ODBC_MAX_STR_LEN
#define ODBC_GET_STMT_ATTR_MAX_LEN ODBC_MAX_STR_LEN
#define ODBC_GET_DATA_MAX_STR_LEN ODBC_MAX_STR_LEN
#define ODBC_DESCRIBE_COL_MAX_STR_LEN ODBC_MAX_STR_LEN
#define ODBC_MAX_CURSOR_NAME_STR_LEN ODBC_MAX_STR_LEN
#define ODBC_MAX_NATIVE_SQL_STR_LEN ODBC_MAX_STR_LEN
#define ODBC_MAX_GET_DESC_FIELD_STR_LEN ODBC_MAX_STR_LEN
#define ODBC_DEBUG_MSGS 1
@ -84,6 +88,14 @@ static s48_value odbc_diag_record_type = S48_FALSE;
#define SR_ODBC_DIAG_NATIVE_ERROR 1
#define SR_ODBC_DIAG_MESSAGE 2
/* corresponds to odbc-parameter */
static s48_value odbc_parameter_record_type = S48_FALSE;
#define SR_ODBC_PARAMETER_TYPE 0
#define SR_ODBC_PARAMETER_SIZE 1
#define SR_ODBC_PARAMETER_DIGITS 2
#define SR_ODBC_PARAMETER_NULLABLE 3
/*
*
* PART 1
@ -109,9 +121,9 @@ s48_value odbc_alloc_statement_handle(s48_value stmt_handle);
/* Connect to a server */
s48_value odbc_sql_connect(s48_value connection_handle,
s48_value ds_name,
s48_value user_name,
s48_value authentication);
s48_value ds_name,
s48_value user_name,
s48_value authentication);
/*
*
@ -193,6 +205,13 @@ s48_value odbc_sql_get_stmt_attr_string(s48_value stmt_handle,
*
*/
/* Returns the value of a single descriptor field (for integers) */
s48_value odbc_sql_get_desc_field_int(s48_value desc_handle, s48_value rec_number,
s48_value field_id);
/* Returns the value of a single descriptor field (for strings/binary data) */
s48_value odbc_sql_get_desc_field_string(s48_value desc_handle, s48_value rec_number,
s48_value field_id);
/*
*
@ -223,6 +242,12 @@ s48_value odbc_sql_execute(s48_value stmt_handle);
s48_value odbc_sql_execute_direct(s48_value stmt_handle, s48_value stmt);
/* Returns the text of an SQL statement as translated by the driver. */
s48_value odbc_sql_native_sql(s48_value conn_handle, s48_value stmt_txt);
/* Returns the description for a specific parameter in a statement */
s48_value odbc_sql_describe_param(s48_value stmt_handle, s48_value parameter_no);
/*
*
* PART 7

View File

@ -71,6 +71,16 @@
(define-exported-binding "odbc-column" :odbc-column)
(define-record-type odbc-parameter :odbc-parameter
(really-make-odbc-column type size digits nullable)
odbc-parameter?
(type odbc-parameter-type)
(size odbc-parameter-size)
(digits odbc-parameter-digits)
(nullable odbc-parameter-nullable))
(define-exported-binding "odbc-parameter" :odbc-parameter)
;;; options for SQLFreeStmt from sql.h
(define sql-disconnect-opt-close 0)
(define sql-disconnect-opt-drop 1)
@ -96,20 +106,20 @@
(define sql-type-c-bit -7)
;;; ODBC type identifier
(define sql-type-unknown 0)
(define sql-type-char 1)
(define sql-type-numeric 2)
(define sql-type-decimal 3)
(define sql-type-integer 4)
(define sql-type-smallint 5)
(define sql-type-float 6)
(define sql-type-real 7)
(define sql-type-double 8)
(define sql-type-datetime 9)
(define sql-type-varchar 12)
(define sql-type-date 91)
(define sql-type-time 92)
(define sql-type-timestamp 93)
(define sql-type-unknown 0) ; SQL_UNKNOWN_TYPE
(define sql-type-char 1) ; SQL_CHAR
(define sql-type-numeric 2) ; SQL_NUMERIC
(define sql-type-decimal 3) ; SQL_DECIMAL
(define sql-type-integer 4) ; SQL_INTEGER
(define sql-type-smallint 5) ; SQL_SMALLINT
(define sql-type-float 6) ; SQL_FLOAT
(define sql-type-real 7) ; SQL_REAL
(define sql-type-double 8) ; SQL_DOUBLE
(define sql-type-datetime 9) ; SQL_DATETIME
(define sql-type-varchar 12) ; SQL_VARCHAR
(define sql-type-date 91) ; SQL_TYPE_DATE
(define sql-type-time 92) ; SQL_TYPE_TIME
(define sql-type-timestamp 93) ; SQL_TYPE_TIMESTAMP
;;; ODBC function ids for SQLGetFunctions
(define sql-api-sqlallocconnect 1)
@ -602,6 +612,24 @@
;;; PART 4
(define (odbc-sql-get-desc-field-int desc-handle record-number field-id)
(check-arg descriptor-handle? desc-handle odbc-sql-get-desc-field-int)
(odbc-sql-get-desc-field-int-internal (descriptor-handle-handle desc-handle)
record-number field-id))
(import-lambda-definition odbc-sql-get-desc-field-int-internal
(desc-handle record-number field-id)
"odbc_sql_get_desc_field_int")
(define (odbc-sql-get-desc-field-string desc-handle record-number field-id)
(check-arg descriptor-handle? desc-handle odbc-sql-get-desc-field-string)
(odbc-sql-get-desc-field-string-internal (descriptor-handle-handle desc-handle)
record-number field-id))
(import-lambda-definition odbc-sql-get-desc-field-string-internal
(desc-handle record-number field-id)
"odbc_sql_get_desc_field_string")
;;; PART 5
(define (odbc-sql-prepare stmt-handle stmt-txt)