From: Michael N. <mne...@us...> - 2002-09-05 09:57:17
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/ext/db2 In directory usw-pr-cvs1:/tmp/cvs-serv2947/ruby-db2/ext/db2 Added Files: constants.h db2cli.c extconf.rb Log Message: initial import from local CVS repository --- NEW FILE: constants.h --- rb_define_const(mDB2CLI, "SQL_SUCCESS", INT2NUM(SQL_SUCCESS)); rb_define_const(mDB2CLI, "SQL_SUCCESS_WITH_INFO", INT2NUM(SQL_SUCCESS_WITH_INFO)); rb_define_const(mDB2CLI, "SQL_INVALID_HANDLE", INT2NUM(SQL_INVALID_HANDLE)); rb_define_const(mDB2CLI, "SQL_STILL_EXECUTING", INT2NUM(SQL_STILL_EXECUTING)); rb_define_const(mDB2CLI, "SQL_ERROR", INT2NUM(SQL_ERROR)); rb_define_const(mDB2CLI, "SQL_NO_DATA_FOUND", INT2NUM(SQL_NO_DATA_FOUND)); rb_define_const(mDB2CLI, "SQL_NULL_DATA", INT2NUM(SQL_NULL_DATA)); rb_define_const(mDB2CLI, "SQL_HANDLE_ENV", INT2NUM(SQL_HANDLE_ENV)); rb_define_const(mDB2CLI, "SQL_HANDLE_DBC", INT2NUM(SQL_HANDLE_DBC)); rb_define_const(mDB2CLI, "SQL_HANDLE_STMT", INT2NUM(SQL_HANDLE_STMT)); rb_define_const(mDB2CLI, "SQL_HANDLE_DESC", INT2NUM(SQL_HANDLE_DESC)); rb_define_const(mDB2CLI, "SQL_NULL_HANDLE", INT2NUM(SQL_NULL_HANDLE)); rb_define_const(mDB2CLI, "SQL_NULL_HENV", INT2NUM(SQL_NULL_HENV)); rb_define_const(mDB2CLI, "SQL_NULL_HDBC", INT2NUM(SQL_NULL_HDBC)); rb_define_const(mDB2CLI, "SQL_NULL_HSTMT", INT2NUM(SQL_NULL_HSTMT)); rb_define_const(mDB2CLI, "SQL_NULL_HDESC", INT2NUM(SQL_NULL_HDESC)); rb_define_const(mDB2CLI, "SQL_NO_NULLS", INT2NUM(SQL_NO_NULLS)); rb_define_const(mDB2CLI, "SQL_NULLABLE", INT2NUM(SQL_NULLABLE)); rb_define_const(mDB2CLI, "SQL_COMMIT", INT2NUM(SQL_COMMIT)); rb_define_const(mDB2CLI, "SQL_ROLLBACK", INT2NUM(SQL_ROLLBACK)); rb_define_const(mDB2CLI, "SQL_TRUE", INT2NUM(SQL_TRUE)); rb_define_const(mDB2CLI, "SQL_FALSE", INT2NUM(SQL_FALSE)); rb_define_const(mDB2CLI, "SQL_MAX_DSN_LENGTH", INT2NUM(SQL_MAX_DSN_LENGTH)); rb_define_const(mDB2CLI, "SQL_BIGINT", INT2NUM(SQL_BIGINT)); rb_define_const(mDB2CLI, "SQL_BLOB", INT2NUM(SQL_BLOB)); rb_define_const(mDB2CLI, "SQL_BLOB_LOCATOR", INT2NUM(SQL_BLOB_LOCATOR)); rb_define_const(mDB2CLI, "SQL_CHAR", INT2NUM(SQL_CHAR)); rb_define_const(mDB2CLI, "SQL_BINARY", INT2NUM(SQL_BINARY)); rb_define_const(mDB2CLI, "SQL_CLOB", INT2NUM(SQL_CLOB)); rb_define_const(mDB2CLI, "SQL_CLOB_LOCATOR", INT2NUM(SQL_CLOB_LOCATOR)); rb_define_const(mDB2CLI, "SQL_TYPE_DATE", INT2NUM(SQL_TYPE_DATE)); rb_define_const(mDB2CLI, "SQL_DBCLOB", INT2NUM(SQL_DBCLOB)); rb_define_const(mDB2CLI, "SQL_DBCLOB_LOCATOR", INT2NUM(SQL_DBCLOB_LOCATOR)); rb_define_const(mDB2CLI, "SQL_DECIMAL", INT2NUM(SQL_DECIMAL)); rb_define_const(mDB2CLI, "SQL_DOUBLE", INT2NUM(SQL_DOUBLE)); rb_define_const(mDB2CLI, "SQL_FLOAT", INT2NUM(SQL_FLOAT)); rb_define_const(mDB2CLI, "SQL_GRAPHIC", INT2NUM(SQL_GRAPHIC)); rb_define_const(mDB2CLI, "SQL_INTEGER", INT2NUM(SQL_INTEGER)); rb_define_const(mDB2CLI, "SQL_LONGVARCHAR", INT2NUM(SQL_LONGVARCHAR)); rb_define_const(mDB2CLI, "SQL_LONGVARBINARY", INT2NUM(SQL_LONGVARBINARY)); rb_define_const(mDB2CLI, "SQL_LONGVARGRAPHIC", INT2NUM(SQL_LONGVARGRAPHIC)); rb_define_const(mDB2CLI, "SQL_NUMERIC", INT2NUM(SQL_NUMERIC)); rb_define_const(mDB2CLI, "SQL_REAL", INT2NUM(SQL_REAL)); rb_define_const(mDB2CLI, "SQL_SMALLINT", INT2NUM(SQL_SMALLINT)); rb_define_const(mDB2CLI, "SQL_TYPE_TIME", INT2NUM(SQL_TYPE_TIME)); rb_define_const(mDB2CLI, "SQL_TYPE_TIMESTAMP", INT2NUM(SQL_TYPE_TIMESTAMP)); rb_define_const(mDB2CLI, "SQL_VARCHAR", INT2NUM(SQL_VARCHAR)); rb_define_const(mDB2CLI, "SQL_VARBINARY", INT2NUM(SQL_VARBINARY)); rb_define_const(mDB2CLI, "SQL_VARGRAPHIC", INT2NUM(SQL_VARGRAPHIC)); rb_define_const(mDB2CLI, "SQL_FETCH_NEXT", INT2NUM(SQL_FETCH_NEXT)); rb_define_const(mDB2CLI, "SQL_FETCH_PRIOR", INT2NUM(SQL_FETCH_PRIOR)); rb_define_const(mDB2CLI, "SQL_FETCH_RELATIVE", INT2NUM(SQL_FETCH_RELATIVE)); rb_define_const(mDB2CLI, "SQL_FETCH_ABSOLUTE", INT2NUM(SQL_FETCH_ABSOLUTE)); rb_define_const(mDB2CLI, "SQL_FETCH_FIRST", INT2NUM(SQL_FETCH_FIRST)); rb_define_const(mDB2CLI, "SQL_FETCH_LAST", INT2NUM(SQL_FETCH_LAST)); rb_define_const(mDB2CLI, "SQL_FETCH_BOOKMARK", INT2NUM(SQL_FETCH_BOOKMARK)); rb_define_const(mDB2CLI, "SQL_CLOSE", INT2NUM(SQL_CLOSE)); rb_define_const(mDB2CLI, "SQL_DROP", INT2NUM(SQL_DROP)); rb_define_const(mDB2CLI, "SQL_UNBIND", INT2NUM(SQL_UNBIND)); rb_define_const(mDB2CLI, "SQL_RESET_PARAMS", INT2NUM(SQL_RESET_PARAMS)); rb_define_const(mDB2CLI, "SQL_DESC_AUTO_UNIQUE_VALUE", INT2NUM(SQL_DESC_AUTO_UNIQUE_VALUE)); rb_define_const(mDB2CLI, "SQL_DESC_CASE_SENSITIVE", INT2NUM(SQL_DESC_CASE_SENSITIVE)); rb_define_const(mDB2CLI, "SQL_DESC_CATALOG_NAME", INT2NUM(SQL_DESC_CATALOG_NAME)); rb_define_const(mDB2CLI, "SQL_DESC_COUNT", INT2NUM(SQL_DESC_COUNT)); rb_define_const(mDB2CLI, "SQL_DESC_DISPLAY_SIZE", INT2NUM(SQL_DESC_DISPLAY_SIZE)); rb_define_const(mDB2CLI, "SQL_DESC_LABEL", INT2NUM(SQL_DESC_LABEL)); rb_define_const(mDB2CLI, "SQL_DESC_DISTINCT_TYPE", INT2NUM(SQL_DESC_DISTINCT_TYPE)); rb_define_const(mDB2CLI, "SQL_DESC_OCTET_LENGTH", INT2NUM(SQL_DESC_OCTET_LENGTH)); rb_define_const(mDB2CLI, "SQL_DESC_FIXED_PREC_SCALE", INT2NUM(SQL_DESC_FIXED_PREC_SCALE)); rb_define_const(mDB2CLI, "SQL_DESC_NAME", INT2NUM(SQL_DESC_NAME)); rb_define_const(mDB2CLI, "SQL_DESC_NULLABLE", INT2NUM(SQL_DESC_NULLABLE)); rb_define_const(mDB2CLI, "SQL_DESC_SCHEMA_NAME", INT2NUM(SQL_DESC_SCHEMA_NAME)); rb_define_const(mDB2CLI, "SQL_DESC_PRECISION", INT2NUM(SQL_DESC_PRECISION)); rb_define_const(mDB2CLI, "SQL_DESC_SCALE", INT2NUM(SQL_DESC_SCALE)); rb_define_const(mDB2CLI, "SQL_DESC_SEARCHABLE", INT2NUM(SQL_DESC_SEARCHABLE)); rb_define_const(mDB2CLI, "SQL_DESC_TABLE_NAME", INT2NUM(SQL_DESC_TABLE_NAME)); rb_define_const(mDB2CLI, "SQL_DESC_TYPE", INT2NUM(SQL_DESC_TYPE)); rb_define_const(mDB2CLI, "SQL_DESC_TYPE_NAME", INT2NUM(SQL_DESC_TYPE_NAME)); rb_define_const(mDB2CLI, "SQL_DESC_UNSIGNED", INT2NUM(SQL_DESC_UNSIGNED)); rb_define_const(mDB2CLI, "SQL_DESC_UPDATABLE", INT2NUM(SQL_DESC_UPDATABLE)); rb_define_const(mDB2CLI, "SQL_DESC_BASE_COLUMN_NAME", INT2NUM(SQL_DESC_BASE_COLUMN_NAME)); rb_define_const(mDB2CLI, "SQL_DESC_BASE_TABLE_NAME", INT2NUM(SQL_DESC_BASE_TABLE_NAME)); rb_define_const(mDB2CLI, "SQL_DESC_CONCISE_TYPE", INT2NUM(SQL_DESC_CONCISE_TYPE)); rb_define_const(mDB2CLI, "SQL_DESC_LENGTH", INT2NUM(SQL_DESC_LENGTH)); rb_define_const(mDB2CLI, "SQL_DESC_LITERAL_PREFIX", INT2NUM(SQL_DESC_LITERAL_PREFIX)); rb_define_const(mDB2CLI, "SQL_DESC_LITERAL_SUFFIX", INT2NUM(SQL_DESC_LITERAL_SUFFIX)); rb_define_const(mDB2CLI, "SQL_DESC_LOCAL_TYPE_NAME", INT2NUM(SQL_DESC_LOCAL_TYPE_NAME)); rb_define_const(mDB2CLI, "SQL_DESC_NUM_PREC_RADIX", INT2NUM(SQL_DESC_NUM_PREC_RADIX)); rb_define_const(mDB2CLI, "SQL_DESC_UNNAMED", INT2NUM(SQL_DESC_UNNAMED)); --- NEW FILE: db2cli.c --- /* * IBM DB2 CLI 5.0 (Call Level Interface) Module for Ruby * * file: db2cli.c * author: Michael Neumann (ne...@s-...) * id: $Id: db2cli.c,v 1.1 2002/09/05 09:57:13 mneumann Exp $ * * Copyright (C) 2001 by Michael Neumann. * Released under the same terms as Ruby itself. * */ /********************************************************************** Description: ====================================================================== - SQLRETURN is always returned as Ruby-Integer (Fixnum or Bignum) - any SQLHANDLE-type (SQLHENV, SQLHDBC, SQLHSTMT, SQLHDESC) is given or returned as Ruby-Integer (Fixnum or Bignum) - SQLSMALLINT etc. are all Ruby-Integer **********************************************************************/ /********************************************************************** Strange Things: ====================================================================== - after allocating an Environment-Handle "p 5.7" gives "5,7.0" on my system (in Germany correct would be "5,7"). Fault of Linux ???? **********************************************************************/ /* Includes */ #include <stdio.h> #include <stdlib.h> #include "sqlcli1.h" #include "ruby.h" /* Macros */ #define TO_C_INT(val) NUM2INT(val) #define TO_RUBY_INT(val) INT2NUM(val) #define MUST_BE_STRING(val) Check_Type(val, T_STRING) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) /* Global Variables */ static VALUE mDB2CLI; static VALUE cDate, cTime, cTimestamp; static VALUE objNull; /* object for a SQL NULL value */ /* Functions */ /******************************************************* SQLAllocHandle ======================================================= PARAMS: handle_type, input_handle : Integer RETURNS: rc, output_handle : Integer ********************************************************/ static VALUE db2_SQLAllocHandle(self, handle_type, input_handle) VALUE self; VALUE handle_type, input_handle; { SQLRETURN rc; SQLHANDLE output_handle; rc = SQLAllocHandle( (SQLSMALLINT) TO_C_INT(handle_type), (SQLHANDLE) TO_C_INT(input_handle), (SQLHANDLE*) &output_handle ); return rb_ary_new3(2, TO_RUBY_INT(rc), TO_RUBY_INT(output_handle)); } /******************************************************* SQLFreeHandle ======================================================= PARAMS: handle_type, handle : Integer RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLFreeHandle(self, handle_type, handle) VALUE self; VALUE handle_type, handle; { SQLRETURN rc; rc = SQLFreeHandle( (SQLSMALLINT) TO_C_INT(handle_type), (SQLHANDLE) TO_C_INT(handle) ); return TO_RUBY_INT(rc); } /******************************************************* SQLFreeStmt ======================================================= PARAMS: statement_handle, option : Integer RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLFreeStmt(self, statement_handle, option) VALUE self; VALUE statement_handle, option; { SQLRETURN rc; rc = SQLFreeStmt( (SQLHSTMT) TO_C_INT(statement_handle), (SQLUSMALLINT) TO_C_INT(option) ); return TO_RUBY_INT(rc); } /******************************************************* SQLDataSources ======================================================= PARAMS: environment_handle : Integer, direction : Integer, server_name_length : Integer, (buffer-length) description_length : Integer (buffer-length) RETURNS: rc : Integer, server_name : String, server_name_length : Integer, (bytes available) description : String, description_length : Integer (bytes available) ********************************************************/ static VALUE db2_SQLDataSources(self, environment_handle, direction, server_name_length, description_length) VALUE self; VALUE environment_handle, direction; VALUE server_name_length, description_length; { SQLRETURN rc; SQLCHAR* server_name; SQLCHAR* description; SQLSMALLINT sl; /* server_name_length */ SQLSMALLINT dl; /* description_length */ SQLSMALLINT sn_length; /* real server_name_length */ SQLSMALLINT ds_length; /* real description_length */ VALUE retval; sl = TO_C_INT(server_name_length); dl = TO_C_INT(description_length); server_name = (SQLCHAR*) ALLOC_N(SQLCHAR, sl); description = (SQLCHAR*) ALLOC_N(SQLCHAR, dl); rc = SQLDataSources( (SQLHENV) TO_C_INT(environment_handle), (SQLUSMALLINT) TO_C_INT(direction), (SQLCHAR*) server_name, (SQLSMALLINT) sl, (SQLSMALLINT*) &sn_length, (SQLCHAR*) description, (SQLSMALLINT) dl, (SQLSMALLINT*) &ds_length ); retval = rb_ary_new3( 5, TO_RUBY_INT(rc), rb_str_new(server_name, MIN(sl, sn_length)), TO_RUBY_INT(sn_length), rb_str_new(description, MIN(dl, ds_length)), TO_RUBY_INT(ds_length) ); free((void*)description); free((void*)server_name); return retval; } /******************************************************* SQLConnect ======================================================= PARAMS: connection_handle : Integer, server_name, user_name, auth : String RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLConnect(self, connection_handle, server_name, user_name, auth) VALUE self; VALUE connection_handle, server_name, user_name, auth; { SQLRETURN rc; MUST_BE_STRING(server_name); MUST_BE_STRING(user_name); MUST_BE_STRING(auth); rc = SQLConnect( (SQLHDBC) TO_C_INT(connection_handle), (SQLCHAR *FAR) RSTRING(server_name)->ptr, (SQLSMALLINT) RSTRING(server_name)->len, (SQLCHAR *FAR) RSTRING(user_name)->ptr, (SQLSMALLINT) RSTRING(user_name)->len, (SQLCHAR *FAR) RSTRING(auth)->ptr, (SQLSMALLINT) RSTRING(auth)->len ); return TO_RUBY_INT(rc); } /******************************************************* SQLDisconnect ======================================================= PARAMS: connection_handle : Integer RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLDisconnect(self, connection_handle) VALUE self; VALUE connection_handle; { SQLRETURN rc; rc = SQLDisconnect( (SQLHDBC) TO_C_INT(connection_handle) ); return TO_RUBY_INT(rc); } /******************************************************* SQLPrepare ======================================================= PARAMS: statement_handle : Integer, statement_text : String RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLPrepare(self, statement_handle, statement_text) VALUE self; VALUE statement_handle, statement_text; { SQLRETURN rc; MUST_BE_STRING(statement_text); rc = SQLPrepare( (SQLHSTMT) TO_C_INT(statement_handle), (SQLCHAR *FAR) RSTRING(statement_text)->ptr, (SQLINTEGER) RSTRING(statement_text)->len ); return TO_RUBY_INT(rc); } /******************************************************* SQLNumResultCols ======================================================= PARAMS: statement_handle : Integer RETURNS: rc, column_count : Integer ********************************************************/ static VALUE db2_SQLNumResultCols(self, statement_handle) VALUE self; VALUE statement_handle; { SQLRETURN rc; SQLSMALLINT column_count; rc = SQLNumResultCols( (SQLHSTMT) TO_C_INT(statement_handle), (SQLSMALLINT*) &column_count ); return rb_ary_new3(2, TO_RUBY_INT(rc), TO_RUBY_INT(column_count)); } /******************************************************* SQLDescribeCol ======================================================= PARAMS: statement_handle : Integer, column_number : Integer, buffer_length : Integer (for column_name) RETURNS: rc : Integer, column_name : String | nil, name_length : Integer, data_type : Integer, column_size : Integer, decimal_digits : Integer, nullable : Integer ********************************************************/ static VALUE db2_SQLDescribeCol(self, statement_handle, column_number, buffer_length) VALUE self; VALUE statement_handle, column_number, buffer_length; { SQLRETURN rc; SQLCHAR* colname_ptr; SQLSMALLINT name_length, data_type, decimal_digits, nullable; SQLUINTEGER column_size; SQLSMALLINT bl; /* buffer_length */ VALUE retval; bl = TO_C_INT(buffer_length); colname_ptr = (SQLCHAR*) ALLOC_N(SQLCHAR, bl); rc = SQLDescribeCol( (SQLHSTMT) TO_C_INT(statement_handle), (SQLUSMALLINT) TO_C_INT(column_number), (SQLCHAR *) colname_ptr, (SQLSMALLINT) bl, (SQLSMALLINT*) &name_length, (SQLSMALLINT*) &data_type, (SQLUINTEGER*) &column_size, (SQLSMALLINT*) &decimal_digits, (SQLSMALLINT*) &nullable ); retval = rb_ary_new3( 7, TO_RUBY_INT(rc), colname_ptr == NULL ? Qnil : rb_str_new(colname_ptr, MIN(name_length, bl)), TO_RUBY_INT(name_length), TO_RUBY_INT(data_type), TO_RUBY_INT(column_size), TO_RUBY_INT(decimal_digits), TO_RUBY_INT(nullable) ); free(colname_ptr); return retval; } /******************************************************* SQLColAttribute ======================================================= PARAMS: statement_handle : Integer, column_number : Integer, field_identifier : Integer, buffer_length : Integer | nil (nil == numeric_attribute) RETURNS: if numeric_attribute (buffer_length==nil): rc : Integer, numeric_attribute : Integer elsif character_attribute (buffer_length != nil): rc : Integer, character_attribute : String, string_length : Integer ********************************************************/ static VALUE db2_SQLColAttribute(self, statement_handle, column_number, field_identifier, buffer_length) VALUE self; VALUE statement_handle, column_number, field_identifier, buffer_length; { SQLRETURN rc; SQLSMALLINT bl; /* buffer_length */ SQLPOINTER character_attr_ptr; SQLSMALLINT string_length; signed long numeric_attribute; VALUE retval; if (NIL_P(buffer_length) != 0) { /* numeric_attribute */ bl = 0; character_attr_ptr = NULL; } else { /* character_attribute */ bl = TO_C_INT(buffer_length); character_attr_ptr = (SQLPOINTER) ALLOC_N(char, bl); } rc = SQLColAttribute( (SQLHSTMT) TO_C_INT(statement_handle), (SQLUSMALLINT) TO_C_INT(column_number), (SQLSMALLINT) TO_C_INT(field_identifier), (SQLPOINTER) character_attr_ptr, (SQLSMALLINT) bl, (SQLSMALLINT*) &string_length, (SQLPOINTER) &numeric_attribute ); if (NIL_P(buffer_length) != 0) { /* numeric_attribute */ retval = rb_ary_new3( 2, TO_RUBY_INT(rc), TO_RUBY_INT(numeric_attribute) ); } else { /* character_attribute */ retval = rb_ary_new3( 3, TO_RUBY_INT(rc), rb_str_new(character_attr_ptr, MIN(string_length, bl)), TO_RUBY_INT(string_length) ); free(character_attr_ptr); } return retval; } /******************************************************* SQLExecDirect ======================================================= PARAMS: statement_handle : Integer, statement_text : String RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLExecDirect(self, statement_handle, statement_text) VALUE self; VALUE statement_handle, statement_text; { SQLRETURN rc; MUST_BE_STRING(statement_text); rc = SQLExecDirect( (SQLHSTMT) TO_C_INT(statement_handle), (SQLCHAR *FAR) RSTRING(statement_text)->ptr, (SQLINTEGER) RSTRING(statement_text)->len ); return TO_RUBY_INT(rc); } /******************************************************* SQLExecute ======================================================= PARAMS: statement_handle : Integer RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLExecute(self, statement_handle) VALUE self; VALUE statement_handle; { SQLRETURN rc; rc = SQLExecute( (SQLHSTMT) TO_C_INT(statement_handle) ); return TO_RUBY_INT(rc); } /******************************************************* SQLRowCount ======================================================= PARAMS: statement_handle : Integer RETURNS: rc, row_count : Integer ********************************************************/ static VALUE db2_SQLRowCount(self, statement_handle) VALUE self; VALUE statement_handle; { SQLRETURN rc; SQLINTEGER row_count; rc = SQLRowCount( (SQLHSTMT) TO_C_INT(statement_handle), (SQLINTEGER*) &row_count ); return rb_ary_new3(2, TO_RUBY_INT(rc), TO_RUBY_INT(row_count)); } /******************************************************* SQLFetch ======================================================= PARAMS: statement_handle : Integer RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLFetch(self, statement_handle) VALUE self; VALUE statement_handle; { SQLRETURN rc; rc = SQLFetch( (SQLHSTMT) TO_C_INT(statement_handle) ); return TO_RUBY_INT(rc); } /******************************************************* SQLFetchScroll ======================================================= PARAMS: statement_handle : Integer, fetch_orientation : Integer, fetch_offset : Integer RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLFetchScroll(self, statement_handle, fetch_orientation, fetch_offset) VALUE self; VALUE statement_handle, fetch_orientation, fetch_offset; { SQLRETURN rc; rc = SQLFetchScroll( (SQLHSTMT) TO_C_INT(statement_handle), (SQLSMALLINT) TO_C_INT(fetch_orientation), (SQLINTEGER) TO_C_INT(fetch_offset) ); return TO_RUBY_INT(rc); } /******************************************************* SQLGetData ======================================================= PARAMS: statement_handle : Integer, column_number : Integer, target_type : Integer, (e.g. SQL_BLOB) buffer_length = nil : Integer (nil for e.g. SQL_INTEGER) RETURNS: rc : Integer, column : ?, strlen_or_indptr : ********************************************************/ static VALUE db2_SQLGetData(argc, argv, self) int argc; VALUE *argv; VALUE self; { VALUE statement_handle, column_number, target_type, buffer_length; SQLRETURN rc; SQLINTEGER strlen_or_indptr; SQLHSTMT sh; /* statement_handle */ SQLUSMALLINT cn; /* column_number */ SQLINTEGER bl; /* buffer_length */ VALUE retval; union { SQLDOUBLE dbl; SQLREAL real; SQLINTEGER integer; SQLSMALLINT smallint; DATE_STRUCT date; TIME_STRUCT time; TIMESTAMP_STRUCT timestamp; } ptr_value; SQLPOINTER ptr; rb_scan_args(argc, argv, "31", &statement_handle, &column_number, &target_type, &buffer_length); sh = TO_C_INT(statement_handle); cn = TO_C_INT(column_number); if (NIL_P(buffer_length) != 0) { bl = 0; } else { bl = TO_C_INT(buffer_length); } #define CALL_SQL_GET_DATA(ptr, type, len) \ rc = SQLGetData( \ (SQLHSTMT) sh, \ (SQLUSMALLINT) cn, \ (SQLSMALLINT) type, \ (SQLPOINTER) ptr, \ (SQLINTEGER) len, \ (SQLINTEGER*) &strlen_or_indptr \ ); #define RETVAL(val) \ if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) \ retval = \ (strlen_or_indptr == SQL_NULL_DATA) ? objNull : val; \ else \ retval = Qnil; \ switch (TO_C_INT(target_type)) { case SQL_DOUBLE: case SQL_FLOAT: CALL_SQL_GET_DATA(&ptr_value, SQL_C_DOUBLE, sizeof(SQLDOUBLE)); RETVAL( rb_float_new(ptr_value.dbl) ); break; case SQL_REAL: CALL_SQL_GET_DATA(&ptr_value, SQL_C_FLOAT, sizeof(SQLREAL)); RETVAL( rb_float_new(ptr_value.real) ); break; case SQL_INTEGER: CALL_SQL_GET_DATA(&ptr_value, SQL_C_LONG, sizeof(SQLINTEGER)); RETVAL( TO_RUBY_INT(ptr_value.integer) ); break; case SQL_SMALLINT: CALL_SQL_GET_DATA(&ptr_value, SQL_C_SHORT, sizeof(SQLSMALLINT)); RETVAL( TO_RUBY_INT(ptr_value.smallint) ); break; case SQL_TYPE_DATE: CALL_SQL_GET_DATA(&ptr_value, SQL_C_TYPE_DATE, sizeof(DATE_STRUCT)); RETVAL( rb_funcall( cDate, rb_intern("new"), 3, TO_RUBY_INT(ptr_value.date.year), TO_RUBY_INT(ptr_value.date.month), TO_RUBY_INT(ptr_value.date.day) ) ); break; case SQL_TYPE_TIME: CALL_SQL_GET_DATA(&ptr_value, SQL_C_TYPE_TIME, sizeof(TIME_STRUCT)); RETVAL( rb_funcall( cTime, rb_intern("new"), 3, TO_RUBY_INT(ptr_value.time.hour), TO_RUBY_INT(ptr_value.time.minute), TO_RUBY_INT(ptr_value.time.second) ) ); break; case SQL_TYPE_TIMESTAMP: CALL_SQL_GET_DATA(&ptr_value, SQL_C_TYPE_TIMESTAMP, sizeof(TIMESTAMP_STRUCT)); RETVAL( rb_funcall( cTimestamp, rb_intern("new"), 7, TO_RUBY_INT(ptr_value.timestamp.year), TO_RUBY_INT(ptr_value.timestamp.month), TO_RUBY_INT(ptr_value.timestamp.day), TO_RUBY_INT(ptr_value.timestamp.hour), TO_RUBY_INT(ptr_value.timestamp.minute), TO_RUBY_INT(ptr_value.timestamp.second), TO_RUBY_INT(ptr_value.timestamp.fraction) ) ); break; case SQL_CHAR: case SQL_CLOB: case SQL_LONGVARCHAR: case SQL_VARCHAR: /* TODO: should handle SQL_DECIMAL and SQL_NUMERIC different ? */ case SQL_DECIMAL: case SQL_NUMERIC: ptr = (SQLPOINTER) ALLOC_N(SQLCHAR, bl); CALL_SQL_GET_DATA(ptr, SQL_C_CHAR, bl); RETVAL( rb_str_new(ptr, MIN(bl, strlen_or_indptr)) ); free((void*)ptr); break; case SQL_BLOB: case SQL_BINARY: case SQL_LONGVARBINARY: case SQL_VARBINARY: ptr = (SQLPOINTER) ALLOC_N(SQLCHAR, bl); CALL_SQL_GET_DATA(ptr, SQL_C_BINARY, bl); RETVAL( rb_str_new(ptr, MIN(bl, strlen_or_indptr)) ); free((void*)ptr); break; case SQL_BLOB_LOCATOR: CALL_SQL_GET_DATA(&ptr_value, SQL_C_BLOB_LOCATOR, sizeof(SQLINTEGER)); RETVAL( TO_RUBY_INT(ptr_value.integer) ); break; case SQL_CLOB_LOCATOR: CALL_SQL_GET_DATA(&ptr_value, SQL_C_CLOB_LOCATOR, sizeof(SQLINTEGER)); RETVAL( TO_RUBY_INT(ptr_value.integer) ); break; case SQL_DBCLOB_LOCATOR: CALL_SQL_GET_DATA(&ptr_value, SQL_C_DBCLOB_LOCATOR, sizeof(SQLINTEGER)); RETVAL( TO_RUBY_INT(ptr_value.integer) ); break; case SQL_BIGINT: /* TODO: How large can a BIGINT be? ==> expect 200 bytes, should be enought? */ ptr = (SQLPOINTER) ALLOC_N(SQLCHAR, MAX(bl,200)); CALL_SQL_GET_DATA(ptr, SQL_C_CHAR, bl); RETVAL( rb_str_new(ptr, MIN(bl, strlen_or_indptr)) ); rc = rb_funcall(rc, rb_intern("to_i"), 0); free((void*)ptr); break; case SQL_DBCLOB: case SQL_GRAPHIC: case SQL_LONGVARGRAPHIC: case SQL_VARGRAPHIC: ptr = (SQLPOINTER) ALLOC_N(SQLCHAR, bl); /* NOTE: not SQLDBCHAR */ CALL_SQL_GET_DATA(ptr, SQL_C_DBCHAR, bl); RETVAL( rb_str_new(ptr, MIN(bl, strlen_or_indptr)) ); free((void*)ptr); break; default: rb_raise(rb_eTypeError, "Wrong parameter for target_type!"); }; #undef RETVAL #undef CALL_SQL_GET_DATA return rb_ary_new3(3, TO_RUBY_INT(rc), retval, TO_RUBY_INT(strlen_or_indptr)); } /******************************************************* SQLEndTran ======================================================= PARAMS: handle_type, handle, completion_type : Integer RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLEndTran(self, handle_type, handle, completion_type) VALUE self; VALUE handle_type, handle, completion_type; { SQLRETURN rc; rc = SQLEndTran( (SQLSMALLINT) TO_C_INT(handle_type), (SQLHANDLE) TO_C_INT(handle), (SQLSMALLINT) TO_C_INT(completion_type) ); return TO_RUBY_INT(rc); } /******************************************************* SQLGetDiagRec ======================================================= PARAMS: handle_type, handle, rec_number, buffer_length : Integer RETURNS: rc : Integer, sql_state : String, native_error : Integer, message_text : String, text_length : Integer ********************************************************/ static VALUE db2_SQLGetDiagRec(self, handle_type, handle, rec_number, buffer_length) VALUE self; VALUE handle_type, handle, rec_number, buffer_length; { SQLRETURN rc; SQLCHAR sql_state[5]; SQLINTEGER native_error; SQLCHAR* message_text; SQLINTEGER bl; /* buffer_length */ SQLSMALLINT text_length; VALUE retval; bl = TO_C_INT(buffer_length); message_text = (SQLCHAR*) ALLOC_N(SQLCHAR, bl); rc = SQLGetDiagRec( (SQLSMALLINT) TO_C_INT(handle_type), (SQLHANDLE) TO_C_INT(handle), (SQLSMALLINT) TO_C_INT(rec_number), (SQLCHAR*) sql_state, (SQLINTEGER*) &native_error, (SQLCHAR*) message_text, (SQLINTEGER) bl, (SQLSMALLINT*) &text_length ); retval = rb_ary_new3( 5, TO_RUBY_INT(rc), rb_str_new(sql_state, 5), TO_RUBY_INT(native_error), rb_str_new(message_text, MIN(bl, text_length)), TO_RUBY_INT(text_length) ); free(message_text); return retval; } /******************************************************* SQLTables ======================================================= PARAMS: statement_handle : Integer, catalog_name : String, (must be set to "") schema_name : String, table_name : String, table_type : String (e.g. "TABLE, VIEW") RETURNS: rc : Integer ********************************************************/ static VALUE db2_SQLTables(self, statement_handle, catalog_name, schema_name, table_name, table_type) VALUE self; VALUE statement_handle, catalog_name, schema_name; VALUE table_name, table_type; { SQLRETURN rc; MUST_BE_STRING(catalog_name); MUST_BE_STRING(schema_name); MUST_BE_STRING(table_name); MUST_BE_STRING(table_type); rc = SQLTables( (SQLHSTMT) TO_C_INT(statement_handle), (SQLCHAR *FAR) RSTRING(catalog_name)->ptr, (SQLSMALLINT) RSTRING(catalog_name)->len, (SQLCHAR *FAR) RSTRING(schema_name)->ptr, (SQLSMALLINT) RSTRING(schema_name)->len, (SQLCHAR *FAR) RSTRING(table_name)->ptr, (SQLSMALLINT) RSTRING(table_name)->len, (SQLCHAR *FAR) RSTRING(table_type)->ptr, (SQLSMALLINT) RSTRING(table_type)->len ); return TO_RUBY_INT(rc); } /* Init */ void Init_db2cli() { mDB2CLI = rb_eval_string("DB2CLI"); #include "constants.h" rb_define_module_function(mDB2CLI, "SQLAllocHandle", db2_SQLAllocHandle, 2); rb_define_module_function(mDB2CLI, "SQLFreeHandle", db2_SQLFreeHandle, 2); rb_define_module_function(mDB2CLI, "SQLFreeStmt", db2_SQLFreeStmt, 2); rb_define_module_function(mDB2CLI, "SQLDataSources", db2_SQLDataSources, 4); rb_define_module_function(mDB2CLI, "SQLConnect", db2_SQLConnect, 4); rb_define_module_function(mDB2CLI, "SQLDisconnect", db2_SQLDisconnect, 1); rb_define_module_function(mDB2CLI, "SQLPrepare", db2_SQLPrepare, 2); rb_define_module_function(mDB2CLI, "SQLNumResultCols", db2_SQLNumResultCols, 1); rb_define_module_function(mDB2CLI, "SQLDescribeCol", db2_SQLDescribeCol, 3); rb_define_module_function(mDB2CLI, "SQLColAttribute", db2_SQLColAttribute, 4); rb_define_module_function(mDB2CLI, "SQLExecDirect", db2_SQLExecDirect, 2); rb_define_module_function(mDB2CLI, "SQLExecute", db2_SQLExecute, 1); rb_define_module_function(mDB2CLI, "SQLRowCount", db2_SQLRowCount, 1); rb_define_module_function(mDB2CLI, "SQLFetch", db2_SQLFetch, 1); rb_define_module_function(mDB2CLI, "SQLFetchScroll", db2_SQLFetchScroll, 3); rb_define_module_function(mDB2CLI, "SQLGetData", db2_SQLGetData, -1); /* 3-4 */ rb_define_module_function(mDB2CLI, "SQLEndTran", db2_SQLEndTran, 3); rb_define_module_function(mDB2CLI, "SQLGetDiagRec", db2_SQLGetDiagRec, 4); rb_define_module_function(mDB2CLI, "SQLTables", db2_SQLTables, 5); /* Datatype classes or objects */ cDate = rb_eval_string("DB2CLI::Date"); cTime = rb_eval_string("DB2CLI::Time"); cTimestamp = rb_eval_string("DB2CLI::Timestamp"); objNull = rb_eval_string("DB2CLI::Null"); } --- NEW FILE: extconf.rb --- require "mkmf" if RUBY_PLATFORM =~ /(mswin32|cygwin|mingw)/ # version 6.1 Windows 95/98/NT DB2LIB = "db2cli" DB2DIR = ENV["DB2DIR"] || "C:/SQLLIB" else # version 7.1 Linux DB2LIB = "db2" DB2DIR = ENV["DB2DIR"] || "/usr/IBMdb2/V7.1" end dir_config( "db2", DB2DIR + "/include", DB2DIR + "/lib" ) if have_library(DB2LIB, "SQLConnect") and have_header("sqlcli.h") create_makefile "db2cli" else puts "ABORT: Could not locate DB2 libraries or headers!" puts "Please set DB2DIR to your DB2 directory, e.g. /usr/IBMdb2/V7.1 (UNIX) " + "or C:/SQLLIB (Windows)" exit 1 end |