- 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:
parent
2e4ac7c244
commit
97744da0da
234
scsh/odbc/odbc.c
234
scsh/odbc/odbc.c
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue