[ruby-oci8-commit] [303] trunk/ruby-oci8: * ext/oci8/attr.c: rewrite code converting the rowid descriptor
nobody at rubyforge.org
nobody at rubyforge.org
Tue Dec 30 08:39:05 EST 2008
Revision: 303
Author: kubo
Date: 2008-12-30 08:39:05 -0500 (Tue, 30 Dec 2008)
Log Message:
-----------
* ext/oci8/attr.c: rewrite code converting the rowid descriptor
to string representation by using oci8_exec_sql().
* ext/oci8/oci8.c, ext/oci8/oci8.h, ext/oci8/oci8lib.c,
ext/oci8/stmt.c: add check code to ensure that the process id
is not changed.
Modified Paths:
--------------
trunk/ruby-oci8/ChangeLog
trunk/ruby-oci8/ext/oci8/attr.c
trunk/ruby-oci8/ext/oci8/oci8.c
trunk/ruby-oci8/ext/oci8/oci8.h
trunk/ruby-oci8/ext/oci8/oci8lib.c
trunk/ruby-oci8/ext/oci8/stmt.c
Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog 2008-12-30 11:13:46 UTC (rev 302)
+++ trunk/ruby-oci8/ChangeLog 2008-12-30 13:39:05 UTC (rev 303)
@@ -1,4 +1,11 @@
2008-12-30 KUBO Takehiro <kubo at jiubao.org>
+ * ext/oci8/attr.c: rewrite code converting the rowid descriptor
+ to string representation by using oci8_exec_sql().
+ * ext/oci8/oci8.c, ext/oci8/oci8.h, ext/oci8/oci8lib.c,
+ ext/oci8/stmt.c: add check code to ensure that the process id
+ is not changed.
+
+2008-12-30 KUBO Takehiro <kubo at jiubao.org>
* ext/oci8/oraconf.rb: add code to check the cpu type of Mac OS X
libclntsh.dylib.
Modified: trunk/ruby-oci8/ext/oci8/attr.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/attr.c 2008-12-30 11:13:46 UTC (rev 302)
+++ trunk/ruby-oci8/ext/oci8/attr.c 2008-12-30 13:39:05 UTC (rev 303)
@@ -75,7 +75,6 @@
oci8_base_t *base;
ub4 attrtype;
OCIRowid *ridp;
- OCIStmt *stmtp;
} rowid_arg_t;
static VALUE get_rowid_attr(rowid_arg_t *arg)
@@ -86,7 +85,7 @@
ub2 buflen;
sword rv;
- /* get a rowid descriptor from OCIHandle */
+ /* get a rowid descriptor from OCIHandle */
rv = OCIDescriptorAlloc(oci8_envhp, (dvoid*)&arg->ridp, OCI_DTYPE_ROWID, 0, NULL);
if (rv != OCI_SUCCESS)
oci8_env_raise(oci8_envhp, rv);
@@ -107,9 +106,7 @@
* Oracle Server.
*/
oci8_base_t *svc;
- OCIBind *bind1 = NULL;
- OCIBind *bind2 = NULL;
- sword rv;
+ oci8_exec_sql_var_t bind_vars[2];
/* search a connection from the handle */
svc = base;
@@ -119,43 +116,29 @@
rb_raise(rb_eRuntimeError, "No connection is found!!");
}
}
- /*
- * equivalent code:
- * cursor = conn.parse("BEGIN :1 := :2; END;")
- * cursor.bind(1, nil, String, MAX_ROWID_LEN)
- * cursor.bind(2, rowid, OCIRowid)
- * cursor.exec()
- * cursor[1] # => rowid's string representation
- */
-#define ROWIDTOCHAR_SQL "BEGIN :1 := :2; END;"
- buflen = 0;
- rv = OCIHandleAlloc(oci8_envhp, (dvoid*)&arg->stmtp, OCI_HTYPE_STMT, 0, NULL);
- if (rv != OCI_SUCCESS) {
- oci8_env_raise(oci8_envhp, rv);
+ /* :strval */
+ bind_vars[0].valuep = buf;
+ bind_vars[0].value_sz = sizeof(buf);
+ bind_vars[0].dty = SQLT_CHR;
+ bind_vars[0].indp = NULL;
+ bind_vars[0].alenp = &buflen;
+ /* :rowid */
+ bind_vars[1].valuep = &arg->ridp;
+ bind_vars[1].value_sz = sizeof(void *);
+ bind_vars[1].dty = SQLT_RDD;
+ bind_vars[1].indp = NULL;
+ bind_vars[1].alenp = NULL;
+ /* convert the rowid descriptor to a string value by querying Oracle server. */
+ oci8_exec_sql((oci8_svcctx_t*)svc, "BEGIN :strval := :rowid; END;", 0, NULL, 2, bind_vars, 1);
+ if (buflen == 0) {
+ return Qnil;
}
- oci_lc(OCIStmtPrepare(arg->stmtp, oci8_errhp, (text*)ROWIDTOCHAR_SQL, strlen(ROWIDTOCHAR_SQL), OCI_NTV_SYNTAX, OCI_DEFAULT));
- oci_lc(OCIBindByPos(arg->stmtp, &bind1, oci8_errhp, 1, buf, MAX_ROWID_LEN, SQLT_STR, NULL, &buflen, 0, 0, 0, OCI_DEFAULT));
- oci_lc(OCIBindByPos(arg->stmtp, &bind2, oci8_errhp, 2, (dvoid*)&arg->ridp, sizeof(void*), SQLT_RDD, NULL, NULL, 0, 0, 0, OCI_DEFAULT));
- rv = OCIStmtExecute_nb((oci8_svcctx_t*)svc, svc->hp.svc, arg->stmtp, oci8_errhp, 1, 0, NULL, NULL, OCI_DEFAULT);
- if (rv == OCI_ERROR) {
- if (oci8_get_error_code(oci8_errhp) == 1000) {
- /* run GC to close unreferred cursors
- * when ORA-01000 (maximum open cursors exceeded).
- */
- rb_gc();
- rv = OCIStmtExecute_nb((oci8_svcctx_t*)svc, svc->hp.svc, arg->stmtp, oci8_errhp, 1, 0, NULL, NULL, OCI_DEFAULT);
- }
- }
- oci_lc(rv);
}
return rb_str_new(buf, buflen);
}
static VALUE rowid_ensure(rowid_arg_t *arg)
{
- if (arg->stmtp != NULL) {
- OCIHandleFree(arg->stmtp, OCI_HTYPE_STMT);
- }
if (arg->ridp != NULL) {
OCIDescriptorFree(arg->ridp, OCI_DTYPE_ROWID);
}
@@ -168,6 +151,5 @@
arg.base = base;
arg.attrtype = attrtype;
arg.ridp = NULL;
- arg.stmtp = NULL;
return rb_ensure(get_rowid_attr, (VALUE)&arg, rowid_ensure, (VALUE)&arg);
}
Modified: trunk/ruby-oci8/ext/oci8/oci8.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.c 2008-12-30 11:13:46 UTC (rev 302)
+++ trunk/ruby-oci8/ext/oci8/oci8.c 2008-12-30 13:39:05 UTC (rev 303)
@@ -6,7 +6,17 @@
*
*/
#include "oci8.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* getpid() */
+#endif
+#ifdef WIN32
+#ifndef getpid
+extern rb_pid_t rb_w32_getpid(void);
+#define getpid() rb_w32_getpid()
+#endif
+#endif
+
/*
* Document-class: OCI8
*
@@ -236,6 +246,7 @@
default:
break;
}
+ svcctx->pid = getpid();
svcctx->is_autocommit = 0;
#ifdef RUBY_VM
svcctx->non_blocking = 0;
@@ -565,3 +576,11 @@
}
return svcctx->authhp;
}
+
+void oci8_check_pid_consistency(oci8_svcctx_t *svcctx)
+{
+ if (svcctx->pid != getpid()) {
+ rb_raise(rb_eRuntimeError, "The connection cannot be reused in the forked process.");
+ }
+}
+
Modified: trunk/ruby-oci8/ext/oci8/oci8.h
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.h 2008-12-30 11:13:46 UTC (rev 302)
+++ trunk/ruby-oci8/ext/oci8/oci8.h 2008-12-30 13:39:05 UTC (rev 303)
@@ -12,9 +12,18 @@
#include "intern.h"
#endif
+#ifndef rb_pid_t
+#ifdef WIN32
+#define rb_pid_t int
+#else
+#define rb_pid_t pid_t
+#endif
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+
#ifdef __cplusplus
extern "C"
{
@@ -234,6 +243,7 @@
enum logon_type_t logon_type;
OCISession *authhp;
OCIServer *srvhp;
+ rb_pid_t pid;
char is_autocommit;
#ifdef RUBY_VM
char non_blocking;
@@ -335,6 +345,7 @@
oci8_svcctx_t *oci8_get_svcctx(VALUE obj);
OCISvcCtx *oci8_get_oci_svcctx(VALUE obj);
OCISession *oci8_get_oci_session(VALUE obj);
+void oci8_check_pid_consistency(oci8_svcctx_t *svcctx);
#define TO_SVCCTX oci8_get_oci_svcctx
#define TO_SESSION oci8_get_oci_session
Modified: trunk/ruby-oci8/ext/oci8/oci8lib.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8lib.c 2008-12-30 11:13:46 UTC (rev 302)
+++ trunk/ruby-oci8/ext/oci8/oci8lib.c 2008-12-30 13:39:05 UTC (rev 303)
@@ -317,6 +317,8 @@
sword oci8_exec_sql(oci8_svcctx_t *svcctx, const char *sql_text, ub4 num_define_vars, oci8_exec_sql_var_t *define_vars, ub4 num_bind_vars, oci8_exec_sql_var_t *bind_vars, int raise_on_error)
{
cb_arg_t arg;
+
+ oci8_check_pid_consistency(svcctx);
arg.svcctx = svcctx;
arg.sql_text = sql_text;
arg.num_define_vars = num_define_vars;
Modified: trunk/ruby-oci8/ext/oci8/stmt.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/stmt.c 2008-12-30 11:13:46 UTC (rev 302)
+++ trunk/ruby-oci8/ext/oci8/stmt.c 2008-12-30 13:39:05 UTC (rev 303)
@@ -67,7 +67,7 @@
rb_scan_args(argc, argv, "11", &svc, &sql);
- oci8_get_svcctx(svc); /* check argument */
+ oci8_check_pid_consistency(oci8_get_svcctx(svc));
if (argc > 1)
StringValue(sql);
More information about the ruby-oci8-commit
mailing list