ruby-oci8-master 2.0.7

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.
Files changed (84) hide show
  1. data/ChangeLog +2321 -0
  2. data/Makefile +88 -0
  3. data/NEWS +303 -0
  4. data/README +76 -0
  5. data/VERSION +1 -0
  6. data/dist-files +83 -0
  7. data/doc/api.en.html +527 -0
  8. data/doc/api.en.rd +554 -0
  9. data/doc/api.ja.html +525 -0
  10. data/doc/api.ja.rd +557 -0
  11. data/doc/manual.css +35 -0
  12. data/ext/oci8/.document +18 -0
  13. data/ext/oci8/MANIFEST +18 -0
  14. data/ext/oci8/apiwrap.c.tmpl +182 -0
  15. data/ext/oci8/apiwrap.h.tmpl +61 -0
  16. data/ext/oci8/apiwrap.rb +91 -0
  17. data/ext/oci8/apiwrap.yml +1455 -0
  18. data/ext/oci8/attr.c +105 -0
  19. data/ext/oci8/bind.c +366 -0
  20. data/ext/oci8/connection_pool.c +199 -0
  21. data/ext/oci8/encoding.c +289 -0
  22. data/ext/oci8/env.c +178 -0
  23. data/ext/oci8/error.c +378 -0
  24. data/ext/oci8/extconf.rb +179 -0
  25. data/ext/oci8/lob.c +805 -0
  26. data/ext/oci8/metadata.c +232 -0
  27. data/ext/oci8/object.c +727 -0
  28. data/ext/oci8/oci8.c +1156 -0
  29. data/ext/oci8/oci8.h +574 -0
  30. data/ext/oci8/oci8lib.c +527 -0
  31. data/ext/oci8/ocidatetime.c +484 -0
  32. data/ext/oci8/ocihandle.c +751 -0
  33. data/ext/oci8/ocinumber.c +1612 -0
  34. data/ext/oci8/oraconf.rb +1119 -0
  35. data/ext/oci8/oradate.c +611 -0
  36. data/ext/oci8/oranumber_util.c +352 -0
  37. data/ext/oci8/oranumber_util.h +24 -0
  38. data/ext/oci8/post-config.rb +5 -0
  39. data/ext/oci8/stmt.c +673 -0
  40. data/ext/oci8/thread_util.c +85 -0
  41. data/ext/oci8/thread_util.h +30 -0
  42. data/ext/oci8/win32.c +137 -0
  43. data/lib/.document +1 -0
  44. data/lib/dbd/OCI8.rb +591 -0
  45. data/lib/oci8.rb.in +94 -0
  46. data/lib/oci8/.document +8 -0
  47. data/lib/oci8/bindtype.rb +349 -0
  48. data/lib/oci8/compat.rb +113 -0
  49. data/lib/oci8/connection_pool.rb +99 -0
  50. data/lib/oci8/datetime.rb +611 -0
  51. data/lib/oci8/encoding-init.rb +74 -0
  52. data/lib/oci8/encoding.yml +537 -0
  53. data/lib/oci8/metadata.rb +2132 -0
  54. data/lib/oci8/object.rb +581 -0
  55. data/lib/oci8/oci8.rb +721 -0
  56. data/lib/oci8/ocihandle.rb +425 -0
  57. data/lib/oci8/oracle_version.rb +144 -0
  58. data/lib/oci8/properties.rb +73 -0
  59. data/metaconfig +142 -0
  60. data/pre-distclean.rb +7 -0
  61. data/ruby-oci8.gemspec +63 -0
  62. data/setup.rb +1331 -0
  63. data/test/README +4 -0
  64. data/test/config.rb +122 -0
  65. data/test/test_all.rb +51 -0
  66. data/test/test_appinfo.rb +63 -0
  67. data/test/test_array_dml.rb +333 -0
  68. data/test/test_bind_raw.rb +46 -0
  69. data/test/test_bind_time.rb +178 -0
  70. data/test/test_break.rb +96 -0
  71. data/test/test_clob.rb +82 -0
  72. data/test/test_connstr.rb +81 -0
  73. data/test/test_datetime.rb +582 -0
  74. data/test/test_dbi.rb +366 -0
  75. data/test/test_dbi_clob.rb +53 -0
  76. data/test/test_encoding.rb +100 -0
  77. data/test/test_error.rb +88 -0
  78. data/test/test_metadata.rb +1399 -0
  79. data/test/test_oci8.rb +434 -0
  80. data/test/test_oracle_version.rb +70 -0
  81. data/test/test_oradate.rb +256 -0
  82. data/test/test_oranumber.rb +746 -0
  83. data/test/test_rowid.rb +33 -0
  84. metadata +137 -0
@@ -0,0 +1,105 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * attr.c
4
+ *
5
+ * Copyright (C) 2002-2007 KUBO Takehiro <kubo@jiubao.org>
6
+ */
7
+ #include "oci8.h"
8
+
9
+ VALUE oci8_get_sb1_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
10
+ {
11
+ sb1 val;
12
+
13
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp),
14
+ base, stmtp);
15
+ return INT2FIX(val);
16
+ }
17
+
18
+ VALUE oci8_get_ub2_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
19
+ {
20
+ ub2 val;
21
+
22
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp),
23
+ base, stmtp);
24
+ return INT2FIX(val);
25
+ }
26
+
27
+ VALUE oci8_get_sb2_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
28
+ {
29
+ sb2 val;
30
+
31
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp),
32
+ base, stmtp);
33
+ return INT2FIX(val);
34
+ }
35
+
36
+ VALUE oci8_get_ub4_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
37
+ {
38
+ ub4 val;
39
+
40
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp),
41
+ base, stmtp);
42
+ #if SIZEOF_LONG > 4
43
+ return LONG2FIX(val);
44
+ #else
45
+ return ULONG2NUM(val);
46
+ #endif
47
+ }
48
+
49
+ VALUE oci8_get_string_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
50
+ {
51
+ text *val;
52
+ ub4 size;
53
+
54
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, &size, attrtype, oci8_errhp),
55
+ base, stmtp);
56
+ return rb_external_str_new_with_enc(TO_CHARPTR(val), size, oci8_encoding);
57
+ }
58
+
59
+ #define MAX_ROWID_LEN 128
60
+
61
+ typedef struct {
62
+ oci8_base_t *base;
63
+ OCIStmt *stmtp;
64
+ ub4 attrtype;
65
+ OCIRowid *ridp;
66
+ } rowid_arg_t;
67
+
68
+ static VALUE get_rowid_attr(rowid_arg_t *arg)
69
+ {
70
+ oci8_base_t *base = arg->base;
71
+ ub4 attrtype = arg->attrtype;
72
+ char buf[MAX_ROWID_LEN];
73
+ ub2 buflen;
74
+ sword rv;
75
+
76
+ /* get a rowid descriptor from OCIHandle */
77
+ rv = OCIDescriptorAlloc(oci8_envhp, (dvoid*)&arg->ridp, OCI_DTYPE_ROWID, 0, NULL);
78
+ if (rv != OCI_SUCCESS)
79
+ oci8_env_raise(oci8_envhp, rv);
80
+ chker3(OCIAttrGet(base->hp.ptr, base->type, arg->ridp, 0, attrtype, oci8_errhp),
81
+ base, arg->stmtp);
82
+ /* convert the rowid descriptor to a string. */
83
+ buflen = MAX_ROWID_LEN;
84
+ chker3(OCIRowidToChar(arg->ridp, TO_ORATEXT(buf), &buflen, oci8_errhp),
85
+ base, arg->stmtp);
86
+ return rb_external_str_new_with_enc(buf, buflen, rb_usascii_encoding());
87
+ }
88
+
89
+ static VALUE rowid_ensure(rowid_arg_t *arg)
90
+ {
91
+ if (arg->ridp != NULL) {
92
+ OCIDescriptorFree(arg->ridp, OCI_DTYPE_ROWID);
93
+ }
94
+ return Qnil;
95
+ }
96
+
97
+ VALUE oci8_get_rowid_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
98
+ {
99
+ rowid_arg_t arg;
100
+ arg.base = base;
101
+ arg.stmtp = stmtp;
102
+ arg.attrtype = attrtype;
103
+ arg.ridp = NULL;
104
+ return rb_ensure(get_rowid_attr, (VALUE)&arg, rowid_ensure, (VALUE)&arg);
105
+ }
@@ -0,0 +1,366 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * bind.c
4
+ *
5
+ * Copyright (C) 2002-2011 KUBO Takehiro <kubo@jiubao.org>
6
+ */
7
+ #include "oci8.h"
8
+
9
+ #ifndef OCI_ATTR_MAXCHAR_SIZE
10
+ #define OCI_ATTR_MAXCHAR_SIZE 164
11
+ #endif
12
+
13
+ static ID id_bind_type;
14
+ static VALUE sym_length;
15
+ static VALUE sym_length_semantics;
16
+ static VALUE sym_char;
17
+ static VALUE sym_nchar;
18
+
19
+ static VALUE cOCI8BindTypeBase;
20
+
21
+ typedef struct {
22
+ oci8_bind_t obind;
23
+ sb4 bytelen;
24
+ sb4 charlen;
25
+ ub1 csfrm;
26
+ } oci8_bind_string_t;
27
+
28
+ /*
29
+ * bind_string
30
+ */
31
+ static VALUE bind_string_get(oci8_bind_t *obind, void *data, void *null_struct)
32
+ {
33
+ oci8_vstr_t *vstr = (oci8_vstr_t *)data;
34
+ return rb_external_str_new_with_enc(vstr->buf, vstr->size, oci8_encoding);
35
+ }
36
+
37
+ static void bind_string_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
38
+ {
39
+ oci8_bind_string_t *obs = (oci8_bind_string_t *)obind;
40
+ oci8_vstr_t *vstr = (oci8_vstr_t *)data;
41
+
42
+ OCI8StringValue(val);
43
+ if (RSTRING_LEN(val) > obs->bytelen) {
44
+ rb_raise(rb_eArgError, "too long String to set. (%ld for %d)", RSTRING_LEN(val), obs->bytelen);
45
+ }
46
+ memcpy(vstr->buf, RSTRING_PTR(val), RSTRING_LEN(val));
47
+ vstr->size = RSTRING_LEN(val);
48
+ }
49
+
50
+ static void bind_string_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE param)
51
+ {
52
+ oci8_bind_string_t *obs = (oci8_bind_string_t *)obind;
53
+ VALUE length;
54
+ VALUE length_semantics;
55
+ VALUE nchar;
56
+ sb4 sz;
57
+
58
+ Check_Type(param, T_HASH);
59
+ length = rb_hash_aref(param, sym_length);
60
+ length_semantics = rb_hash_aref(param, sym_length_semantics);
61
+ nchar = rb_hash_aref(param, sym_nchar);
62
+
63
+ sz = NUM2INT(length);
64
+ if (sz < 0) {
65
+ rb_raise(rb_eArgError, "invalid bind length %d", sz);
66
+ }
67
+ if (length_semantics == sym_char) {
68
+ /* character semantics */
69
+ obs->charlen = sz;
70
+ obs->bytelen = sz = sz * oci8_nls_ratio;
71
+ if (oci8_nls_ratio == 1) {
72
+ /* sz must be bigger than charlen to suppress ORA-06502.
73
+ * I don't know the reason...
74
+ */
75
+ sz *= 2;
76
+ }
77
+ } else {
78
+ /* byte semantics */
79
+ obs->bytelen = sz;
80
+ obs->charlen = 0;
81
+ }
82
+ if (RTEST(nchar)) {
83
+ obs->csfrm = SQLCS_NCHAR; /* bind as NCHAR/NVARCHAR2 */
84
+ } else {
85
+ obs->csfrm = SQLCS_IMPLICIT; /* bind as CHAR/VARCHAR2 */
86
+ }
87
+ if (sz == 0) {
88
+ sz = 1; /* to avoid ORA-01459. */
89
+ }
90
+ sz += sizeof(sb4);
91
+ obind->value_sz = sz;
92
+ obind->alloc_sz = (sz + (sizeof(sb4) - 1)) & ~(sizeof(sb4) - 1);
93
+ }
94
+
95
+ static void bind_string_post_bind_hook(oci8_bind_t *obind)
96
+ {
97
+ oci8_bind_string_t *obs = (oci8_bind_string_t *)obind;
98
+
99
+ if (obs->charlen != 0) {
100
+ chker2(OCIAttrSet(obind->base.hp.ptr, obind->base.type, (void*)&obs->charlen, 0, OCI_ATTR_MAXCHAR_SIZE, oci8_errhp),
101
+ &obind->base);
102
+ }
103
+ chker2(OCIAttrSet(obind->base.hp.ptr, obind->base.type, (void*)&obs->csfrm, 0, OCI_ATTR_CHARSET_FORM, oci8_errhp),
104
+ &obind->base);
105
+ }
106
+
107
+ static const oci8_bind_vtable_t bind_string_vtable = {
108
+ {
109
+ NULL,
110
+ oci8_bind_free,
111
+ sizeof(oci8_bind_string_t)
112
+ },
113
+ bind_string_get,
114
+ bind_string_set,
115
+ bind_string_init,
116
+ NULL,
117
+ NULL,
118
+ SQLT_LVC,
119
+ bind_string_post_bind_hook,
120
+ };
121
+
122
+ /*
123
+ * bind_raw
124
+ */
125
+ static VALUE bind_raw_get(oci8_bind_t *obind, void *data, void *null_struct)
126
+ {
127
+ oci8_vstr_t *vstr = (oci8_vstr_t *)data;
128
+ return rb_str_new(vstr->buf, vstr->size);
129
+ }
130
+
131
+ static void bind_raw_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
132
+ {
133
+ oci8_bind_string_t *obs = (oci8_bind_string_t *)obind;
134
+ oci8_vstr_t *vstr = (oci8_vstr_t *)data;
135
+
136
+ StringValue(val);
137
+ if (RSTRING_LEN(val) > obs->bytelen) {
138
+ rb_raise(rb_eArgError, "too long String to set. (%ld for %d)", RSTRING_LEN(val), obs->bytelen);
139
+ }
140
+ memcpy(vstr->buf, RSTRING_PTR(val), RSTRING_LEN(val));
141
+ vstr->size = RSTRING_LEN(val);
142
+ }
143
+
144
+ static const oci8_bind_vtable_t bind_raw_vtable = {
145
+ {
146
+ NULL,
147
+ oci8_bind_free,
148
+ sizeof(oci8_bind_string_t)
149
+ },
150
+ bind_raw_get,
151
+ bind_raw_set,
152
+ bind_string_init,
153
+ NULL,
154
+ NULL,
155
+ SQLT_LVB
156
+ };
157
+
158
+ /*
159
+ * bind_binary_double
160
+ */
161
+ static VALUE bind_binary_double_get(oci8_bind_t *obind, void *data, void *null_struct)
162
+ {
163
+ return rb_float_new(*(double*)data);
164
+ }
165
+
166
+ static void bind_binary_double_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
167
+ {
168
+ /* val is converted to Float if it isn't Float. */
169
+ *(double*)data = RFLOAT_VALUE(rb_Float(val));
170
+ }
171
+
172
+ static void bind_binary_double_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
173
+ {
174
+ obind->value_sz = sizeof(double);
175
+ obind->alloc_sz = sizeof(double);
176
+ }
177
+
178
+ #ifndef SQLT_BDOUBLE
179
+ #define SQLT_BDOUBLE 22
180
+ #endif
181
+ static const oci8_bind_vtable_t bind_binary_double_vtable = {
182
+ {
183
+ NULL,
184
+ oci8_bind_free,
185
+ sizeof(oci8_bind_t)
186
+ },
187
+ bind_binary_double_get,
188
+ bind_binary_double_set,
189
+ bind_binary_double_init,
190
+ NULL,
191
+ NULL,
192
+ SQLT_BDOUBLE
193
+ };
194
+
195
+ static VALUE oci8_bind_get(VALUE self)
196
+ {
197
+ oci8_bind_t *obind = DATA_PTR(self);
198
+ const oci8_bind_vtable_t *vptr = (const oci8_bind_vtable_t *)obind->base.vptr;
199
+ ub4 idx = obind->curar_idx;
200
+ void **null_structp = NULL;
201
+
202
+ if (NIL_P(obind->tdo)) {
203
+ if (obind->u.inds[idx] != 0)
204
+ return Qnil;
205
+ }
206
+ return vptr->get(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp);
207
+ }
208
+
209
+ VALUE oci8_bind_get_data(VALUE self)
210
+ {
211
+ oci8_bind_t *obind = DATA_PTR(self);
212
+
213
+ if (obind->maxar_sz == 0) {
214
+ obind->curar_idx = 0;
215
+ return rb_funcall(self, oci8_id_get, 0);
216
+ } else {
217
+ volatile VALUE ary = rb_ary_new2(obind->curar_sz);
218
+ ub4 idx;
219
+
220
+ for (idx = 0; idx < obind->curar_sz; idx++) {
221
+ obind->curar_idx = idx;
222
+ rb_ary_store(ary, idx, rb_funcall(self, oci8_id_get, 0));
223
+ }
224
+ return ary;
225
+ }
226
+ }
227
+
228
+ static VALUE oci8_bind_set(VALUE self, VALUE val)
229
+ {
230
+ oci8_bind_t *obind = DATA_PTR(self);
231
+ const oci8_bind_vtable_t *vptr = (const oci8_bind_vtable_t *)obind->base.vptr;
232
+ ub4 idx = obind->curar_idx;
233
+
234
+ if (NIL_P(val)) {
235
+ if (NIL_P(obind->tdo)) {
236
+ obind->u.inds[idx] = -1;
237
+ } else {
238
+ *(OCIInd*)obind->u.null_structs[idx] = -1;
239
+ }
240
+ } else {
241
+ void **null_structp = NULL;
242
+
243
+ if (NIL_P(obind->tdo)) {
244
+ null_structp = NULL;
245
+ obind->u.inds[idx] = 0;
246
+ } else {
247
+ null_structp = &obind->u.null_structs[idx];
248
+ *(OCIInd*)obind->u.null_structs[idx] = 0;
249
+ }
250
+ vptr->set(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp, val);
251
+ }
252
+ return self;
253
+ }
254
+
255
+ void oci8_bind_set_data(VALUE self, VALUE val)
256
+ {
257
+ oci8_bind_t *obind = DATA_PTR(self);
258
+
259
+ if (obind->maxar_sz == 0) {
260
+ obind->curar_idx = 0;
261
+ rb_funcall(self, oci8_id_set, 1, val);
262
+ } else {
263
+ ub4 size;
264
+ ub4 idx;
265
+ Check_Type(val, T_ARRAY);
266
+
267
+ size = RARRAY_LEN(val);
268
+ if (size > obind->maxar_sz) {
269
+ rb_raise(rb_eRuntimeError, "over the max array size");
270
+ }
271
+ for (idx = 0; idx < size; idx++) {
272
+ obind->curar_idx = idx;
273
+ rb_funcall(self, oci8_id_set, 1, RARRAY_PTR(val)[idx]);
274
+ }
275
+ obind->curar_sz = size;
276
+ }
277
+ }
278
+
279
+ static VALUE oci8_bind_initialize(VALUE self, VALUE svc, VALUE val, VALUE length, VALUE max_array_size)
280
+ {
281
+ oci8_bind_t *obind = DATA_PTR(self);
282
+ const oci8_bind_vtable_t *bind_class = (const oci8_bind_vtable_t *)obind->base.vptr;
283
+ ub4 cnt = 1;
284
+
285
+ obind->tdo = Qnil;
286
+ obind->maxar_sz = NIL_P(max_array_size) ? 0 : NUM2UINT(max_array_size);
287
+ obind->curar_sz = 0;
288
+ if (obind->maxar_sz > 0)
289
+ cnt = obind->maxar_sz;
290
+ bind_class->init(obind, svc, val, length);
291
+ if (obind->alloc_sz > 0) {
292
+ obind->valuep = xmalloc(obind->alloc_sz * cnt);
293
+ memset(obind->valuep, 0, obind->alloc_sz * cnt);
294
+ } else {
295
+ obind->valuep = NULL;
296
+ }
297
+ if (NIL_P(obind->tdo)) {
298
+ obind->u.inds = xmalloc(sizeof(sb2) * cnt);
299
+ memset(obind->u.inds, -1, sizeof(sb2) * cnt);
300
+ } else {
301
+ obind->u.null_structs = xmalloc(sizeof(void *) * cnt);
302
+ memset(obind->u.null_structs, 0, sizeof(void *) * cnt);
303
+ }
304
+ if (bind_class->init_elem != NULL) {
305
+ bind_class->init_elem(obind, svc);
306
+ }
307
+ if (!NIL_P(val)) {
308
+ oci8_bind_set_data(self, val);
309
+ }
310
+ return Qnil;
311
+ }
312
+
313
+ void oci8_bind_free(oci8_base_t *base)
314
+ {
315
+ oci8_bind_t *obind = (oci8_bind_t *)base;
316
+ if (obind->valuep != NULL) {
317
+ xfree(obind->valuep);
318
+ obind->valuep = NULL;
319
+ }
320
+ if (obind->u.inds != NULL) {
321
+ xfree(obind->u.inds);
322
+ obind->u.inds = NULL;
323
+ }
324
+ }
325
+
326
+ void oci8_bind_hp_obj_mark(oci8_base_t *base)
327
+ {
328
+ oci8_bind_t *obind = (oci8_bind_t *)base;
329
+ oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
330
+
331
+ if (oho != NULL) {
332
+ ub4 idx = 0;
333
+
334
+ do {
335
+ rb_gc_mark(oho[idx].obj);
336
+ } while (++idx < obind->maxar_sz);
337
+ }
338
+ }
339
+
340
+ void Init_oci8_bind(VALUE klass)
341
+ {
342
+ cOCI8BindTypeBase = klass;
343
+ id_bind_type = rb_intern("bind_type");
344
+ sym_length = ID2SYM(rb_intern("length"));
345
+ sym_length_semantics = ID2SYM(rb_intern("length_semantics"));
346
+ sym_char = ID2SYM(rb_intern("char"));
347
+ sym_nchar = ID2SYM(rb_intern("nchar"));
348
+
349
+ rb_define_method(cOCI8BindTypeBase, "initialize", oci8_bind_initialize, 4);
350
+ rb_define_method(cOCI8BindTypeBase, "get", oci8_bind_get, 0);
351
+ rb_define_method(cOCI8BindTypeBase, "set", oci8_bind_set, 1);
352
+
353
+ /* register primitive data types. */
354
+ oci8_define_bind_class("String", &bind_string_vtable);
355
+ oci8_define_bind_class("RAW", &bind_raw_vtable);
356
+ if (oracle_client_version >= ORAVER_10_1) {
357
+ oci8_define_bind_class("BinaryDouble", &bind_binary_double_vtable);
358
+ }
359
+ }
360
+
361
+ oci8_bind_t *oci8_get_bind(VALUE obj)
362
+ {
363
+ oci8_base_t *base;
364
+ Check_Handle(obj, cOCI8BindTypeBase, base);
365
+ return (oci8_bind_t *)base;
366
+ }