ruby-oci8 1.0.7 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +1254 -390
- data/Makefile +10 -13
- data/README +56 -385
- data/VERSION +1 -1
- data/dist-files +26 -27
- data/ext/oci8/.document +1 -0
- data/ext/oci8/MANIFEST +0 -4
- data/ext/oci8/apiwrap.c.tmpl +172 -0
- data/ext/oci8/apiwrap.h.tmpl +61 -0
- data/ext/oci8/apiwrap.rb +91 -0
- data/ext/oci8/apiwrap.yml +1243 -0
- data/ext/oci8/attr.c +124 -384
- data/ext/oci8/bind.c +472 -164
- data/ext/oci8/encoding.c +196 -0
- data/ext/oci8/env.c +84 -253
- data/ext/oci8/error.c +196 -127
- data/ext/oci8/extconf.rb +82 -59
- data/ext/oci8/lob.c +710 -370
- data/ext/oci8/metadata.c +359 -0
- data/ext/oci8/object.c +622 -0
- data/ext/oci8/oci8.c +577 -161
- data/ext/oci8/oci8.h +354 -258
- data/ext/oci8/oci8lib.c +493 -0
- data/ext/oci8/ocidatetime.c +473 -0
- data/ext/oci8/ocinumber.c +1123 -24
- data/ext/oci8/oraconf.rb +72 -106
- data/ext/oci8/oradate.c +511 -321
- data/ext/oci8/stmt.c +752 -572
- data/ext/oci8/win32.c +131 -0
- data/ext/oci8/xmldb.c +383 -0
- data/lib/.document +2 -0
- data/lib/dbd/OCI8.rb +2 -17
- data/lib/oci8.rb.in +41 -1622
- data/lib/oci8/.document +5 -0
- data/lib/oci8/compat.rb +108 -0
- data/lib/oci8/datetime.rb +489 -0
- data/lib/oci8/encoding-init.rb +40 -0
- data/lib/oci8/encoding.yml +537 -0
- data/lib/oci8/metadata.rb +2077 -0
- data/lib/oci8/object.rb +548 -0
- data/lib/oci8/oci8.rb +773 -0
- data/lib/oci8/oracle_version.rb +144 -0
- data/metaconfig +3 -3
- data/ruby-oci8.gemspec +5 -5
- data/setup.rb +4 -4
- data/test/config.rb +64 -84
- data/test/test_all.rb +14 -21
- data/test/test_array_dml.rb +317 -0
- data/test/test_bind_raw.rb +18 -25
- data/test/test_bind_time.rb +78 -91
- data/test/test_break.rb +37 -35
- data/test/test_clob.rb +33 -89
- data/test/test_connstr.rb +5 -4
- data/test/test_datetime.rb +469 -0
- data/test/test_dbi.rb +99 -60
- data/test/test_dbi_clob.rb +3 -8
- data/test/test_metadata.rb +65 -51
- data/test/test_oci8.rb +151 -55
- data/test/test_oracle_version.rb +70 -0
- data/test/test_oradate.rb +76 -83
- data/test/test_oranumber.rb +405 -71
- data/test/test_rowid.rb +6 -11
- metadata +31 -32
- data/NEWS +0 -420
- data/ext/oci8/const.c +0 -165
- data/ext/oci8/define.c +0 -53
- data/ext/oci8/describe.c +0 -81
- data/ext/oci8/descriptor.c +0 -39
- data/ext/oci8/handle.c +0 -273
- data/ext/oci8/oranumber.c +0 -445
- data/ext/oci8/param.c +0 -37
- data/ext/oci8/server.c +0 -182
- data/ext/oci8/session.c +0 -99
- data/ext/oci8/svcctx.c +0 -238
- data/ruby-oci8.spec +0 -62
- data/support/README +0 -4
- data/support/runit/assert.rb +0 -281
- data/support/runit/cui/testrunner.rb +0 -101
- data/support/runit/error.rb +0 -4
- data/support/runit/method_mappable.rb +0 -20
- data/support/runit/robserver.rb +0 -25
- data/support/runit/setuppable.rb +0 -15
- data/support/runit/teardownable.rb +0 -16
- data/support/runit/testcase.rb +0 -113
- data/support/runit/testfailure.rb +0 -25
- data/support/runit/testresult.rb +0 -121
- data/support/runit/testsuite.rb +0 -43
- data/support/runit/version.rb +0 -3
- data/test/test_describe.rb +0 -137
data/ext/oci8/encoding.c
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* encoding.c - part of ruby-oci8
|
4
|
+
*
|
5
|
+
* Copyright (C) 2008 KUBO Takehiro <kubo@jiubao.org>
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
#include "oci8.h"
|
9
|
+
|
10
|
+
#ifndef OCI_NLS_MAXBUFSZ
|
11
|
+
#define OCI_NLS_MAXBUFSZ 100
|
12
|
+
#endif
|
13
|
+
|
14
|
+
/* type of callback function's argument */
|
15
|
+
typedef struct {
|
16
|
+
oci8_svcctx_t *svcctx;
|
17
|
+
OCIStmt *stmtp;
|
18
|
+
union {
|
19
|
+
VALUE name;
|
20
|
+
int csid;
|
21
|
+
} u;
|
22
|
+
} cb_arg_t;
|
23
|
+
|
24
|
+
/* Oracle charset id -> Oracle charset name */
|
25
|
+
static VALUE csid2name;
|
26
|
+
|
27
|
+
/* Oracle charset name -> Oracle charset id */
|
28
|
+
static ID id_upcase;
|
29
|
+
static VALUE csname2id;
|
30
|
+
static VALUE oci8_charset_name2id(VALUE svc, VALUE name);
|
31
|
+
#ifdef HAVE_TYPE_RB_ENCODING
|
32
|
+
rb_encoding *oci8_encoding;
|
33
|
+
#endif
|
34
|
+
|
35
|
+
VALUE oci8_charset_id2name(VALUE svc, VALUE csid)
|
36
|
+
{
|
37
|
+
VALUE name = rb_hash_aref(csid2name, csid);
|
38
|
+
|
39
|
+
if (!NIL_P(name)) {
|
40
|
+
return name;
|
41
|
+
}
|
42
|
+
Check_Type(csid, T_FIXNUM);
|
43
|
+
if (have_OCINlsCharSetIdToName) {
|
44
|
+
/* Oracle 9iR2 or upper */
|
45
|
+
char buf[OCI_NLS_MAXBUFSZ];
|
46
|
+
sword rv;
|
47
|
+
|
48
|
+
rv = OCINlsCharSetIdToName(oci8_envhp, TO_ORATEXT(buf), sizeof(buf), FIX2INT(csid));
|
49
|
+
if (rv != OCI_SUCCESS) {
|
50
|
+
return Qnil;
|
51
|
+
}
|
52
|
+
name = rb_usascii_str_new_cstr(buf);
|
53
|
+
} else {
|
54
|
+
/* Oracle 9iR1 or lower */
|
55
|
+
oci8_exec_sql_var_t bind_vars[2];
|
56
|
+
char buf[OCI_NLS_MAXBUFSZ];
|
57
|
+
ub2 buflen = 0;
|
58
|
+
int ival = FIX2INT(csid);
|
59
|
+
|
60
|
+
/* :name */
|
61
|
+
bind_vars[0].valuep = buf;
|
62
|
+
bind_vars[0].value_sz = OCI_NLS_MAXBUFSZ;
|
63
|
+
bind_vars[0].dty = SQLT_CHR;
|
64
|
+
bind_vars[0].indp = NULL;
|
65
|
+
bind_vars[0].alenp = &buflen;
|
66
|
+
/* :csid */
|
67
|
+
bind_vars[1].valuep = &ival;
|
68
|
+
bind_vars[1].value_sz = sizeof(int);
|
69
|
+
bind_vars[1].dty = SQLT_INT;
|
70
|
+
bind_vars[1].indp = NULL;
|
71
|
+
bind_vars[1].alenp = NULL;
|
72
|
+
|
73
|
+
/* convert chaset id to charset name by querying Oracle server. */
|
74
|
+
oci8_exec_sql(oci8_get_svcctx(svc), "BEGIN :name := nls_charset_name(:csid); END;", 0, NULL, 2, bind_vars, 1);
|
75
|
+
if (buflen == 0) {
|
76
|
+
return Qnil;
|
77
|
+
}
|
78
|
+
name = rb_usascii_str_new(buf, buflen);
|
79
|
+
}
|
80
|
+
OBJ_FREEZE(name);
|
81
|
+
rb_hash_aset(csid2name, csid, name);
|
82
|
+
rb_hash_aset(csname2id, name, csid);
|
83
|
+
return name;
|
84
|
+
}
|
85
|
+
|
86
|
+
static VALUE oci8_charset_name2id(VALUE svc, VALUE name)
|
87
|
+
{
|
88
|
+
VALUE csid;
|
89
|
+
|
90
|
+
name = rb_funcall(name, id_upcase, 0);
|
91
|
+
csid = rb_hash_aref(csname2id, StringValue(name));
|
92
|
+
if (!NIL_P(csid)) {
|
93
|
+
return csid;
|
94
|
+
}
|
95
|
+
if (have_OCINlsCharSetNameToId) {
|
96
|
+
/* Oracle 9iR2 or upper */
|
97
|
+
ub2 rv;
|
98
|
+
|
99
|
+
rv = OCINlsCharSetNameToId(oci8_envhp, RSTRING_ORATEXT(name));
|
100
|
+
if (rv == 0) {
|
101
|
+
return Qnil;
|
102
|
+
}
|
103
|
+
csid = INT2FIX(rv);
|
104
|
+
} else {
|
105
|
+
/* Oracle 9iR1 or lower */
|
106
|
+
oci8_exec_sql_var_t bind_vars[2];
|
107
|
+
int ival;
|
108
|
+
sb2 ind = 0; /* null indicator */
|
109
|
+
|
110
|
+
/* :csid */
|
111
|
+
bind_vars[0].valuep = &ival;
|
112
|
+
bind_vars[0].value_sz = sizeof(int);
|
113
|
+
bind_vars[0].dty = SQLT_INT;
|
114
|
+
bind_vars[0].indp = &ind;
|
115
|
+
bind_vars[0].alenp = NULL;
|
116
|
+
/* :name */
|
117
|
+
bind_vars[1].valuep = RSTRING_PTR(name);
|
118
|
+
bind_vars[1].value_sz = RSTRING_LEN(name);
|
119
|
+
bind_vars[1].dty = SQLT_CHR;
|
120
|
+
bind_vars[1].indp = NULL;
|
121
|
+
bind_vars[1].alenp = NULL;
|
122
|
+
|
123
|
+
/* convert chaset name to charset id by querying Oracle server. */
|
124
|
+
oci8_exec_sql(oci8_get_svcctx(svc), "BEGIN :csid := nls_charset_id(:name); END;", 0, NULL, 2, bind_vars, 1);
|
125
|
+
if (ind) {
|
126
|
+
return Qnil;
|
127
|
+
}
|
128
|
+
csid = INT2FIX(ival);
|
129
|
+
}
|
130
|
+
rb_hash_aset(csid2name, csid, name);
|
131
|
+
rb_hash_aset(csname2id, name, csid);
|
132
|
+
return csid;
|
133
|
+
}
|
134
|
+
|
135
|
+
#ifdef HAVE_TYPE_RB_ENCODING
|
136
|
+
|
137
|
+
/*
|
138
|
+
* call-seq:
|
139
|
+
* OCI8.encoding -> enc
|
140
|
+
*
|
141
|
+
* (new in ruby 1.9)
|
142
|
+
*
|
143
|
+
* Returns Oracle client encoding.
|
144
|
+
*
|
145
|
+
* String values passed to Oracle, such as SQL statements,
|
146
|
+
* bind values etc., are converted from their encoding to
|
147
|
+
* the Oracle client encoding.
|
148
|
+
*
|
149
|
+
* If <code>Encoding.default_internal</code> is nil,
|
150
|
+
* string values got from Oracle are tagged by
|
151
|
+
* <code>OCI8.encoding</code>. If not nil, they are
|
152
|
+
* converted from <code>OCI8.encoding</code> to
|
153
|
+
* <code>Encoding.default_internal</code> by default.
|
154
|
+
*
|
155
|
+
* If it is 'ASCII-8BIT', no encoding conversions are done.
|
156
|
+
*/
|
157
|
+
static VALUE oci8_get_encoding(VALUE klass)
|
158
|
+
{
|
159
|
+
return rb_enc_from_encoding(oci8_encoding);
|
160
|
+
}
|
161
|
+
|
162
|
+
/*
|
163
|
+
* call-seq:
|
164
|
+
* OCI8.encoding = enc or nil
|
165
|
+
*
|
166
|
+
* (new in ruby 1.9)
|
167
|
+
*
|
168
|
+
* Sets Oracle client encoding.
|
169
|
+
*/
|
170
|
+
static VALUE oci8_set_encoding(VALUE klass, VALUE encoding)
|
171
|
+
{
|
172
|
+
if (NIL_P(encoding)) {
|
173
|
+
oci8_encoding = NULL;
|
174
|
+
} else {
|
175
|
+
oci8_encoding = rb_to_encoding(encoding);
|
176
|
+
}
|
177
|
+
return encoding;
|
178
|
+
}
|
179
|
+
#endif
|
180
|
+
|
181
|
+
void Init_oci8_encoding(VALUE cOCI8)
|
182
|
+
{
|
183
|
+
csid2name = rb_hash_new();
|
184
|
+
rb_global_variable(&csid2name);
|
185
|
+
|
186
|
+
id_upcase = rb_intern("upcase");
|
187
|
+
csname2id = rb_hash_new();
|
188
|
+
rb_global_variable(&csname2id);
|
189
|
+
|
190
|
+
rb_define_method(cOCI8, "charset_name2id", oci8_charset_name2id, 1);
|
191
|
+
rb_define_method(cOCI8, "charset_id2name", oci8_charset_id2name, 1);
|
192
|
+
#ifdef HAVE_TYPE_RB_ENCODING
|
193
|
+
rb_define_singleton_method(cOCI8, "encoding", oci8_get_encoding, 0);
|
194
|
+
rb_define_singleton_method(cOCI8, "encoding=", oci8_set_encoding, 1);
|
195
|
+
#endif
|
196
|
+
}
|
data/ext/oci8/env.c
CHANGED
@@ -1,276 +1,107 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
1
2
|
/*
|
2
3
|
env.c - part of ruby-oci8
|
3
4
|
|
4
|
-
Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
|
5
|
+
Copyright (C) 2002-2008 KUBO Takehiro <kubo@jiubao.org>
|
5
6
|
|
6
|
-
=begin
|
7
|
-
== OCIEnv
|
8
|
-
The environment handle is the source of all OCI objects.
|
9
|
-
Usually there is one instance per one application.
|
10
|
-
|
11
|
-
super class: ((<OCIHandle>))
|
12
|
-
|
13
|
-
correspond native OCI datatype: ((|OCIEnv|))
|
14
|
-
=end
|
15
7
|
*/
|
16
8
|
#include "oci8.h"
|
17
|
-
#include <util.h> /* ruby_setenv */
|
18
|
-
|
19
|
-
RBOCI_NORETURN(static void oci8_raise_init_error(void));
|
20
|
-
|
21
|
-
static void oci8_raise_init_error(void)
|
22
|
-
{
|
23
|
-
VALUE msg = rb_str_new2("OCI Library Initialization Error");
|
24
|
-
VALUE exc = rb_funcall(eOCIError, oci8_id_new, 1, msg);
|
25
|
-
rb_ivar_set(exc, oci8_id_code, rb_ary_new3(1, INT2FIX(-1)));
|
26
|
-
rb_ivar_set(exc, oci8_id_message, rb_ary_new3(1, msg));
|
27
|
-
rb_exc_raise(exc);
|
28
|
-
}
|
29
|
-
|
30
|
-
static VALUE oci8_env_s_initialize(int argc, VALUE *argv, VALUE klass)
|
31
|
-
{
|
32
|
-
VALUE vmode;
|
33
|
-
ub4 mode;
|
34
|
-
sword rv;
|
35
|
-
|
36
|
-
#ifndef WIN32
|
37
|
-
/* workaround code.
|
38
|
-
*
|
39
|
-
* Some instant clients set the environment variables
|
40
|
-
* ORA_NLS_PROFILE33, ORA_NLS10 and ORACLE_HOME if they aren't
|
41
|
-
* set. It causes problems on some platforms.
|
42
|
-
*/
|
43
|
-
if (RTEST(rb_eval_string("RUBY_VERSION == \"1.8.4\""))) {
|
44
|
-
if (getenv("ORA_NLS_PROFILE33") == NULL) {
|
45
|
-
ruby_setenv("ORA_NLS_PROFILE33", "");
|
46
|
-
}
|
47
|
-
if (getenv("ORA_NLS10") == NULL) {
|
48
|
-
ruby_setenv("ORA_NLS10", "");
|
49
|
-
}
|
50
|
-
if (getenv("ORACLE_HOME") == NULL) {
|
51
|
-
ruby_setenv("ORACLE_HOME", ".");
|
52
|
-
}
|
53
|
-
}
|
54
|
-
#endif /* WIN32 */
|
55
|
-
|
56
|
-
rb_scan_args(argc, argv, "01", &vmode);
|
57
|
-
Get_Int_With_Default(argc, 1, vmode, mode, OCI_DEFAULT); /* 1 */
|
58
|
-
|
59
|
-
rv = OCIInitialize(mode, NULL, NULL, NULL, NULL);
|
60
|
-
return INT2FIX(rv);
|
61
|
-
}
|
62
|
-
|
63
|
-
static VALUE oci8_env_s_init(int argc, VALUE *argv, VALUE klass)
|
64
|
-
{
|
65
|
-
VALUE vmode;
|
66
|
-
ub4 mode;
|
67
|
-
OCIEnv *envhp = NULL;
|
68
|
-
OCIError *errhp;
|
69
|
-
oci8_handle_t *h;
|
70
|
-
sword rv;
|
71
|
-
|
72
|
-
rb_scan_args(argc, argv, "01", &vmode);
|
73
|
-
Get_Int_With_Default(argc, 1, vmode, mode, OCI_DEFAULT); /* 1 */
|
74
|
-
|
75
|
-
rv = OCIEnvInit(&envhp, OCI_DEFAULT, 0, NULL);
|
76
|
-
if (envhp == NULL) {
|
77
|
-
oci8_raise_init_error();
|
78
|
-
}
|
79
|
-
if (rv != OCI_SUCCESS)
|
80
|
-
oci8_env_raise(envhp, rv);
|
81
|
-
rv = OCIHandleAlloc(envhp, (dvoid *)&errhp, OCI_HTYPE_ERROR, 0, NULL);
|
82
|
-
if (rv != OCI_SUCCESS)
|
83
|
-
oci8_env_raise(envhp, rv);
|
84
|
-
h = oci8_make_handle(OCI_HTYPE_ENV, envhp, errhp, NULL, 0);
|
85
|
-
return h->self;
|
86
|
-
}
|
87
|
-
|
88
|
-
/*
|
89
|
-
=begin
|
90
|
-
--- OCIEnv.create([mode])
|
91
|
-
create the environment handle. Don't call `new'.
|
92
|
-
|
93
|
-
:mode
|
94
|
-
((|OCI_DEFAULT|)), ((|OCI_THREADED|)), ((|OCI_OBJECT|)), ((|OCI_SHARED|))
|
95
|
-
or these combination.
|
96
|
-
But I test only ((|OCI_DEFAULT|)). Default value is ((|OCI_DEFAULT|)).
|
97
|
-
|
98
|
-
((|OCI_THREADED|)): if your application use native thread(not ruby's thread), use this.
|
99
|
-
|
100
|
-
((|OCI_OBJECT|)): for OCI objects. But current implementation doesn't support OCI Object-Relational functions.
|
101
|
-
This is for ((*far future*)) extension, because my plan doesn't include `OCI object support'.
|
102
|
-
|
103
|
-
((|OCI_SHARED|))(Oracle 8i or later): for ((<Shared Data Mode>)).
|
104
|
-
|
105
|
-
:return value
|
106
|
-
A instance of ((<OCIEnv>)).
|
107
|
-
|
108
|
-
correspond native OCI function: ((|OCIEnvCreate|)) (if ((|OCIEnvCreate|)) is not found, the combination of ((|OCIInitialize|)) and ((|OCIEnvInit|)).)
|
109
|
-
=end
|
110
|
-
*/
|
111
|
-
#ifdef HAVE_OCIENVCREATE
|
112
|
-
static VALUE oci8_env_s_create(int argc, VALUE *argv, VALUE klass)
|
113
|
-
{
|
114
|
-
VALUE vmode;
|
115
|
-
ub4 mode;
|
116
|
-
OCIEnv *envhp = NULL;
|
117
|
-
OCIError *errhp;
|
118
|
-
oci8_handle_t *h;
|
119
|
-
sword rv;
|
120
9
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
rv = OCIEnvCreate(&envhp, mode, NULL, NULL, NULL, NULL, 0, NULL);
|
125
|
-
if (envhp == NULL) {
|
126
|
-
oci8_raise_init_error();
|
127
|
-
}
|
128
|
-
if (rv != OCI_SUCCESS)
|
129
|
-
oci8_env_raise(envhp, rv);
|
130
|
-
rv = OCIHandleAlloc(envhp, (dvoid *)&errhp, OCI_HTYPE_ERROR, 0, NULL);
|
131
|
-
if (rv != OCI_SUCCESS)
|
132
|
-
oci8_env_raise(envhp, rv);
|
133
|
-
h = oci8_make_handle(OCI_HTYPE_ENV, envhp, errhp, NULL, 0);
|
134
|
-
return h->self;
|
135
|
-
}
|
10
|
+
#if !defined(RUBY_VM)
|
11
|
+
/* ruby_setenv for workaround ruby 1.8.4 */
|
12
|
+
#include <util.h>
|
136
13
|
#endif
|
137
14
|
|
15
|
+
OCIEnv *oci8_envhp;
|
16
|
+
#ifdef RUBY_VM
|
138
17
|
/*
|
139
|
-
|
140
|
-
|
141
|
-
:mode
|
142
|
-
((|OCI_DEFAULT|)) only valid. Default value is ((|OCI__DEFAULT|)).
|
143
|
-
|
144
|
-
correspond native OCI function: ((|OCITerminate|))
|
145
|
-
=end
|
146
|
-
*/
|
147
|
-
#ifdef HAVE_OCITERMINATE
|
148
|
-
static VALUE oci8_env_s_terminate(int argc, VALUE *argv, VALUE klass)
|
149
|
-
{
|
150
|
-
VALUE vmode;
|
151
|
-
ub4 mode;
|
152
|
-
|
153
|
-
if (rb_scan_args(argc, argv, "01", &vmode) == 1) {
|
154
|
-
Check_Type(vmode, T_FIXNUM);
|
155
|
-
mode = FIX2INT(vmode);
|
156
|
-
} else {
|
157
|
-
mode = OCI_DEFAULT;
|
158
|
-
}
|
159
|
-
|
160
|
-
OCITerminate(mode);
|
161
|
-
return Qnil;
|
162
|
-
}
|
163
|
-
#endif
|
18
|
+
* oci8_errhp is a thread local object in ruby 1.9.
|
19
|
+
*/
|
164
20
|
|
165
|
-
/*
|
166
|
-
|
167
|
-
--- OCIEnv#alloc(handle)
|
168
|
-
create a new OCI handle.
|
169
|
-
:handle
|
170
|
-
The valid values are ((<OCISvcCtx>)), ((<OCIStmt>)),
|
171
|
-
((<OCIServer>)), ((<OCISession>)), and ((<OCIDescribe>)).
|
172
|
-
:return value
|
173
|
-
A newly created handle.
|
21
|
+
oci8_tls_key_t oci8_tls_key; /* native thread key */
|
22
|
+
static ID id_thread_key; /* ruby's thread key */
|
174
23
|
|
175
|
-
|
176
|
-
=end
|
177
|
-
*/
|
178
|
-
typedef sword (*alloc_func_t)(CONST dvoid *, dvoid **, CONST ub4, CONST size_t, dvoid **);
|
179
|
-
static VALUE oci8_handle_alloc(VALUE self, VALUE klass)
|
24
|
+
static void oci8_free_errhp(OCIError *errhp)
|
180
25
|
{
|
181
|
-
|
182
|
-
dvoid *hp;
|
183
|
-
oci8_handle_t *envh;
|
184
|
-
oci8_handle_t *h;
|
185
|
-
int i;
|
186
|
-
struct {
|
187
|
-
VALUE *klass;
|
188
|
-
ub4 type;
|
189
|
-
alloc_func_t alloc_func;
|
190
|
-
} alloc_map[] = {
|
191
|
-
{&cOCISvcCtx, OCI_HTYPE_SVCCTX, (alloc_func_t)OCIHandleAlloc},
|
192
|
-
{&cOCIStmt, OCI_HTYPE_STMT, (alloc_func_t)OCIHandleAlloc},
|
193
|
-
{&cOCIServer, OCI_HTYPE_SERVER, (alloc_func_t)OCIHandleAlloc},
|
194
|
-
{&cOCISession, OCI_HTYPE_SESSION, (alloc_func_t)OCIHandleAlloc},
|
195
|
-
{&cOCIDescribe, OCI_HTYPE_DESCRIBE, (alloc_func_t)OCIHandleAlloc},
|
196
|
-
{&cOCILobLocator, OCI_DTYPE_LOB, (alloc_func_t)OCIDescriptorAlloc},
|
197
|
-
{&cOCIFileLocator, OCI_DTYPE_FILE, (alloc_func_t)OCIDescriptorAlloc},
|
198
|
-
};
|
199
|
-
#define ALLOC_MAP_SIZE (sizeof(alloc_map) / sizeof(alloc_map[0]))
|
200
|
-
|
201
|
-
Get_Handle(self, envh);
|
202
|
-
for (i = 0;i < ALLOC_MAP_SIZE;i++) {
|
203
|
-
if (alloc_map[i].klass[0] == klass)
|
204
|
-
break;
|
205
|
-
}
|
206
|
-
if (i == ALLOC_MAP_SIZE) {
|
207
|
-
rb_raise(rb_eTypeError, "not valid handle type %s", rb_class2name(CLASS_OF(klass)));
|
208
|
-
}
|
209
|
-
|
210
|
-
rv = alloc_map[i].alloc_func(envh->hp, &hp, alloc_map[i].type, 0, NULL);
|
211
|
-
if (rv != OCI_SUCCESS)
|
212
|
-
oci8_env_raise(envh->hp, rv);
|
213
|
-
h = oci8_make_handle(alloc_map[i].type, hp, envh->errhp, envh, 0);
|
214
|
-
return h->self;
|
26
|
+
OCIHandleFree(errhp, OCI_HTYPE_ERROR);
|
215
27
|
}
|
216
28
|
|
217
|
-
|
218
|
-
=begin
|
219
|
-
--- OCIEnv#logon(username, password, dbname)
|
220
|
-
Logon to the Oracle server.
|
221
|
-
|
222
|
-
See ((<Simplified Logon>)) and ((<Explicit Attach and Begin Session>))
|
223
|
-
|
224
|
-
:username
|
225
|
-
the username.
|
226
|
-
:password
|
227
|
-
the user's password.
|
228
|
-
:dbname
|
229
|
-
the name of the database, or nil.
|
230
|
-
:return value
|
231
|
-
A instance of ((<OCISvcCtx>))
|
232
|
-
For example:
|
233
|
-
env = OCIEnv.create()
|
234
|
-
svc = env.logon("SCOTT", "TIGER", nil)
|
235
|
-
or
|
236
|
-
svc = env.logon("SCOTT", "TIGER", "ORCL.WORLD")
|
237
|
-
|
238
|
-
correspond native OCI function: ((|OCILogon|))
|
239
|
-
=end
|
240
|
-
*/
|
241
|
-
static VALUE oci8_logon(VALUE self, VALUE username, VALUE password, VALUE dbname)
|
29
|
+
OCIError *oci8_make_errhp(void)
|
242
30
|
{
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
31
|
+
OCIError *errhp;
|
32
|
+
VALUE obj;
|
33
|
+
sword rv;
|
34
|
+
|
35
|
+
/* create a new errhp. */
|
36
|
+
rv = OCIHandleAlloc(oci8_envhp, (dvoid *)&errhp, OCI_HTYPE_ERROR, 0, NULL);
|
37
|
+
if (rv != OCI_SUCCESS) {
|
38
|
+
oci8_env_raise(oci8_envhp, rv);
|
39
|
+
}
|
40
|
+
/* create a new ruby object which contains errhp to make
|
41
|
+
* sure that the errhp is freed when it become unnecessary.
|
42
|
+
*/
|
43
|
+
obj = Data_Wrap_Struct(rb_cObject, NULL, oci8_free_errhp, errhp);
|
44
|
+
/* set the ruby object to ruby's thread local storage to prevent
|
45
|
+
* it from being freed while the thread is available.
|
46
|
+
*/
|
47
|
+
rb_thread_local_aset(rb_thread_current(), id_thread_key, obj);
|
48
|
+
|
49
|
+
oci8_tls_set(oci8_tls_key, (void*)errhp);
|
50
|
+
return errhp;
|
262
51
|
}
|
52
|
+
#else
|
53
|
+
/*
|
54
|
+
* oci8_errhp is global in ruby 1.8.
|
55
|
+
*/
|
56
|
+
OCIError *oci8_errhp;
|
57
|
+
#endif
|
263
58
|
|
264
59
|
void Init_oci8_env(void)
|
265
60
|
{
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
61
|
+
sword rv;
|
62
|
+
#ifdef RUBY_VM
|
63
|
+
ub4 mode = OCI_OBJECT | OCI_THREADED;
|
64
|
+
int error;
|
65
|
+
#else
|
66
|
+
ub4 mode = OCI_OBJECT;
|
270
67
|
#endif
|
271
|
-
|
272
|
-
|
68
|
+
|
69
|
+
#if !defined(RUBY_VM) && !defined(_WIN32)
|
70
|
+
/* workaround code.
|
71
|
+
*
|
72
|
+
* Some instant clients set the environment variables
|
73
|
+
* ORA_NLS_PROFILE33, ORA_NLS10 and ORACLE_HOME if they aren't
|
74
|
+
* set. It causes problems on some platforms.
|
75
|
+
*/
|
76
|
+
if (RTEST(rb_eval_string("RUBY_VERSION == \"1.8.4\""))) {
|
77
|
+
if (getenv("ORA_NLS_PROFILE33") == NULL) {
|
78
|
+
ruby_setenv("ORA_NLS_PROFILE33", "");
|
79
|
+
}
|
80
|
+
if (getenv("ORA_NLS10") == NULL) {
|
81
|
+
ruby_setenv("ORA_NLS10", "");
|
82
|
+
}
|
83
|
+
if (getenv("ORACLE_HOME") == NULL) {
|
84
|
+
ruby_setenv("ORACLE_HOME", ".");
|
85
|
+
}
|
86
|
+
}
|
87
|
+
#endif /* WIN32 */
|
88
|
+
rv = OCIInitialize(mode, NULL, NULL, NULL, NULL);
|
89
|
+
if (rv != OCI_SUCCESS) {
|
90
|
+
oci8_raise_init_error();
|
91
|
+
}
|
92
|
+
rv = OCIEnvInit(&oci8_envhp, OCI_DEFAULT, 0, NULL);
|
93
|
+
if (rv != OCI_SUCCESS) {
|
94
|
+
oci8_raise_init_error();
|
95
|
+
}
|
96
|
+
#ifdef RUBY_VM
|
97
|
+
id_thread_key = rb_intern("__oci8_errhp__");
|
98
|
+
error = oci8_tls_key_init(&oci8_tls_key);
|
99
|
+
if (error != 0) {
|
100
|
+
rb_raise(rb_eRuntimeError, "Cannot create thread local key (errno = %d)", error);
|
101
|
+
}
|
102
|
+
#else /* RUBY_VM */
|
103
|
+
rv = OCIHandleAlloc(oci8_envhp, (dvoid *)&oci8_errhp, OCI_HTYPE_ERROR, 0, NULL);
|
104
|
+
if (rv != OCI_SUCCESS)
|
105
|
+
oci8_env_raise(oci8_envhp, rv);
|
273
106
|
#endif
|
274
|
-
rb_define_method(cOCIEnv, "alloc", oci8_handle_alloc, 1);
|
275
|
-
rb_define_method(cOCIEnv, "logon", oci8_logon, 3);
|
276
107
|
}
|