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/lob.c
CHANGED
@@ -1,403 +1,743 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
1
2
|
#include "oci8.h"
|
2
3
|
|
3
|
-
static
|
4
|
+
static ID id_plus;
|
5
|
+
static ID id_dir_alias;
|
6
|
+
static ID id_filename;
|
7
|
+
static VALUE cOCI8LOB;
|
8
|
+
static VALUE cOCI8CLOB;
|
9
|
+
static VALUE cOCI8NCLOB;
|
10
|
+
static VALUE cOCI8BLOB;
|
11
|
+
static VALUE cOCI8BFILE;
|
12
|
+
static VALUE seek_set;
|
13
|
+
static VALUE seek_cur;
|
14
|
+
static VALUE seek_end;
|
15
|
+
|
16
|
+
enum state {
|
17
|
+
S_NO_OPEN_CLOSE,
|
18
|
+
S_OPEN,
|
19
|
+
S_CLOSE,
|
20
|
+
S_BFILE_CLOSE,
|
21
|
+
S_BFILE_OPEN,
|
22
|
+
};
|
23
|
+
typedef struct {
|
24
|
+
oci8_base_t base;
|
25
|
+
VALUE svc;
|
26
|
+
ub4 pos;
|
27
|
+
int char_width;
|
28
|
+
ub1 csfrm;
|
29
|
+
enum state state;
|
30
|
+
} oci8_lob_t;
|
31
|
+
|
32
|
+
static VALUE oci8_lob_write(VALUE self, VALUE data);
|
33
|
+
|
34
|
+
static VALUE oci8_make_lob(VALUE klass, oci8_svcctx_t *svcctx, OCILobLocator *s)
|
35
|
+
{
|
36
|
+
oci8_lob_t *lob;
|
37
|
+
VALUE lob_obj;
|
38
|
+
|
39
|
+
lob_obj = rb_funcall(klass, oci8_id_new, 1, svcctx->base.self);
|
40
|
+
lob = DATA_PTR(lob_obj);
|
41
|
+
/* If 's' is a temporary lob, use OCILobLocatorAssign instead. */
|
42
|
+
oci_lc(OCILobAssign(oci8_envhp, oci8_errhp, s, &lob->base.hp.lob));
|
43
|
+
return lob_obj;
|
44
|
+
}
|
4
45
|
|
5
|
-
|
6
|
-
static VALUE oci8_lob_set_char_width(VALUE self, VALUE vsize)
|
46
|
+
VALUE oci8_make_clob(oci8_svcctx_t *svcctx, OCILobLocator *s)
|
7
47
|
{
|
8
|
-
|
9
|
-
|
48
|
+
return oci8_make_lob(cOCI8CLOB, svcctx, s);
|
49
|
+
}
|
10
50
|
|
11
|
-
|
12
|
-
|
51
|
+
VALUE oci8_make_nclob(oci8_svcctx_t *svcctx, OCILobLocator *s)
|
52
|
+
{
|
53
|
+
return oci8_make_lob(cOCI8NCLOB, svcctx, s);
|
54
|
+
}
|
13
55
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
return vsize;
|
56
|
+
VALUE oci8_make_blob(oci8_svcctx_t *svcctx, OCILobLocator *s)
|
57
|
+
{
|
58
|
+
return oci8_make_lob(cOCI8BLOB, svcctx, s);
|
18
59
|
}
|
19
|
-
#endif
|
20
60
|
|
21
|
-
|
61
|
+
VALUE oci8_make_bfile(oci8_svcctx_t *svcctx, OCILobLocator *s)
|
22
62
|
{
|
23
|
-
|
24
|
-
|
25
|
-
boolean is_initialized;
|
26
|
-
sword rv;
|
63
|
+
return oci8_make_lob(cOCI8BFILE, svcctx, s);
|
64
|
+
}
|
27
65
|
|
28
|
-
|
29
|
-
|
66
|
+
static void oci8_lob_mark(oci8_base_t *base)
|
67
|
+
{
|
68
|
+
oci8_lob_t *lob = (oci8_lob_t *)base;
|
69
|
+
rb_gc_mark(lob->svc);
|
70
|
+
}
|
30
71
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
72
|
+
static void oci8_lob_free(oci8_base_t *base)
|
73
|
+
{
|
74
|
+
oci8_lob_t *lob = (oci8_lob_t *)base;
|
75
|
+
lob->svc = Qnil;
|
35
76
|
}
|
36
77
|
|
78
|
+
static oci8_base_class_t oci8_lob_class = {
|
79
|
+
oci8_lob_mark,
|
80
|
+
oci8_lob_free,
|
81
|
+
sizeof(oci8_lob_t),
|
82
|
+
};
|
37
83
|
|
38
|
-
|
39
|
-
=begin
|
40
|
-
--- OCILobLocator#GetLength()
|
41
|
-
get the length of LOB.
|
42
|
-
counts by bytes for BLOB, by charactors for CLOB.
|
43
|
-
=end
|
44
|
-
*/
|
45
|
-
static VALUE oci8_lob_get_length(VALUE self, VALUE vsvc)
|
84
|
+
static ub4 oci8_lob_get_length(oci8_lob_t *lob)
|
46
85
|
{
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
86
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
87
|
+
ub4 len;
|
88
|
+
|
89
|
+
oci_lc(OCILobGetLength_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &len));
|
90
|
+
return len;
|
91
|
+
}
|
92
|
+
|
93
|
+
static void lob_open(oci8_lob_t *lob)
|
94
|
+
{
|
95
|
+
if (lob->state == S_CLOSE) {
|
96
|
+
if (have_OCILobOpen_nb) {
|
97
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
98
|
+
|
99
|
+
oci_lc(OCILobOpen_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, OCI_DEFAULT));
|
100
|
+
}
|
101
|
+
lob->state = S_OPEN;
|
102
|
+
}
|
103
|
+
}
|
51
104
|
|
52
|
-
|
53
|
-
|
105
|
+
static void lob_close(oci8_lob_t *lob)
|
106
|
+
{
|
107
|
+
if (lob->state == S_OPEN) {
|
108
|
+
if (have_OCILobClose_nb) {
|
109
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
54
110
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
111
|
+
oci_lc(OCILobClose_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob));
|
112
|
+
}
|
113
|
+
lob->state = S_CLOSE;
|
114
|
+
}
|
59
115
|
}
|
60
116
|
|
61
|
-
|
62
|
-
static VALUE oci8_lob_get_chunk_size(VALUE self, VALUE vsvc)
|
117
|
+
static void bfile_close(oci8_lob_t *lob)
|
63
118
|
{
|
64
|
-
|
65
|
-
|
66
|
-
ub4 len;
|
67
|
-
sword rv;
|
119
|
+
if (lob->state == S_BFILE_OPEN) {
|
120
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
68
121
|
|
69
|
-
|
70
|
-
|
122
|
+
oci_lc(OCILobFileClose_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob));
|
123
|
+
lob->state = S_BFILE_CLOSE;
|
124
|
+
}
|
125
|
+
}
|
71
126
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
127
|
+
static VALUE oci8_lob_close(VALUE self)
|
128
|
+
{
|
129
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
130
|
+
lob_close(lob);
|
131
|
+
oci8_base_free(DATA_PTR(self));
|
132
|
+
return self;
|
76
133
|
}
|
77
|
-
#endif
|
78
134
|
|
79
|
-
|
80
|
-
static sb4 oci8_callback_lob_read(dvoid *ctxp, CONST dvoid *bufp, ub4 len, ub1 piece)
|
135
|
+
static VALUE oci8_lob_do_initialize(int argc, VALUE *argv, VALUE self, ub1 csfrm, ub1 lobtype)
|
81
136
|
{
|
82
|
-
|
137
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
138
|
+
VALUE svc;
|
139
|
+
VALUE val;
|
140
|
+
sword rv;
|
141
|
+
|
142
|
+
rb_scan_args(argc, argv, "11", &svc, &val);
|
143
|
+
TO_SVCCTX(svc); /* check argument type */
|
144
|
+
rv = OCIDescriptorAlloc(oci8_envhp, &lob->base.hp.ptr, OCI_DTYPE_LOB, 0, NULL);
|
145
|
+
if (rv != OCI_SUCCESS)
|
146
|
+
oci8_env_raise(oci8_envhp, rv);
|
147
|
+
lob->base.type = OCI_DTYPE_LOB;
|
148
|
+
lob->svc = svc;
|
149
|
+
lob->pos = 0;
|
150
|
+
lob->char_width = 1;
|
151
|
+
lob->csfrm = csfrm;
|
152
|
+
lob->state = S_NO_OPEN_CLOSE;
|
153
|
+
oci8_link_to_parent((oci8_base_t*)lob, (oci8_base_t*)DATA_PTR(svc));
|
154
|
+
if (!NIL_P(val)) {
|
155
|
+
if (have_OCILobCreateTemporary_nb) {
|
156
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(svc);
|
157
|
+
OCI8StringValue(val);
|
158
|
+
oci_lc(OCILobCreateTemporary_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, 0, csfrm, lobtype, TRUE, OCI_DURATION_SESSION));
|
159
|
+
oci8_lob_write(self, val);
|
160
|
+
} else {
|
161
|
+
rb_raise(rb_eRuntimeError, "creating a temporary lob is not supported on this Oracle version");
|
162
|
+
}
|
163
|
+
}
|
164
|
+
return Qnil;
|
165
|
+
}
|
83
166
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
167
|
+
static VALUE oci8_clob_initialize(int argc, VALUE *argv, VALUE self)
|
168
|
+
{
|
169
|
+
oci8_lob_do_initialize(argc, argv, self, SQLCS_IMPLICIT, OCI_TEMP_CLOB);
|
170
|
+
return Qnil;
|
171
|
+
}
|
88
172
|
|
89
|
-
|
90
|
-
|
173
|
+
static VALUE oci8_nclob_initialize(int argc, VALUE *argv, VALUE self)
|
174
|
+
{
|
175
|
+
oci8_lob_do_initialize(argc, argv, self, SQLCS_NCHAR, OCI_TEMP_CLOB);
|
176
|
+
return Qnil;
|
177
|
+
}
|
178
|
+
|
179
|
+
static VALUE oci8_blob_initialize(int argc, VALUE *argv, VALUE self)
|
180
|
+
{
|
181
|
+
oci8_lob_do_initialize(argc, argv, self, SQLCS_IMPLICIT, OCI_TEMP_BLOB);
|
182
|
+
return Qnil;
|
183
|
+
}
|
184
|
+
|
185
|
+
static VALUE oci8_lob_set_char_width(VALUE self, VALUE vsize)
|
186
|
+
{
|
187
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
188
|
+
int size;
|
189
|
+
|
190
|
+
size = NUM2INT(vsize); /* 1 */
|
191
|
+
|
192
|
+
if (size <= 0)
|
193
|
+
rb_raise(rb_eArgError, "size must be more than one.");
|
194
|
+
lob->char_width = size;
|
195
|
+
return vsize;
|
196
|
+
}
|
197
|
+
|
198
|
+
static VALUE oci8_lob_available_p(VALUE self)
|
199
|
+
{
|
200
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
201
|
+
boolean is_initialized;
|
202
|
+
|
203
|
+
oci_lc(OCILobLocatorIsInit(oci8_envhp, oci8_errhp, lob->base.hp.lob, &is_initialized));
|
204
|
+
return is_initialized ? Qtrue : Qfalse;
|
205
|
+
}
|
206
|
+
|
207
|
+
static VALUE oci8_lob_get_size(VALUE self)
|
208
|
+
{
|
209
|
+
return UB4_TO_NUM(oci8_lob_get_length(DATA_PTR(self)));
|
210
|
+
}
|
211
|
+
|
212
|
+
static VALUE oci8_lob_get_pos(VALUE self)
|
213
|
+
{
|
214
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
215
|
+
return UB4_TO_NUM(lob->pos);
|
216
|
+
}
|
217
|
+
|
218
|
+
static VALUE oci8_lob_eof_p(VALUE self)
|
219
|
+
{
|
220
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
221
|
+
if (oci8_lob_get_length(lob) < lob->pos)
|
222
|
+
return Qfalse;
|
223
|
+
else
|
224
|
+
return Qtrue;
|
225
|
+
}
|
226
|
+
|
227
|
+
static VALUE oci8_lob_seek(int argc, VALUE *argv, VALUE self)
|
228
|
+
{
|
229
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
230
|
+
VALUE position, whence;
|
231
|
+
|
232
|
+
rb_scan_args(argc, argv, "11", &position, &whence);
|
233
|
+
if (argc == 2 && (whence != seek_set && whence != seek_cur && whence != seek_end)) {
|
234
|
+
if (FIXNUM_P(whence)) {
|
235
|
+
rb_raise(rb_eArgError, "expect IO::SEEK_SET, IO::SEEK_CUR or IO::SEEK_END but %d",
|
236
|
+
FIX2INT(whence));
|
237
|
+
} else {
|
238
|
+
rb_raise(rb_eArgError, "expect IO::SEEK_SET, IO::SEEK_CUR or IO::SEEK_END but %s",
|
239
|
+
rb_class2name(CLASS_OF(whence)));
|
240
|
+
}
|
241
|
+
}
|
242
|
+
if (whence == seek_cur) {
|
243
|
+
position = rb_funcall(UB4_TO_NUM(lob->pos), id_plus, 1, position);
|
244
|
+
} else if (whence == seek_end) {
|
245
|
+
position = rb_funcall(UB4_TO_NUM(oci8_lob_get_length(lob)), id_plus, 1, position);
|
246
|
+
}
|
247
|
+
lob->pos = NUM2UINT(position);
|
248
|
+
return self;
|
249
|
+
}
|
250
|
+
|
251
|
+
static VALUE oci8_lob_rewind(VALUE self)
|
252
|
+
{
|
253
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
254
|
+
lob->pos = 0;
|
255
|
+
return self;
|
256
|
+
}
|
257
|
+
|
258
|
+
static VALUE oci8_lob_truncate(VALUE self, VALUE len)
|
259
|
+
{
|
260
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
261
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
262
|
+
|
263
|
+
lob_open(lob);
|
264
|
+
oci_lc(OCILobTrim_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, NUM2UINT(len)));
|
265
|
+
return self;
|
266
|
+
}
|
267
|
+
|
268
|
+
static VALUE oci8_lob_set_size(VALUE self, VALUE len)
|
269
|
+
{
|
270
|
+
oci8_lob_truncate(self, len);
|
271
|
+
return len;
|
91
272
|
}
|
92
|
-
#endif
|
93
273
|
|
94
274
|
static VALUE oci8_lob_read(int argc, VALUE *argv, VALUE self)
|
95
275
|
{
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
#ifdef OCI8_USE_CALLBACK_LOB_READ
|
119
|
-
/* This raises ORA-24812, when the size of readed data is two or
|
120
|
-
* three times longer than the size of buf. I couldn't fix it. Thus
|
121
|
-
* I use polling way instead of callback method.
|
122
|
-
*/
|
123
|
-
rv = OCILobRead(svch->hp, h->errhp, h->hp, &amt, offset, buf, sizeof(buf), &v, oci8_callback_lob_read, csid, csfrm);
|
124
|
-
if (rv != OCI_SUCCESS)
|
125
|
-
oci8_raise(h->errhp, rv, NULL);
|
126
|
-
#else
|
127
|
-
/* Disadvantage of polling way in contrast with callback method is
|
128
|
-
* that it sets 'amt' the number of characters readed, when charset
|
129
|
-
* is fixed size. For single byte charset or variable size charset,
|
130
|
-
* it cause no problem because the unit of 'amt' is byte. But for
|
131
|
-
* fixed size multibyte charset, how can I know the size of a
|
132
|
-
* character from system? Therefore who want to use fixed size
|
133
|
-
* multibyte charset must set the size explicitly.
|
134
|
-
*
|
135
|
-
* Umm, if I could use callback method, I have no need to care about
|
136
|
-
* it.
|
137
|
-
*/
|
138
|
-
buf_size_in_char = sizeof(buf) / h->u.lob_locator.char_width;
|
139
|
-
do {
|
140
|
-
/* initialize buf in zeros everytime to check a nul characters. */
|
141
|
-
memset(buf, 0, sizeof(buf));
|
142
|
-
rv = OCILobRead(svch->hp, h->errhp, h->hp, &amt, offset, buf, sizeof(buf), NULL, NULL, csid, csfrm);
|
143
|
-
if (rv != OCI_SUCCESS && rv != OCI_NEED_DATA)
|
144
|
-
oci8_raise(h->errhp, rv, NULL);
|
145
|
-
|
146
|
-
/* Workaround when using Oracle 10.2.0.4 or 11.1.0.6 client and
|
147
|
-
* variable-length character set (e.g. AL32UTF8).
|
148
|
-
*
|
149
|
-
* When the above mentioned condition, amt may be shorter. So
|
150
|
-
* amt is increaded until a nul character to know the actually
|
151
|
-
* read size.
|
152
|
-
*/
|
153
|
-
while (amt < sizeof(buf) && buf[amt] != '\0') {
|
154
|
-
amt++;
|
276
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
277
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
278
|
+
ub4 length;
|
279
|
+
ub4 nchar;
|
280
|
+
ub4 amt;
|
281
|
+
sword rv;
|
282
|
+
char buf[8192];
|
283
|
+
size_t buf_size_in_char;
|
284
|
+
VALUE size;
|
285
|
+
VALUE v = rb_ary_new();
|
286
|
+
|
287
|
+
rb_scan_args(argc, argv, "01", &size);
|
288
|
+
length = oci8_lob_get_length(lob);
|
289
|
+
if (length <= lob->pos) /* EOF */
|
290
|
+
return Qnil;
|
291
|
+
length -= lob->pos;
|
292
|
+
if (NIL_P(size)) {
|
293
|
+
nchar = length; /* read until EOF */
|
294
|
+
} else {
|
295
|
+
nchar = NUM2UINT(size);
|
296
|
+
if (nchar > length)
|
297
|
+
nchar = length;
|
155
298
|
}
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
}
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
}
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
}
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
{
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
{
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
}
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
299
|
+
amt = nchar;
|
300
|
+
buf_size_in_char = sizeof(buf) / lob->char_width;
|
301
|
+
do {
|
302
|
+
if (lob->state == S_BFILE_CLOSE) {
|
303
|
+
rv = OCILobFileOpen_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, OCI_FILE_READONLY);
|
304
|
+
if (rv == OCI_ERROR && oci8_get_error_code(oci8_errhp) == 22290) {
|
305
|
+
/* ORA-22290: operation would exceed the maximum number of opened files or LOBs */
|
306
|
+
/* close all opened BFILE implicitly. */
|
307
|
+
oci8_base_t *base;
|
308
|
+
for (base = &lob->base; base != &lob->base; base = base->next) {
|
309
|
+
if (base->type == OCI_DTYPE_LOB) {
|
310
|
+
oci8_lob_t *tmp = (oci8_lob_t *)base;
|
311
|
+
if (tmp->state == S_BFILE_OPEN) {
|
312
|
+
tmp->state = S_BFILE_CLOSE;
|
313
|
+
}
|
314
|
+
}
|
315
|
+
}
|
316
|
+
oci_lc(OCILobFileCloseAll_nb(svcctx, svcctx->base.hp.svc, oci8_errhp));
|
317
|
+
continue;
|
318
|
+
}
|
319
|
+
if (rv != OCI_SUCCESS)
|
320
|
+
oci8_raise(oci8_errhp, rv, NULL);
|
321
|
+
lob->state = S_BFILE_OPEN;
|
322
|
+
}
|
323
|
+
/* initialize buf in zeros everytime to check a nul characters. */
|
324
|
+
memset(buf, 0, sizeof(buf));
|
325
|
+
rv = OCILobRead_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &amt, lob->pos + 1, buf, sizeof(buf), NULL, NULL, 0, lob->csfrm);
|
326
|
+
if (rv == OCI_ERROR && oci8_get_error_code(oci8_errhp) == 22289) {
|
327
|
+
/* ORA-22289: cannot perform FILEREAD operation on an unopened file or LOB */
|
328
|
+
if (lob->state == S_BFILE_CLOSE)
|
329
|
+
continue;
|
330
|
+
}
|
331
|
+
if (rv != OCI_SUCCESS && rv != OCI_NEED_DATA)
|
332
|
+
oci8_raise(oci8_errhp, rv, NULL);
|
333
|
+
|
334
|
+
/* Workaround when using Oracle 10.2.0.4 or 11.1.0.6 client and
|
335
|
+
* variable-length character set (e.g. AL32UTF8).
|
336
|
+
*
|
337
|
+
* When the above mentioned condition, amt may be shorter. So
|
338
|
+
* amt is increaded until a nul character to know the actually
|
339
|
+
* read size.
|
340
|
+
*/
|
341
|
+
while (amt < sizeof(buf) && buf[amt] != '\0') {
|
342
|
+
amt++;
|
343
|
+
}
|
344
|
+
|
345
|
+
if (amt == 0)
|
346
|
+
break;
|
347
|
+
/* for fixed size charset, amt is the number of characters stored in buf. */
|
348
|
+
if (amt > buf_size_in_char)
|
349
|
+
rb_raise(eOCIException, "Too large buffer fetched or you set too large size of a character.");
|
350
|
+
amt *= lob->char_width;
|
351
|
+
rb_ary_push(v, rb_str_new(buf, amt));
|
352
|
+
} while (rv == OCI_NEED_DATA);
|
353
|
+
lob->pos += nchar;
|
354
|
+
if (nchar == length) {
|
355
|
+
lob_close(lob);
|
356
|
+
bfile_close(lob);
|
357
|
+
}
|
358
|
+
if (RARRAY_LEN(v) == 0) {
|
359
|
+
return Qnil;
|
360
|
+
}
|
361
|
+
v = rb_ary_join(v, Qnil);
|
362
|
+
OBJ_TAINT(v);
|
363
|
+
rb_enc_associate(v, oci8_encoding);
|
364
|
+
return rb_str_conv_enc(v, oci8_encoding, rb_default_internal_encoding());
|
365
|
+
}
|
366
|
+
|
367
|
+
static VALUE oci8_lob_write(VALUE self, VALUE data)
|
368
|
+
{
|
369
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
370
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
371
|
+
ub4 amt;
|
372
|
+
|
373
|
+
lob_open(lob);
|
374
|
+
OCI8StringValue(data);
|
375
|
+
amt = RSTRING_LEN(data);
|
376
|
+
oci_lc(OCILobWrite_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &amt, lob->pos + 1, RSTRING_PTR(data), amt, OCI_ONE_PIECE, NULL, NULL, 0, lob->csfrm));
|
377
|
+
lob->pos += amt;
|
378
|
+
return UINT2NUM(amt);
|
379
|
+
}
|
380
|
+
|
381
|
+
static VALUE oci8_lob_get_sync(VALUE self)
|
382
|
+
{
|
383
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
384
|
+
return (lob->state == S_NO_OPEN_CLOSE) ? Qtrue : Qfalse;
|
385
|
+
}
|
386
|
+
|
387
|
+
static VALUE oci8_lob_set_sync(VALUE self, VALUE b)
|
388
|
+
{
|
389
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
390
|
+
if (RTEST(b)) {
|
391
|
+
lob_close(lob);
|
392
|
+
lob->state = S_NO_OPEN_CLOSE;
|
393
|
+
} else {
|
394
|
+
if (lob->state == S_NO_OPEN_CLOSE)
|
395
|
+
lob->state = S_CLOSE;
|
396
|
+
}
|
397
|
+
return b;
|
398
|
+
}
|
399
|
+
|
400
|
+
static VALUE oci8_lob_flush(VALUE self)
|
401
|
+
{
|
402
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
403
|
+
lob_close(lob);
|
404
|
+
return self;
|
405
|
+
}
|
406
|
+
|
407
|
+
static VALUE oci8_lob_get_chunk_size(VALUE self)
|
408
|
+
{
|
409
|
+
if (have_OCILobGetChunkSize_nb) {
|
410
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
411
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
412
|
+
ub4 len;
|
413
|
+
|
414
|
+
oci_lc(OCILobGetChunkSize_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &len));
|
415
|
+
return UINT2NUM(len);
|
416
|
+
} else {
|
417
|
+
rb_notimplement();
|
418
|
+
}
|
419
|
+
}
|
420
|
+
|
421
|
+
static VALUE oci8_lob_clone(VALUE self)
|
422
|
+
{
|
423
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
424
|
+
oci8_lob_t *newlob;
|
425
|
+
VALUE newobj;
|
426
|
+
sword rv;
|
427
|
+
boolean is_temporary;
|
428
|
+
|
429
|
+
newobj = rb_funcall(CLASS_OF(self), oci8_id_new, 1, lob->svc);
|
430
|
+
newlob = DATA_PTR(newobj);
|
431
|
+
if (have_OCILobLocatorAssign_nb && have_OCILobIsTemporary
|
432
|
+
&& OCILobIsTemporary(oci8_envhp, oci8_errhp, lob->base.hp.lob, &is_temporary) == OCI_SUCCESS
|
433
|
+
&& is_temporary) {
|
434
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
435
|
+
rv = OCILobLocatorAssign_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &newlob->base.hp.lob);
|
436
|
+
} else {
|
437
|
+
rv = OCILobAssign(oci8_envhp, oci8_errhp, lob->base.hp.lob, &newlob->base.hp.lob);
|
438
|
+
}
|
439
|
+
if (rv != OCI_SUCCESS) {
|
440
|
+
oci8_raise(oci8_errhp, rv, NULL);
|
441
|
+
}
|
442
|
+
return newobj;
|
443
|
+
}
|
444
|
+
|
445
|
+
static void oci8_bfile_get_name(VALUE self, VALUE *dir_alias_p, VALUE *filename_p)
|
446
|
+
{
|
447
|
+
int need_get = 0;
|
448
|
+
if (dir_alias_p != NULL) {
|
449
|
+
*dir_alias_p = rb_ivar_get(self, id_dir_alias);
|
450
|
+
if (NIL_P(*dir_alias_p))
|
451
|
+
need_get = 1;
|
452
|
+
}
|
453
|
+
if (filename_p != NULL) {
|
454
|
+
*filename_p = rb_ivar_get(self, id_filename);
|
455
|
+
if (NIL_P(*filename_p))
|
456
|
+
need_get = 1;
|
457
|
+
}
|
458
|
+
if (need_get) {
|
459
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
460
|
+
char d_buf[31];
|
461
|
+
ub2 d_length = sizeof(d_buf);
|
462
|
+
char f_buf[256];
|
463
|
+
ub2 f_length = sizeof(f_buf);
|
464
|
+
VALUE dir_alias;
|
465
|
+
VALUE filename;
|
466
|
+
|
467
|
+
oci_lc(OCILobFileGetName(oci8_envhp, oci8_errhp, lob->base.hp.lob, TO_ORATEXT(d_buf), &d_length, TO_ORATEXT(f_buf), &f_length));
|
468
|
+
dir_alias = rb_external_str_new_with_enc(d_buf, d_length, oci8_encoding);
|
469
|
+
filename = rb_external_str_new_with_enc(f_buf, f_length, oci8_encoding);
|
470
|
+
rb_ivar_set(self, id_dir_alias, dir_alias);
|
471
|
+
rb_ivar_set(self, id_filename, filename);
|
472
|
+
if (dir_alias_p != NULL) {
|
473
|
+
*dir_alias_p = dir_alias;
|
474
|
+
}
|
475
|
+
if (filename_p != NULL) {
|
476
|
+
*filename_p = filename;
|
477
|
+
}
|
478
|
+
}
|
479
|
+
}
|
480
|
+
|
481
|
+
static void oci8_bfile_set_name(VALUE self, VALUE dir_alias, VALUE filename)
|
482
|
+
{
|
483
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
484
|
+
|
485
|
+
bfile_close(lob);
|
486
|
+
oci_lc(OCILobFileSetName(oci8_envhp, oci8_errhp, &lob->base.hp.lob,
|
487
|
+
RSTRING_ORATEXT(dir_alias), RSTRING_LEN(dir_alias),
|
488
|
+
RSTRING_ORATEXT(filename), RSTRING_LEN(filename)));
|
489
|
+
}
|
490
|
+
|
491
|
+
static VALUE oci8_bfile_initialize(int argc, VALUE *argv, VALUE self)
|
492
|
+
{
|
493
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
494
|
+
VALUE svc;
|
495
|
+
VALUE dir_alias;
|
496
|
+
VALUE filename;
|
497
|
+
|
498
|
+
rb_scan_args(argc, argv, "12", &svc, &dir_alias, &filename);
|
499
|
+
TO_SVCCTX(svc); /* check argument type */
|
500
|
+
oci_lc(OCIDescriptorAlloc(oci8_envhp, &lob->base.hp.ptr, OCI_DTYPE_LOB, 0, NULL));
|
501
|
+
lob->base.type = OCI_DTYPE_LOB;
|
502
|
+
lob->svc = svc;
|
503
|
+
lob->pos = 0;
|
504
|
+
lob->char_width = 1;
|
505
|
+
lob->csfrm = SQLCS_IMPLICIT;
|
506
|
+
lob->state = S_BFILE_CLOSE;
|
507
|
+
if (argc != 1) {
|
508
|
+
OCI8SafeStringValue(dir_alias);
|
509
|
+
OCI8SafeStringValue(filename);
|
510
|
+
oci8_bfile_set_name(self, dir_alias, filename);
|
511
|
+
}
|
512
|
+
oci8_link_to_parent((oci8_base_t*)lob, (oci8_base_t*)DATA_PTR(svc));
|
513
|
+
return Qnil;
|
514
|
+
}
|
515
|
+
|
516
|
+
static VALUE oci8_bfile_get_dir_alias(VALUE self)
|
517
|
+
{
|
518
|
+
VALUE dir_alias;
|
519
|
+
|
520
|
+
oci8_bfile_get_name(self, &dir_alias, NULL);
|
521
|
+
return dir_alias;
|
522
|
+
}
|
523
|
+
|
524
|
+
static VALUE oci8_bfile_get_filename(VALUE self)
|
525
|
+
{
|
526
|
+
VALUE filename;
|
527
|
+
|
528
|
+
oci8_bfile_get_name(self, NULL, &filename);
|
529
|
+
return filename;
|
530
|
+
}
|
531
|
+
|
532
|
+
static VALUE oci8_bfile_set_dir_alias(VALUE self, VALUE dir_alias)
|
533
|
+
{
|
534
|
+
VALUE filename;
|
535
|
+
|
536
|
+
OCI8SafeStringValue(dir_alias);
|
537
|
+
oci8_bfile_get_name(self, NULL, &filename);
|
538
|
+
oci8_bfile_set_name(self, dir_alias, filename);
|
539
|
+
rb_ivar_set(self, id_dir_alias, dir_alias);
|
540
|
+
return dir_alias;
|
541
|
+
}
|
542
|
+
|
543
|
+
static VALUE oci8_bfile_set_filename(VALUE self, VALUE filename)
|
544
|
+
{
|
545
|
+
VALUE dir_alias;
|
546
|
+
|
547
|
+
OCI8SafeStringValue(filename);
|
548
|
+
oci8_bfile_get_name(self, &dir_alias, NULL);
|
549
|
+
oci8_bfile_set_name(self, dir_alias, filename);
|
550
|
+
rb_ivar_set(self, id_filename, filename);
|
551
|
+
return filename;
|
552
|
+
}
|
553
|
+
|
554
|
+
static VALUE oci8_bfile_exists_p(VALUE self)
|
555
|
+
{
|
556
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
557
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
558
|
+
boolean flag;
|
559
|
+
|
560
|
+
oci_lc(OCILobFileExists_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &flag));
|
561
|
+
return flag ? Qtrue : Qfalse;
|
562
|
+
}
|
563
|
+
|
564
|
+
static VALUE oci8_bfile_error(VALUE self, VALUE dummy)
|
565
|
+
{
|
566
|
+
rb_raise(rb_eRuntimeError, "cannot modify a read-only BFILE object");
|
567
|
+
}
|
568
|
+
|
569
|
+
/*
|
570
|
+
* bind_clob/blob/bfile
|
571
|
+
*/
|
572
|
+
|
573
|
+
typedef struct {
|
574
|
+
oci8_bind_class_t bind;
|
575
|
+
VALUE *klass;
|
576
|
+
} oci8_bind_lob_class_t;
|
577
|
+
|
578
|
+
static VALUE bind_lob_get(oci8_bind_t *obind, void *data, void *null_struct)
|
579
|
+
{
|
580
|
+
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
|
581
|
+
return oci8_lob_clone(oho->obj);
|
582
|
+
}
|
583
|
+
|
584
|
+
static void bind_lob_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
585
|
+
{
|
586
|
+
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
|
587
|
+
const oci8_bind_lob_class_t *klass = (const oci8_bind_lob_class_t *)obind->base.klass;
|
588
|
+
oci8_base_t *h;
|
589
|
+
if (!rb_obj_is_kind_of(val, *klass->klass))
|
590
|
+
rb_raise(rb_eArgError, "Invalid argument: %s (expect %s)", rb_class2name(CLASS_OF(val)), rb_class2name(*klass->klass));
|
591
|
+
h = DATA_PTR(val);
|
592
|
+
oho->hp = h->hp.ptr;
|
593
|
+
oho->obj = val;
|
594
|
+
}
|
595
|
+
|
596
|
+
static void bind_lob_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
597
|
+
{
|
598
|
+
obind->value_sz = sizeof(void *);
|
599
|
+
obind->alloc_sz = sizeof(oci8_hp_obj_t);
|
600
|
+
}
|
601
|
+
|
602
|
+
static void bind_lob_init_elem(oci8_bind_t *obind, VALUE svc)
|
603
|
+
{
|
604
|
+
const oci8_bind_lob_class_t *klass = (const oci8_bind_lob_class_t *)obind->base.klass;
|
605
|
+
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
|
606
|
+
oci8_base_t *h;
|
607
|
+
ub4 idx = 0;
|
608
|
+
|
609
|
+
do {
|
610
|
+
oho[idx].obj = rb_funcall(*klass->klass, oci8_id_new, 1, svc);
|
611
|
+
h = DATA_PTR(oho[idx].obj);
|
612
|
+
oho[idx].hp = h->hp.ptr;
|
613
|
+
} while (++idx < obind->maxar_sz);
|
614
|
+
}
|
615
|
+
|
616
|
+
static const oci8_bind_lob_class_t bind_clob_class = {
|
617
|
+
{
|
618
|
+
{
|
619
|
+
oci8_bind_hp_obj_mark,
|
620
|
+
oci8_bind_free,
|
621
|
+
sizeof(oci8_bind_t)
|
622
|
+
},
|
623
|
+
bind_lob_get,
|
624
|
+
bind_lob_set,
|
625
|
+
bind_lob_init,
|
626
|
+
bind_lob_init_elem,
|
627
|
+
NULL,
|
628
|
+
NULL,
|
629
|
+
NULL,
|
630
|
+
SQLT_CLOB
|
631
|
+
},
|
632
|
+
&cOCI8CLOB
|
633
|
+
};
|
634
|
+
|
635
|
+
static const oci8_bind_lob_class_t bind_nclob_class = {
|
636
|
+
{
|
637
|
+
{
|
638
|
+
oci8_bind_hp_obj_mark,
|
639
|
+
oci8_bind_free,
|
640
|
+
sizeof(oci8_bind_t)
|
641
|
+
},
|
642
|
+
bind_lob_get,
|
643
|
+
bind_lob_set,
|
644
|
+
bind_lob_init,
|
645
|
+
bind_lob_init_elem,
|
646
|
+
NULL,
|
647
|
+
NULL,
|
648
|
+
NULL,
|
649
|
+
SQLT_CLOB,
|
650
|
+
SQLCS_NCHAR,
|
651
|
+
},
|
652
|
+
&cOCI8NCLOB
|
653
|
+
};
|
654
|
+
|
655
|
+
static const oci8_bind_lob_class_t bind_blob_class = {
|
656
|
+
{
|
657
|
+
{
|
658
|
+
oci8_bind_hp_obj_mark,
|
659
|
+
oci8_bind_free,
|
660
|
+
sizeof(oci8_bind_t)
|
661
|
+
},
|
662
|
+
bind_lob_get,
|
663
|
+
bind_lob_set,
|
664
|
+
bind_lob_init,
|
665
|
+
bind_lob_init_elem,
|
666
|
+
NULL,
|
667
|
+
NULL,
|
668
|
+
NULL,
|
669
|
+
SQLT_BLOB
|
670
|
+
},
|
671
|
+
&cOCI8BLOB
|
672
|
+
};
|
673
|
+
|
674
|
+
static const oci8_bind_lob_class_t bind_bfile_class = {
|
675
|
+
{
|
676
|
+
{
|
677
|
+
oci8_bind_hp_obj_mark,
|
678
|
+
oci8_bind_free,
|
679
|
+
sizeof(oci8_bind_t)
|
680
|
+
},
|
681
|
+
bind_lob_get,
|
682
|
+
bind_lob_set,
|
683
|
+
bind_lob_init,
|
684
|
+
bind_lob_init_elem,
|
685
|
+
NULL,
|
686
|
+
NULL,
|
687
|
+
NULL,
|
688
|
+
SQLT_BFILE
|
689
|
+
},
|
690
|
+
&cOCI8BFILE
|
691
|
+
};
|
692
|
+
|
693
|
+
void Init_oci8_lob(VALUE cOCI8)
|
694
|
+
{
|
695
|
+
id_plus = rb_intern("+");
|
696
|
+
id_dir_alias = rb_intern("@dir_alias");
|
697
|
+
id_filename = rb_intern("@filename");
|
698
|
+
seek_set = rb_eval_string("::IO::SEEK_SET");
|
699
|
+
seek_cur = rb_eval_string("::IO::SEEK_CUR");
|
700
|
+
seek_end = rb_eval_string("::IO::SEEK_END");
|
701
|
+
|
702
|
+
cOCI8LOB = oci8_define_class_under(cOCI8, "LOB", &oci8_lob_class);
|
703
|
+
cOCI8CLOB = rb_define_class_under(cOCI8, "CLOB", cOCI8LOB);
|
704
|
+
cOCI8NCLOB = rb_define_class_under(cOCI8, "NCLOB", cOCI8LOB);
|
705
|
+
cOCI8BLOB = rb_define_class_under(cOCI8, "BLOB", cOCI8LOB);
|
706
|
+
cOCI8BFILE = rb_define_class_under(cOCI8, "BFILE", cOCI8LOB);
|
707
|
+
|
708
|
+
rb_define_method(cOCI8CLOB, "initialize", oci8_clob_initialize, -1);
|
709
|
+
rb_define_method(cOCI8NCLOB, "initialize", oci8_nclob_initialize, -1);
|
710
|
+
rb_define_method(cOCI8BLOB, "initialize", oci8_blob_initialize, -1);
|
711
|
+
rb_define_private_method(cOCI8LOB, "__char_width=", oci8_lob_set_char_width, 1);
|
712
|
+
rb_define_method(cOCI8LOB, "available?", oci8_lob_available_p, 0);
|
713
|
+
rb_define_method(cOCI8LOB, "size", oci8_lob_get_size, 0);
|
714
|
+
rb_define_method(cOCI8LOB, "pos", oci8_lob_get_pos, 0);
|
715
|
+
rb_define_alias(cOCI8LOB, "tell", "pos");
|
716
|
+
rb_define_method(cOCI8LOB, "eof?", oci8_lob_eof_p, 0);
|
717
|
+
rb_define_method(cOCI8LOB, "seek", oci8_lob_seek, -1);
|
718
|
+
rb_define_method(cOCI8LOB, "rewind", oci8_lob_rewind, 0);
|
719
|
+
rb_define_method(cOCI8LOB, "truncate", oci8_lob_truncate, 1);
|
720
|
+
rb_define_method(cOCI8LOB, "size=", oci8_lob_set_size, 1);
|
721
|
+
rb_define_method(cOCI8LOB, "read", oci8_lob_read, -1);
|
722
|
+
rb_define_method(cOCI8LOB, "write", oci8_lob_write, 1);
|
723
|
+
rb_define_method(cOCI8LOB, "close", oci8_lob_close, 0);
|
724
|
+
rb_define_method(cOCI8LOB, "sync", oci8_lob_get_sync, 0);
|
725
|
+
rb_define_method(cOCI8LOB, "sync=", oci8_lob_set_sync, 1);
|
726
|
+
rb_define_method(cOCI8LOB, "flush", oci8_lob_flush, 0);
|
727
|
+
rb_define_method(cOCI8LOB, "chunk_size", oci8_lob_get_chunk_size, 0);
|
728
|
+
|
729
|
+
rb_define_method(cOCI8BFILE, "initialize", oci8_bfile_initialize, -1);
|
730
|
+
rb_define_method(cOCI8BFILE, "dir_alias", oci8_bfile_get_dir_alias, 0);
|
731
|
+
rb_define_method(cOCI8BFILE, "filename", oci8_bfile_get_filename, 0);
|
732
|
+
rb_define_method(cOCI8BFILE, "dir_alias=", oci8_bfile_set_dir_alias, 1);
|
733
|
+
rb_define_method(cOCI8BFILE, "filename=", oci8_bfile_set_filename, 1);
|
734
|
+
rb_define_method(cOCI8BFILE, "exists?", oci8_bfile_exists_p, 0);
|
735
|
+
rb_define_method(cOCI8BFILE, "truncate", oci8_bfile_error, 1);
|
736
|
+
rb_define_method(cOCI8BFILE, "size=", oci8_bfile_error, 1);
|
737
|
+
rb_define_method(cOCI8BFILE, "write", oci8_bfile_error, 1);
|
738
|
+
|
739
|
+
oci8_define_bind_class("CLOB", &bind_clob_class.bind);
|
740
|
+
oci8_define_bind_class("NCLOB", &bind_nclob_class.bind);
|
741
|
+
oci8_define_bind_class("BLOB", &bind_blob_class.bind);
|
742
|
+
oci8_define_bind_class("BFILE", &bind_bfile_class.bind);
|
403
743
|
}
|