Skip to content

Straight mapping of OCI transaction functions to ruby-oci8 #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
33 changes: 33 additions & 0 deletions ext/oci8/apiwrap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,30 @@ OCITransCommit_nb:
- OCIError *errhp
- ub4 flags

# round trip: 1
OCITransDetach_nb:
:version: 800
:args:
- OCISvcCtx *svchp
- OCIError *errhp
- ub4 flags

# round trip: 1
OCITransForget_nb:
:version: 800
:args:
- OCISvcCtx *svchp
- OCIError *errhp
- ub4 flags

# round trip: 1
OCITransPrepare_nb:
:version: 800
:args:
- OCISvcCtx *svchp
- OCIError *errhp
- ub4 flags

# round trip: 1
OCITransRollback:
:version: 800
Expand All @@ -883,6 +907,15 @@ OCITransRollback_nb:
- OCIError *errhp
- ub4 flags

# round trip: 1
OCITransStart_nb:
:version: 800
:args:
- OCISvcCtx *svchp
- OCIError *errhp
- uword timeout
- ub4 flags

# round trip: 0 ?
OCITypeTypeCode:
:version: 800
Expand Down
4 changes: 3 additions & 1 deletion ext/oci8/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ def fmt.%(x)
"stmt.o", "bind.o", "metadata.o", "attr.o",
"lob.o", "oradate.o",
"ocinumber.o", "ocidatetime.o", "object.o", "apiwrap.o",
"encoding.o", "oranumber_util.o", "thread_util.o", "util.o"]
"encoding.o", "oranumber_util.o", "thread_util.o",
"transaction.o",
"util.o"]

if RUBY_PLATFORM =~ /mswin32|cygwin|mingw32|bccwin32/
$defs << "-DUSE_WIN32_C"
Expand Down
140 changes: 136 additions & 4 deletions ext/oci8/oci8.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,54 @@ static VALUE cEnvironment;
static VALUE cProcess;
static ID id_at_session_handle;
static ID id_at_server_handle;
static ID id_at_trans_handle;

typedef struct {
const char *name;
ub4 val;
} ub4_flag_def_t;

static ub4 check_ub4_flags(int argc, VALUE *argv, const ub4_flag_def_t *flag_defs, const char *flag_name)
{
ub4 flags = 0;
int i;

for (i = 0; i < argc; i++) {
VALUE val = argv[i];
const char *name;
size_t len;
int j;

if (SYMBOL_P(val)) {
#ifdef HAVE_RB_SYM2STR
VALUE symstr = rb_sym2str(val);
name = RSTRING_PTR(symstr);
len = RSTRING_LEN(symstr);
#else
name = rb_id2name(SYM2ID(val));
len = strlen(symname);
#endif
} else {
SafeStringValue(val);
name = RSTRING_PTR(val);
len = RSTRING_LEN(val);
}
for (j = 0; flag_defs[j].name != NULL; j++) {
if (strncmp(name, flag_defs[j].name, len) != 0) {
continue;
}
if (flag_defs[j].name[len] != '\0') {
continue;
}
flags |= flag_defs[j].val;
break;
}
if (flag_defs[j].name == NULL) {
rb_raise(rb_eArgError, "Unknown %s flag: %.*s", flag_name, (int)len, name);
}
}
return flags;
}

static VALUE dummy_env_method_missing(int argc, VALUE *argv, VALUE self)
{
Expand Down Expand Up @@ -644,14 +692,27 @@ static VALUE oci8_svcctx_logoff(VALUE self)
}

/*
* @overload commit
* @overload commit(*flags)
*
* Commits the transaction.
*
* @param []
*/
static VALUE oci8_commit(VALUE self)
static VALUE oci8_commit(int argc, VALUE *argv, VALUE self)
{
static const ub4_flag_def_t flag_defs[] = {
{"two_phase", OCI_TRANS_TWOPHASE},
{"write_immediate", OCI_TRANS_WRITEIMMED},
{"write_batch", OCI_TRANS_WRITEBATCH},
{"write_wait", OCI_TRANS_WRITEWAIT},
{"write_no_wait", OCI_TRANS_WRITENOWAIT},
{NULL, 0},
};
oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
chker2(OCITransCommit_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT), &svcctx->base);
ub4 flags = check_ub4_flags(argc, argv, flag_defs, "commit");

chker2(OCITransCommit_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, flags),
&svcctx->base);
return self;
}

Expand Down Expand Up @@ -975,6 +1036,70 @@ static VALUE oci8_set_client_info(VALUE self, VALUE val)
return val;
}

static VALUE oci8_get_trans_handle(VALUE self)
{
return rb_ivar_get(self, id_at_trans_handle);
}

static VALUE oci8_set_trans_handle(VALUE self, VALUE obj)
{
oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
oci8_base_t *trans = oci8_check_typeddata(obj, &oci8_trans_data_type, 1);
chker2(OCIAttrSet(svcctx->base.hp.svc, OCI_HTYPE_SVCCTX, trans->hp.ptr, 0, OCI_ATTR_TRANS, oci8_errhp),
&svcctx->base);
rb_ivar_set(self, id_at_trans_handle, obj);
return obj;
}

static VALUE oci8_trans_start(int argc, VALUE *argv, VALUE self)
{
static const ub4_flag_def_t flag_defs[] = {
{"new", OCI_TRANS_NEW},
{"tight", OCI_TRANS_TIGHT},
{"loose", OCI_TRANS_LOOSE},
{"resume", OCI_TRANS_RESUME},
{"readonly", OCI_TRANS_READONLY},
{"serializable", OCI_TRANS_SERIALIZABLE},
{NULL, 0},
};
oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
uword timeout;
ub4 flags;

if (argc == 0) {
rb_raise(rb_eArgError, "wrong number of arguments (given 0, expected 1+)");
}
timeout = NUM2UINT(argv[0]);
flags = check_ub4_flags(argc - 1, argv + 1, flag_defs, "trans_start");
chker2(OCITransStart_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, timeout, flags),
&svcctx->base);
return self;
}

static VALUE oci8_trans_detach(VALUE self)
{
oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
chker2(OCITransDetach_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT),
&svcctx->base);
return self;
}

static VALUE oci8_trans_prepare(VALUE self)
{
oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
sword rv = OCITransPrepare_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT);
chker2(rv, &svcctx->base);
return rv == OCI_SUCCESS ? Qtrue : Qfalse;
}

static VALUE oci8_trans_forget(VALUE self)
{
oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
chker2(OCITransForget_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT),
&svcctx->base);
return self;
}

void Init_oci8(VALUE *out)
{
VALUE obj;
Expand All @@ -990,6 +1115,7 @@ void Init_oci8(VALUE *out)
cProcess = oci8_define_class_under(cOCI8, "Process", &oci8_process_data_type, oci8_process_alloc);
id_at_session_handle = rb_intern("@session_handle");
id_at_server_handle = rb_intern("@server_handle");
id_at_trans_handle = rb_intern("@trans_handle");

/* setup a dummy environment handle to lazily initialize the environment handle */
obj = rb_obj_alloc(rb_cObject);
Expand Down Expand Up @@ -1020,7 +1146,7 @@ void Init_oci8(VALUE *out)
rb_define_private_method(cOCI8, "server_attach", oci8_server_attach, 2);
rb_define_private_method(cOCI8, "session_begin", oci8_session_begin, 2);
rb_define_method(cOCI8, "logoff", oci8_svcctx_logoff, 0);
rb_define_method(cOCI8, "commit", oci8_commit, 0);
rb_define_method(cOCI8, "commit", oci8_commit, -1);
rb_define_method(cOCI8, "rollback", oci8_rollback, 0);
rb_define_method(cOCI8, "non_blocking?", oci8_non_blocking_p, 0);
rb_define_method(cOCI8, "non_blocking=", oci8_set_non_blocking, 1);
Expand All @@ -1035,6 +1161,12 @@ void Init_oci8(VALUE *out)
rb_define_method(cOCI8, "module=", oci8_set_module, 1);
rb_define_method(cOCI8, "action=", oci8_set_action, 1);
rb_define_method(cOCI8, "client_info=", oci8_set_client_info, 1);
rb_define_method(cOCI8, "trans_handle", oci8_get_trans_handle, 0);
rb_define_method(cOCI8, "trans_handle=", oci8_set_trans_handle, 1);
rb_define_method(cOCI8, "trans_start", oci8_trans_start, -1);
rb_define_method(cOCI8, "trans_detach", oci8_trans_detach, 0);
rb_define_method(cOCI8, "trans_prepare", oci8_trans_prepare, 0);
rb_define_method(cOCI8, "trans_forget", oci8_trans_forget, 0);
*out = cOCI8;
}

Expand Down
4 changes: 4 additions & 0 deletions ext/oci8/oci8.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,10 @@ VALUE oci8_make_interval_ds(OCIInterval *s);
/* object.c */
void Init_oci_object(VALUE mOCI);

/* transaction.c */
void Init_oci8_transaction(VALUE cOCI8);
extern const oci8_handle_data_type_t oci8_trans_data_type;

/* attr.c */
VALUE oci8_get_rowid_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp);

Expand Down
1 change: 1 addition & 0 deletions ext/oci8/oci8lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ Init_oci8lib()
Init_ora_date();
Init_oci_datetime();
Init_oci_object(cOCI8);
Init_oci8_transaction(cOCI8);

#ifdef USE_WIN32_C
Init_oci8_win32(cOCI8);
Expand Down
Loading