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,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
+ }