ruby-oci8 1.0.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/ChangeLog +1254 -390
  2. data/Makefile +10 -13
  3. data/README +56 -385
  4. data/VERSION +1 -1
  5. data/dist-files +26 -27
  6. data/ext/oci8/.document +1 -0
  7. data/ext/oci8/MANIFEST +0 -4
  8. data/ext/oci8/apiwrap.c.tmpl +172 -0
  9. data/ext/oci8/apiwrap.h.tmpl +61 -0
  10. data/ext/oci8/apiwrap.rb +91 -0
  11. data/ext/oci8/apiwrap.yml +1243 -0
  12. data/ext/oci8/attr.c +124 -384
  13. data/ext/oci8/bind.c +472 -164
  14. data/ext/oci8/encoding.c +196 -0
  15. data/ext/oci8/env.c +84 -253
  16. data/ext/oci8/error.c +196 -127
  17. data/ext/oci8/extconf.rb +82 -59
  18. data/ext/oci8/lob.c +710 -370
  19. data/ext/oci8/metadata.c +359 -0
  20. data/ext/oci8/object.c +622 -0
  21. data/ext/oci8/oci8.c +577 -161
  22. data/ext/oci8/oci8.h +354 -258
  23. data/ext/oci8/oci8lib.c +493 -0
  24. data/ext/oci8/ocidatetime.c +473 -0
  25. data/ext/oci8/ocinumber.c +1123 -24
  26. data/ext/oci8/oraconf.rb +72 -106
  27. data/ext/oci8/oradate.c +511 -321
  28. data/ext/oci8/stmt.c +752 -572
  29. data/ext/oci8/win32.c +131 -0
  30. data/ext/oci8/xmldb.c +383 -0
  31. data/lib/.document +2 -0
  32. data/lib/dbd/OCI8.rb +2 -17
  33. data/lib/oci8.rb.in +41 -1622
  34. data/lib/oci8/.document +5 -0
  35. data/lib/oci8/compat.rb +108 -0
  36. data/lib/oci8/datetime.rb +489 -0
  37. data/lib/oci8/encoding-init.rb +40 -0
  38. data/lib/oci8/encoding.yml +537 -0
  39. data/lib/oci8/metadata.rb +2077 -0
  40. data/lib/oci8/object.rb +548 -0
  41. data/lib/oci8/oci8.rb +773 -0
  42. data/lib/oci8/oracle_version.rb +144 -0
  43. data/metaconfig +3 -3
  44. data/ruby-oci8.gemspec +5 -5
  45. data/setup.rb +4 -4
  46. data/test/config.rb +64 -84
  47. data/test/test_all.rb +14 -21
  48. data/test/test_array_dml.rb +317 -0
  49. data/test/test_bind_raw.rb +18 -25
  50. data/test/test_bind_time.rb +78 -91
  51. data/test/test_break.rb +37 -35
  52. data/test/test_clob.rb +33 -89
  53. data/test/test_connstr.rb +5 -4
  54. data/test/test_datetime.rb +469 -0
  55. data/test/test_dbi.rb +99 -60
  56. data/test/test_dbi_clob.rb +3 -8
  57. data/test/test_metadata.rb +65 -51
  58. data/test/test_oci8.rb +151 -55
  59. data/test/test_oracle_version.rb +70 -0
  60. data/test/test_oradate.rb +76 -83
  61. data/test/test_oranumber.rb +405 -71
  62. data/test/test_rowid.rb +6 -11
  63. metadata +31 -32
  64. data/NEWS +0 -420
  65. data/ext/oci8/const.c +0 -165
  66. data/ext/oci8/define.c +0 -53
  67. data/ext/oci8/describe.c +0 -81
  68. data/ext/oci8/descriptor.c +0 -39
  69. data/ext/oci8/handle.c +0 -273
  70. data/ext/oci8/oranumber.c +0 -445
  71. data/ext/oci8/param.c +0 -37
  72. data/ext/oci8/server.c +0 -182
  73. data/ext/oci8/session.c +0 -99
  74. data/ext/oci8/svcctx.c +0 -238
  75. data/ruby-oci8.spec +0 -62
  76. data/support/README +0 -4
  77. data/support/runit/assert.rb +0 -281
  78. data/support/runit/cui/testrunner.rb +0 -101
  79. data/support/runit/error.rb +0 -4
  80. data/support/runit/method_mappable.rb +0 -20
  81. data/support/runit/robserver.rb +0 -25
  82. data/support/runit/setuppable.rb +0 -15
  83. data/support/runit/teardownable.rb +0 -16
  84. data/support/runit/testcase.rb +0 -113
  85. data/support/runit/testfailure.rb +0 -25
  86. data/support/runit/testresult.rb +0 -121
  87. data/support/runit/testsuite.rb +0 -43
  88. data/support/runit/version.rb +0 -3
  89. data/test/test_describe.rb +0 -137
@@ -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
+ }
@@ -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
- rb_scan_args(argc, argv, "01", &vmode);
122
- Get_Int_With_Default(argc, 1, vmode, mode, OCI_DEFAULT); /* 1 */
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
- =begin
140
- --- OCIEnv.terminate([mode])
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
- =begin
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
- correspond native OCI function: ((|OCIHandleAlloc|))
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
- sword rv;
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
- oci8_handle_t *envh;
244
- oci8_handle_t *svch;
245
- OCISvcCtx *svchp;
246
- oci8_string_t u, p, d;
247
- VALUE obj;
248
- sword rv;
249
-
250
- Get_Handle(self, envh);
251
- Get_String(username, u);
252
- Get_String(password, p);
253
- Get_String(dbname, d);
254
- rv = OCILogon(envh->hp, envh->errhp, &svchp,
255
- u.ptr, u.len, p.ptr, p.len, d.ptr, d.len);
256
- if (rv != OCI_SUCCESS) {
257
- oci8_raise(envh->errhp, rv, NULL);
258
- }
259
- svch = oci8_make_handle(OCI_HTYPE_SVCCTX, svchp, envh->errhp, envh, 0);
260
- obj = svch->self;
261
- return obj;
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
- rb_define_singleton_method(cOCIEnv, "initialise", oci8_env_s_initialize, -1);
267
- rb_define_singleton_method(cOCIEnv, "init", oci8_env_s_init, -1);
268
- #ifdef HAVE_OCIENVCREATE
269
- rb_define_singleton_method(cOCIEnv, "create", oci8_env_s_create, -1);
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
- #ifdef HAVE_OCITERMINATE
272
- rb_define_singleton_method(cOCIEnv, "terminate", oci8_env_s_terminate, -1);
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
  }