diff --git a/scsh/odbc/odbc.c b/scsh/odbc/odbc.c index 05c4c82..739bb4c 100644 --- a/scsh/odbc/odbc.c +++ b/scsh/odbc/odbc.c @@ -1707,7 +1707,47 @@ s48_value odbc_sql_describe_param(s48_value stmt_handle, s48_value parameter_no) } } } - + +/* Returns the number of parameters in a statement */ +s48_value odbc_sql_num_params(s48_value stmt_handle) +{ + SQLHSTMT sh; + SQLSMALLINT params; + SQLRETURN retval; + + ODBC_DEBUG_PRINTF("odbc_sql_num_params\n"); + + sh = (SQLHSTMT) s48_extract_integer(stmt_handle); + retval = SQLNumParams(sh, ¶ms); + + switch (retval) + { + case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: + { + return s48_enter_integer(params); + } + case SQL_STILL_EXECUTING: + { + ODBC_RAISE_EXCEPTION("SQLNumParams returned SQL_STILL_EXECUTING. Not implemented"); + break; + } + case SQL_ERROR: + { + ODBC_RAISE_EXCEPTION("SQLNumParams returned SQL_ERROR"); + break; + } + case SQL_INVALID_HANDLE: + { + ODBC_RAISE_EXCEPTION("SQLNumParams got invalid handle"); + break; + } + default: + { + ODBC_RAISE_EXCEPTION("SQLNumParams returned unknown error code"); + break; + } + } +} /* * @@ -2152,6 +2192,74 @@ s48_value odbc_sql_describe_col(s48_value stmt_handle, s48_value column_number) } } +/* Describes attributes of a column in the result set */ +s48_value odbc_sql_col_attribute(s48_value stmt_handle, s48_value column_number, + s48_value field_id) +{ + SQLHSTMT sh; + SQLUSMALLINT cn, fi; + SQLCHAR *buffer = NULL; + SQLSMALLINT buffer_len, buffer_needed; + SQLINTEGER intbuffer; + SQLRETURN retval; + s48_value res_string, res; + + S48_DECLARE_GC_PROTECT(1); + S48_GC_PROTECT_1(res); + + ODBC_DEBUG_PRINTF("odbc_sql_col_attribute\n"); + + sh = (SQLHSTMT) s48_extract_integer(stmt_handle); + cn = (SQLUSMALLINT) s48_extract_integer(column_number); + fi = (SQLUSMALLINT) s48_extract_integer(field_id); + + buffer_len = ODBC_RETVAL_BUFFER_INITIAL_SIZE; + for (;;) + { + odbc_sql_alloc((void **) &buffer, buffer_len, sizeof(SQLCHAR)); + + retval = SQLColAttribute(sh, cn, fi, + buffer, buffer_len, &buffer_needed, + &intbuffer); + + if (ODBC_SUCCESS(retval) && (buffer_needed > buffer_len)) + buffer_len = buffer_needed+1; + else + break; + } + + switch (retval) + { + case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: + { + res = s48_cons(s48_enter_string(buffer), s48_enter_integer(intbuffer)); + free(buffer); + S48_GC_UNPROTECT(); + return res; + } + case SQL_STILL_EXECUTING: + { + ODBC_RAISE_EXCEPTION("SQLColAttribute returned SQL_STILL_EXECUTING. Not implemented yet."); + break; + } + case SQL_ERROR: + { + ODBC_RAISE_EXCEPTION("SQLColAttribute returned SQL_ERROR"); + break; + } + case SQL_INVALID_HANDLE: + { + ODBC_RAISE_EXCEPTION("SQLColAttribute got invalid handle"); + break; + } + default: + { + ODBC_RAISE_EXCEPTION("SQLColAttribute returned unknown error code"); + break; + } + } +} + /* * * PART 8 @@ -3259,6 +3367,8 @@ void s48_init_odbc(void) S48_EXPORT_FUNCTION(odbc_sql_execute); S48_EXPORT_FUNCTION(odbc_sql_execute_direct); S48_EXPORT_FUNCTION(odbc_sql_native_sql); + S48_EXPORT_FUNCTION(odbc_sql_describe_param); + S48_EXPORT_FUNCTION(odbc_sql_num_params); /* PART 7 */ S48_EXPORT_FUNCTION(odbc_sql_row_count); @@ -3269,6 +3379,7 @@ void s48_init_odbc(void) S48_EXPORT_FUNCTION(odbc_sql_fetch); S48_EXPORT_FUNCTION(odbc_sql_num_result_cols); S48_EXPORT_FUNCTION(odbc_sql_describe_col); + S48_EXPORT_FUNCTION(odbc_sql_col_attribute); /* PART 8 */ S48_EXPORT_FUNCTION(odbc_sql_column_privileges); diff --git a/scsh/odbc/odbc.h b/scsh/odbc/odbc.h index 27961ec..e40b7f8 100644 --- a/scsh/odbc/odbc.h +++ b/scsh/odbc/odbc.h @@ -253,6 +253,10 @@ 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); +/* Returns the number of parameters in a statement */ +s48_value odbc_sql_num_params(s48_value stmt_handle); + + /* * * PART 7 @@ -289,6 +293,10 @@ s48_value odbc_sql_num_result_cols(s48_value stmt_handle); s48_value odbc_sql_describe_col(s48_value stmt_handle, s48_value column_number); +/* Describes attributes of a column in the result set */ +s48_value odbc_sql_col_attribute(s48_value stmt_handle, s48_value column_number, + s48_value field_id); + /* * * PART 8 diff --git a/scsh/odbc/odbc.scm b/scsh/odbc/odbc.scm index 9e9f5b3..a39eea8 100644 --- a/scsh/odbc/odbc.scm +++ b/scsh/odbc/odbc.scm @@ -694,6 +694,23 @@ (conn-handle stmt-txt) "odbc_sql_native_sql") +(define (odbc-sql-describe-param stmt-handle parameter-no) + (check-arg statement-handle? stmt-handle odbc-sql-describe-param) + (odbc-sql-describe-param-internal (statement-handle-handle stmt-handle) + parameter-no)) + +(import-lambda-definition odbc-sql-describe-param-internal + (stmt-handle parameter-no) + "odbc_sql_describe_param") + +(define (odbc-sql-num-params stmt-handle) + (check-arg statement-handle? stmt-handle odbc-sql-num-params) + (odbc-sql-num-params-internal (statement-handle-handle stmt-handle))) + +(import-lambda-definition odbc-sql-num-params-internal + (stmt-handle) + "odbc_sql_num_params") + ;;; PART 7 (define (odbc-sql-row-count stmt-handle) @@ -895,6 +912,19 @@ (stmt-handle column-number) "odbc_sql_describe_col") +(define (odbc-sql-col-attribute stmt-handle column-number field-id) + (check-arg statement-handle? stmt-handle odbc-sql-col-attribute) + (let ((pair (odbc-sql-col-attribute-internal + (statement-handle-handle stmt-handle) + column-number field-id))) + (if (zero? (string-length (car pair))) + (cdr pair) + (car pair)))) + +(import-lambda-definition odbc-sql-col-attribute-internal + (stmt-handle column-number field-id) + "odbc_sql_col_attribute") + ;;; PART 10 (define (odbc-sql-disconnect conn-handle)