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.
- data/ChangeLog +1254 -390
- data/Makefile +10 -13
- data/README +56 -385
- data/VERSION +1 -1
- data/dist-files +26 -27
- data/ext/oci8/.document +1 -0
- data/ext/oci8/MANIFEST +0 -4
- data/ext/oci8/apiwrap.c.tmpl +172 -0
- data/ext/oci8/apiwrap.h.tmpl +61 -0
- data/ext/oci8/apiwrap.rb +91 -0
- data/ext/oci8/apiwrap.yml +1243 -0
- data/ext/oci8/attr.c +124 -384
- data/ext/oci8/bind.c +472 -164
- data/ext/oci8/encoding.c +196 -0
- data/ext/oci8/env.c +84 -253
- data/ext/oci8/error.c +196 -127
- data/ext/oci8/extconf.rb +82 -59
- data/ext/oci8/lob.c +710 -370
- data/ext/oci8/metadata.c +359 -0
- data/ext/oci8/object.c +622 -0
- data/ext/oci8/oci8.c +577 -161
- data/ext/oci8/oci8.h +354 -258
- data/ext/oci8/oci8lib.c +493 -0
- data/ext/oci8/ocidatetime.c +473 -0
- data/ext/oci8/ocinumber.c +1123 -24
- data/ext/oci8/oraconf.rb +72 -106
- data/ext/oci8/oradate.c +511 -321
- data/ext/oci8/stmt.c +752 -572
- data/ext/oci8/win32.c +131 -0
- data/ext/oci8/xmldb.c +383 -0
- data/lib/.document +2 -0
- data/lib/dbd/OCI8.rb +2 -17
- data/lib/oci8.rb.in +41 -1622
- data/lib/oci8/.document +5 -0
- data/lib/oci8/compat.rb +108 -0
- data/lib/oci8/datetime.rb +489 -0
- data/lib/oci8/encoding-init.rb +40 -0
- data/lib/oci8/encoding.yml +537 -0
- data/lib/oci8/metadata.rb +2077 -0
- data/lib/oci8/object.rb +548 -0
- data/lib/oci8/oci8.rb +773 -0
- data/lib/oci8/oracle_version.rb +144 -0
- data/metaconfig +3 -3
- data/ruby-oci8.gemspec +5 -5
- data/setup.rb +4 -4
- data/test/config.rb +64 -84
- data/test/test_all.rb +14 -21
- data/test/test_array_dml.rb +317 -0
- data/test/test_bind_raw.rb +18 -25
- data/test/test_bind_time.rb +78 -91
- data/test/test_break.rb +37 -35
- data/test/test_clob.rb +33 -89
- data/test/test_connstr.rb +5 -4
- data/test/test_datetime.rb +469 -0
- data/test/test_dbi.rb +99 -60
- data/test/test_dbi_clob.rb +3 -8
- data/test/test_metadata.rb +65 -51
- data/test/test_oci8.rb +151 -55
- data/test/test_oracle_version.rb +70 -0
- data/test/test_oradate.rb +76 -83
- data/test/test_oranumber.rb +405 -71
- data/test/test_rowid.rb +6 -11
- metadata +31 -32
- data/NEWS +0 -420
- data/ext/oci8/const.c +0 -165
- data/ext/oci8/define.c +0 -53
- data/ext/oci8/describe.c +0 -81
- data/ext/oci8/descriptor.c +0 -39
- data/ext/oci8/handle.c +0 -273
- data/ext/oci8/oranumber.c +0 -445
- data/ext/oci8/param.c +0 -37
- data/ext/oci8/server.c +0 -182
- data/ext/oci8/session.c +0 -99
- data/ext/oci8/svcctx.c +0 -238
- data/ruby-oci8.spec +0 -62
- data/support/README +0 -4
- data/support/runit/assert.rb +0 -281
- data/support/runit/cui/testrunner.rb +0 -101
- data/support/runit/error.rb +0 -4
- data/support/runit/method_mappable.rb +0 -20
- data/support/runit/robserver.rb +0 -25
- data/support/runit/setuppable.rb +0 -15
- data/support/runit/teardownable.rb +0 -16
- data/support/runit/testcase.rb +0 -113
- data/support/runit/testfailure.rb +0 -25
- data/support/runit/testresult.rb +0 -121
- data/support/runit/testsuite.rb +0 -43
- data/support/runit/version.rb +0 -3
- data/test/test_describe.rb +0 -137
data/ext/oci8/bind.c
CHANGED
@@ -1,194 +1,502 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
1
2
|
/*
|
2
|
-
|
3
|
+
* bind.c
|
4
|
+
*
|
5
|
+
* $Author: kubo $
|
6
|
+
* $Date: 2009-01-12 00:11:09 +0900 (Mon, 12 Jan 2009) $
|
7
|
+
*
|
8
|
+
* Copyright (C) 2002-2008 KUBO Takehiro <kubo@jiubao.org>
|
9
|
+
*/
|
10
|
+
#include "oci8.h"
|
11
|
+
|
12
|
+
static ID id_bind_type;
|
13
|
+
static ID id_set;
|
3
14
|
|
4
|
-
|
15
|
+
static VALUE cOCI8BindTypeBase;
|
5
16
|
|
6
|
-
|
7
|
-
|
8
|
-
|
17
|
+
/*
|
18
|
+
* bind_string
|
19
|
+
*/
|
20
|
+
static VALUE bind_string_get(oci8_bind_t *obind, void *data, void *null_struct)
|
21
|
+
{
|
22
|
+
oci8_vstr_t *vstr = (oci8_vstr_t *)data;
|
23
|
+
return rb_external_str_new_with_enc(vstr->buf, vstr->size, oci8_encoding);
|
24
|
+
}
|
9
25
|
|
10
|
-
|
26
|
+
static void bind_string_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
27
|
+
{
|
28
|
+
oci8_vstr_t *vstr = (oci8_vstr_t *)data;
|
11
29
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
30
|
+
OCI8StringValue(val);
|
31
|
+
if (RSTRING_LEN(val) > obind->value_sz - sizeof(vstr->size)) {
|
32
|
+
rb_raise(rb_eArgError, "too long String to set. (%ld for %d)", RSTRING_LEN(val), obind->value_sz - (sb4)sizeof(vstr->size));
|
33
|
+
}
|
34
|
+
memcpy(vstr->buf, RSTRING_PTR(val), RSTRING_LEN(val));
|
35
|
+
vstr->size = RSTRING_LEN(val);
|
36
|
+
}
|
37
|
+
|
38
|
+
static void bind_string_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
39
|
+
{
|
40
|
+
sb4 sz;
|
41
|
+
if (NIL_P(length)) {
|
42
|
+
if (NIL_P(val)) {
|
43
|
+
rb_raise(rb_eArgError, "value and length are both null.");
|
44
|
+
}
|
45
|
+
StringValue(val);
|
46
|
+
sz = RSTRING_LEN(val);
|
47
|
+
} else {
|
48
|
+
sz = NUM2INT(length);
|
49
|
+
}
|
50
|
+
if (sz <= 0) {
|
51
|
+
rb_raise(rb_eArgError, "invalid bind length %d", sz);
|
52
|
+
}
|
53
|
+
sz += sizeof(sb4);
|
54
|
+
obind->value_sz = sz;
|
55
|
+
obind->alloc_sz = (sz + (sizeof(sb4) - 1)) & ~(sizeof(sb4) - 1);
|
56
|
+
}
|
57
|
+
|
58
|
+
static const oci8_bind_class_t bind_string_class = {
|
59
|
+
{
|
60
|
+
NULL,
|
61
|
+
oci8_bind_free,
|
62
|
+
sizeof(oci8_bind_t)
|
63
|
+
},
|
64
|
+
bind_string_get,
|
65
|
+
bind_string_set,
|
66
|
+
bind_string_init,
|
67
|
+
NULL,
|
68
|
+
NULL,
|
69
|
+
NULL,
|
70
|
+
NULL,
|
71
|
+
SQLT_LVC
|
72
|
+
};
|
16
73
|
|
17
74
|
/*
|
18
|
-
|
19
|
-
|
20
|
-
|
75
|
+
* bind_raw
|
76
|
+
*/
|
77
|
+
static VALUE bind_raw_get(oci8_bind_t *obind, void *data, void *null_struct)
|
78
|
+
{
|
79
|
+
oci8_vstr_t *vstr = (oci8_vstr_t *)data;
|
80
|
+
return rb_str_new(vstr->buf, vstr->size);
|
81
|
+
}
|
21
82
|
|
22
|
-
|
23
|
-
|
83
|
+
static const oci8_bind_class_t bind_raw_class = {
|
84
|
+
{
|
85
|
+
NULL,
|
86
|
+
oci8_bind_free,
|
87
|
+
sizeof(oci8_bind_t)
|
88
|
+
},
|
89
|
+
bind_raw_get,
|
90
|
+
bind_string_set,
|
91
|
+
bind_string_init,
|
92
|
+
NULL,
|
93
|
+
NULL,
|
94
|
+
NULL,
|
95
|
+
NULL,
|
96
|
+
SQLT_LVB
|
97
|
+
};
|
24
98
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
99
|
+
#ifdef USE_DYNAMIC_FETCH /* don't use DYNAMIC_FETCH. It doesn't work well... */
|
100
|
+
/*
|
101
|
+
* bind_long
|
102
|
+
*/
|
103
|
+
typedef struct {
|
104
|
+
VALUE obj;
|
105
|
+
ub4 alen;
|
106
|
+
char buf[1];
|
107
|
+
} bind_long_t;
|
108
|
+
#define bind_long_offset ((size_t)((bind_long_t*)0)->buf)
|
109
|
+
|
110
|
+
static void bind_long_mark(oci8_base_t *base)
|
29
111
|
{
|
30
|
-
|
31
|
-
|
112
|
+
oci8_bind_t *obind = (oci8_bind_t*)base;
|
113
|
+
ub4 idx = 0;
|
32
114
|
|
33
|
-
|
34
|
-
|
35
|
-
|
115
|
+
if (obind->valuep == NULL)
|
116
|
+
return;
|
117
|
+
do {
|
118
|
+
bind_long_t *bl = (bind_long_t *)((char*)obind->valuep + obind->alloc_sz * idx);
|
119
|
+
rb_gc_mark(bl->obj);
|
120
|
+
} while (++idx < obind->maxar_sz);
|
36
121
|
}
|
37
122
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
123
|
+
static VALUE bind_long_get(oci8_bind_t *obind, void *data, void *null_struct)
|
124
|
+
{
|
125
|
+
bind_long_t *bl = (bind_long_t *)data;
|
126
|
+
return RTEST(bl->obj) ? rb_str_dup(bl->obj) : Qnil;
|
127
|
+
}
|
42
128
|
|
43
|
-
|
44
|
-
|
129
|
+
static void bind_long_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
130
|
+
{
|
131
|
+
bind_long_t *bl = (bind_long_t *)data;
|
132
|
+
bl->obj = rb_str_dup(val);
|
133
|
+
}
|
45
134
|
|
46
|
-
|
47
|
-
=end
|
48
|
-
*/
|
49
|
-
static VALUE oci8_set_data(VALUE self, VALUE val)
|
135
|
+
static void bind_long_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
50
136
|
{
|
51
|
-
|
137
|
+
sb4 sz = 0;
|
52
138
|
|
53
|
-
|
54
|
-
|
55
|
-
|
139
|
+
if (!NIL_P(length)) {
|
140
|
+
sz = NUM2INT(length);
|
141
|
+
}
|
142
|
+
if (sz < 4000) {
|
143
|
+
sz = 4000;
|
144
|
+
}
|
145
|
+
sz += bind_long_offset;
|
146
|
+
obind->value_sz = INT_MAX;
|
147
|
+
obind->alloc_sz = (sz + (sizeof(VALUE) - 1)) & ~(sizeof(VALUE) - 1);
|
56
148
|
}
|
57
149
|
|
58
|
-
void
|
150
|
+
static void bind_long_init_elem(oci8_bind_t *obind, VALUE svc)
|
59
151
|
{
|
60
|
-
|
61
|
-
|
152
|
+
ub4 idx = 0;
|
153
|
+
|
154
|
+
do {
|
155
|
+
bind_long_t *bl = (bind_long_t *)((char*)obind->valuep + obind->alloc_sz * idx);
|
156
|
+
bl->obj = Qnil;
|
157
|
+
} while (++idx < obind->maxar_sz);
|
62
158
|
}
|
63
159
|
|
64
|
-
|
160
|
+
static ub1 bind_long_in(oci8_bind_t *obind, ub4 idx, ub1 piece, void **valuepp, ub4 **alenpp, void **indpp)
|
65
161
|
{
|
66
|
-
|
67
|
-
ora_vnumber_t *ovn;
|
68
|
-
VALUE obj;
|
69
|
-
unsigned char buf[ORA_NUMBER_BUF_SIZE];
|
70
|
-
int year, month, day, hour, minute, second;
|
71
|
-
static ID id_local = (ID)-1;
|
162
|
+
bind_long_t *bl = (bind_long_t *)((char*)obind->valuep + obind->alloc_sz * idx);
|
72
163
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
164
|
+
*alenpp = &bl->alen;
|
165
|
+
*indpp = &obind->u.inds[idx];
|
166
|
+
if (NIL_P(bl->obj)) {
|
167
|
+
*valuepp = NULL;
|
168
|
+
bl->alen = 0;
|
169
|
+
obind->u.inds[idx] = -1;
|
170
|
+
} else {
|
171
|
+
StringValue(bl->obj);
|
172
|
+
*valuepp = RSTRING_PTR(bl->obj);
|
173
|
+
bl->alen = RSTRING_LEN(bl->obj);
|
174
|
+
obind->u.inds[idx] = 0;
|
175
|
+
}
|
176
|
+
return OCI_ONE_PIECE;
|
177
|
+
}
|
178
|
+
|
179
|
+
static void bind_long_out(oci8_bind_t *obind, ub4 idx, ub1 piece, void **valuepp, ub4 **alenpp, void **indpp)
|
180
|
+
{
|
181
|
+
bind_long_t *bl = (bind_long_t *)((char*)obind->valuep + obind->alloc_sz * idx);
|
182
|
+
|
183
|
+
switch (piece) {
|
184
|
+
case OCI_NEXT_PIECE:
|
185
|
+
case OCI_LAST_PIECE:
|
186
|
+
if (bl->alen > 0) {
|
187
|
+
if (!RTEST(bl->obj)) {
|
188
|
+
bl->obj = rb_str_buf_new(bl->alen);
|
189
|
+
}
|
190
|
+
rb_str_buf_cat(bl->obj, bl->buf, bl->alen);
|
191
|
+
}
|
192
|
+
break;
|
193
|
+
default:
|
194
|
+
/* OCI_FIRST_PIECE is passed at the first call according to manuals.
|
195
|
+
* But OCI_ONE_PIECE is passed on Oracle 8 and 8i on Windows...
|
196
|
+
*/
|
197
|
+
bl->obj = Qnil;
|
198
|
+
}
|
199
|
+
*valuepp = bl->buf;
|
200
|
+
*alenpp = &bl->alen;
|
201
|
+
*indpp = &obind->u.inds[idx];
|
202
|
+
bl->alen = obind->alloc_sz - bind_long_offset;
|
203
|
+
obind->u.inds[idx] = 0;
|
204
|
+
}
|
205
|
+
|
206
|
+
static const oci8_bind_class_t bind_long_class = {
|
207
|
+
{
|
208
|
+
bind_long_mark,
|
209
|
+
oci8_bind_free,
|
210
|
+
sizeof(oci8_bind_t)
|
211
|
+
},
|
212
|
+
bind_long_get,
|
213
|
+
bind_long_set,
|
214
|
+
bind_long_init,
|
215
|
+
bind_long_init_elem,
|
216
|
+
bind_long_in,
|
217
|
+
bind_long_out,
|
218
|
+
NULL,
|
219
|
+
SQLT_CHR
|
220
|
+
};
|
221
|
+
|
222
|
+
/*
|
223
|
+
* bind_long_raw
|
224
|
+
*/
|
225
|
+
static const oci8_bind_class_t bind_long_raw_class = {
|
226
|
+
{
|
227
|
+
bind_long_mark,
|
228
|
+
oci8_bind_free,
|
229
|
+
sizeof(oci8_bind_t)
|
230
|
+
},
|
231
|
+
bind_long_get,
|
232
|
+
bind_long_set,
|
233
|
+
bind_long_init,
|
234
|
+
bind_long_init_elem,
|
235
|
+
bind_long_in,
|
236
|
+
bind_long_out,
|
237
|
+
NULL,
|
238
|
+
SQLT_BIN
|
239
|
+
};
|
240
|
+
#endif /* USE_DYNAMIC_FETCH */
|
241
|
+
|
242
|
+
/*
|
243
|
+
* bind_fixnum
|
244
|
+
*/
|
245
|
+
static VALUE bind_fixnum_get(oci8_bind_t *obind, void *data, void *null_struct)
|
246
|
+
{
|
247
|
+
return LONG2NUM(*(long*)data);
|
248
|
+
}
|
249
|
+
|
250
|
+
static void bind_fixnum_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
251
|
+
{
|
124
252
|
Check_Type(val, T_FIXNUM);
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
253
|
+
*(long*)data = FIX2LONG(val);
|
254
|
+
}
|
255
|
+
|
256
|
+
static void bind_fixnum_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
257
|
+
{
|
258
|
+
obind->value_sz = sizeof(long);
|
259
|
+
obind->alloc_sz = sizeof(long);
|
260
|
+
}
|
261
|
+
|
262
|
+
static const oci8_bind_class_t bind_fixnum_class = {
|
263
|
+
{
|
264
|
+
NULL,
|
265
|
+
oci8_bind_free,
|
266
|
+
sizeof(oci8_bind_t)
|
267
|
+
},
|
268
|
+
bind_fixnum_get,
|
269
|
+
bind_fixnum_set,
|
270
|
+
bind_fixnum_init,
|
271
|
+
NULL,
|
272
|
+
NULL,
|
273
|
+
NULL,
|
274
|
+
NULL,
|
275
|
+
SQLT_INT
|
276
|
+
};
|
277
|
+
|
278
|
+
/*
|
279
|
+
* bind_float
|
280
|
+
*/
|
281
|
+
static VALUE bind_float_get(oci8_bind_t *obind, void *data, void *null_struct)
|
282
|
+
{
|
283
|
+
return rb_float_new(*(double*)data);
|
284
|
+
}
|
285
|
+
|
286
|
+
static void bind_float_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
287
|
+
{
|
153
288
|
Check_Type(val, T_FLOAT);
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
289
|
+
*(double*)data = RFLOAT_VALUE(val);
|
290
|
+
}
|
291
|
+
|
292
|
+
static void bind_float_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
293
|
+
{
|
294
|
+
obind->value_sz = sizeof(double);
|
295
|
+
obind->alloc_sz = sizeof(double);
|
296
|
+
}
|
297
|
+
|
298
|
+
static const oci8_bind_class_t bind_float_class = {
|
299
|
+
{
|
300
|
+
NULL,
|
301
|
+
oci8_bind_free,
|
302
|
+
sizeof(oci8_bind_t)
|
303
|
+
},
|
304
|
+
bind_float_get,
|
305
|
+
bind_float_set,
|
306
|
+
bind_float_init,
|
307
|
+
NULL,
|
308
|
+
NULL,
|
309
|
+
NULL,
|
310
|
+
NULL,
|
311
|
+
SQLT_FLT
|
312
|
+
};
|
313
|
+
|
314
|
+
#ifndef SQLT_BDOUBLE
|
315
|
+
#define SQLT_BDOUBLE 22
|
316
|
+
#endif
|
317
|
+
static const oci8_bind_class_t bind_binary_double_class = {
|
318
|
+
{
|
319
|
+
NULL,
|
320
|
+
oci8_bind_free,
|
321
|
+
sizeof(oci8_bind_t)
|
322
|
+
},
|
323
|
+
bind_float_get,
|
324
|
+
bind_float_set,
|
325
|
+
bind_float_init,
|
326
|
+
NULL,
|
327
|
+
NULL,
|
328
|
+
NULL,
|
329
|
+
NULL,
|
330
|
+
SQLT_BDOUBLE
|
331
|
+
};
|
332
|
+
|
333
|
+
static inline VALUE oci8_get_data_at(const oci8_bind_class_t *obc, oci8_bind_t *obind, ub4 idx)
|
334
|
+
{
|
335
|
+
void **null_structp = NULL;
|
336
|
+
|
337
|
+
if (NIL_P(obind->tdo)) {
|
338
|
+
if (obind->u.inds[idx] != 0)
|
339
|
+
return Qnil;
|
340
|
+
} else {
|
341
|
+
null_structp = &obind->u.null_structs[idx];
|
342
|
+
if (*(OCIInd*)*null_structp != 0)
|
343
|
+
return Qnil;
|
344
|
+
}
|
345
|
+
return obc->get(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp);
|
346
|
+
}
|
347
|
+
|
348
|
+
static VALUE oci8_get_data(VALUE self)
|
349
|
+
{
|
350
|
+
oci8_bind_t *obind = DATA_PTR(self);
|
351
|
+
const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
|
352
|
+
|
353
|
+
if (obind->maxar_sz == 0) {
|
354
|
+
return oci8_get_data_at(obc, obind, 0);
|
355
|
+
} else {
|
356
|
+
volatile VALUE ary = rb_ary_new2(obind->curar_sz);
|
357
|
+
ub4 idx;
|
358
|
+
|
359
|
+
for (idx = 0; idx < obind->curar_sz; idx++) {
|
360
|
+
rb_ary_store(ary, idx, oci8_get_data_at(obc, obind, idx));
|
361
|
+
}
|
362
|
+
return ary;
|
363
|
+
}
|
364
|
+
}
|
365
|
+
|
366
|
+
static inline void oci8_set_data_at(const oci8_bind_class_t *obc, oci8_bind_t *obind, ub4 idx, VALUE val)
|
367
|
+
{
|
368
|
+
|
369
|
+
if (NIL_P(val)) {
|
370
|
+
if (NIL_P(obind->tdo)) {
|
371
|
+
obind->u.inds[idx] = -1;
|
372
|
+
} else {
|
373
|
+
*(OCIInd*)obind->u.null_structs[idx] = -1;
|
374
|
+
}
|
375
|
+
} else {
|
376
|
+
void **null_structp = NULL;
|
377
|
+
|
378
|
+
if (NIL_P(obind->tdo)) {
|
379
|
+
null_structp = NULL;
|
380
|
+
obind->u.inds[idx] = 0;
|
381
|
+
} else {
|
382
|
+
null_structp = &obind->u.null_structs[idx];
|
383
|
+
}
|
384
|
+
obc->set(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp, val);
|
385
|
+
}
|
386
|
+
}
|
387
|
+
|
388
|
+
static VALUE oci8_set_data(VALUE self, VALUE val)
|
389
|
+
{
|
390
|
+
oci8_bind_t *obind = DATA_PTR(self);
|
391
|
+
const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
|
392
|
+
|
393
|
+
if (obind->maxar_sz == 0) {
|
394
|
+
oci8_set_data_at(obc, obind, 0, val);
|
395
|
+
} else {
|
396
|
+
ub4 size;
|
397
|
+
ub4 idx;
|
398
|
+
Check_Type(val, T_ARRAY);
|
399
|
+
|
400
|
+
size = RARRAY_LEN(val);
|
401
|
+
if (size > obind->maxar_sz) {
|
402
|
+
rb_raise(rb_eRuntimeError, "over the max array size");
|
403
|
+
}
|
404
|
+
for (idx = 0; idx < size; idx++) {
|
405
|
+
oci8_set_data_at(obc, obind, idx, RARRAY_PTR(val)[idx]);
|
406
|
+
}
|
407
|
+
obind->curar_sz = size;
|
408
|
+
}
|
409
|
+
return self;
|
410
|
+
}
|
411
|
+
|
412
|
+
static VALUE oci8_bind_initialize(VALUE self, VALUE svc, VALUE val, VALUE length, VALUE max_array_size)
|
413
|
+
{
|
414
|
+
oci8_bind_t *obind = DATA_PTR(self);
|
415
|
+
const oci8_bind_class_t *bind_class = (const oci8_bind_class_t *)obind->base.klass;
|
416
|
+
ub4 cnt = 1;
|
417
|
+
|
418
|
+
obind->tdo = Qnil;
|
419
|
+
obind->maxar_sz = NIL_P(max_array_size) ? 0 : NUM2UINT(max_array_size);
|
420
|
+
obind->curar_sz = 0;
|
421
|
+
if (obind->maxar_sz > 0)
|
422
|
+
cnt = obind->maxar_sz;
|
423
|
+
bind_class->init(obind, svc, val, length);
|
424
|
+
if (obind->alloc_sz > 0) {
|
425
|
+
obind->valuep = xmalloc(obind->alloc_sz * cnt);
|
426
|
+
memset(obind->valuep, 0, obind->alloc_sz * cnt);
|
176
427
|
} else {
|
177
|
-
|
178
|
-
}
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
oci8_handle_t *h;
|
183
|
-
Get_Handle(val, h);
|
184
|
-
hp->value.handle.v = val;
|
185
|
-
hp->value.handle.hp = h->hp;
|
428
|
+
obind->valuep = NULL;
|
429
|
+
}
|
430
|
+
if (NIL_P(obind->tdo)) {
|
431
|
+
obind->u.inds = xmalloc(sizeof(sb2) * cnt);
|
432
|
+
memset(obind->u.inds, -1, sizeof(sb2) * cnt);
|
186
433
|
} else {
|
187
|
-
|
434
|
+
obind->u.null_structs = xmalloc(sizeof(void *) * cnt);
|
435
|
+
memset(obind->u.null_structs, 0, sizeof(void *) * cnt);
|
436
|
+
}
|
437
|
+
if (bind_class->init_elem != NULL) {
|
438
|
+
bind_class->init_elem(obind, svc);
|
439
|
+
}
|
440
|
+
if (!NIL_P(val)) {
|
441
|
+
rb_funcall(self, id_set, 1, val);
|
442
|
+
}
|
443
|
+
return Qnil;
|
444
|
+
}
|
445
|
+
|
446
|
+
void oci8_bind_free(oci8_base_t *base)
|
447
|
+
{
|
448
|
+
oci8_bind_t *obind = (oci8_bind_t *)base;
|
449
|
+
if (obind->valuep != NULL) {
|
450
|
+
xfree(obind->valuep);
|
451
|
+
obind->valuep = NULL;
|
452
|
+
}
|
453
|
+
if (obind->u.inds != NULL) {
|
454
|
+
xfree(obind->u.inds);
|
455
|
+
obind->u.inds = NULL;
|
188
456
|
}
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
457
|
+
}
|
458
|
+
|
459
|
+
void oci8_bind_hp_obj_mark(oci8_base_t *base)
|
460
|
+
{
|
461
|
+
oci8_bind_t *obind = (oci8_bind_t *)base;
|
462
|
+
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
|
463
|
+
|
464
|
+
if (oho != NULL) {
|
465
|
+
ub4 idx = 0;
|
466
|
+
|
467
|
+
do {
|
468
|
+
rb_gc_mark(oho[idx].obj);
|
469
|
+
} while (++idx < obind->maxar_sz);
|
470
|
+
}
|
471
|
+
}
|
472
|
+
|
473
|
+
void Init_oci8_bind(VALUE klass)
|
474
|
+
{
|
475
|
+
cOCI8BindTypeBase = klass;
|
476
|
+
id_bind_type = rb_intern("bind_type");
|
477
|
+
id_set = rb_intern("set");
|
478
|
+
|
479
|
+
rb_define_method(cOCI8BindTypeBase, "initialize", oci8_bind_initialize, 4);
|
480
|
+
rb_define_method(cOCI8BindTypeBase, "get", oci8_get_data, 0);
|
481
|
+
rb_define_method(cOCI8BindTypeBase, "set", oci8_set_data, 1);
|
482
|
+
|
483
|
+
/* register primitive data types. */
|
484
|
+
oci8_define_bind_class("String", &bind_string_class);
|
485
|
+
oci8_define_bind_class("RAW", &bind_raw_class);
|
486
|
+
#ifdef USE_DYNAMIC_FETCH
|
487
|
+
oci8_define_bind_class("Long", &bind_long_class);
|
488
|
+
oci8_define_bind_class("LongRaw", &bind_long_raw_class);
|
489
|
+
#endif /* USE_DYNAMIC_FETCH */
|
490
|
+
oci8_define_bind_class("Fixnum", &bind_fixnum_class);
|
491
|
+
oci8_define_bind_class("Float", &bind_float_class);
|
492
|
+
if (oracle_client_version >= ORAVER_10_1) {
|
493
|
+
oci8_define_bind_class("BinaryDouble", &bind_binary_double_class);
|
494
|
+
}
|
495
|
+
}
|
496
|
+
|
497
|
+
oci8_bind_t *oci8_get_bind(VALUE obj)
|
498
|
+
{
|
499
|
+
oci8_base_t *base;
|
500
|
+
Check_Handle(obj, cOCI8BindTypeBase, base);
|
501
|
+
return (oci8_bind_t *)base;
|
194
502
|
}
|