ruby-staci 2.2.9
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.
- checksums.yaml +7 -0
- data/.yardopts +14 -0
- data/COPYING +30 -0
- data/COPYING_old +64 -0
- data/ChangeLog +3826 -0
- data/Makefile +92 -0
- data/NEWS +1194 -0
- data/README.md +66 -0
- data/dist-files +113 -0
- data/docs/bind-array-to-in_cond.md +38 -0
- data/docs/conflicts-local-connections-and-processes.md +98 -0
- data/docs/hanging-after-inactivity.md +63 -0
- data/docs/install-binary-package.md +44 -0
- data/docs/install-full-client.md +111 -0
- data/docs/install-instant-client.md +194 -0
- data/docs/install-on-osx.md +133 -0
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/docs/osx-install-dev-tools.png +0 -0
- data/docs/platform-specific-issues.md +164 -0
- data/docs/report-installation-issue.md +50 -0
- data/docs/timeout-parameters.md +94 -0
- data/ext/oci8/.document +18 -0
- data/ext/oci8/MANIFEST +18 -0
- data/ext/oci8/apiwrap.c.tmpl +178 -0
- data/ext/oci8/apiwrap.h.tmpl +61 -0
- data/ext/oci8/apiwrap.rb +96 -0
- data/ext/oci8/apiwrap.yml +1322 -0
- data/ext/oci8/attr.c +57 -0
- data/ext/oci8/bind.c +838 -0
- data/ext/oci8/connection_pool.c +216 -0
- data/ext/oci8/encoding.c +196 -0
- data/ext/oci8/env.c +139 -0
- data/ext/oci8/error.c +385 -0
- data/ext/oci8/extconf.rb +219 -0
- data/ext/oci8/hook_funcs.c +407 -0
- data/ext/oci8/lob.c +1278 -0
- data/ext/oci8/metadata.c +279 -0
- data/ext/oci8/object.c +919 -0
- data/ext/oci8/oci8.c +1058 -0
- data/ext/oci8/oci8.h +556 -0
- data/ext/oci8/oci8lib.c +704 -0
- data/ext/oci8/ocidatetime.c +506 -0
- data/ext/oci8/ocihandle.c +852 -0
- data/ext/oci8/ocinumber.c +1922 -0
- data/ext/oci8/oraconf.rb +1145 -0
- data/ext/oci8/oradate.c +670 -0
- data/ext/oci8/oranumber_util.c +352 -0
- data/ext/oci8/oranumber_util.h +24 -0
- data/ext/oci8/plthook.h +66 -0
- data/ext/oci8/plthook_elf.c +702 -0
- data/ext/oci8/plthook_osx.c +505 -0
- data/ext/oci8/plthook_win32.c +391 -0
- data/ext/oci8/post-config.rb +5 -0
- data/ext/oci8/stmt.c +448 -0
- data/ext/oci8/thread_util.c +81 -0
- data/ext/oci8/thread_util.h +18 -0
- data/ext/oci8/util.c +71 -0
- data/ext/oci8/win32.c +117 -0
- data/lib/.document +1 -0
- data/lib/dbd/STACI.rb +591 -0
- data/lib/oci8/.document +8 -0
- data/lib/oci8/bindtype.rb +333 -0
- data/lib/oci8/check_load_error.rb +146 -0
- data/lib/oci8/compat.rb +117 -0
- data/lib/oci8/connection_pool.rb +179 -0
- data/lib/oci8/cursor.rb +605 -0
- data/lib/oci8/datetime.rb +605 -0
- data/lib/oci8/encoding-init.rb +45 -0
- data/lib/oci8/encoding.yml +537 -0
- data/lib/oci8/metadata.rb +2148 -0
- data/lib/oci8/object.rb +641 -0
- data/lib/oci8/oci8.rb +756 -0
- data/lib/oci8/ocihandle.rb +591 -0
- data/lib/oci8/oracle_version.rb +153 -0
- data/lib/oci8/properties.rb +196 -0
- data/lib/oci8/version.rb +3 -0
- data/lib/ruby-staci.rb +1 -0
- data/lib/staci.rb +190 -0
- data/metaconfig +142 -0
- data/pre-distclean.rb +7 -0
- data/ruby-aci.gemspec +83 -0
- data/setup.rb +1342 -0
- data/test/README.md +37 -0
- data/test/config.rb +201 -0
- data/test/setup_test_object.sql +199 -0
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +56 -0
- data/test/test_appinfo.rb +62 -0
- data/test/test_array_dml.rb +333 -0
- data/test/test_bind_array.rb +70 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_bind_integer.rb +47 -0
- data/test/test_bind_raw.rb +45 -0
- data/test/test_bind_string.rb +105 -0
- data/test/test_bind_time.rb +177 -0
- data/test/test_break.rb +124 -0
- data/test/test_clob.rb +86 -0
- data/test/test_connection_pool.rb +124 -0
- data/test/test_connstr.rb +220 -0
- data/test/test_datetime.rb +585 -0
- data/test/test_dbi.rb +365 -0
- data/test/test_dbi_clob.rb +53 -0
- data/test/test_encoding.rb +103 -0
- data/test/test_error.rb +87 -0
- data/test/test_metadata.rb +2674 -0
- data/test/test_object.rb +546 -0
- data/test/test_oci8.rb +624 -0
- data/test/test_oracle_version.rb +68 -0
- data/test/test_oradate.rb +255 -0
- data/test/test_oranumber.rb +786 -0
- data/test/test_package_type.rb +981 -0
- data/test/test_properties.rb +17 -0
- data/test/test_rowid.rb +32 -0
- metadata +158 -0
data/ext/oci8/object.c
ADDED
@@ -0,0 +1,919 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright (C) 2002-2016 Kubo Takehiro <kubo@jiubao.org>
|
4
|
+
*/
|
5
|
+
|
6
|
+
/*
|
7
|
+
*
|
8
|
+
* Document-class: STACI::TDO
|
9
|
+
*
|
10
|
+
* STACI::TDO is the class for Type Descriptor Object, which describe
|
11
|
+
* Oracle's object type.
|
12
|
+
*
|
13
|
+
* An instance of STACI::TDO is specific to the connection. This means
|
14
|
+
* One TDO instance for a connection is not available to another connection.
|
15
|
+
*/
|
16
|
+
#include "oci8.h"
|
17
|
+
//#include <orid.h>
|
18
|
+
|
19
|
+
static VALUE cOCI8TDO;
|
20
|
+
static VALUE cOCI8NamedType;
|
21
|
+
static VALUE cOCI8NamedCollection;
|
22
|
+
static VALUE cOCI8BindNamedType;
|
23
|
+
static VALUE cOCI8MetadataType;
|
24
|
+
static ID id_to_value;
|
25
|
+
static ID id_set_attributes;
|
26
|
+
static ID id_get_tdo_by_metadata;
|
27
|
+
static ID id_at_is_final_type;
|
28
|
+
|
29
|
+
#define TO_TDO(obj) ((oci8_base_t *)oci8_check_typeddata((obj), &oci8_tdo_data_type, 1))
|
30
|
+
#define CHECK_TDO(obj) ((void)oci8_check_typeddata((obj), &oci8_tdo_data_type, 1))
|
31
|
+
|
32
|
+
typedef struct {
|
33
|
+
oci8_base_t base;
|
34
|
+
VALUE tdo;
|
35
|
+
char **instancep;
|
36
|
+
char **null_structp;
|
37
|
+
} oci8_named_type_t;
|
38
|
+
|
39
|
+
enum {
|
40
|
+
ATTR_INVALID = 0,
|
41
|
+
ATTR_STRING,
|
42
|
+
ATTR_RAW,
|
43
|
+
ATTR_OCINUMBER,
|
44
|
+
ATTR_FLOAT,
|
45
|
+
ATTR_INTEGER,
|
46
|
+
ATTR_OCIDATE,
|
47
|
+
ATTR_TIMESTAMP,
|
48
|
+
ATTR_TIMESTAMP_TZ,
|
49
|
+
ATTR_BINARY_DOUBLE,
|
50
|
+
ATTR_BINARY_FLOAT,
|
51
|
+
ATTR_NAMED_TYPE,
|
52
|
+
ATTR_NAMED_COLLECTION,
|
53
|
+
ATTR_CLOB,
|
54
|
+
ATTR_NCLOB,
|
55
|
+
ATTR_BLOB,
|
56
|
+
ATTR_BFILE,
|
57
|
+
};
|
58
|
+
|
59
|
+
static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, ACIInd *ind);
|
60
|
+
static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, ACIInd *ind, VALUE val);
|
61
|
+
|
62
|
+
static void oci8_tdo_mark(oci8_base_t *base)
|
63
|
+
{
|
64
|
+
if (base->parent != NULL) {
|
65
|
+
rb_gc_mark(base->parent->self);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
static void oci8_tdo_free(oci8_base_t *base)
|
70
|
+
{
|
71
|
+
if (base->hp.tdo != NULL) {
|
72
|
+
ACIObjectUnpin(oci8_envhp, oci8_errhp, base->hp.tdo);
|
73
|
+
base->hp.tdo = NULL;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
static const oci8_handle_data_type_t oci8_tdo_data_type = {
|
78
|
+
{
|
79
|
+
"OCI8::TDO",
|
80
|
+
{
|
81
|
+
(RUBY_DATA_FUNC)oci8_tdo_mark,
|
82
|
+
oci8_handle_cleanup,
|
83
|
+
oci8_handle_size,
|
84
|
+
},
|
85
|
+
&oci8_handle_data_type.rb_data_type, NULL,
|
86
|
+
#ifdef RUBY_TYPED_WB_PROTECTED
|
87
|
+
RUBY_TYPED_WB_PROTECTED,
|
88
|
+
#endif
|
89
|
+
},
|
90
|
+
oci8_tdo_free,
|
91
|
+
sizeof(oci8_base_t)
|
92
|
+
};
|
93
|
+
|
94
|
+
static VALUE oci8_tdo_setup(VALUE self, VALUE svc, VALUE md_obj)
|
95
|
+
{
|
96
|
+
oci8_base_t *tdo = TO_TDO(self);
|
97
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(svc);
|
98
|
+
oci8_base_t *md = oci8_check_typeddata(md_obj, &oci8_metadata_base_data_type, 1);
|
99
|
+
ACIRef *tdo_ref = NULL;
|
100
|
+
|
101
|
+
if (tdo->hp.tdo != NULL) {
|
102
|
+
ACIObjectUnpin(oci8_envhp, oci8_errhp, tdo->hp.tdo);
|
103
|
+
tdo->hp.tdo = NULL;
|
104
|
+
}
|
105
|
+
chker2(ACIAttrGet(md->hp.ptr, ACI_DTYPE_PARAM, &tdo_ref, NULL, ACI_ATTR_REF_TDO, oci8_errhp),
|
106
|
+
&svcctx->base);
|
107
|
+
if (tdo_ref == NULL)
|
108
|
+
return Qnil;
|
109
|
+
chker2(ACIObjectPin_nb(svcctx, oci8_envhp, oci8_errhp, tdo_ref, 0, ACI_PIN_ANY, ACI_DURATION_SESSION, ACI_LOCK_NONE, &tdo->hp.ptr),
|
110
|
+
&svcctx->base);
|
111
|
+
oci8_link_to_parent(tdo, &svcctx->base);
|
112
|
+
RB_OBJ_WRITTEN(self, Qundef, svc);
|
113
|
+
return self;
|
114
|
+
}
|
115
|
+
|
116
|
+
static VALUE oci8_tdo_alloc(VALUE klass)
|
117
|
+
{
|
118
|
+
return oci8_allocate_typeddata(klass, &oci8_tdo_data_type);
|
119
|
+
}
|
120
|
+
|
121
|
+
static void oci8_named_type_mark(oci8_base_t *base)
|
122
|
+
{
|
123
|
+
if (base->parent != NULL) {
|
124
|
+
rb_gc_mark(base->parent->self);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
static void oci8_named_type_free(oci8_base_t *base)
|
129
|
+
{
|
130
|
+
oci8_named_type_t *obj = (oci8_named_type_t *)base;
|
131
|
+
obj->instancep = NULL;
|
132
|
+
obj->null_structp = NULL;
|
133
|
+
}
|
134
|
+
|
135
|
+
static VALUE oci8_named_type_initialize(VALUE self)
|
136
|
+
{
|
137
|
+
oci8_named_type_t *obj = DATA_PTR(self);
|
138
|
+
|
139
|
+
obj->tdo = Qnil;
|
140
|
+
obj->instancep = NULL;
|
141
|
+
obj->null_structp = NULL;
|
142
|
+
return Qnil;
|
143
|
+
}
|
144
|
+
|
145
|
+
typedef struct get_tdo_by_instance_arg {
|
146
|
+
VALUE svc;
|
147
|
+
void *instance;
|
148
|
+
void *typeref;
|
149
|
+
} get_tdo_by_instance_arg_t;
|
150
|
+
|
151
|
+
static VALUE get_tdo_by_instance(VALUE data)
|
152
|
+
{
|
153
|
+
get_tdo_by_instance_arg_t *arg = (get_tdo_by_instance_arg_t *)data;
|
154
|
+
VALUE metadata;
|
155
|
+
|
156
|
+
chkerr(ACIObjectGetTypeRef(oci8_envhp, oci8_errhp, arg->instance, arg->typeref));
|
157
|
+
metadata = oci8_do_describe(arg->svc, arg->typeref, 0, ACI_OTYPE_REF, cOCI8MetadataType, Qfalse);
|
158
|
+
return rb_funcall(arg->svc, id_get_tdo_by_metadata, 1, metadata);
|
159
|
+
}
|
160
|
+
|
161
|
+
static VALUE oci8_named_type_tdo(VALUE self)
|
162
|
+
{
|
163
|
+
oci8_named_type_t *obj = DATA_PTR(self);
|
164
|
+
VALUE tdo = obj->tdo;
|
165
|
+
|
166
|
+
if (!RTEST(rb_ivar_get(tdo, id_at_is_final_type))) {
|
167
|
+
/* The type of the instance may be a subtype. */
|
168
|
+
oci8_base_t *svcctx;
|
169
|
+
get_tdo_by_instance_arg_t arg;
|
170
|
+
int state = 0;
|
171
|
+
|
172
|
+
/* search svcctx */
|
173
|
+
svcctx = DATA_PTR(obj->tdo);
|
174
|
+
while (svcctx->type != ACI_HTYPE_SVCCTX) {
|
175
|
+
svcctx = svcctx->parent;
|
176
|
+
}
|
177
|
+
|
178
|
+
arg.svc = svcctx->self;
|
179
|
+
arg.instance = *obj->instancep;
|
180
|
+
chkerr(ACIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, ACI_TYPECODE_REF, NULL, NULL, ACI_DURATION_DEFAULT, TRUE, &arg.typeref));
|
181
|
+
tdo = rb_protect(get_tdo_by_instance, (VALUE)&arg, &state);
|
182
|
+
chkerr(ACIObjectFree(oci8_envhp, oci8_errhp, arg.typeref, ACI_OBJECTFREE_FORCE));
|
183
|
+
if (state != 0) {
|
184
|
+
rb_jump_tag(state);
|
185
|
+
}
|
186
|
+
}
|
187
|
+
return tdo;
|
188
|
+
}
|
189
|
+
|
190
|
+
static void oci8_named_type_check_offset(VALUE self, VALUE val_offset, VALUE ind_offset, size_t val_size, void **instancep, ACIInd **indp)
|
191
|
+
{
|
192
|
+
oci8_named_type_t *obj = DATA_PTR(self);
|
193
|
+
if (obj->instancep == NULL || obj->null_structp == NULL) {
|
194
|
+
rb_raise(rb_eRuntimeError, "%s is not initialized or freed", rb_obj_classname(self));
|
195
|
+
}
|
196
|
+
Check_Type(val_offset, T_FIXNUM);
|
197
|
+
Check_Type(ind_offset, T_FIXNUM);
|
198
|
+
*instancep = (void*)(*obj->instancep + FIX2INT(val_offset));
|
199
|
+
*indp = (ACIInd *)(*obj->null_structp + FIX2INT(ind_offset));
|
200
|
+
}
|
201
|
+
|
202
|
+
/*
|
203
|
+
* attribute
|
204
|
+
*/
|
205
|
+
static VALUE oci8_named_type_get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, VALUE val_offset, VALUE ind_offset)
|
206
|
+
{
|
207
|
+
void *data;
|
208
|
+
ACIInd *ind;
|
209
|
+
|
210
|
+
oci8_named_type_check_offset(self, val_offset, ind_offset, sizeof(ACIString*), &data, &ind);
|
211
|
+
return get_attribute(self, datatype, typeinfo, data, ind);
|
212
|
+
}
|
213
|
+
|
214
|
+
static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, ACIInd *ind)
|
215
|
+
{
|
216
|
+
VALUE rv;
|
217
|
+
VALUE tmp_obj;
|
218
|
+
oci8_named_type_t *obj;
|
219
|
+
|
220
|
+
if (*ind) {
|
221
|
+
return Qnil;
|
222
|
+
}
|
223
|
+
Check_Type(datatype, T_FIXNUM);
|
224
|
+
switch (FIX2INT(datatype)) {
|
225
|
+
case ATTR_STRING:
|
226
|
+
return rb_external_str_new_with_enc(TO_CHARPTR(ACIStringPtr(oci8_envhp, *(ACIString **)data)),
|
227
|
+
ACIStringSize(oci8_envhp, *(ACIString **)data),
|
228
|
+
oci8_encoding);
|
229
|
+
case ATTR_RAW:
|
230
|
+
return rb_str_new(TO_CHARPTR(ACIRawPtr(oci8_envhp, *(ACIRaw **)data)),
|
231
|
+
ACIRawSize(oci8_envhp, *(ACIRaw **)data));
|
232
|
+
case ATTR_OCINUMBER:
|
233
|
+
return oci8_make_ocinumber((ACINumber *)data, oci8_errhp);
|
234
|
+
case ATTR_FLOAT:
|
235
|
+
return oci8_make_float((ACINumber *)data, oci8_errhp);
|
236
|
+
case ATTR_INTEGER:
|
237
|
+
return oci8_make_integer((ACINumber *)data, oci8_errhp);
|
238
|
+
case ATTR_OCIDATE:
|
239
|
+
return oci8_make_ocidate((OCIDate *)data);
|
240
|
+
case ATTR_TIMESTAMP:
|
241
|
+
return oci8_make_ocitimestamp(*(ACIDateTime**)data, FALSE);
|
242
|
+
case ATTR_TIMESTAMP_TZ:
|
243
|
+
return oci8_make_ocitimestamp(*(ACIDateTime**)data, TRUE);
|
244
|
+
case ATTR_BINARY_DOUBLE:
|
245
|
+
return rb_float_new(*(double*)data);
|
246
|
+
case ATTR_BINARY_FLOAT:
|
247
|
+
return rb_float_new((double)*(float*)data);
|
248
|
+
case ATTR_NAMED_TYPE:
|
249
|
+
CHECK_TDO(typeinfo);
|
250
|
+
/* Be carefull. Don't use *tmp_obj* out of this function. */
|
251
|
+
tmp_obj = rb_class_new_instance(0, NULL, cOCI8NamedType);
|
252
|
+
obj = DATA_PTR(tmp_obj);
|
253
|
+
RB_OBJ_WRITE(tmp_obj, &obj->tdo, typeinfo);
|
254
|
+
obj->instancep = (char**)&data;
|
255
|
+
obj->null_structp = (char**)&ind;
|
256
|
+
oci8_link_to_parent(&obj->base, DATA_PTR(self));
|
257
|
+
RB_OBJ_WRITTEN(tmp_obj, Qundef, self);
|
258
|
+
rv = rb_funcall(tmp_obj, id_to_value, 0);
|
259
|
+
oci8_unlink_from_parent(&obj->base);
|
260
|
+
RB_OBJ_WRITTEN(tmp_obj, self, Qundef);
|
261
|
+
return rv;
|
262
|
+
case ATTR_NAMED_COLLECTION:
|
263
|
+
CHECK_TDO(typeinfo);
|
264
|
+
/* Be carefull. Don't use *tmp_obj* out of this function. */
|
265
|
+
tmp_obj = rb_class_new_instance(0, NULL, cOCI8NamedCollection);
|
266
|
+
obj = DATA_PTR(tmp_obj);
|
267
|
+
RB_OBJ_WRITE(tmp_obj, &obj->tdo, typeinfo);
|
268
|
+
obj->instancep = (char**)data;
|
269
|
+
obj->null_structp = (char**)&ind;
|
270
|
+
oci8_link_to_parent(&obj->base, DATA_PTR(self));
|
271
|
+
RB_OBJ_WRITTEN(tmp_obj, Qundef, self);
|
272
|
+
rv = rb_funcall(tmp_obj, id_to_value, 0);
|
273
|
+
oci8_unlink_from_parent(&obj->base);
|
274
|
+
RB_OBJ_WRITTEN(tmp_obj, self, Qundef);
|
275
|
+
return rv;
|
276
|
+
case ATTR_CLOB:
|
277
|
+
return oci8_make_clob(oci8_get_svcctx(typeinfo), *(ACILobLocator**)data);
|
278
|
+
case ATTR_NCLOB:
|
279
|
+
return oci8_make_nclob(oci8_get_svcctx(typeinfo), *(ACILobLocator**)data);
|
280
|
+
case ATTR_BLOB:
|
281
|
+
return oci8_make_blob(oci8_get_svcctx(typeinfo), *(ACILobLocator**)data);
|
282
|
+
case ATTR_BFILE:
|
283
|
+
return oci8_make_bfile(oci8_get_svcctx(typeinfo), *(ACILobLocator**)data);
|
284
|
+
default:
|
285
|
+
rb_raise(rb_eRuntimeError, "not supported datatype");
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
static VALUE oci8_named_coll_get_coll_element(VALUE self, VALUE datatype, VALUE typeinfo)
|
290
|
+
{
|
291
|
+
oci8_named_type_t *obj = DATA_PTR(self);
|
292
|
+
ACIColl *coll;
|
293
|
+
void *data;
|
294
|
+
ACIInd *ind;
|
295
|
+
VALUE ary;
|
296
|
+
sb4 size;
|
297
|
+
sb4 idx;
|
298
|
+
|
299
|
+
if (obj->instancep == NULL || obj->null_structp == NULL) {
|
300
|
+
rb_raise(rb_eRuntimeError, "%s is not initialized or freed", rb_obj_classname(self));
|
301
|
+
}
|
302
|
+
coll = (ACIColl*)*obj->instancep;
|
303
|
+
ind = (ACIInd*)*obj->null_structp;
|
304
|
+
if (*ind) {
|
305
|
+
return Qnil;
|
306
|
+
}
|
307
|
+
chker2(ACICollSize(oci8_envhp, oci8_errhp, coll, &size), &obj->base);
|
308
|
+
ary = rb_ary_new2(size);
|
309
|
+
for (idx = 0; idx < size; idx++) {
|
310
|
+
boolean exists;
|
311
|
+
chker2(ACICollGetElem(oci8_envhp, oci8_errhp, coll, idx, &exists, &data, (dvoid**)&ind), &obj->base);
|
312
|
+
if (exists) {
|
313
|
+
void *tmp;
|
314
|
+
if (datatype == INT2FIX(ATTR_NAMED_COLLECTION)) {
|
315
|
+
tmp = data;
|
316
|
+
data = &tmp;
|
317
|
+
}
|
318
|
+
rb_ary_store(ary, idx, get_attribute(self, datatype, typeinfo, data, ind));
|
319
|
+
}
|
320
|
+
}
|
321
|
+
return ary;
|
322
|
+
}
|
323
|
+
|
324
|
+
static VALUE oci8_named_type_set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, VALUE val_offset, VALUE ind_offset, VALUE val)
|
325
|
+
{
|
326
|
+
void *data;
|
327
|
+
ACIInd *ind;
|
328
|
+
|
329
|
+
oci8_named_type_check_offset(self, val_offset, ind_offset, sizeof(ACIString*), &data, &ind);
|
330
|
+
set_attribute(self, datatype, typeinfo, data, ind, val);
|
331
|
+
return Qnil;
|
332
|
+
}
|
333
|
+
|
334
|
+
static VALUE oci8_named_type_null_p(VALUE self)
|
335
|
+
{
|
336
|
+
void *data;
|
337
|
+
ACIInd *ind;
|
338
|
+
|
339
|
+
oci8_named_type_check_offset(self, INT2FIX(0), INT2FIX(0), sizeof(void*), &data, &ind);
|
340
|
+
return *ind ? Qtrue : Qfalse;
|
341
|
+
}
|
342
|
+
|
343
|
+
static VALUE oci8_named_type_set_null(VALUE self, VALUE val)
|
344
|
+
{
|
345
|
+
void *data;
|
346
|
+
ACIInd *ind;
|
347
|
+
|
348
|
+
oci8_named_type_check_offset(self, INT2FIX(0), INT2FIX(0), sizeof(void*), &data, &ind);
|
349
|
+
*ind = RTEST(val) ? -1 : 0;
|
350
|
+
return val;
|
351
|
+
}
|
352
|
+
|
353
|
+
typedef struct {
|
354
|
+
VALUE self;
|
355
|
+
VALUE datatype;
|
356
|
+
VALUE typeinfo;
|
357
|
+
VALUE val;
|
358
|
+
ACIColl *coll;
|
359
|
+
union {
|
360
|
+
void *ptr;
|
361
|
+
ACINumber num;
|
362
|
+
double dbl;
|
363
|
+
float flt;
|
364
|
+
} data;
|
365
|
+
ACIInd ind; /* for data.num, data.dbl, data.flt */
|
366
|
+
ACIInd *indp;
|
367
|
+
} set_coll_element_cb_data_t;
|
368
|
+
|
369
|
+
static VALUE set_coll_element_func(set_coll_element_cb_data_t *cb_data);
|
370
|
+
static VALUE set_coll_element_ensure(set_coll_element_cb_data_t *cb_data);
|
371
|
+
|
372
|
+
static VALUE oci8_named_coll_set_coll_element(VALUE self, VALUE datatype, VALUE typeinfo, VALUE val)
|
373
|
+
{
|
374
|
+
oci8_named_type_t *obj = DATA_PTR(self);
|
375
|
+
ACIInd *ind;
|
376
|
+
set_coll_element_cb_data_t cb_data;
|
377
|
+
oci8_base_t *tdo;
|
378
|
+
oci8_base_t *svcctx;
|
379
|
+
|
380
|
+
if (obj->instancep == NULL || obj->null_structp == NULL) {
|
381
|
+
rb_raise(rb_eRuntimeError, "%s is not initialized or freed", rb_obj_classname(self));
|
382
|
+
}
|
383
|
+
Check_Type(datatype, T_FIXNUM);
|
384
|
+
ind = (ACIInd*)*obj->null_structp;
|
385
|
+
if (NIL_P(val)) {
|
386
|
+
*ind = -1;
|
387
|
+
return Qnil;
|
388
|
+
}
|
389
|
+
Check_Type(val, T_ARRAY);
|
390
|
+
/* search svcctx */
|
391
|
+
svcctx = DATA_PTR(obj->tdo);
|
392
|
+
while (svcctx->type != ACI_HTYPE_SVCCTX) {
|
393
|
+
svcctx = svcctx->parent;
|
394
|
+
}
|
395
|
+
/* setup cb_data */
|
396
|
+
memset(&cb_data, 0, sizeof(cb_data));
|
397
|
+
cb_data.self = self;
|
398
|
+
cb_data.datatype = datatype;
|
399
|
+
cb_data.typeinfo = typeinfo;
|
400
|
+
cb_data.val = val;
|
401
|
+
cb_data.coll = (ACIColl*)*obj->instancep;
|
402
|
+
switch (FIX2INT(datatype)) {
|
403
|
+
case ATTR_STRING:
|
404
|
+
chker2(ACIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, ACI_TYPECODE_VARCHAR2, NULL, NULL, ACI_DURATION_SESSION, TRUE, &cb_data.data.ptr),
|
405
|
+
svcctx);
|
406
|
+
cb_data.indp = &cb_data.ind;
|
407
|
+
break;
|
408
|
+
case ATTR_RAW:
|
409
|
+
chker2(ACIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, ACI_TYPECODE_RAW, NULL, NULL, ACI_DURATION_SESSION, TRUE, &cb_data.data.ptr),
|
410
|
+
svcctx);
|
411
|
+
cb_data.indp = &cb_data.ind;
|
412
|
+
break;
|
413
|
+
case ATTR_OCINUMBER:
|
414
|
+
case ATTR_FLOAT:
|
415
|
+
case ATTR_INTEGER:
|
416
|
+
ACINumberSetZero(oci8_errhp, &cb_data.data.num);
|
417
|
+
cb_data.indp = &cb_data.ind;
|
418
|
+
break;
|
419
|
+
case ATTR_OCIDATE:
|
420
|
+
cb_data.indp = &cb_data.ind;
|
421
|
+
break;
|
422
|
+
case ATTR_TIMESTAMP:
|
423
|
+
chker2(ACIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, ACI_TYPECODE_TIMESTAMP, NULL, NULL, ACI_DURATION_SESSION, TRUE, &cb_data.data.ptr),
|
424
|
+
svcctx);
|
425
|
+
chker2(ACIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp),
|
426
|
+
svcctx);
|
427
|
+
break;
|
428
|
+
case ATTR_TIMESTAMP_TZ:
|
429
|
+
chker2(ACIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, ACI_TYPECODE_TIMESTAMP_TZ, NULL, NULL, ACI_DURATION_SESSION, TRUE, &cb_data.data.ptr),
|
430
|
+
svcctx);
|
431
|
+
chker2(ACIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp),
|
432
|
+
svcctx);
|
433
|
+
break;
|
434
|
+
case ATTR_BINARY_DOUBLE:
|
435
|
+
cb_data.data.dbl = 0.0;
|
436
|
+
cb_data.indp = &cb_data.ind;
|
437
|
+
break;
|
438
|
+
case ATTR_BINARY_FLOAT:
|
439
|
+
cb_data.data.flt = 0.0;
|
440
|
+
cb_data.indp = &cb_data.ind;
|
441
|
+
break;
|
442
|
+
case ATTR_NAMED_TYPE:
|
443
|
+
tdo = TO_TDO(typeinfo);
|
444
|
+
chker2(ACIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, ACI_TYPECODE_OBJECT, tdo->hp.tdo, NULL, ACI_DURATION_SESSION, TRUE, &cb_data.data.ptr),
|
445
|
+
svcctx);
|
446
|
+
chker2(ACIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp),
|
447
|
+
svcctx);
|
448
|
+
break;
|
449
|
+
case ATTR_NAMED_COLLECTION:
|
450
|
+
tdo = TO_TDO(typeinfo);
|
451
|
+
chker2(ACIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, ACI_TYPECODE_NAMEDCOLLECTION, tdo->hp.tdo, NULL, ACI_DURATION_SESSION, TRUE, &cb_data.data.ptr),
|
452
|
+
svcctx);
|
453
|
+
chker2(ACIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp),
|
454
|
+
svcctx);
|
455
|
+
break;
|
456
|
+
case ATTR_CLOB:
|
457
|
+
case ATTR_NCLOB:
|
458
|
+
case ATTR_BLOB:
|
459
|
+
case ATTR_BFILE:
|
460
|
+
rb_raise(rb_eRuntimeError, "Could not set LOB objects to collection types yet.");
|
461
|
+
default:
|
462
|
+
rb_raise(rb_eRuntimeError, "not supported datatype");
|
463
|
+
}
|
464
|
+
#if 0
|
465
|
+
/* TODO: */
|
466
|
+
rb_ensure(set_coll_element_func, (VALUE)&cb_data, set_coll_element_ensure, (VALUE)&cb_data);
|
467
|
+
#else
|
468
|
+
set_coll_element_func(&cb_data);
|
469
|
+
set_coll_element_ensure(&cb_data);
|
470
|
+
#endif
|
471
|
+
*ind = 0;
|
472
|
+
return Qnil;
|
473
|
+
}
|
474
|
+
|
475
|
+
static VALUE set_coll_element_func(set_coll_element_cb_data_t *cb_data)
|
476
|
+
{
|
477
|
+
VALUE self = cb_data->self;
|
478
|
+
VALUE val = cb_data->val;
|
479
|
+
VALUE datatype = cb_data->datatype;
|
480
|
+
VALUE typeinfo = cb_data->typeinfo;
|
481
|
+
ACIColl *coll = cb_data->coll;
|
482
|
+
sb4 size;
|
483
|
+
sb4 idx;
|
484
|
+
void *elem_ptr;
|
485
|
+
|
486
|
+
chkerr(ACICollSize(oci8_envhp, oci8_errhp, coll, &size));
|
487
|
+
if (RARRAY_LEN(val) < size) {
|
488
|
+
chkerr(ACICollTrim(oci8_envhp, oci8_errhp, size - RARRAY_LEN(val), coll));
|
489
|
+
}
|
490
|
+
for (idx = 0; idx < RARRAY_LEN(val); idx++) {
|
491
|
+
switch (FIX2INT(datatype)) {
|
492
|
+
case ATTR_NAMED_TYPE:
|
493
|
+
set_attribute(self, datatype, typeinfo, cb_data->data.ptr, cb_data->indp, RARRAY_AREF(val, idx));
|
494
|
+
break;
|
495
|
+
default:
|
496
|
+
set_attribute(self, datatype, typeinfo, (void*)&cb_data->data, cb_data->indp, RARRAY_AREF(val, idx));
|
497
|
+
break;
|
498
|
+
}
|
499
|
+
switch (FIX2INT(datatype)) {
|
500
|
+
case ATTR_OCINUMBER:
|
501
|
+
case ATTR_FLOAT:
|
502
|
+
case ATTR_INTEGER:
|
503
|
+
case ATTR_OCIDATE:
|
504
|
+
case ATTR_BINARY_DOUBLE:
|
505
|
+
case ATTR_BINARY_FLOAT:
|
506
|
+
elem_ptr = &cb_data->data;
|
507
|
+
break;
|
508
|
+
default:
|
509
|
+
elem_ptr = cb_data->data.ptr;
|
510
|
+
break;
|
511
|
+
}
|
512
|
+
if (idx < size) {
|
513
|
+
chkerr(ACICollAssignElem(oci8_envhp, oci8_errhp, idx, elem_ptr, cb_data->indp, cb_data->coll));
|
514
|
+
} else {
|
515
|
+
chkerr(ACICollAppend(oci8_envhp, oci8_errhp, elem_ptr, cb_data->indp, coll));
|
516
|
+
}
|
517
|
+
}
|
518
|
+
return Qnil;
|
519
|
+
}
|
520
|
+
|
521
|
+
static VALUE set_coll_element_ensure(set_coll_element_cb_data_t *cb_data)
|
522
|
+
{
|
523
|
+
VALUE datatype = cb_data->datatype;
|
524
|
+
|
525
|
+
switch (FIX2INT(datatype)) {
|
526
|
+
case ATTR_STRING:
|
527
|
+
case ATTR_RAW:
|
528
|
+
case ATTR_TIMESTAMP:
|
529
|
+
case ATTR_TIMESTAMP_TZ:
|
530
|
+
case ATTR_NAMED_TYPE:
|
531
|
+
case ATTR_NAMED_COLLECTION:
|
532
|
+
if (cb_data->data.ptr != NULL) {
|
533
|
+
ACIObjectFree(oci8_envhp, oci8_errhp, cb_data->data.ptr, ACI_DEFAULT);
|
534
|
+
}
|
535
|
+
break;
|
536
|
+
case ATTR_OCINUMBER:
|
537
|
+
case ATTR_FLOAT:
|
538
|
+
case ATTR_INTEGER:
|
539
|
+
case ATTR_OCIDATE:
|
540
|
+
case ATTR_BINARY_DOUBLE:
|
541
|
+
case ATTR_BINARY_FLOAT:
|
542
|
+
break;
|
543
|
+
}
|
544
|
+
return Qnil;
|
545
|
+
}
|
546
|
+
|
547
|
+
|
548
|
+
static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, ACIInd *ind, VALUE val)
|
549
|
+
{
|
550
|
+
VALUE tmp_obj;
|
551
|
+
oci8_named_type_t *obj;
|
552
|
+
|
553
|
+
if (NIL_P(val)) {
|
554
|
+
*ind = -1;
|
555
|
+
return;
|
556
|
+
}
|
557
|
+
Check_Type(datatype, T_FIXNUM);
|
558
|
+
switch (FIX2INT(datatype)) {
|
559
|
+
case ATTR_STRING:
|
560
|
+
OCI8StringValue(val);
|
561
|
+
chkerr(ACIStringAssignText(oci8_envhp, oci8_errhp,
|
562
|
+
RSTRING_ORATEXT(val), RSTRING_LEN(val),
|
563
|
+
(ACIString **)data));
|
564
|
+
break;
|
565
|
+
case ATTR_RAW:
|
566
|
+
StringValue(val);
|
567
|
+
chkerr(ACIRawAssignBytes(oci8_envhp, oci8_errhp,
|
568
|
+
RSTRING_ORATEXT(val), RSTRING_LEN(val),
|
569
|
+
(ACIRaw **)data));
|
570
|
+
break;
|
571
|
+
case ATTR_OCINUMBER:
|
572
|
+
case ATTR_FLOAT:
|
573
|
+
oci8_set_ocinumber((ACINumber*)data, val, oci8_errhp);
|
574
|
+
break;
|
575
|
+
case ATTR_INTEGER:
|
576
|
+
oci8_set_integer((ACINumber*)data, val, oci8_errhp);
|
577
|
+
break;
|
578
|
+
case ATTR_OCIDATE:
|
579
|
+
oci8_set_ocidate((OCIDate*)data, val);
|
580
|
+
break;
|
581
|
+
case ATTR_TIMESTAMP:
|
582
|
+
oci8_set_ocitimestamp_tz(*(ACIDateTime **)data, val, Qnil);
|
583
|
+
break;
|
584
|
+
case ATTR_TIMESTAMP_TZ:
|
585
|
+
oci8_set_ocitimestamp_tz(*(ACIDateTime **)data, val, Qnil);
|
586
|
+
break;
|
587
|
+
case ATTR_BINARY_DOUBLE:
|
588
|
+
*(double*)data = NUM2DBL(val);
|
589
|
+
break;
|
590
|
+
case ATTR_BINARY_FLOAT:
|
591
|
+
*(float*)data = (float)NUM2DBL(val);
|
592
|
+
break;
|
593
|
+
case ATTR_NAMED_TYPE:
|
594
|
+
CHECK_TDO(typeinfo);
|
595
|
+
/* Be carefull. Don't use *tmp_obj* out of this function. */
|
596
|
+
tmp_obj = rb_class_new_instance(0, NULL, cOCI8NamedType);
|
597
|
+
obj = DATA_PTR(tmp_obj);
|
598
|
+
RB_OBJ_WRITE(tmp_obj, &obj->tdo, typeinfo);
|
599
|
+
obj->instancep = (char**)&data;
|
600
|
+
obj->null_structp = (char**)&ind;
|
601
|
+
oci8_link_to_parent(&obj->base, DATA_PTR(self));
|
602
|
+
RB_OBJ_WRITTEN(tmp_obj, Qundef, self);
|
603
|
+
rb_funcall(tmp_obj, id_set_attributes, 1, val);
|
604
|
+
oci8_unlink_from_parent(&obj->base);
|
605
|
+
RB_OBJ_WRITTEN(tmp_obj, self, Qundef);
|
606
|
+
break;
|
607
|
+
case ATTR_NAMED_COLLECTION:
|
608
|
+
CHECK_TDO(typeinfo);
|
609
|
+
/* Be carefull. Don't use *tmp_obj* out of this function. */
|
610
|
+
tmp_obj = rb_class_new_instance(0, NULL, cOCI8NamedCollection);
|
611
|
+
obj = DATA_PTR(tmp_obj);
|
612
|
+
RB_OBJ_WRITE(tmp_obj, &obj->tdo, typeinfo);
|
613
|
+
obj->instancep = (char**)data;
|
614
|
+
obj->null_structp = (char**)&ind;
|
615
|
+
oci8_link_to_parent(&obj->base, DATA_PTR(self));
|
616
|
+
RB_OBJ_WRITTEN(tmp_obj, Qundef, self);
|
617
|
+
rb_funcall(tmp_obj, id_set_attributes, 1, val);
|
618
|
+
oci8_unlink_from_parent(&obj->base);
|
619
|
+
RB_OBJ_WRITTEN(tmp_obj, self, Qundef);
|
620
|
+
break;
|
621
|
+
case ATTR_CLOB:
|
622
|
+
oci8_assign_clob(oci8_get_svcctx(typeinfo), val, (ACILobLocator **)data);
|
623
|
+
break;
|
624
|
+
case ATTR_NCLOB:
|
625
|
+
oci8_assign_nclob(oci8_get_svcctx(typeinfo), val, (ACILobLocator **)data);
|
626
|
+
break;
|
627
|
+
case ATTR_BLOB:
|
628
|
+
oci8_assign_blob(oci8_get_svcctx(typeinfo), val, (ACILobLocator **)data);
|
629
|
+
break;
|
630
|
+
case ATTR_BFILE:
|
631
|
+
oci8_assign_bfile(oci8_get_svcctx(typeinfo), val, (ACILobLocator **)data);
|
632
|
+
break;
|
633
|
+
default:
|
634
|
+
rb_raise(rb_eRuntimeError, "not supported datatype");
|
635
|
+
}
|
636
|
+
*ind = 0;
|
637
|
+
}
|
638
|
+
|
639
|
+
static const oci8_handle_data_type_t oci8_named_type_data_type = {
|
640
|
+
{
|
641
|
+
"STACI::NamedType",
|
642
|
+
{
|
643
|
+
(RUBY_DATA_FUNC)oci8_named_type_mark,
|
644
|
+
oci8_handle_cleanup,
|
645
|
+
oci8_handle_size,
|
646
|
+
},
|
647
|
+
&oci8_handle_data_type.rb_data_type, NULL,
|
648
|
+
#ifdef RUBY_TYPED_WB_PROTECTED
|
649
|
+
RUBY_TYPED_WB_PROTECTED,
|
650
|
+
#endif
|
651
|
+
},
|
652
|
+
oci8_named_type_free,
|
653
|
+
sizeof(oci8_named_type_t)
|
654
|
+
};
|
655
|
+
|
656
|
+
static const oci8_handle_data_type_t oci8_named_collection_data_type = {
|
657
|
+
{
|
658
|
+
"STACI::NamedCollection",
|
659
|
+
{
|
660
|
+
(RUBY_DATA_FUNC)oci8_named_type_mark,
|
661
|
+
oci8_handle_cleanup,
|
662
|
+
oci8_handle_size,
|
663
|
+
},
|
664
|
+
&oci8_handle_data_type.rb_data_type, NULL,
|
665
|
+
#ifdef RUBY_TYPED_WB_PROTECTED
|
666
|
+
RUBY_TYPED_WB_PROTECTED,
|
667
|
+
#endif
|
668
|
+
},
|
669
|
+
oci8_named_type_free,
|
670
|
+
sizeof(oci8_named_type_t)
|
671
|
+
};
|
672
|
+
|
673
|
+
static VALUE oci8_named_type_alloc(VALUE klass)
|
674
|
+
{
|
675
|
+
return oci8_allocate_typeddata(klass, &oci8_named_type_data_type);
|
676
|
+
}
|
677
|
+
|
678
|
+
static VALUE oci8_named_collection_alloc(VALUE klass)
|
679
|
+
{
|
680
|
+
return oci8_allocate_typeddata(klass, &oci8_named_collection_data_type);
|
681
|
+
}
|
682
|
+
|
683
|
+
typedef struct {
|
684
|
+
oci8_bind_t bind;
|
685
|
+
VALUE *obj;
|
686
|
+
} bind_named_type_t;
|
687
|
+
|
688
|
+
static void bind_named_type_mark(oci8_base_t *base)
|
689
|
+
{
|
690
|
+
bind_named_type_t *bnt = (bind_named_type_t *)base;
|
691
|
+
|
692
|
+
if (bnt->obj != NULL) {
|
693
|
+
ub4 idx = 0;
|
694
|
+
|
695
|
+
do {
|
696
|
+
rb_gc_mark(bnt->obj[idx]);
|
697
|
+
} while (++idx < bnt->bind.maxar_sz);
|
698
|
+
}
|
699
|
+
rb_gc_mark(bnt->bind.tdo);
|
700
|
+
}
|
701
|
+
|
702
|
+
static void bind_named_type_free(oci8_base_t *base)
|
703
|
+
{
|
704
|
+
bind_named_type_t *bnt = (bind_named_type_t *)base;
|
705
|
+
void **hp = (void **)bnt->bind.valuep;
|
706
|
+
|
707
|
+
if (hp != NULL) {
|
708
|
+
ub4 idx = 0;
|
709
|
+
|
710
|
+
do {
|
711
|
+
if (hp[idx] != NULL) {
|
712
|
+
ACIObjectFree(oci8_envhp, oci8_errhp, hp[idx], ACI_DEFAULT);
|
713
|
+
hp[idx] = NULL;
|
714
|
+
}
|
715
|
+
} while (++idx < bnt->bind.maxar_sz);
|
716
|
+
}
|
717
|
+
if (bnt->obj != NULL) {
|
718
|
+
xfree(bnt->obj);
|
719
|
+
bnt->obj = NULL;
|
720
|
+
}
|
721
|
+
oci8_bind_free(base);
|
722
|
+
}
|
723
|
+
|
724
|
+
static VALUE bind_named_type_get(oci8_bind_t *obind, void *data, void *null_struct)
|
725
|
+
{
|
726
|
+
bind_named_type_t *bnt = (bind_named_type_t *)obind;
|
727
|
+
ub4 idx = obind->curar_idx;
|
728
|
+
|
729
|
+
return bnt->obj[idx];
|
730
|
+
}
|
731
|
+
|
732
|
+
static void bind_named_type_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
733
|
+
{
|
734
|
+
rb_raise(rb_eRuntimeError, "not supported");
|
735
|
+
}
|
736
|
+
|
737
|
+
static void bind_named_type_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
738
|
+
{
|
739
|
+
bind_named_type_t *bnt = (bind_named_type_t *)obind;
|
740
|
+
VALUE tdo_obj = length;
|
741
|
+
|
742
|
+
obind->value_sz = sizeof(void*);
|
743
|
+
obind->alloc_sz = sizeof(void*);
|
744
|
+
bnt->obj = xcalloc(sizeof(VALUE), obind->maxar_sz ? obind->maxar_sz : 1);
|
745
|
+
|
746
|
+
CHECK_TDO(tdo_obj);
|
747
|
+
RB_OBJ_WRITE(obind->base.self, &obind->tdo, tdo_obj);
|
748
|
+
}
|
749
|
+
|
750
|
+
static void bind_named_type_init_elem(oci8_bind_t *obind, VALUE svc)
|
751
|
+
{
|
752
|
+
bind_named_type_t *bnt = (bind_named_type_t *)obind;
|
753
|
+
void **hp = (void **)obind->valuep;
|
754
|
+
oci8_base_t *tdo = DATA_PTR(obind->tdo);
|
755
|
+
ACITypeCode tc = ACITypeTypeCode(oci8_envhp, oci8_errhp, tdo->hp.tdo);
|
756
|
+
VALUE klass = Qnil;
|
757
|
+
oci8_named_type_t *obj;
|
758
|
+
oci8_svcctx_t *svcctx;
|
759
|
+
ub4 idx = 0;
|
760
|
+
|
761
|
+
switch (tc) {
|
762
|
+
case ACI_TYPECODE_OBJECT:
|
763
|
+
klass = cOCI8NamedType;
|
764
|
+
break;
|
765
|
+
case ACI_TYPECODE_NAMEDCOLLECTION:
|
766
|
+
klass = cOCI8NamedCollection;
|
767
|
+
break;
|
768
|
+
}
|
769
|
+
svcctx = oci8_get_svcctx(svc);
|
770
|
+
do {
|
771
|
+
bnt->obj[idx] = rb_class_new_instance(0, NULL, klass);
|
772
|
+
RB_OBJ_WRITTEN(obind->base.self, Qundef, bnt->obj[idx]);
|
773
|
+
obj = DATA_PTR(bnt->obj[idx]);
|
774
|
+
RB_OBJ_WRITE(bnt->obj[idx], &obj->tdo, obind->tdo);
|
775
|
+
obj->instancep = (char**)&hp[idx];
|
776
|
+
obj->null_structp = (char**)&obind->u.null_structs[idx];
|
777
|
+
oci8_link_to_parent(&obj->base, &obind->base);
|
778
|
+
RB_OBJ_WRITTEN(bnt->obj[idx], Qundef, obind->base.self);
|
779
|
+
|
780
|
+
chker2(ACIObjectNew(oci8_envhp, oci8_errhp, svcctx->base.hp.svc, tc, tdo->hp.tdo, NULL, ACI_DURATION_SESSION, TRUE, (dvoid**)obj->instancep),
|
781
|
+
&svcctx->base);
|
782
|
+
chker2(ACIObjectGetInd(oci8_envhp, oci8_errhp, (dvoid*)*obj->instancep, (dvoid**)obj->null_structp),
|
783
|
+
&svcctx->base);
|
784
|
+
*(ACIInd*)*obj->null_structp = -1;
|
785
|
+
} while (++idx < obind->maxar_sz);
|
786
|
+
}
|
787
|
+
|
788
|
+
static void bind_name_type_post_bind_hook(oci8_bind_t *obind)
|
789
|
+
{
|
790
|
+
oci8_base_t *tdo = DATA_PTR(obind->tdo);
|
791
|
+
switch (obind->base.type) {
|
792
|
+
case ACI_HTYPE_DEFINE:
|
793
|
+
chker2(ACIDefineObject(obind->base.hp.dfn, oci8_errhp, tdo->hp.tdo,
|
794
|
+
obind->valuep, 0, obind->u.null_structs, 0),
|
795
|
+
&obind->base);
|
796
|
+
break;
|
797
|
+
case ACI_HTYPE_BIND:
|
798
|
+
chker2(ACIBindObject(obind->base.hp.bnd, oci8_errhp, tdo->hp.tdo,
|
799
|
+
obind->valuep, 0, obind->u.null_structs, 0),
|
800
|
+
&obind->base);
|
801
|
+
break;
|
802
|
+
}
|
803
|
+
}
|
804
|
+
|
805
|
+
static const oci8_bind_data_type_t bind_named_type_data_type = {
|
806
|
+
{
|
807
|
+
{
|
808
|
+
"STACI::BindType::NamedType",
|
809
|
+
{
|
810
|
+
(RUBY_DATA_FUNC)bind_named_type_mark,
|
811
|
+
oci8_handle_cleanup,
|
812
|
+
oci8_handle_size,
|
813
|
+
},
|
814
|
+
&oci8_bind_data_type.rb_data_type, NULL,
|
815
|
+
#ifdef RUBY_TYPED_WB_PROTECTED
|
816
|
+
RUBY_TYPED_WB_PROTECTED,
|
817
|
+
#endif
|
818
|
+
},
|
819
|
+
bind_named_type_free,
|
820
|
+
sizeof(bind_named_type_t)
|
821
|
+
},
|
822
|
+
bind_named_type_get,
|
823
|
+
bind_named_type_set,
|
824
|
+
bind_named_type_init,
|
825
|
+
bind_named_type_init_elem,
|
826
|
+
NULL,
|
827
|
+
SQLT_NTY,
|
828
|
+
bind_name_type_post_bind_hook,
|
829
|
+
};
|
830
|
+
|
831
|
+
static VALUE bind_named_type_alloc(VALUE klass)
|
832
|
+
{
|
833
|
+
return oci8_allocate_typeddata(klass, &bind_named_type_data_type.base);
|
834
|
+
}
|
835
|
+
|
836
|
+
void Init_oci_object(VALUE cOCI8)
|
837
|
+
{
|
838
|
+
cOCI8MetadataType = rb_eval_string("STACI::Metadata::Type");
|
839
|
+
id_to_value = rb_intern("to_value");
|
840
|
+
id_set_attributes = rb_intern("attributes=");
|
841
|
+
id_get_tdo_by_metadata = rb_intern("get_tdo_by_metadata");
|
842
|
+
id_at_is_final_type = rb_intern("@is_final_type");
|
843
|
+
|
844
|
+
/* STACI::TDO */
|
845
|
+
cOCI8TDO = oci8_define_class_under(cOCI8, "TDO", &oci8_tdo_data_type, oci8_tdo_alloc);
|
846
|
+
rb_define_private_method(cOCI8TDO, "setup", oci8_tdo_setup, 2);
|
847
|
+
/* @private */
|
848
|
+
rb_define_const(cOCI8TDO, "ATTR_STRING", INT2FIX(ATTR_STRING));
|
849
|
+
/* @private */
|
850
|
+
rb_define_const(cOCI8TDO, "ATTR_RAW", INT2FIX(ATTR_RAW));
|
851
|
+
/* @private */
|
852
|
+
rb_define_const(cOCI8TDO, "ATTR_OCINUMBER", INT2FIX(ATTR_OCINUMBER));
|
853
|
+
/* @private */
|
854
|
+
rb_define_const(cOCI8TDO, "ATTR_FLOAT", INT2FIX(ATTR_FLOAT));
|
855
|
+
/* @private */
|
856
|
+
rb_define_const(cOCI8TDO, "ATTR_INTEGER", INT2FIX(ATTR_INTEGER));
|
857
|
+
/* @private */
|
858
|
+
rb_define_const(cOCI8TDO, "ATTR_OCIDATE", INT2FIX(ATTR_OCIDATE));
|
859
|
+
/* @private */
|
860
|
+
rb_define_const(cOCI8TDO, "ATTR_TIMESTAMP", INT2FIX(ATTR_TIMESTAMP));
|
861
|
+
/* @private */
|
862
|
+
rb_define_const(cOCI8TDO, "ATTR_TIMESTAMP_TZ", INT2FIX(ATTR_TIMESTAMP_TZ));
|
863
|
+
/* @private */
|
864
|
+
rb_define_const(cOCI8TDO, "ATTR_BINARY_DOUBLE", INT2FIX(ATTR_BINARY_DOUBLE));
|
865
|
+
/* @private */
|
866
|
+
rb_define_const(cOCI8TDO, "ATTR_BINARY_FLOAT", INT2FIX(ATTR_BINARY_FLOAT));
|
867
|
+
/* @private */
|
868
|
+
rb_define_const(cOCI8TDO, "ATTR_NAMED_TYPE", INT2FIX(ATTR_NAMED_TYPE));
|
869
|
+
/* @private */
|
870
|
+
rb_define_const(cOCI8TDO, "ATTR_NAMED_COLLECTION", INT2FIX(ATTR_NAMED_COLLECTION));
|
871
|
+
/* @private */
|
872
|
+
rb_define_const(cOCI8TDO, "ATTR_CLOB", INT2FIX(ATTR_CLOB));
|
873
|
+
/* @private */
|
874
|
+
rb_define_const(cOCI8TDO, "ATTR_NCLOB", INT2FIX(ATTR_NCLOB));
|
875
|
+
/* @private */
|
876
|
+
rb_define_const(cOCI8TDO, "ATTR_BLOB", INT2FIX(ATTR_BLOB));
|
877
|
+
/* @private */
|
878
|
+
rb_define_const(cOCI8TDO, "ATTR_BFILE", INT2FIX(ATTR_BFILE));
|
879
|
+
#define ALIGNMENT_OF(type) (size_t)&(((struct {char c; type t;}*)0)->t)
|
880
|
+
/* @private */
|
881
|
+
rb_define_const(cOCI8TDO, "SIZE_OF_POINTER", INT2FIX(sizeof(void *)));
|
882
|
+
/* @private */
|
883
|
+
rb_define_const(cOCI8TDO, "ALIGNMENT_OF_POINTER", INT2FIX(ALIGNMENT_OF(void *)));
|
884
|
+
/* @private */
|
885
|
+
rb_define_const(cOCI8TDO, "SIZE_OF_OCINUMBER", INT2FIX(sizeof(ACINumber)));
|
886
|
+
/* @private */
|
887
|
+
rb_define_const(cOCI8TDO, "ALIGNMENT_OF_OCINUMBER", INT2FIX(ALIGNMENT_OF(ACINumber)));
|
888
|
+
/* @private */
|
889
|
+
rb_define_const(cOCI8TDO, "SIZE_OF_OCIDATE", INT2FIX(sizeof(OCIDate)));
|
890
|
+
/* @private */
|
891
|
+
rb_define_const(cOCI8TDO, "ALIGNMENT_OF_OCIDATE", INT2FIX(ALIGNMENT_OF(OCIDate)));
|
892
|
+
/* @private */
|
893
|
+
rb_define_const(cOCI8TDO, "SIZE_OF_FLOAT", INT2FIX(sizeof(float)));
|
894
|
+
/* @private */
|
895
|
+
rb_define_const(cOCI8TDO, "ALIGNMENT_OF_FLOAT", INT2FIX(ALIGNMENT_OF(float)));
|
896
|
+
/* @private */
|
897
|
+
rb_define_const(cOCI8TDO, "SIZE_OF_DOUBLE", INT2FIX(sizeof(double)));
|
898
|
+
/* @private */
|
899
|
+
rb_define_const(cOCI8TDO, "ALIGNMENT_OF_DOUBLE", INT2FIX(ALIGNMENT_OF(double)));
|
900
|
+
|
901
|
+
/* OCI8::NamedType */
|
902
|
+
cOCI8NamedType = oci8_define_class_under(cOCI8, "NamedType", &oci8_named_type_data_type, oci8_named_type_alloc);
|
903
|
+
rb_define_method(cOCI8NamedType, "initialize", oci8_named_type_initialize, 0);
|
904
|
+
rb_define_method(cOCI8NamedType, "tdo", oci8_named_type_tdo, 0);
|
905
|
+
rb_define_private_method(cOCI8NamedType, "get_attribute", oci8_named_type_get_attribute, 4);
|
906
|
+
rb_define_private_method(cOCI8NamedType, "set_attribute", oci8_named_type_set_attribute, 5);
|
907
|
+
rb_define_method(cOCI8NamedType, "null?", oci8_named_type_null_p, 0);
|
908
|
+
rb_define_method(cOCI8NamedType, "null=", oci8_named_type_set_null, 1);
|
909
|
+
|
910
|
+
/* STACI::NamedCollection */
|
911
|
+
cOCI8NamedCollection = oci8_define_class_under(cOCI8, "NamedCollection", &oci8_named_collection_data_type, oci8_named_collection_alloc);
|
912
|
+
rb_define_method(cOCI8NamedCollection, "initialize", oci8_named_type_initialize, 0);
|
913
|
+
rb_define_method(cOCI8NamedCollection, "tdo", oci8_named_type_tdo, 0);
|
914
|
+
rb_define_private_method(cOCI8NamedCollection, "get_coll_element", oci8_named_coll_get_coll_element, 2);
|
915
|
+
rb_define_private_method(cOCI8NamedCollection, "set_coll_element", oci8_named_coll_set_coll_element, 3);
|
916
|
+
|
917
|
+
/* STACI::BindType::NamedType */
|
918
|
+
cOCI8BindNamedType = oci8_define_bind_class("NamedType", &bind_named_type_data_type, bind_named_type_alloc);
|
919
|
+
}
|