scsh-odbc/c/odbc.h

583 lines
18 KiB
C
Raw Normal View History

2004-02-11 02:26:10 -05:00
#include "scheme48.h"
#include <stdio.h>
/* ODBC header files */
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
/* darwin 6.1 sql header files do not define SQLLEN */
#ifndef SQLLEN
#define SQLLEN SQLINTEGER
#endif
#define ERROR_MSG_BUFFER_LEN 255
/* turn debug messages on/off. */
#define ODBC_DEBUG_MSGS 1
#ifdef ODBC_DEBUG_MSGS
#define ODBC_DEBUG_DIAGREC(ht, h) odbc_debug_msgs(ht, h);
#else
#define ODBC_DEBUG_DIAGREC(ht, h) ;
#endif
#ifdef ODBC_DEBUG_MSGS
#define ODBC_DEBUG_PRINTF_1(str) printf(str);
#define ODBC_DEBUG_PRINTF_2(str, arg) printf(str, arg);
#define ODBC_DEBUG_PRINTF_3(str, arg1, arg2) printf(str, arg1, arg2);
#define ODBC_DEBUG_PRINTF_4(str, arg1, arg2, arg3) printf(str, arg1, arg2, arg3);
#define ODBC_DEBUG_PRINTF_5(str, arg1, arg2, arg3, arg4) printf(str, arg1, arg2, arg3, arg4);
#else
#define ODBC_DEBUG_PRINTF_1(str) ;
#define ODBC_DEBUG_PRINTF_2(str, arg) ;
#define ODBC_DEBUG_PRINTF_3(str, arg1, arg2) ;
#define ODBC_DEBUG_PRINTF_4(str, arg1, arg2, arg3) ;
#define ODBC_DEBUG_PRINTF_5(str, arg1, arg2, arg3, arg4) ;
#endif
/* import conditions */
static s48_value raise_odbc_api_version_mismatch_error = S48_FALSE;
#define RAISE_API_VERSION_MISMATCH(FUNNAME, APIVER, APIVERNEEDED) \
s48_call_scheme(S48_SHARED_BINDING_REF(raise_odbc_api_version_mismatch_error), \
3, s48_enter_string(FUNNAME), \
s48_enter_integer(APIVER), s48_enter_integer(APIVERNEEDED));
static s48_value raise_odbc_unknown_integer_type_error = S48_FALSE;
#define RAISE_UNKNOWN_INTEGER_TYPE_ERROR(FUNNAME, TYPEID) \
s48_call_scheme(S48_SHARED_BINDING_REF(raise_odbc_unknown_integer_type_error), \
2, s48_enter_string(FUNNAME), s48_enter_integer(TYPEID));
static s48_value raise_odbc_buffer_alloc_error = S48_FALSE;
#define RAISE_ODBC_BUFFER_ALLOC_ERROR(BUFFERLEN) \
s48_call_scheme(S48_SHARED_BINDING_REF(raise_odbc_buffer_alloc_error), \
1, s48_enter_integer(BUFFERLEN));
static s48_value raise_odbc_unknown_c_type_identifier_error = S48_FALSE;
#define RAISE_ODBC_UNKNOWN_C_TYPE_IDENTIFIER_ERROR(BUFFER, TYPEID) \
s48_call_scheme(S48_SHARED_BINDING_REF(raise_odbc_unknown_c_type_identifier_error), \
2, s48_enter_integer(BUFFER), s48_enter_integer(TYPEID));
static s48_value raise_odbc_bindcol_unbound_column_error = S48_FALSE;
#define RAISE_ODBC_BINDCOL_UNBOUND_COLUMN_ERROR(STMTHANDLE, COLUMNNO) \
s48_call_scheme(S48_SHARED_BINDING_REF(raise_odbc_bindcol_unbound_column_error), \
2, s48_enter_integer(STMTHANDLE), s48_enter_integer(COLUMNNO));
static s48_value raise_odbc_bindcol_rebinding_error = S48_FALSE;
#define RAISE_ODBC_BINDCOL_REBINDING_ERROR(TEXTMSG) \
s48_call_scheme(S48_SHARED_BINDING_REF(raise_odbc_bindcol_rebinding_error), \
1, s48_enter_string(TEXTMSG));
#define ODBC_ENTER_RECORD(FN, TN, RN) \
s48_value FN(TN p) \
{ \
s48_value rec = S48_FALSE; \
S48_DECLARE_GC_PROTECT(1); \
\
S48_GC_PROTECT_1(rec); \
rec = s48_make_record(RN); \
S48_RECORD_SET(rec, 0, s48_enter_integer((long) p)); \
S48_GC_UNPROTECT(); \
return rec; \
}
/* corresponds to environment-handle */
static s48_value odbc_environment_handle_record_type = S48_FALSE;
s48_value odbc_enter_environment_handle(SQLHENV h);
#define odbc_extract_environment_handle(h) \
((SQLHENV) s48_extract_integer \
(s48_checked_record_ref(h, 0, odbc_environment_handle_record_type)))
/* corresponds to connection-handle */
static s48_value odbc_connection_handle_record_type = S48_FALSE;
s48_value odbc_enter_connection_handle(SQLHDBC h);
#define odbc_extract_connection_handle(h) \
((SQLHDBC) s48_extract_integer \
(s48_checked_record_ref(h, 0, odbc_connection_handle_record_type)))
/* correspons to statement-handle */
static odbc_statement_handle_record_type = S48_FALSE;
s48_value odbc_enter_statement_handle(SQLHSTMT h);
#define odbc_extract_statement_handle(h) \
((SQLHSTMT) s48_extract_integer \
(s48_checked_record_ref(h, odbc_statement_handle_record_type)))
/* corresponds to sql-date */
static s48_value sql_date_record_type = S48_FALSE;
#define SR_SQL_DATE_YEAR 0
#define SR_SQL_DATE_MONTH 1
#define SR_SQL_DATE_DAY 2
/* corresponds to sql-time */
static s48_value sql_time_record_type = S48_FALSE;
#define SR_SQL_TIME_HOUR 0
#define SR_SQL_TIME_MINUTE 1
#define SR_SQL_TIME_SECOND 2
/* corresponds to sql-timestamp */
static s48_value sql_timestamp_record_type = S48_FALSE;
#define SR_SQL_TIMESTAMP_YEAR 0
#define SR_SQL_TIMESTAMP_MONTH 1
#define SR_SQL_TIMESTAMP_DAY 2
#define SR_SQL_TIMESTAMP_HOUR 3
#define SR_SQL_TIMESTAMP_MINUTE 4
#define SR_SQL_TIMESTAMP_SECOND 5
#define SR_SQL_TIMESTAMP_FRACTION 6
/* corresponds to sql-numeric */
#define SR_SQL_NUMERIC_PRECISION 0
#define SR_SQL_NUMERIC_SCALE 1
#define SR_SQL_NUMERIC_SIGN 2
#define SR_SQL_NUMERIC_VALUE 3
/* corresponds to odbc-column */
static s48_value odbc_column_record_type = S48_FALSE;
#define SR_ODBC_COLUMN_NAME 0
#define SR_ODBC_COLUMN_TYPE 1
#define SR_ODBC_COLUMN_SIZE 2
#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
/* 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
/* correspons to odbc-bind-parameter */
static s48_value odbc_bind_parameter_record_type = S48_FALSE;
#define SR_ODBC_BIND_PARAMETER_STATEMENT_HANDLE 0
#define SR_ODBC_BIND_PARAMETER_PARAM_NO 1
#define SR_ODBC_BIND_PARAMETER_INPUT_OUTPUT_TYPE 2
#define SR_ODBC_BIND_PARAMETER_VALUE_TYPE 3
#define SR_ODBC_BIND_PARAMETER_PARAMETER_TYPE 4
#define SR_ODBC_BIND_PARAMETER_COLUMN_SIZE 5
#define SR_ODBC_BIND_PARAMETER_DECIMAL_DIGITS 6
#define SR_ODBC_BIND_PARAMETER_PARAMETER_VALUE_INPUT_PTR 7
#define SR_ODBC_BIND_PARAMETER_PARAMETER_VALUE_OUTPUT_PTR 8
#define SR_ODBC_BIND_PARAMETER_BUFFER_LENGTH 9
/* stuff needed for SQLBindCol() */
/* correspons to bindcol-buffer */
static s48_value bindcol_buffer_record_type = S48_FALSE;
#define SR_BINDCOL_BUFFER_POINTER 0
#define SR_BINDCOL_BUFFER_LENGTH 1
#define SR_BINDCOL_BUFFER_TARGET_TYPE 2
typedef struct bindcol_col_rec *ColumnRecPtr;
typedef struct bindcol_col_rec {
SQLUSMALLINT col_no;
void *col_buffer;
SQLSMALLINT target_type;
SQLLEN buffer_len;
SQLLEN buffer_needed;
ColumnRecPtr next;
} ColumnRec;
typedef struct bindcol_stmt_rec *StmtRecPtr;
typedef struct bindcol_stmt_rec {
SQLHSTMT stmt_handle;
ColumnRecPtr col_recs;
StmtRecPtr next;
} StmtRec;
/* global variables */
StmtRecPtr global_bindcol_list = NULL;
/* helper functions needed for SQLBindCol() */
ColumnRecPtr bindcol_lookup_binding(SQLHSTMT stmt_handle, SQLUSMALLINT column_no);
s48_value bindcol_lookup_binding_scheme(s48_value stmt_handle, s48_value column_no);
void bindcol_bind_column(SQLHSTMT stmt_handle, SQLUSMALLINT column_no, ColumnRecPtr new_col);
void bindcol_unbind_colum(SQLHSTMT stmt_handle, SQLUSMALLINT column_no);
s48_value bindcol_finalize_bindcols(s48_value stmt_handle);
s48_value odbc_sql_bindcol(s48_value stmt_handle, s48_value column_no,
s48_value target_type, s48_value buffer_len);
/*
*
* PART 1
*
* Connecting to a data source
*
*/
/* Call SQLAllocHandle and get an environment handle. After that
* call odbc_set_environment to set the ODBC version */
s48_value odbc_alloc_environment_handle();
/* Given a valid environment handle get a connection handle */
s48_value odbc_alloc_connection_handle(s48_value env_handle);
/* Given a valid connection handle get a statement handle */
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 odbc_sql_browse_connect(s48_value conn_handle, s48_value conn_string);
/*
*
* PART 2
*
* Obtaining information about a driver and data source
*
*/
/* Returns a list of available data sources. */
s48_value odbc_sql_data_sources(s48_value env_handle);
/* Returns the list of installed drivers and their attributes. */
s48_value odbc_sql_drivers(s48_value env_handle);
/* Returns information about a specific driver and data source.
* (use if the information is an integer) */
s48_value odbc_sql_get_info_int(s48_value conn_handle, s48_value info_key);
/* Returns information about a specific driver and data source.
* (use if the information is a string) */
s48_value odbc_sql_get_info_string(s48_value conn_handle, s48_value info_key);
/* Returns supported driver functions. */
s48_value odbc_sql_get_func_exists(s48_value conn_handle, s48_value fun_id);
/* Returns information about supported data types. */
s48_value odbc_sql_get_type_info(s48_value stmt_handle, s48_value data_type);
/*
*
* PART 3
*
* Setting and retrieving driver attributes
*
*/
s48_value
odbc_sql_set_connect_attr_int(s48_value conn_handle,
s48_value attribute,
s48_value value,
s48_value pass_by_ref);
s48_value
odbc_sql_set_connect_attr_string(s48_value conn_handle,
s48_value attribute,
s48_value value);
s48_value
odbc_sql_get_connect_attr_string(s48_value conn_handle,
s48_value attribute);
s48_value
odbc_sql_get_connect_attr_int(s48_value conn_handle,
s48_value attribute);
s48_value
odbc_sql_set_env_attr_int(s48_value env_handle,
s48_value attribute,
s48_value value,
s48_value pass_by_ref);
s48_value
odbc_sql_get_env_attr_int(s48_value env_handle,
s48_value attribute,
s48_value value);
s48_value
odbc_sql_set_stmt_attr_int(s48_value stmt_handle,
s48_value attribute,
s48_value value,
s48_value pass_by_ref);
s48_value
odbc_sql_set_stmt_attr_string(s48_value stmt_handle,
s48_value attribute,
s48_value value);
s48_value
odbc_sql_get_stmt_attr_int(s48_value stmt_handle,
s48_value attribute);
s48_value
odbc_sql_get_stmt_attr_string(s48_value stmt_handle,
s48_value attribute);
/*
*
* 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);
/* 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);
/*
*
* PART 5
*
* Preparing SQL requests
*
*/
/* Prepare a SQL statement for execution */
s48_value odbc_sql_prepare(s48_value stmt_handle, s48_value stmt_txt);
s48_value odbc_sql_bind_parameter(s48_value bind_parameter_rec);
s48_value bind_parameter_set_buffer(s48_value bind_parameter_rec, s48_value value);
s48_value bind_parameter_get_buffer(s48_value bind_parameter_rec);
s48_value odbc_sql_get_cursor_name(s48_value stmt_handle);
s48_value odbc_sql_set_cursor_name(s48_value stmt_handle, s48_value cursorname);
/*
*
* PART 6
*
* Submitting requests
*
*/
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);
/* Returns the number of parameters in a statement */
s48_value odbc_sql_num_params(s48_value stmt_handle);
/*
*
* PART 7
*
* Retrieving results and information about results
*
*/
s48_value odbc_sql_row_count(s48_value stmt_handle);
s48_value odbc_sql_get_data(s48_value stmt_handle, s48_value column_number,
s48_value target_type);
/* Positions a cursor within a fetched block of data and allows an application
to refresh data in the rowset or to update or delete data in the result
set */
s48_value odbc_sql_set_pos(s48_value stmt_handle, s48_value row_number,
s48_value operation, s48_value lock_type);
/* Performs bulk insertions and bulk bookmark operations, including
update, delete, and fetch by bookmark. */
s48_value odbc_sql_bulk_operations(s48_value stmt_handle, s48_value operation);
/* Determines whether there are more result sets available and, if so,
initializes processing for the next result set */
s48_value odbc_sql_more_results(s48_value stmt_handle);
s48_value odbc_sql_fetch(s48_value stmt_handle);
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
*
* Obtaining information about the data source's
* system tables (catalog functions)
*
*/
/* Returns a list of columns and associated privileges for one or more tables */
s48_value odbc_sql_column_privileges(s48_value stmt_handle, s48_value catalog_name,
s48_value schema_name, s48_value table_name,
s48_value column_name);
/* Returns the list of column names in a specified table */
s48_value odbc_sql_columns(s48_value stmt_handle, s48_value catalog_name,
s48_value schema_name, s48_value table_name,
s48_value column_name);
/* Returns a list of columns names that make up foreign keys,
if the exist for a specified table */
s48_value odbc_sql_foreign_keys(s48_value stmt_handle, s48_value pk_catalog_name,
s48_value pk_schema_name, s48_value pk_table_name,
s48_value fk_catalog_name, s48_value fk_schema_name,
s48_value fk_table_name);
/* Returns the list of column names that make up the primary key for a table */
s48_value odbc_sql_primary_keys(s48_value stmt_handle, s48_value catalog_name,
s48_value schema_name, s48_value table_name);
/* Returns the list of input and output parameters, as well as the columns
that make up the result set for the specified procedures */
s48_value odbc_sql_procedure_columns(s48_value stmt_handle, s48_value catalog_name,
s48_value schema_name, s48_value proc_name,
s48_value column_name);
/* Returns the list of procedure names stored in a specific data source. */
s48_value odbc_sql_procedures(s48_value stmt_handle, s48_value catalog_name,
s48_value schema_name, s48_value proc_name);
/* Returns information about the optimal set of columns that uniquely identifies
a row in a specified table, or the columns that are automatically updated
when any value in the row is updated by a transaction */
s48_value odbc_sql_special_columns(s48_value stmt_handle, s48_value identifier_type,
s48_value catalog_name, s48_value schema_name,
s48_value table_name, s48_value scope,
s48_value nullable);
/* Returns statistics about a single table and the list of indexes associated
with the table */
s48_value odbc_sql_statistics(s48_value stmt_handle, s48_value catalog_name,
s48_value schema_name, s48_value table_name,
s48_value unique, s48_value reserved);
/* Returns a list of tables and the privileges associated with each table */
s48_value odbc_sql_table_privileges(s48_value stmt_handle, s48_value catalog_name,
s48_value schema_name, s48_value table_name);
/* Returns the list of table names stored in a specific data source */
s48_value odbc_sql_tables(s48_value stmt_handle, s48_value catalog_name,
s48_value schema_name, s48_value table_name,
s48_value table_type);
/*
*
* PART 9
*
* Terminating a statement
*
*/
/* Ends statement processing, discards pending resilt, and,
* optionally, frees all resources associated with the
* statement handle */
s48_value odbc_sql_free_statement(s48_value stmt_handle, s48_value option);
/* Closes a cursor that has been opened on a statement handle */
s48_value odbc_sql_close_cursor(s48_value stmt_handle);
/* Cancels an SQL statement */
s48_value odbc_sql_cancel(s48_value stmt_handle);
/* Commits or rolls back a transaction */
s48_value odbc_sql_endtran(s48_value handle_type, s48_value handle,
s48_value completion_type);
/*
*
* PART 10
*
* Terminating a connection
*
*/
/* Closes the connection */
s48_value odbc_sql_disconnect(s48_value conn_handle);
/* Free a handle */
s48_value odbc_sql_free_handle(s48_value handle_type, s48_value handle);
/*
*
* PART 11
*
* misc. functions
*
*/
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);
#endif
/* convert Scheme sql-date record to SQL_DATE_STRUCT */
void sql_date_record_to_struct(s48_value sql_date, SQL_DATE_STRUCT *ds);
/* convert SQL_DATE_STRUCT to Scheme sql-date record */
s48_value struct_to_sql_date_record(SQL_DATE_STRUCT *ds);
/* convert Scheme sql-time record to SQL_TIME_STRUCT */
void sql_time_record_to_struct(s48_value sql_time, SQL_TIME_STRUCT *ts);
/* convert SQL_TIME_STRUCT to Scheme sql-time record */
s48_value struct_to_sql_time_record(SQL_TIME_STRUCT *ts);
/* convert SQL_TIME_STRUCT to Scheme sql-time record */
s48_value struct_to_sql_time_record(SQL_TIME_STRUCT *ts);
/* convert Scheme sql-timestamp record to SQL_TIMESTAMP_STRUCT */
void sql_timestamp_record_to_struct(s48_value sql_timestamp,
SQL_TIMESTAMP_STRUCT *ts);
/* initial return value buffer size */
#define ODBC_RETVAL_BUFFER_DEFAULT_SIZE 255
static SQLUSMALLINT odbc_initial_retval_buffer_size = ODBC_RETVAL_BUFFER_DEFAULT_SIZE;
/* set initial return value buffer size */
s48_value odbc_set_initial_retval_buffer_size(s48_value nobytes);
/* get initial return value buffer size */
s48_value odbc_get_intial_retval_buffer_size();
void odbc_sql_alloc(void **buffer, size_t buffer_len, size_t type_len);
size_t sizeof_sql_c_type_identifier(SQLSMALLINT ctypeid);
s48_value buffer_to_s48_value(void *buffer, SQLSMALLINT ctypeid);
void s48_init_odbc(void);