From a62bf26d5b0f5b2b7ea213e50312b1647f4ee5e7 Mon Sep 17 00:00:00 2001 From: eknauel Date: Mon, 2 Sep 2002 13:36:00 +0000 Subject: [PATCH] - support for SQLGetDiagRec - bugfixes fpr odbc_sql_data_sources and odbc_sql_drivers --- scsh/odbc/odbc.c | 135 ++++++++++++++++++++++++++++++++++++++--------- scsh/odbc/odbc.h | 9 ++++ 2 files changed, 118 insertions(+), 26 deletions(-) diff --git a/scsh/odbc/odbc.c b/scsh/odbc/odbc.c index 845fd8e..ca26a75 100644 --- a/scsh/odbc/odbc.c +++ b/scsh/odbc/odbc.c @@ -254,16 +254,18 @@ s48_value odbc_sql_data_sources(s48_value env_handle) SQLCHAR driver_descr[ODBC_MAX_DRIVER_NAME_LEN]; SQLSMALLINT driver_descr_len; s48_value result; - int first; + int first, more_items; + + S48_DECLARE_GC_PROTECT(1); + S48_GC_PROTECT_1(result); eh = (SQLHENV) s48_extract_integer(env_handle); ODBC_DEBUG_PRINTF("odbc_sql_data_sources\n"); - result = S48_NULL; - first = 1; + first = more_items = 1; - while (1) { + while (more_items) { retval = SQLDataSources(eh, (first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT), @@ -284,7 +286,8 @@ s48_value odbc_sql_data_sources(s48_value env_handle) } case SQL_NO_DATA: { - return result; + more_items = 0; + break; } case SQL_ERROR: { @@ -305,6 +308,9 @@ s48_value odbc_sql_data_sources(s48_value env_handle) } } } + + S48_GC_UNPROTECT(); + return result; } /* Returns the list of installed drivers and their attributes. */ @@ -318,15 +324,18 @@ s48_value odbc_sql_drivers(s48_value env_handle) SQLCHAR driver_attr[ODBC_MAX_DRIVER_NAME_LEN]; SQLSMALLINT driver_attr_len; s48_value result; - int first; + int first, more_items; + + S48_DECLARE_GC_PROTECT(1); + S48_GC_PROTECT_1(result); + + eh = (SQLHENV) s48_extract_integer(env_handle); ODBC_DEBUG_PRINTF("odbc_sql_drivers\n"); - - eh = (SQLHENV) s48_extract_integer(env_handle); result = S48_NULL; - first = 0; + first = more_items = 0; - while (1) { + while (more_items) { retval = SQLDrivers(eh, (SQLUSMALLINT) (first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT), @@ -347,7 +356,8 @@ s48_value odbc_sql_drivers(s48_value env_handle) } case SQL_NO_DATA: { - return result; + more_items = 0; + break; } case SQL_ERROR: { @@ -368,6 +378,9 @@ s48_value odbc_sql_drivers(s48_value env_handle) } } } + + S48_GC_UNPROTECT(); + return result; } /* Returns information about a specific driver and data source. @@ -2011,7 +2024,74 @@ s48_value odbc_sql_free_handle(s48_value handle_type, s48_value handle) * */ +s48_value odbc_sql_get_diag_recs(s48_value handle_type, s48_value handle) +{ + SQLSMALLINT ht; + SQLHANDLE h; + SQLCHAR sql_state[6]; + SQLINTEGER native_error; + SQLCHAR message[ERROR_MSG_BUFFER_LEN]; + SQLSMALLINT i, message_len; + SQLRETURN retval; + s48_value res; + S48_DECLARE_GC_PROTECT(2); + S48_GC_PROTECT_1(res); + + ht = (SQLSMALLINT) s48_extract_integer(handle_type); + h = (SQLHANDLE) s48_extract_integer(handle); + res = S48_NULL; + + ODBC_DEBUG_PRINTF("odbc_sql_get_diag_recs"); + + i = 1; + while (1) { + + s48_value diag_rec = s48_make_record(odbc_diag_record_type); + S48_GC_PROTECT_1(diag_rec); + + retval = SQLGetDiagRec(ht, h, i, + sql_state, &native_error, + message, sizeof(message), &message_len); + + switch (retval) + { + case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: + { + S48_RECORD_SET(diag_rec, SR_ODBC_DIAG_SQL_STATE, s48_enter_integer(sql_state)); + S48_RECORD_SET(diag_rec, SR_ODBC_DIAG_NATIVE_ERROR, s48_enter_string(native_error)); + S48_RECORD_SET(diag_rec, SR_ODBC_DIAG_MESSAGE, s48_enter_string(message)); + + res = s48_cons(diag_rec, res); + } + case SQL_NO_DATA: + { + break; + } + case SQL_ERROR: + { + ODBC_RAISE_EXCEPTION("SQLGetDiagRec returned SQL_ERROR"); + break; + } + case SQL_INVALID_HANDLE: + { + ODBC_RAISE_EXCEPTION("SQLGetDiagRec got invalid handle"); + break; + } + default: + { + ODBC_RAISE_EXCEPTION("SQLGetDiagRec returned unknown error code"); + break; + } + } + + i++; + } + + S48_GC_UNPROTECT(); + return res; +} + #ifdef ODBC_DEBUG_MSGS /* print detailed debug information */ @@ -2194,24 +2274,24 @@ void s48_init_odbc(void) S48_EXPORT_FUNCTION(odbc_sql_connect); /* PART 2 */ -/* S48_EXPORT_FUNCTION(odbc_sql_data_sources); */ -/* S48_EXPORT_FUNCTION(odbc_sql_drivers); */ -/* S48_EXPORT_FUNCTION(odbc_sql_get_info_int); */ -/* S48_EXPORT_FUNCTION(odbc_sql_get_info_string); */ + S48_EXPORT_FUNCTION(odbc_sql_data_sources); + S48_EXPORT_FUNCTION(odbc_sql_drivers); + S48_EXPORT_FUNCTION(odbc_sql_get_info_int); + S48_EXPORT_FUNCTION(odbc_sql_get_info_string); S48_EXPORT_FUNCTION(odbc_sql_get_func_exists); -/* S48_EXPORT_FUNCTION(odbc_sql_get_type_info); */ + S48_EXPORT_FUNCTION(odbc_sql_get_type_info); /* PART 3 */ -/* S48_EXPORT_FUNCTION(odbc_sql_set_connect_attr_int); */ -/* S48_EXPORT_FUNCTION(odbc_sql_set_connect_attr_string); */ -/* S48_EXPORT_FUNCTION(odbc_sql_get_connect_attr_string); */ -/* S48_EXPORT_FUNCTION(odbc_sql_get_connect_attr_int); */ -/* S48_EXPORT_FUNCTION(odbc_sql_set_env_attr_int); */ -/* S48_EXPORT_FUNCTION(odbc_sql_get_env_attr_int); */ -/* S48_EXPORT_FUNCTION(odbc_sql_set_stmt_attr_int); */ -/* S48_EXPORT_FUNCTION(odbc_sql_set_stmt_attr_string); */ -/* S48_EXPORT_FUNCTION(odbc_sql_get_stmt_attr_int); */ -/* S48_EXPORT_FUNCTION(odbc_sql_get_stmt_attr_string); */ + S48_EXPORT_FUNCTION(odbc_sql_set_connect_attr_int); + S48_EXPORT_FUNCTION(odbc_sql_set_connect_attr_string); + S48_EXPORT_FUNCTION(odbc_sql_get_connect_attr_string); + S48_EXPORT_FUNCTION(odbc_sql_get_connect_attr_int); + S48_EXPORT_FUNCTION(odbc_sql_set_env_attr_int); + S48_EXPORT_FUNCTION(odbc_sql_get_env_attr_int); + S48_EXPORT_FUNCTION(odbc_sql_set_stmt_attr_int); + S48_EXPORT_FUNCTION(odbc_sql_set_stmt_attr_string); + S48_EXPORT_FUNCTION(odbc_sql_get_stmt_attr_int); + S48_EXPORT_FUNCTION(odbc_sql_get_stmt_attr_string); /* PART 4 */ @@ -2240,4 +2320,7 @@ void s48_init_odbc(void) /* PART 10 */ S48_EXPORT_FUNCTION(odbc_sql_disconnect); S48_EXPORT_FUNCTION(odbc_sql_free_handle); + + /* PART 11 */ + S48_EXPORT_FUNCTION(odbc_sql_get_diag_recs); } diff --git a/scsh/odbc/odbc.h b/scsh/odbc/odbc.h index 2982364..2f3bc55 100644 --- a/scsh/odbc/odbc.h +++ b/scsh/odbc/odbc.h @@ -76,6 +76,13 @@ static s48_value odbc_column_record_type = S48_FALSE; #define SR_ODBC_COLUMN_DIGITS 3 #define SR_ODBC_COLUMN_NULLABLE 4 +/* corresponds to odbc-diag */ +static s48_value odbc_diag_record_type = S48_FALSE; + +#define SR_ODBC_DIAG_SQL_STATE 0 +#define SR_ODBC_DIAG_NATIVE_ERROR 1 +#define SR_ODBC_DIAG_MESSAGE 2 + /* * * PART 1 @@ -286,6 +293,8 @@ s48_value odbc_sql_free_handle(s48_value handle_type, s48_value handle); * */ +s48_value odbc_sql_get_diag_recs(s48_value handle_type, s48_value handle); + #ifdef ODBC_DEBUG_MSGS /* print detailed debug information */ void odbc_debug_msgs(SQLSMALLINT handle_type, SQLHANDLE handle);