Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
ODBC binding for Ruby
---------------------
Thu Jun 27 2024 version 0.103.cv release <[email protected]>
* Argument data type fix to support Ruby 3.3 by replacing NULL with 0 in method rb_funcall
* Include ruby/thread.h to implicitly declare rb_thread_call_without_gvl
* Cast first argument of rb_thread_call_without_gvl to void * data type

Mon Aug 21 2023 version 0.102.cv release <[email protected]>
* Syntax changes to support Ruby 3.2 by using native "rb_str_new" instead of "rb_tainted_str_new"
Remove tained usage (thanks @vhermecz)
Expand Down
123 changes: 70 additions & 53 deletions ext/odbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <stdarg.h>
#include <ctype.h>
#include "ruby.h"
#include "ruby/thread.h"
#ifdef HAVE_VERSION_H
#include "version.h"
#endif
Expand Down Expand Up @@ -175,6 +176,14 @@ SQLExecute_wrapper(void *data)
return SQLExecute(args->StatementHandle);
}

void *
SQLExecute_wrapper_with_gvl(void *data) {
// Call the original function
VALUE result = SQLExecute_wrapper(data);
// Cast the result to void* and return
return (void *)result;
}

void
SQLExecute_unblock(void *data)
{
Expand All @@ -189,6 +198,14 @@ SQLExecDirect_wrapper(void *data)
return SQLExecDirect(args->StatementHandle, args->StatementText, args->TextLength);
}

void *
SQLExecDirect_wrapper_with_gvl(void *data) {
// Call the original function
VALUE result = SQLExecDirect_wrapper(data);
// Cast the result to void* and return
return (void *)result;
}

void
SQLExecDirect_unblock(void *data)
{
Expand Down Expand Up @@ -979,7 +996,7 @@ free_stmt(STMT *q)
static void
start_gc()
{
rb_funcall(rb_mGC, IDstart, 0, NULL);
rb_funcall(rb_mGC, IDstart, 0, 0);
}

static void
Expand Down Expand Up @@ -1246,7 +1263,7 @@ tracesql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
(long) henv, (long) hdbc, (long) hstmt);
trace_sql_ret(ret);
}

return ret;
}
#endif
Expand Down Expand Up @@ -1669,7 +1686,7 @@ conf_dsn(int argc, VALUE *argv, VALUE self, int op)
if (rb_obj_is_kind_of(attr, rb_cHash) == Qtrue) {
VALUE a, x;

a = rb_funcall(attr, IDkeys, 0, NULL);
a = rb_funcall(attr, IDkeys, 0, 0);
while ((x = rb_ary_shift(a)) != Qnil) {
VALUE v = rb_hash_aref(attr, x);

Expand Down Expand Up @@ -2131,7 +2148,7 @@ dbc_connect(int argc, VALUE *argv, VALUE self)
#endif
rb_raise(Cerror, "%s", msg);
}

{
SQLRETURN nRet;

Expand All @@ -2144,7 +2161,7 @@ dbc_connect(int argc, VALUE *argv, VALUE self)
nRet = SQLSetConnectAttr(dbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)nTimeout, SQL_IS_INTEGER);
if (!SQL_SUCCEEDED(nRet)) fprintf(stderr, "Failed to set timeout to %d: error %d\n", nTimeout, nRet);
}

if (!succeeded(SQL_NULL_HENV, dbc, SQL_NULL_HSTMT,
SQLConnect(dbc, (SQLTCHAR *) sdsn, SQL_NTS,
(SQLTCHAR *) suser,
Expand Down Expand Up @@ -2188,7 +2205,7 @@ dbc_drvconnect(VALUE self, VALUE drv)
VALUE d, a, x;

d = rb_str_new2("");
a = rb_funcall(rb_iv_get(drv, "@attrs"), IDkeys, 0, NULL);
a = rb_funcall(rb_iv_get(drv, "@attrs"), IDkeys, 0, 0);
while ((x = rb_ary_shift(a)) != Qnil) {
VALUE v = rb_hash_aref(rb_iv_get(drv, "@attrs"), x);

Expand Down Expand Up @@ -4798,16 +4815,16 @@ date_init(int argc, VALUE *argv, VALUE self)
if (argc > 1) {
rb_raise(rb_eArgError, "wrong # arguments");
}
d = rb_funcall(y, IDday, 0, NULL);
m = rb_funcall(y, IDmonth, 0, NULL);
y = rb_funcall(y, IDyear, 0, NULL);
d = rb_funcall(y, IDday, 0, 0);
m = rb_funcall(y, IDmonth, 0, 0);
y = rb_funcall(y, IDyear, 0, 0);
} else if (rb_obj_is_kind_of(y, rb_cDate) == Qtrue) {
if (argc > 1) {
rb_raise(rb_eArgError, "wrong # arguments");
}
d = rb_funcall(y, IDmday, 0, NULL);
m = rb_funcall(y, IDmonth, 0, NULL);
y = rb_funcall(y, IDyear, 0, NULL);
d = rb_funcall(y, IDmday, 0, 0);
m = rb_funcall(y, IDmonth, 0, 0);
y = rb_funcall(y, IDyear, 0, 0);
} else if ((argc == 1) && (rb_obj_is_kind_of(y, rb_cString) == Qtrue)) {
if (date_load1(self, y, 0) != Qnil) {
return self;
Expand Down Expand Up @@ -5033,9 +5050,9 @@ time_init(int argc, VALUE *argv, VALUE self)
if (argc > 1) {
rb_raise(rb_eArgError, "wrong # arguments");
}
s = rb_funcall(h, IDsec, 0, NULL);
m = rb_funcall(h, IDmin, 0, NULL);
h = rb_funcall(h, IDhour, 0, NULL);
s = rb_funcall(h, IDsec, 0, 0);
m = rb_funcall(h, IDmin, 0, 0);
h = rb_funcall(h, IDhour, 0, 0);
} else if ((argc == 1) && (rb_obj_is_kind_of(h, rb_cString) == Qtrue)) {
if (time_load1(self, h, 0) != Qnil) {
return self;
Expand Down Expand Up @@ -5273,13 +5290,13 @@ timestamp_init(int argc, VALUE *argv, VALUE self)
if (argc > 1) {
rb_raise(rb_eArgError, "wrong # arguments");
}
f = rb_funcall(y, IDusec, 0, NULL);
ss = rb_funcall(y, IDsec, 0, NULL);
mm = rb_funcall(y, IDmin, 0, NULL);
hh = rb_funcall(y, IDhour, 0, NULL);
d = rb_funcall(y, IDday, 0, NULL);
m = rb_funcall(y, IDmonth, 0, NULL);
y = rb_funcall(y, IDyear, 0, NULL);
f = rb_funcall(y, IDusec, 0, 0);
ss = rb_funcall(y, IDsec, 0, 0);
mm = rb_funcall(y, IDmin, 0, 0);
hh = rb_funcall(y, IDhour, 0, 0);
d = rb_funcall(y, IDday, 0, 0);
m = rb_funcall(y, IDmonth, 0, 0);
y = rb_funcall(y, IDyear, 0, 0);
f = INT2NUM(NUM2INT(f) * 1000);
} else if (rb_obj_is_kind_of(y, rb_cDate) == Qtrue) {
if (argc > 1) {
Expand All @@ -5289,9 +5306,9 @@ timestamp_init(int argc, VALUE *argv, VALUE self)
ss = INT2FIX(0);
mm = INT2FIX(0);
hh = INT2FIX(0);
d = rb_funcall(y, IDmday, 0, NULL);
m = rb_funcall(y, IDmonth, 0, NULL);
y = rb_funcall(y, IDyear, 0, NULL);
d = rb_funcall(y, IDmday, 0, 0);
m = rb_funcall(y, IDmonth, 0, 0);
y = rb_funcall(y, IDyear, 0, 0);
} else if ((argc == 1) && (rb_obj_is_kind_of(y, rb_cString) == Qtrue)) {
if (timestamp_load1(self, y, 0) != Qnil) {
return self;
Expand Down Expand Up @@ -5766,13 +5783,13 @@ stmt_param_output_value(int argc, VALUE *argv, VALUE self)

time = (TIME_STRUCT *) q->paraminfo[vnum].outbuf;
frac = rb_float_new(0.0);
now = rb_funcall(rb_cTime, IDnow, 0, NULL);
now = rb_funcall(rb_cTime, IDnow, 0, 0);
v = rb_funcall(rb_cTime,
(q->dbcp->gmtime == Qtrue) ? IDutc : IDlocal,
7,
rb_funcall(now, IDyear, 0, NULL),
rb_funcall(now, IDmonth, 0, NULL),
rb_funcall(now, IDday, 0, NULL),
rb_funcall(now, IDyear, 0, 0),
rb_funcall(now, IDmonth, 0, 0),
rb_funcall(now, IDday, 0, 0),
INT2NUM(time->hour),
INT2NUM(time->minute),
INT2NUM(time->second),
Expand Down Expand Up @@ -6423,14 +6440,14 @@ do_fetch(STMT *q, int mode)

time = (TIME_STRUCT *) valp;
frac = rb_float_new(0.0);
now = rb_funcall(rb_cTime, IDnow, 0, NULL);
now = rb_funcall(rb_cTime, IDnow, 0, 0);
v = rb_funcall(rb_cTime,
(q->dbcp->gmtime == Qtrue) ?
IDutc : IDlocal,
7,
rb_funcall(now, IDyear, 0, NULL),
rb_funcall(now, IDmonth, 0, NULL),
rb_funcall(now, IDday, 0, NULL),
rb_funcall(now, IDyear, 0, 0),
rb_funcall(now, IDmonth, 0, 0),
rb_funcall(now, IDday, 0, 0),
INT2NUM(time->hour),
INT2NUM(time->minute),
INT2NUM(time->second),
Expand Down Expand Up @@ -7097,7 +7114,7 @@ stmt_prep_int(int argc, VALUE *argv, VALUE self, int mode)
args.StatementHandle = hstmt;
args.StatementText = ssql;
args.TextLength = SQL_NTS;
ret = (SQLRETURN)rb_thread_call_without_gvl(SQLExecDirect_wrapper, &args, SQLExecDirect_unblock, &args);
ret = (SQLRETURN)rb_thread_call_without_gvl(SQLExecDirect_wrapper_with_gvl, &args, SQLExecDirect_unblock, &args);

if (!succeeded_nodata(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt, ret, &msg, "SQLExecDirect('%s')", csql)) {
goto sqlerr;
Expand Down Expand Up @@ -7289,9 +7306,9 @@ bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
ctype = SQL_C_TIME;
time = (TIME_STRUCT *) valp;
memset(time, 0, sizeof (TIME_STRUCT));
time->hour = rb_funcall(arg, IDhour, 0, NULL);
time->minute = rb_funcall(arg, IDmin, 0, NULL);
time->second = rb_funcall(arg, IDsec, 0, NULL);
time->hour = rb_funcall(arg, IDhour, 0, 0);
time->minute = rb_funcall(arg, IDmin, 0, 0);
time->second = rb_funcall(arg, IDsec, 0, 0);
rlen = 1;
vlen = sizeof (TIME_STRUCT);
} else if (q->paraminfo[pnum].type == SQL_DATE) {
Expand All @@ -7300,9 +7317,9 @@ bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
ctype = SQL_C_DATE;
date = (DATE_STRUCT *) valp;
memset(date, 0, sizeof (DATE_STRUCT));
date->year = rb_funcall(arg, IDyear, 0, NULL);
date->month = rb_funcall(arg, IDmonth, 0, NULL);
date->day = rb_funcall(arg, IDday, 0, NULL);
date->year = rb_funcall(arg, IDyear, 0, 0);
date->month = rb_funcall(arg, IDmonth, 0, 0);
date->day = rb_funcall(arg, IDday, 0, 0);
rlen = 1;
vlen = sizeof (TIMESTAMP_STRUCT);
} else {
Expand All @@ -7311,16 +7328,16 @@ bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
ctype = SQL_C_TIMESTAMP;
ts = (TIMESTAMP_STRUCT *) valp;
memset(ts, 0, sizeof (TIMESTAMP_STRUCT));
ts->year = rb_funcall(arg, IDyear, 0, NULL);
ts->month = rb_funcall(arg, IDmonth, 0, NULL);
ts->day = rb_funcall(arg, IDday, 0, NULL);
ts->hour = rb_funcall(arg, IDhour, 0, NULL);
ts->minute = rb_funcall(arg, IDmin, 0, NULL);
ts->second = rb_funcall(arg, IDsec, 0, NULL);
ts->year = rb_funcall(arg, IDyear, 0, 0);
ts->month = rb_funcall(arg, IDmonth, 0, 0);
ts->day = rb_funcall(arg, IDday, 0, 0);
ts->hour = rb_funcall(arg, IDhour, 0, 0);
ts->minute = rb_funcall(arg, IDmin, 0, 0);
ts->second = rb_funcall(arg, IDsec, 0, 0);
#ifdef TIME_USE_USEC
ts->fraction = rb_funcall(arg, IDusec, 0, NULL) * 1000;
ts->fraction = rb_funcall(arg, IDusec, 0, 0) * 1000;
#else
ts->fraction = rb_funcall(arg, IDnsec, 0, NULL);
ts->fraction = rb_funcall(arg, IDnsec, 0, 0);
#endif
rlen = 1;
vlen = sizeof (TIMESTAMP_STRUCT);
Expand All @@ -7333,9 +7350,9 @@ bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
ctype = SQL_C_DATE;
date = (DATE_STRUCT *) valp;
memset(date, 0, sizeof (DATE_STRUCT));
date->year = rb_funcall(arg, IDyear, 0, NULL);
date->month = rb_funcall(arg, IDmonth, 0, NULL);
date->day = rb_funcall(arg, IDmday, 0, NULL);
date->year = rb_funcall(arg, IDyear, 0, 0);
date->month = rb_funcall(arg, IDmonth, 0, 0);
date->day = rb_funcall(arg, IDmday, 0, 0);
rlen = 1;
vlen = sizeof (DATE_STRUCT);
break;
Expand Down Expand Up @@ -7546,7 +7563,7 @@ stmt_exec_int(int argc, VALUE *argv, VALUE self, int mode)
}

args.StatementHandle = q->hstmt;
ret = (SQLRETURN)rb_thread_call_without_gvl(SQLExecute_wrapper, &args, SQLExecute_unblock, &args);
ret = (SQLRETURN)rb_thread_call_without_gvl(SQLExecute_wrapper_with_gvl, &args, SQLExecute_unblock, &args);

if (!succeeded_nodata(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, &msg, "SQLExecute")) {
error:
Expand Down Expand Up @@ -7862,7 +7879,7 @@ mod_2time(int argc, VALUE *argv, VALUE self)
rb_raise(rb_eTypeError, "expecting ODBC::Date");
}
} else {
VALUE now = rb_funcall(rb_cTime, IDnow, 0, NULL);
VALUE now = rb_funcall(rb_cTime, IDnow, 0, 0);

y = rb_funcall(rb_cTime, IDyear, 1, now);
m = rb_funcall(rb_cTime, IDmonth, 1, now);
Expand Down
2 changes: 1 addition & 1 deletion ruby-odbc.gemspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'date'
spec = Gem::Specification.new do |s|
s.name = "ruby-odbc"
s.version = "0.102.cv"
s.version = "0.103.cv"
s.date = Date.today.to_s
s.author = "Christian Werner"
s.email = "chw @nospam@ ch-werner.de"
Expand Down