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.
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,359 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * metadata.c
4
+ *
5
+ * Copyright (C) 2006-2007 KUBO Takehiro <kubo@jiubao.org>
6
+ *
7
+ * implement private methods of classes in OCI8::Metadata module.
8
+ *
9
+ * public methods are implemented by oci8/metadata.rb.
10
+ */
11
+ #include "oci8.h"
12
+
13
+ static VALUE mOCI8Metadata;
14
+ VALUE cOCI8MetadataBase;
15
+ static VALUE ptype_to_class;
16
+ static VALUE class_to_ptype;
17
+
18
+ typedef struct {
19
+ oci8_base_t base;
20
+ VALUE svc;
21
+ ub1 is_implicit;
22
+ } oci8_metadata_t;
23
+
24
+ static void oci8_metadata_mark(oci8_base_t *base)
25
+ {
26
+ oci8_metadata_t *md = (oci8_metadata_t *)base;
27
+ if (base->parent != NULL)
28
+ rb_gc_mark(base->parent->self);
29
+ rb_gc_mark(md->svc);
30
+ }
31
+
32
+ VALUE oci8_metadata_create(OCIParam *parmhp, VALUE svc, VALUE parent)
33
+ {
34
+ oci8_metadata_t *md;
35
+ oci8_base_t *p;
36
+ ub1 ptype;
37
+ ub4 size;
38
+ VALUE klass;
39
+ VALUE obj;
40
+
41
+ Check_Handle(parent, oci8_cOCIHandle, p);
42
+
43
+ oci_lc(OCIAttrGet(parmhp, OCI_DTYPE_PARAM, &ptype, &size, OCI_ATTR_PTYPE, oci8_errhp));
44
+ klass = rb_hash_aref(ptype_to_class, INT2FIX(ptype));
45
+ if (NIL_P(klass))
46
+ rb_raise(rb_eRuntimeError, "unknown parameter type %d", ptype);
47
+ obj = rb_obj_alloc(klass);
48
+ if (!RTEST(rb_obj_is_kind_of(obj, cOCI8MetadataBase))) {
49
+ rb_raise(rb_eRuntimeError, "invalid class in PTYPE_TO_CLASS");
50
+ }
51
+ md = DATA_PTR(obj);
52
+ md->base.type = OCI_DTYPE_PARAM;
53
+ md->base.hp.prm = parmhp;
54
+ md->svc = svc;
55
+
56
+ if (p->type == OCI_HTYPE_STMT) {
57
+ md->is_implicit = 1;
58
+ } else {
59
+ md->is_implicit = 0;
60
+ }
61
+ oci8_link_to_parent(&md->base, p);
62
+ return obj;
63
+ }
64
+
65
+ static VALUE metadata_s_register_ptype(VALUE klass, VALUE ptype)
66
+ {
67
+ rb_hash_aset(ptype_to_class, ptype, klass);
68
+ rb_hash_aset(class_to_ptype, klass, ptype);
69
+ return Qnil;
70
+ }
71
+
72
+ static VALUE metadata_get_ub1(VALUE self, VALUE idx)
73
+ {
74
+ oci8_base_t *base = DATA_PTR(self);
75
+ ub1 value = 0;
76
+ ub4 size = sizeof(value);
77
+
78
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
79
+ if (size != 1) {
80
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 1, but %d", size);
81
+ }
82
+ return INT2FIX(value);
83
+ }
84
+
85
+ static VALUE metadata_get_ub2(VALUE self, VALUE idx)
86
+ {
87
+ oci8_base_t *base = DATA_PTR(self);
88
+ ub2 value = 0;
89
+ ub4 size = sizeof(value);
90
+
91
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
92
+ if (size != 2) {
93
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 2, but %d", size);
94
+ }
95
+ return INT2FIX(value);
96
+ }
97
+
98
+ /* get ub2 without size check. */
99
+ static VALUE metadata_get_ub2_nc(VALUE self, VALUE idx)
100
+ {
101
+ oci8_base_t *base = DATA_PTR(self);
102
+ ub2 value = 0;
103
+
104
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, 0, FIX2INT(idx), oci8_errhp));
105
+ return INT2FIX(value);
106
+ }
107
+
108
+ static VALUE metadata_get_ub4(VALUE self, VALUE idx)
109
+ {
110
+ oci8_base_t *base = DATA_PTR(self);
111
+ ub4 value = 0;
112
+ ub4 size = sizeof(value);
113
+
114
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
115
+ if (size != 4) {
116
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 4, but %d", size);
117
+ }
118
+ #if SIZEOF_LONG > 4
119
+ return INT2FIX(value);
120
+ #else
121
+ return UINT2NUM(value);
122
+ #endif
123
+ }
124
+
125
+ static VALUE metadata_get_sb1(VALUE self, VALUE idx)
126
+ {
127
+ oci8_base_t *base = DATA_PTR(self);
128
+ sb1 value = 0;
129
+ ub4 size = sizeof(value);
130
+
131
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
132
+ if (size != 1) {
133
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 1, but %d", size);
134
+ }
135
+ return INT2FIX(value);
136
+ }
137
+
138
+ static VALUE metadata_get_sb2(VALUE self, VALUE idx)
139
+ {
140
+ oci8_base_t *base = DATA_PTR(self);
141
+ sb2 value = 0;
142
+ ub4 size = sizeof(value);
143
+
144
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
145
+ if (size != 2) {
146
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 2, but %d", size);
147
+ }
148
+ return INT2FIX(value);
149
+ }
150
+
151
+ static VALUE metadata_get_sb4(VALUE self, VALUE idx)
152
+ {
153
+ oci8_base_t *base = DATA_PTR(self);
154
+ sb4 value = 0;
155
+ ub4 size = sizeof(value);
156
+
157
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
158
+ if (size != 4) {
159
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 4, but %d", size);
160
+ }
161
+ #if SIZEOF_LONG > 4
162
+ return INT2FIX(value);
163
+ #else
164
+ return INT2NUM(value);
165
+ #endif
166
+ }
167
+
168
+ static VALUE metadata_get_text(VALUE self, VALUE idx)
169
+ {
170
+ oci8_metadata_t *md = DATA_PTR(self);
171
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(md->svc);
172
+ text *value;
173
+ ub4 size;
174
+
175
+ /* remote call sometimes? */
176
+ oci_lc(OCIAttrGet_nb(svcctx, md->base.hp.ptr, md->base.type, &value, &size, FIX2INT(idx), oci8_errhp));
177
+ return rb_external_str_new_with_enc(TO_CHARPTR(value), size, oci8_encoding);
178
+ }
179
+
180
+ static VALUE metadata_get_oradate(VALUE self, VALUE idx)
181
+ {
182
+ oci8_base_t *base = DATA_PTR(self);
183
+ ub1 *value;
184
+ ub4 size = 7;
185
+ static VALUE cOraDate = Qnil;
186
+ VALUE obj;
187
+
188
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
189
+ if (size != 7) {
190
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 7, but %d", size);
191
+ }
192
+ if (NIL_P(cOraDate))
193
+ cOraDate = rb_eval_string("OraDate");
194
+ obj = rb_funcall(cOraDate, oci8_id_new, 0);
195
+ memcpy(DATA_PTR(obj), value, 7);
196
+ return obj;
197
+ }
198
+
199
+ static VALUE metadata_get_oraint(VALUE self, VALUE idx)
200
+ {
201
+ oci8_base_t *base = DATA_PTR(self);
202
+ ub1 *value;
203
+ ub4 size = 21;
204
+ OCINumber on;
205
+
206
+ oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
207
+ if (size >= 22) {
208
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect less than 22, but %d", size);
209
+ }
210
+ memset(&on, 0, sizeof(on));
211
+ on.OCINumberPart[0] = size;
212
+ memcpy(&on.OCINumberPart[1], value, size);
213
+ return oci8_make_integer(&on);
214
+ }
215
+
216
+ static VALUE metadata_get_param(VALUE self, VALUE idx)
217
+ {
218
+ oci8_metadata_t *md = DATA_PTR(self);
219
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(md->svc);
220
+ OCIParam *value;
221
+ ub4 size = sizeof(value);
222
+
223
+ /* remote call? */
224
+ oci_lc(OCIAttrGet_nb(svcctx, md->base.hp.ptr, md->base.type, &value, &size, FIX2INT(idx), oci8_errhp));
225
+ if (size != sizeof(OCIParam *)) {
226
+ rb_raise(rb_eRuntimeError, "Invalid attribute size. expect %d, but %d", (sb4)sizeof(OCIParam *), size);
227
+ }
228
+ return oci8_metadata_create(value, md->svc, self);
229
+ }
230
+
231
+ static VALUE metadata_get_param_at(VALUE self, VALUE idx)
232
+ {
233
+ oci8_metadata_t *md = DATA_PTR(self);
234
+ OCIParam *value;
235
+
236
+ oci_lc(OCIParamGet(md->base.hp.ptr, md->base.type, oci8_errhp, (dvoid *)&value, FIX2INT(idx)));
237
+ return oci8_metadata_create(value, md->svc, self);
238
+ }
239
+
240
+ static VALUE metadata_get_charset_name(VALUE self, VALUE charset_id)
241
+ {
242
+ oci8_metadata_t *md = DATA_PTR(self);
243
+
244
+ return oci8_charset_id2name(md->svc, charset_id);
245
+ }
246
+
247
+ static VALUE metadata_get_con(VALUE self)
248
+ {
249
+ oci8_metadata_t *md = DATA_PTR(self);
250
+ return md->svc;
251
+ }
252
+
253
+ static VALUE metadata_is_implicit_p(VALUE self)
254
+ {
255
+ oci8_metadata_t *md = DATA_PTR(self);
256
+ return md->is_implicit ? Qtrue : Qfalse;
257
+ }
258
+
259
+ static VALUE oci8_do_describe(VALUE self, void *objptr, ub4 objlen, ub1 objtype, VALUE klass, VALUE check_public)
260
+ {
261
+ oci8_svcctx_t *svcctx = DATA_PTR(self);
262
+ OCIParam *parmhp;
263
+ VALUE type;
264
+ VALUE obj;
265
+ oci8_base_t *desc;
266
+
267
+ /* make a describe handle object */
268
+ obj = rb_obj_alloc(oci8_cOCIHandle);
269
+ desc = DATA_PTR(obj);
270
+ oci_lc(OCIHandleAlloc(oci8_envhp, (dvoid *)&desc->hp.dschp, OCI_HTYPE_DESCRIBE, 0, 0));
271
+ desc->type = OCI_HTYPE_DESCRIBE;
272
+
273
+ type = rb_hash_aref(class_to_ptype, klass);
274
+ if (RTEST(check_public)) {
275
+ sb4 val = -1;
276
+ /* size of OCI_ATTR_DESC_PUBLIC is undocumented. */
277
+ oci_lc(OCIAttrSet(desc->hp.dschp, OCI_HTYPE_DESCRIBE, &val, 0, OCI_ATTR_DESC_PUBLIC, oci8_errhp));
278
+ }
279
+ oci_lc(OCIDescribeAny_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, objptr, objlen,
280
+ objtype, OCI_DEFAULT, FIX2INT(type), desc->hp.dschp));
281
+ oci_lc(OCIAttrGet(desc->hp.dschp, OCI_HTYPE_DESCRIBE, &parmhp, 0, OCI_ATTR_PARAM, oci8_errhp));
282
+ return oci8_metadata_create(parmhp, self, obj);
283
+ }
284
+
285
+ static VALUE oci8_describe(VALUE self, VALUE name, VALUE klass, VALUE check_public)
286
+ {
287
+ OCI8SafeStringValue(name);
288
+ if (RSTRING_LEN(name) == 0) {
289
+ rb_raise(rb_eArgError, "empty string is set.");
290
+ }
291
+ return oci8_do_describe(self, RSTRING_PTR(name), RSTRING_LEN(name), OCI_OTYPE_NAME, klass, check_public);
292
+ }
293
+
294
+ static VALUE metadata_get_type_metadata(VALUE self, VALUE klass)
295
+ {
296
+ oci8_metadata_t *md = DATA_PTR(self);
297
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(md->svc);
298
+ OCIRef *ref = NULL;
299
+
300
+ /* remote call */
301
+ oci_lc(OCIAttrGet_nb(svcctx, md->base.hp.ptr, md->base.type, &ref, NULL, OCI_ATTR_REF_TDO, oci8_errhp));
302
+ return oci8_do_describe(md->svc, ref, 0, OCI_OTYPE_REF, klass, Qfalse);
303
+ }
304
+
305
+ static VALUE metadata_get_tdo_id(VALUE self)
306
+ {
307
+ oci8_metadata_t *md = DATA_PTR(self);
308
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(md->svc);
309
+ OCIRef *tdo_ref = NULL;
310
+ void *tdo;
311
+
312
+ oci_lc(OCIAttrGet_nb(svcctx, md->base.hp.ptr, md->base.type, &tdo_ref, NULL, OCI_ATTR_REF_TDO, oci8_errhp));
313
+ if (tdo_ref == NULL)
314
+ return Qnil;
315
+ oci_lc(OCIObjectPin_nb(svcctx, oci8_envhp, oci8_errhp, tdo_ref, 0, OCI_PIN_ANY, OCI_DURATION_SESSION, OCI_LOCK_NONE, &tdo));
316
+ oci_lc(OCIObjectUnpin(oci8_envhp, oci8_errhp, tdo));
317
+ #if SIZEOF_LONG == SIZEOF_VOIDP
318
+ return ((VALUE)tdo | (VALUE)1);
319
+ #else
320
+ return LL2NUM(((LONG_LONG)tdo) >>1);
321
+ #endif
322
+ }
323
+
324
+ oci8_base_class_t oci8_metadata_class = {
325
+ oci8_metadata_mark,
326
+ NULL,
327
+ sizeof(oci8_metadata_t),
328
+ };
329
+
330
+ void Init_oci8_metadata(VALUE cOCI8)
331
+ {
332
+ mOCI8Metadata = rb_define_module_under(cOCI8, "Metadata");
333
+ cOCI8MetadataBase = oci8_define_class_under(mOCI8Metadata, "Base", &oci8_metadata_class);
334
+ ptype_to_class = rb_hash_new();
335
+ class_to_ptype = rb_hash_new();
336
+ rb_global_variable(&ptype_to_class);
337
+ rb_global_variable(&class_to_ptype);
338
+
339
+ rb_define_singleton_method(cOCI8MetadataBase, "register_ptype", metadata_s_register_ptype, 1);
340
+ rb_define_private_method(cOCI8MetadataBase, "__ub1", metadata_get_ub1, 1);
341
+ rb_define_private_method(cOCI8MetadataBase, "__ub2", metadata_get_ub2, 1);
342
+ rb_define_private_method(cOCI8MetadataBase, "__ub2_nc", metadata_get_ub2_nc, 1);
343
+ rb_define_private_method(cOCI8MetadataBase, "__ub4", metadata_get_ub4, 1);
344
+ rb_define_private_method(cOCI8MetadataBase, "__sb1", metadata_get_sb1, 1);
345
+ rb_define_private_method(cOCI8MetadataBase, "__sb2", metadata_get_sb2, 1);
346
+ rb_define_private_method(cOCI8MetadataBase, "__sb4", metadata_get_sb4, 1);
347
+ rb_define_private_method(cOCI8MetadataBase, "__text", metadata_get_text, 1);
348
+ rb_define_private_method(cOCI8MetadataBase, "__oradate", metadata_get_oradate, 1);
349
+ rb_define_private_method(cOCI8MetadataBase, "__oraint", metadata_get_oraint, 1);
350
+ rb_define_private_method(cOCI8MetadataBase, "__param", metadata_get_param, 1);
351
+ rb_define_private_method(cOCI8MetadataBase, "__param_at", metadata_get_param_at, 1);
352
+ rb_define_private_method(cOCI8MetadataBase, "__charset_name", metadata_get_charset_name, 1);
353
+ rb_define_private_method(cOCI8MetadataBase, "__con", metadata_get_con, 0);
354
+ rb_define_private_method(cOCI8MetadataBase, "__is_implicit?", metadata_is_implicit_p, 0);
355
+
356
+ rb_define_private_method(cOCI8, "__describe", oci8_describe, 3);
357
+ rb_define_private_method(cOCI8MetadataBase, "__type_metadata", metadata_get_type_metadata, 1);
358
+ rb_define_method(cOCI8MetadataBase, "tdo_id", metadata_get_tdo_id, 0);
359
+ }
@@ -0,0 +1,622 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Document-class: OCI8::TDO
4
+ *
5
+ * OCI8::TDO is the class for Type Descriptor Object, which describe
6
+ * Oracle's object type.
7
+ *
8
+ * An instance of OCI8::TDO is specific to the connection. This means
9
+ * One TDO instance for a connection is not available to another connection.
10
+ */
11
+ #include "oci8.h"
12
+ #include <orid.h>
13
+
14
+ static VALUE cOCI8TDO;
15
+ static VALUE cOCI8NamedType;
16
+ static VALUE cOCI8NamedCollection;
17
+ static VALUE cOCI8BindNamedType;
18
+ static ID id_to_value;
19
+ static ID id_set_attributes;
20
+
21
+ typedef struct {
22
+ oci8_base_t base;
23
+ VALUE tdo;
24
+ char **instancep;
25
+ char **null_structp;
26
+ } oci8_named_type_t;
27
+
28
+ enum {
29
+ ATTR_INVALID = 0,
30
+ ATTR_STRING,
31
+ ATTR_RAW,
32
+ ATTR_OCINUMBER,
33
+ ATTR_FLOAT,
34
+ ATTR_INTEGER,
35
+ ATTR_BINARY_DOUBLE,
36
+ ATTR_BINARY_FLOAT,
37
+ ATTR_NAMED_TYPE,
38
+ ATTR_NAMED_COLLECTION,
39
+ };
40
+
41
+ static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, OCIInd *ind);
42
+ static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, OCIInd *ind, VALUE val);
43
+
44
+ static void oci8_tdo_mark(oci8_base_t *base)
45
+ {
46
+ if (base->parent != NULL) {
47
+ rb_gc_mark(base->parent->self);
48
+ }
49
+ }
50
+
51
+ static void oci8_tdo_free(oci8_base_t *base)
52
+ {
53
+ if (base->hp.tdo != NULL) {
54
+ OCIObjectUnpin(oci8_envhp, oci8_errhp, base->hp.tdo);
55
+ base->hp.tdo = NULL;
56
+ }
57
+ }
58
+
59
+ static VALUE oci8_tdo_setup(VALUE self, VALUE svc, VALUE md_obj)
60
+ {
61
+ oci8_base_t *tdo = DATA_PTR(self);
62
+ oci8_svcctx_t *svcctx = oci8_get_svcctx(svc);
63
+ oci8_base_t *md;
64
+ OCIRef *tdo_ref = NULL;
65
+
66
+ Check_Object(md_obj, cOCI8MetadataBase);
67
+ md = DATA_PTR(md_obj);
68
+
69
+ if (tdo->hp.tdo != NULL) {
70
+ OCIObjectUnpin(oci8_envhp, oci8_errhp, tdo->hp.tdo);
71
+ tdo->hp.tdo = NULL;
72
+ }
73
+ oci_lc(OCIAttrGet(md->hp.ptr, OCI_DTYPE_PARAM, &tdo_ref, NULL, OCI_ATTR_REF_TDO, oci8_errhp));
74
+ if (tdo_ref == NULL)
75
+ return Qnil;
76
+ oci_lc(OCIObjectPin_nb(svcctx, oci8_envhp, oci8_errhp, tdo_ref, 0, OCI_PIN_ANY, OCI_DURATION_SESSION, OCI_LOCK_NONE, &tdo->hp.ptr));
77
+ oci8_link_to_parent(tdo, &svcctx->base);
78
+ return self;
79
+ }
80
+
81
+ static oci8_base_class_t oci8_tdo_class = {
82
+ oci8_tdo_mark,
83
+ oci8_tdo_free,
84
+ sizeof(oci8_base_t)
85
+ };
86
+
87
+ static void oci8_named_type_mark(oci8_base_t *base)
88
+ {
89
+ if (base->parent != NULL) {
90
+ rb_gc_mark(base->parent->self);
91
+ }
92
+ }
93
+
94
+ static void oci8_named_type_free(oci8_base_t *base)
95
+ {
96
+ oci8_named_type_t *obj = (oci8_named_type_t *)base;
97
+ obj->instancep = NULL;
98
+ obj->null_structp = NULL;
99
+ }
100
+
101
+ static VALUE oci8_named_type_initialize(VALUE self)
102
+ {
103
+ oci8_named_type_t *obj = DATA_PTR(self);
104
+
105
+ obj->tdo = Qnil;
106
+ obj->instancep = NULL;
107
+ obj->null_structp = NULL;
108
+ return Qnil;
109
+ }
110
+
111
+ static VALUE oci8_named_type_tdo(VALUE self)
112
+ {
113
+ oci8_named_type_t *obj = DATA_PTR(self);
114
+ return obj->tdo;
115
+ }
116
+
117
+ static void oci8_named_type_check_offset(VALUE self, VALUE val_offset, VALUE ind_offset, size_t val_size, void **instancep, OCIInd **indp)
118
+ {
119
+ oci8_named_type_t *obj = DATA_PTR(self);
120
+ if (obj->instancep == NULL || obj->null_structp == NULL) {
121
+ rb_raise(rb_eRuntimeError, "%s is not initialized or freed", rb_obj_classname(self));
122
+ }
123
+ Check_Type(val_offset, T_FIXNUM);
124
+ Check_Type(ind_offset, T_FIXNUM);
125
+ *instancep = (void*)(*obj->instancep + FIX2INT(val_offset));
126
+ *indp = (OCIInd *)(*obj->null_structp + FIX2INT(ind_offset));
127
+ }
128
+
129
+ /*
130
+ * attribute
131
+ */
132
+ static VALUE oci8_named_type_get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, VALUE val_offset, VALUE ind_offset)
133
+ {
134
+ void *data;
135
+ OCIInd *ind;
136
+
137
+ oci8_named_type_check_offset(self, val_offset, ind_offset, sizeof(OCIString*), &data, &ind);
138
+ return get_attribute(self, datatype, typeinfo, data, ind);
139
+ }
140
+
141
+ static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, OCIInd *ind)
142
+ {
143
+ VALUE rv;
144
+ VALUE tmp_obj;
145
+ oci8_named_type_t *obj;
146
+
147
+ if (*ind) {
148
+ return Qnil;
149
+ }
150
+ Check_Type(datatype, T_FIXNUM);
151
+ switch (FIX2INT(datatype)) {
152
+ case ATTR_STRING:
153
+ return rb_external_str_new_with_enc(TO_CHARPTR(OCIStringPtr(oci8_envhp, *(OCIString **)data)),
154
+ OCIStringSize(oci8_envhp, *(OCIString **)data),
155
+ oci8_encoding);
156
+ case ATTR_RAW:
157
+ return rb_str_new(TO_CHARPTR(OCIRawPtr(oci8_envhp, *(OCIRaw **)data)),
158
+ OCIRawSize(oci8_envhp, *(OCIRaw **)data));
159
+ case ATTR_OCINUMBER:
160
+ return oci8_make_ocinumber((OCINumber *)data);
161
+ case ATTR_FLOAT:
162
+ return oci8_make_float((OCINumber *)data);
163
+ case ATTR_INTEGER:
164
+ return oci8_make_integer((OCINumber *)data);
165
+ case ATTR_BINARY_DOUBLE:
166
+ return rb_float_new(*(double*)data);
167
+ case ATTR_BINARY_FLOAT:
168
+ return rb_float_new((double)*(float*)data);
169
+ case ATTR_NAMED_TYPE:
170
+ Check_Object(typeinfo, cOCI8TDO);
171
+ /* Be carefull. Don't use *tmp_obj* out of this function. */
172
+ tmp_obj = rb_funcall(cOCI8NamedType, oci8_id_new, 0);
173
+ obj = DATA_PTR(tmp_obj);
174
+ obj->tdo = typeinfo;
175
+ obj->instancep = (char**)&data;
176
+ obj->null_structp = (char**)&ind;
177
+ oci8_link_to_parent(&obj->base, DATA_PTR(self));
178
+ rv = rb_funcall(tmp_obj, id_to_value, 0);
179
+ oci8_unlink_from_parent(&obj->base);
180
+ return rv;
181
+ case ATTR_NAMED_COLLECTION:
182
+ Check_Object(typeinfo, cOCI8TDO);
183
+ /* Be carefull. Don't use *tmp_obj* out of this function. */
184
+ tmp_obj = rb_funcall(cOCI8NamedCollection, oci8_id_new, 0);
185
+ obj = DATA_PTR(tmp_obj);
186
+ obj->tdo = typeinfo;
187
+ obj->instancep = (char**)data;
188
+ obj->null_structp = (char**)&ind;
189
+ oci8_link_to_parent(&obj->base, DATA_PTR(self));
190
+ rv = rb_funcall(tmp_obj, id_to_value, 0);
191
+ oci8_unlink_from_parent(&obj->base);
192
+ return rv;
193
+ default:
194
+ rb_raise(rb_eRuntimeError, "not supported datatype");
195
+ }
196
+ }
197
+
198
+ static VALUE oci8_named_coll_get_coll_element(VALUE self, VALUE datatype, VALUE typeinfo)
199
+ {
200
+ oci8_named_type_t *obj = DATA_PTR(self);
201
+ OCIColl *coll;
202
+ void *data;
203
+ OCIInd *ind;
204
+ VALUE ary;
205
+ sb4 size;
206
+ sb4 idx;
207
+
208
+ if (obj->instancep == NULL || obj->null_structp == NULL) {
209
+ rb_raise(rb_eRuntimeError, "%s is not initialized or freed", rb_obj_classname(self));
210
+ }
211
+ coll = (OCIColl*)*obj->instancep;
212
+ ind = (OCIInd*)*obj->null_structp;
213
+ if (*ind) {
214
+ return Qnil;
215
+ }
216
+ oci_lc(OCICollSize(oci8_envhp, oci8_errhp, coll, &size));
217
+ ary = rb_ary_new2(size);
218
+ for (idx = 0; idx < size; idx++) {
219
+ boolean exists;
220
+ oci_lc(OCICollGetElem(oci8_envhp, oci8_errhp, coll, idx, &exists, &data, (dvoid**)&ind));
221
+ if (exists) {
222
+ void *tmp;
223
+ if (datatype == INT2FIX(ATTR_NAMED_COLLECTION)) {
224
+ tmp = data;
225
+ data = &tmp;
226
+ }
227
+ rb_ary_store(ary, idx, get_attribute(self, datatype, typeinfo, data, ind));
228
+ }
229
+ }
230
+ return ary;
231
+ }
232
+
233
+ static VALUE oci8_named_type_set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, VALUE val_offset, VALUE ind_offset, VALUE val)
234
+ {
235
+ void *data;
236
+ OCIInd *ind;
237
+
238
+ oci8_named_type_check_offset(self, val_offset, ind_offset, sizeof(OCIString*), &data, &ind);
239
+ set_attribute(self, datatype, typeinfo, data, ind, val);
240
+ return Qnil;
241
+ }
242
+
243
+ typedef struct {
244
+ VALUE self;
245
+ VALUE datatype;
246
+ VALUE typeinfo;
247
+ VALUE val;
248
+ OCIColl *coll;
249
+ union {
250
+ void *ptr;
251
+ OCINumber num;
252
+ double dbl;
253
+ float flt;
254
+ } data;
255
+ OCIInd ind; /* for data.num, data.dbl, data.flt */
256
+ OCIInd *indp;
257
+ } set_coll_element_cb_data_t;
258
+
259
+ static VALUE set_coll_element_func(set_coll_element_cb_data_t *cb_data);
260
+ static VALUE set_coll_element_ensure(set_coll_element_cb_data_t *cb_data);
261
+
262
+ static VALUE oci8_named_coll_set_coll_element(VALUE self, VALUE datatype, VALUE typeinfo, VALUE val)
263
+ {
264
+ oci8_named_type_t *obj = DATA_PTR(self);
265
+ OCIInd *ind;
266
+ set_coll_element_cb_data_t cb_data;
267
+ oci8_base_t *tdo;
268
+ oci8_base_t *svcctx;
269
+
270
+ if (obj->instancep == NULL || obj->null_structp == NULL) {
271
+ rb_raise(rb_eRuntimeError, "%s is not initialized or freed", rb_obj_classname(self));
272
+ }
273
+ Check_Type(datatype, T_FIXNUM);
274
+ ind = (OCIInd*)*obj->null_structp;
275
+ if (NIL_P(val)) {
276
+ *ind = -1;
277
+ return Qnil;
278
+ }
279
+ Check_Type(val, T_ARRAY);
280
+ /* search svcctx */
281
+ svcctx = DATA_PTR(obj->tdo);
282
+ while (svcctx->type != OCI_HTYPE_SVCCTX) {
283
+ svcctx = svcctx->parent;
284
+ }
285
+ /* setup cb_data */
286
+ memset(&cb_data, 0, sizeof(cb_data));
287
+ cb_data.self = self;
288
+ cb_data.datatype = datatype;
289
+ cb_data.typeinfo = typeinfo;
290
+ cb_data.val = val;
291
+ cb_data.coll = (OCIColl*)*obj->instancep;
292
+ switch (FIX2INT(datatype)) {
293
+ case ATTR_STRING:
294
+ oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_VARCHAR2, NULL, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr));
295
+ oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp));
296
+ break;
297
+ case ATTR_RAW:
298
+ oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_RAW, NULL, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr));
299
+ oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp));
300
+ break;
301
+ case ATTR_OCINUMBER:
302
+ case ATTR_FLOAT:
303
+ case ATTR_INTEGER:
304
+ OCINumberSetZero(oci8_errhp, &cb_data.data.num);
305
+ cb_data.indp = &cb_data.ind;
306
+ break;
307
+ case ATTR_BINARY_DOUBLE:
308
+ cb_data.data.dbl = 0.0;
309
+ cb_data.indp = &cb_data.ind;
310
+ break;
311
+ case ATTR_BINARY_FLOAT:
312
+ cb_data.data.flt = 0.0;
313
+ cb_data.indp = &cb_data.ind;
314
+ break;
315
+ case ATTR_NAMED_TYPE:
316
+ Check_Object(typeinfo, cOCI8TDO);
317
+ tdo = DATA_PTR(typeinfo);
318
+ oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_OBJECT, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr));
319
+ oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp));
320
+ break;
321
+ case ATTR_NAMED_COLLECTION:
322
+ Check_Object(typeinfo, cOCI8TDO);
323
+ tdo = DATA_PTR(typeinfo);
324
+ oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_NAMEDCOLLECTION, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr));
325
+ oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp));
326
+ break;
327
+ default:
328
+ rb_raise(rb_eRuntimeError, "not supported datatype");
329
+ }
330
+ #if 0
331
+ /* TODO: */
332
+ rb_ensure(set_coll_element_func, (VALUE)&cb_data, set_coll_element_ensure, (VALUE)&cb_data);
333
+ #else
334
+ set_coll_element_func(&cb_data);
335
+ set_coll_element_ensure(&cb_data);
336
+ #endif
337
+ return Qnil;
338
+ }
339
+
340
+ static VALUE set_coll_element_func(set_coll_element_cb_data_t *cb_data)
341
+ {
342
+ VALUE self = cb_data->self;
343
+ VALUE val = cb_data->val;
344
+ VALUE datatype = cb_data->datatype;
345
+ VALUE typeinfo = cb_data->typeinfo;
346
+ OCIColl *coll = cb_data->coll;
347
+ sb4 size;
348
+ sb4 idx;
349
+ void *elem_ptr;
350
+
351
+ oci_lc(OCICollSize(oci8_envhp, oci8_errhp, coll, &size));
352
+ if (RARRAY_LEN(val) < size) {
353
+ oci_lc(OCICollTrim(oci8_envhp, oci8_errhp, size - RARRAY_LEN(val), coll));
354
+ }
355
+ for (idx = 0; idx < RARRAY_LEN(val); idx++) {
356
+ switch (FIX2INT(datatype)) {
357
+ case ATTR_NAMED_TYPE:
358
+ set_attribute(self, datatype, typeinfo, cb_data->data.ptr, cb_data->indp, RARRAY_PTR(val)[idx]);
359
+ break;
360
+ default:
361
+ set_attribute(self, datatype, typeinfo, (void*)&cb_data->data, cb_data->indp, RARRAY_PTR(val)[idx]);
362
+ break;
363
+ }
364
+ switch (FIX2INT(datatype)) {
365
+ case ATTR_OCINUMBER:
366
+ case ATTR_FLOAT:
367
+ case ATTR_INTEGER:
368
+ case ATTR_BINARY_DOUBLE:
369
+ case ATTR_BINARY_FLOAT:
370
+ elem_ptr = &cb_data->data;
371
+ break;
372
+ default:
373
+ elem_ptr = cb_data->data.ptr;
374
+ break;
375
+ }
376
+ if (idx < size) {
377
+ oci_lc(OCICollAssignElem(oci8_envhp, oci8_errhp, idx, elem_ptr, cb_data->indp, cb_data->coll));
378
+ } else {
379
+ oci_lc(OCICollAppend(oci8_envhp, oci8_errhp, elem_ptr, cb_data->indp, coll));
380
+ }
381
+ }
382
+ return Qnil;
383
+ }
384
+
385
+ static VALUE set_coll_element_ensure(set_coll_element_cb_data_t *cb_data)
386
+ {
387
+ VALUE datatype = cb_data->datatype;
388
+
389
+ switch (FIX2INT(datatype)) {
390
+ case ATTR_STRING:
391
+ case ATTR_RAW:
392
+ case ATTR_NAMED_TYPE:
393
+ case ATTR_NAMED_COLLECTION:
394
+ if (cb_data->data.ptr != NULL) {
395
+ OCIObjectFree(oci8_envhp, oci8_errhp, cb_data->data.ptr, OCI_DEFAULT);
396
+ }
397
+ break;
398
+ case ATTR_OCINUMBER:
399
+ case ATTR_FLOAT:
400
+ case ATTR_INTEGER:
401
+ case ATTR_BINARY_DOUBLE:
402
+ case ATTR_BINARY_FLOAT:
403
+ break;
404
+ }
405
+ return Qnil;
406
+ }
407
+
408
+
409
+ static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, OCIInd *ind, VALUE val)
410
+ {
411
+ VALUE tmp_obj;
412
+ oci8_named_type_t *obj;
413
+
414
+ if (NIL_P(val)) {
415
+ *ind = -1;
416
+ return;
417
+ }
418
+ Check_Type(datatype, T_FIXNUM);
419
+ switch (FIX2INT(datatype)) {
420
+ case ATTR_STRING:
421
+ OCI8StringValue(val);
422
+ oci_lc(OCIStringAssignText(oci8_envhp, oci8_errhp,
423
+ RSTRING_ORATEXT(val), RSTRING_LEN(val),
424
+ (OCIString **)data));
425
+ break;
426
+ case ATTR_RAW:
427
+ StringValue(val);
428
+ oci_lc(OCIRawAssignBytes(oci8_envhp, oci8_errhp,
429
+ RSTRING_ORATEXT(val), RSTRING_LEN(val),
430
+ (OCIRaw **)data));
431
+ break;
432
+ case ATTR_OCINUMBER:
433
+ case ATTR_FLOAT:
434
+ oci8_set_ocinumber((OCINumber*)data, val);
435
+ break;
436
+ case ATTR_INTEGER:
437
+ oci8_set_integer((OCINumber*)data, val);
438
+ break;
439
+ case ATTR_BINARY_DOUBLE:
440
+ *(double*)data = NUM2DBL(val);
441
+ break;
442
+ case ATTR_BINARY_FLOAT:
443
+ *(float*)data = (float)NUM2DBL(val);
444
+ break;
445
+ case ATTR_NAMED_TYPE:
446
+ Check_Object(typeinfo, cOCI8TDO);
447
+ /* Be carefull. Don't use *tmp_obj* out of this function. */
448
+ tmp_obj = rb_funcall(cOCI8NamedType, oci8_id_new, 0);
449
+ obj = DATA_PTR(tmp_obj);
450
+ obj->tdo = typeinfo;
451
+ obj->instancep = (char**)&data;
452
+ obj->null_structp = (char**)&ind;
453
+ oci8_link_to_parent(&obj->base, DATA_PTR(self));
454
+ rb_funcall(tmp_obj, id_set_attributes, 1, val);
455
+ oci8_unlink_from_parent(&obj->base);
456
+ break;
457
+ case ATTR_NAMED_COLLECTION:
458
+ Check_Object(typeinfo, cOCI8TDO);
459
+ /* Be carefull. Don't use *tmp_obj* out of this function. */
460
+ tmp_obj = rb_funcall(cOCI8NamedCollection, oci8_id_new, 0);
461
+ obj = DATA_PTR(tmp_obj);
462
+ obj->tdo = typeinfo;
463
+ obj->instancep = (char**)data;
464
+ obj->null_structp = (char**)&ind;
465
+ oci8_link_to_parent(&obj->base, DATA_PTR(self));
466
+ rb_funcall(tmp_obj, id_set_attributes, 1, val);
467
+ oci8_unlink_from_parent(&obj->base);
468
+ break;
469
+ default:
470
+ rb_raise(rb_eRuntimeError, "not supported datatype");
471
+ }
472
+ *ind = 0;
473
+ }
474
+
475
+ static oci8_base_class_t oci8_named_type_class = {
476
+ oci8_named_type_mark,
477
+ oci8_named_type_free,
478
+ sizeof(oci8_named_type_t)
479
+ };
480
+
481
+ static void bind_named_type_mark(oci8_base_t *base)
482
+ {
483
+ oci8_bind_t *obind = (oci8_bind_t *)base;
484
+ oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
485
+ ub4 idx = 0;
486
+
487
+ do {
488
+ rb_gc_mark(oho[idx].obj);
489
+ } while (++idx < obind->maxar_sz);
490
+ rb_gc_mark(obind->tdo);
491
+ }
492
+
493
+ static void bind_named_type_free(oci8_base_t *base)
494
+ {
495
+ oci8_bind_t *obind = (oci8_bind_t *)base;
496
+ oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
497
+ ub4 idx = 0;
498
+
499
+ do {
500
+ if (oho[idx].hp != NULL) {
501
+ OCIObjectFree(oci8_envhp, oci8_errhp, oho[idx].hp, OCI_DEFAULT);
502
+ oho[idx].hp = NULL;
503
+ }
504
+ } while (++idx < obind->maxar_sz);
505
+ }
506
+
507
+ static VALUE bind_named_type_get(oci8_bind_t *obind, void *data, void *null_struct)
508
+ {
509
+ oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
510
+ return oho->obj;
511
+ }
512
+
513
+ static void bind_named_type_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
514
+ {
515
+ rb_raise(rb_eRuntimeError, "not supported");
516
+ }
517
+
518
+ static void bind_named_type_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
519
+ {
520
+ VALUE tdo_obj = length;
521
+
522
+ obind->value_sz = sizeof(void*);
523
+ obind->alloc_sz = sizeof(oci8_hp_obj_t);
524
+
525
+ Check_Object(tdo_obj, cOCI8TDO);
526
+ obind->tdo = tdo_obj;
527
+ }
528
+
529
+ static void bind_named_type_init_elem(oci8_bind_t *obind, VALUE svc)
530
+ {
531
+ oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
532
+ oci8_base_t *tdo = DATA_PTR(obind->tdo);
533
+ OCITypeCode tc = OCITypeTypeCode(oci8_envhp, oci8_errhp, tdo->hp.tdo);
534
+ VALUE klass = Qnil;
535
+ oci8_named_type_t *obj;
536
+ oci8_svcctx_t *svcctx;
537
+ ub4 idx = 0;
538
+
539
+ switch (tc) {
540
+ case OCI_TYPECODE_OBJECT:
541
+ klass = cOCI8NamedType;
542
+ break;
543
+ case OCI_TYPECODE_NAMEDCOLLECTION:
544
+ klass = cOCI8NamedCollection;
545
+ break;
546
+ }
547
+ svcctx = oci8_get_svcctx(svc);
548
+ do {
549
+ oho[idx].obj = rb_funcall(klass, oci8_id_new, 0);
550
+ obj = DATA_PTR(oho[idx].obj);
551
+ obj->tdo = obind->tdo;
552
+ obj->instancep = (char**)&oho[idx].hp;
553
+ obj->null_structp = (char**)&obind->u.null_structs[idx];
554
+ oci8_link_to_parent(&obj->base, &obind->base);
555
+
556
+ oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->base.hp.svc, tc, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, (dvoid**)obj->instancep));
557
+ oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, (dvoid*)*obj->instancep, (dvoid**)obj->null_structp));
558
+ } while (++idx < obind->maxar_sz);
559
+ }
560
+
561
+ static const oci8_bind_class_t bind_named_type_class = {
562
+ {
563
+ bind_named_type_mark,
564
+ bind_named_type_free,
565
+ sizeof(oci8_bind_t)
566
+ },
567
+ bind_named_type_get,
568
+ bind_named_type_set,
569
+ bind_named_type_init,
570
+ bind_named_type_init_elem,
571
+ NULL,
572
+ NULL,
573
+ NULL,
574
+ SQLT_NTY
575
+ };
576
+
577
+ void Init_oci_object(VALUE cOCI8)
578
+ {
579
+ id_to_value = rb_intern("to_value");
580
+ id_set_attributes = rb_intern("attributes=");
581
+
582
+ /* OCI8::TDO */
583
+ cOCI8TDO = oci8_define_class_under(cOCI8, "TDO", &oci8_tdo_class);
584
+ rb_define_private_method(cOCI8TDO, "setup", oci8_tdo_setup, 2);
585
+ rb_define_const(cOCI8TDO, "ATTR_STRING", INT2FIX(ATTR_STRING));
586
+ rb_define_const(cOCI8TDO, "ATTR_RAW", INT2FIX(ATTR_RAW));
587
+ rb_define_const(cOCI8TDO, "ATTR_OCINUMBER", INT2FIX(ATTR_OCINUMBER));
588
+ rb_define_const(cOCI8TDO, "ATTR_FLOAT", INT2FIX(ATTR_FLOAT));
589
+ rb_define_const(cOCI8TDO, "ATTR_INTEGER", INT2FIX(ATTR_INTEGER));
590
+ rb_define_const(cOCI8TDO, "ATTR_BINARY_DOUBLE", INT2FIX(ATTR_BINARY_DOUBLE));
591
+ rb_define_const(cOCI8TDO, "ATTR_BINARY_FLOAT", INT2FIX(ATTR_BINARY_FLOAT));
592
+ rb_define_const(cOCI8TDO, "ATTR_NAMED_TYPE", INT2FIX(ATTR_NAMED_TYPE));
593
+ rb_define_const(cOCI8TDO, "ATTR_NAMED_COLLECTION", INT2FIX(ATTR_NAMED_COLLECTION));
594
+ #define ALIGNMENT_OF(type) (size_t)&(((struct {char c; type t;}*)0)->t)
595
+ rb_define_const(cOCI8TDO, "SIZE_OF_POINTER", INT2FIX(sizeof(void *)));
596
+ rb_define_const(cOCI8TDO, "ALIGNMENT_OF_POINTER", INT2FIX(ALIGNMENT_OF(void *)));
597
+ rb_define_const(cOCI8TDO, "SIZE_OF_OCINUMBER", INT2FIX(sizeof(OCINumber)));
598
+ rb_define_const(cOCI8TDO, "ALIGNMENT_OF_OCINUMBER", INT2FIX(ALIGNMENT_OF(OCINumber)));
599
+ rb_define_const(cOCI8TDO, "SIZE_OF_OCIDATE", INT2FIX(sizeof(OCIDate)));
600
+ rb_define_const(cOCI8TDO, "ALIGNMENT_OF_OCIDATE", INT2FIX(ALIGNMENT_OF(OCIDate)));
601
+ rb_define_const(cOCI8TDO, "SIZE_OF_FLOAT", INT2FIX(sizeof(float)));
602
+ rb_define_const(cOCI8TDO, "ALIGNMENT_OF_FLOAT", INT2FIX(ALIGNMENT_OF(float)));
603
+ rb_define_const(cOCI8TDO, "SIZE_OF_DOUBLE", INT2FIX(sizeof(double)));
604
+ rb_define_const(cOCI8TDO, "ALIGNMENT_OF_DOUBLE", INT2FIX(ALIGNMENT_OF(double)));
605
+
606
+ /* OCI8::NamedType */
607
+ cOCI8NamedType = oci8_define_class_under(cOCI8, "NamedType", &oci8_named_type_class);
608
+ rb_define_method(cOCI8NamedType, "initialize", oci8_named_type_initialize, 0);
609
+ rb_define_method(cOCI8NamedType, "tdo", oci8_named_type_tdo, 0);
610
+ rb_define_private_method(cOCI8NamedType, "get_attribute", oci8_named_type_get_attribute, 4);
611
+ rb_define_private_method(cOCI8NamedType, "set_attribute", oci8_named_type_set_attribute, 5);
612
+
613
+ /* OCI8::NamedCollection */
614
+ cOCI8NamedCollection = oci8_define_class_under(cOCI8, "NamedCollection", &oci8_named_type_class);
615
+ rb_define_method(cOCI8NamedCollection, "initialize", oci8_named_type_initialize, 0);
616
+ rb_define_method(cOCI8NamedCollection, "tdo", oci8_named_type_tdo, 0);
617
+ rb_define_private_method(cOCI8NamedCollection, "get_coll_element", oci8_named_coll_get_coll_element, 2);
618
+ rb_define_private_method(cOCI8NamedCollection, "set_coll_element", oci8_named_coll_set_coll_element, 3);
619
+
620
+ /* OCI8::BindType::NamedType */
621
+ cOCI8BindNamedType = oci8_define_bind_class("NamedType", &bind_named_type_class);
622
+ }