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.
- 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
|
}
|