ruby-oci8 2.0.6 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +366 -19
- data/Makefile +2 -8
- data/NEWS +111 -0
- data/README +4 -85
- data/VERSION +1 -1
- data/dist-files +9 -2
- data/ext/oci8/.document +1 -0
- data/ext/oci8/apiwrap.c.tmpl +12 -2
- data/ext/oci8/apiwrap.yml +37 -21
- data/ext/oci8/attr.c +23 -74
- data/ext/oci8/bind.c +93 -225
- data/ext/oci8/connection_pool.c +201 -0
- data/ext/oci8/encoding.c +117 -24
- data/ext/oci8/env.c +5 -10
- data/ext/oci8/error.c +171 -189
- data/ext/oci8/extconf.rb +6 -2
- data/ext/oci8/lob.c +81 -79
- data/ext/oci8/metadata.c +42 -177
- data/ext/oci8/object.c +55 -28
- data/ext/oci8/oci8.c +426 -294
- data/ext/oci8/oci8.h +84 -51
- data/ext/oci8/oci8lib.c +75 -53
- data/ext/oci8/ocidatetime.c +67 -88
- data/ext/oci8/ocihandle.c +78 -37
- data/ext/oci8/ocinumber.c +166 -109
- data/ext/oci8/oraconf.rb +68 -157
- data/ext/oci8/oradate.c +2 -7
- data/ext/oci8/stmt.c +40 -183
- data/ext/oci8/thread_util.c +85 -0
- data/ext/oci8/thread_util.h +30 -0
- data/lib/oci8.rb.in +19 -13
- data/lib/oci8/.document +2 -0
- data/lib/oci8/bindtype.rb +62 -45
- data/lib/oci8/connection_pool.rb +118 -0
- data/lib/oci8/datetime.rb +304 -320
- data/lib/oci8/encoding-init.rb +62 -30
- data/lib/oci8/encoding.yml +3 -3
- data/lib/oci8/metadata.rb +552 -497
- data/lib/oci8/object.rb +9 -9
- data/lib/oci8/oci8.rb +161 -2
- data/lib/oci8/ocihandle.rb +427 -0
- data/lib/oci8/properties.rb +31 -1
- data/ruby-oci8.gemspec +10 -3
- data/test/README +41 -3
- data/test/config.rb +16 -0
- data/test/test_all.rb +3 -0
- data/test/test_bind_string.rb +106 -0
- data/test/test_break.rb +33 -7
- data/test/test_clob.rb +13 -10
- data/test/test_connection_pool.rb +125 -0
- data/test/test_connstr.rb +2 -2
- data/test/test_datetime.rb +26 -66
- data/test/test_encoding.rb +7 -3
- data/test/test_error.rb +88 -0
- data/test/test_metadata.rb +1356 -204
- data/test/test_oci8.rb +27 -8
- data/test/test_oranumber.rb +41 -0
- metadata +34 -9
- data/ext/oci8/xmldb.c +0 -383
data/ext/oci8/extconf.rb
CHANGED
@@ -69,7 +69,9 @@ have_type('OCIInterval*', 'ociap.h')
|
|
69
69
|
have_type('OCICallbackLobRead2', 'ociap.h')
|
70
70
|
have_type('OCICallbackLobWrite2', 'ociap.h')
|
71
71
|
have_type('OCIAdmin*', 'ociap.h')
|
72
|
+
have_type('OCIAuthInfo*', 'ociap.h')
|
72
73
|
have_type('OCIMsg*', 'ociap.h')
|
74
|
+
have_type('OCICPool*', 'ociap.h')
|
73
75
|
|
74
76
|
if with_config('oracle-version')
|
75
77
|
oci_client_version = OCI8::OracleVersion.new(with_config('oracle-version')).to_i
|
@@ -84,10 +86,11 @@ if with_config('runtime-check')
|
|
84
86
|
end
|
85
87
|
|
86
88
|
$objs = ["oci8lib.o", "env.o", "error.o", "oci8.o", "ocihandle.o",
|
89
|
+
"connection_pool.o",
|
87
90
|
"stmt.o", "bind.o", "metadata.o", "attr.o",
|
88
91
|
"lob.o", "oradate.o",
|
89
92
|
"ocinumber.o", "ocidatetime.o", "object.o", "apiwrap.o",
|
90
|
-
"encoding.o", "
|
93
|
+
"encoding.o", "oranumber_util.o", "thread_util.o"]
|
91
94
|
|
92
95
|
if RUBY_PLATFORM =~ /mswin32|cygwin|mingw32|bccwin32/
|
93
96
|
$defs << "-DUSE_WIN32_C"
|
@@ -112,7 +115,7 @@ have_type('rb_encoding', ['ruby/ruby.h', 'ruby/encoding.h'])
|
|
112
115
|
have_var("ruby_errinfo", "ruby.h") # ruby 1.8
|
113
116
|
have_func("rb_errinfo", "ruby.h") # ruby 1.9
|
114
117
|
|
115
|
-
have_type("rb_blocking_function_t", "ruby.h")
|
118
|
+
have_type("rb_blocking_function_t*", "ruby.h")
|
116
119
|
have_func("rb_set_end_proc", "ruby.h")
|
117
120
|
have_func("rb_class_superclass", "ruby.h")
|
118
121
|
have_func("rb_thread_blocking_region", "ruby.h")
|
@@ -139,6 +142,7 @@ so_basename += Config::CONFIG["ruby_version"].gsub(/\W/, '')
|
|
139
142
|
|
140
143
|
$defs << "-DInit_oci8lib=Init_#{so_basename}"
|
141
144
|
$defs << "-Doci8lib=#{so_basename}"
|
145
|
+
$defs << "-DOCI8LIB_VERSION=\\\"#{RUBY_OCI8_VERSION}\\\""
|
142
146
|
if defined? RUBY_ENGINE and RUBY_ENGINE == 'rbx'
|
143
147
|
$defs << "-DCHAR_IS_NOT_A_SHORTCUT_TO_ID"
|
144
148
|
end
|
data/ext/oci8/lob.c
CHANGED
@@ -41,7 +41,8 @@ static VALUE oci8_make_lob(VALUE klass, oci8_svcctx_t *svcctx, OCILobLocator *s)
|
|
41
41
|
lob_obj = rb_funcall(klass, oci8_id_new, 1, svcctx->base.self);
|
42
42
|
lob = DATA_PTR(lob_obj);
|
43
43
|
/* If 's' is a temporary lob, use OCILobLocatorAssign instead. */
|
44
|
-
|
44
|
+
chker2(OCILobAssign(oci8_envhp, oci8_errhp, s, &lob->base.hp.lob),
|
45
|
+
&svcctx->base);
|
45
46
|
return lob_obj;
|
46
47
|
}
|
47
48
|
|
@@ -68,7 +69,7 @@ VALUE oci8_make_bfile(oci8_svcctx_t *svcctx, OCILobLocator *s)
|
|
68
69
|
static void oci8_assign_lob(VALUE klass, oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
|
69
70
|
{
|
70
71
|
oci8_base_t *base = oci8_get_handle(lob, klass);
|
71
|
-
|
72
|
+
chker2(OCILobLocatorAssign_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, base->hp.lob, dest), base);
|
72
73
|
}
|
73
74
|
|
74
75
|
void oci8_assign_clob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
|
@@ -102,7 +103,7 @@ static void oci8_lob_free(oci8_base_t *base)
|
|
102
103
|
oci8_lob_t *lob = (oci8_lob_t *)base;
|
103
104
|
boolean is_temporary;
|
104
105
|
|
105
|
-
if (
|
106
|
+
if (lob->svchp != NULL
|
106
107
|
&& OCILobIsTemporary(oci8_envhp, oci8_errhp, lob->base.hp.lob, &is_temporary) == OCI_SUCCESS
|
107
108
|
&& is_temporary) {
|
108
109
|
|
@@ -113,7 +114,7 @@ static void oci8_lob_free(oci8_base_t *base)
|
|
113
114
|
lob->svchp = NULL;
|
114
115
|
}
|
115
116
|
|
116
|
-
static
|
117
|
+
static oci8_base_vtable_t oci8_lob_vtable = {
|
117
118
|
oci8_lob_mark,
|
118
119
|
oci8_lob_free,
|
119
120
|
sizeof(oci8_lob_t),
|
@@ -124,18 +125,18 @@ static ub4 oci8_lob_get_length(oci8_lob_t *lob)
|
|
124
125
|
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
125
126
|
ub4 len;
|
126
127
|
|
127
|
-
|
128
|
+
chker2(OCILobGetLength_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &len),
|
129
|
+
&svcctx->base);
|
128
130
|
return len;
|
129
131
|
}
|
130
132
|
|
131
133
|
static void lob_open(oci8_lob_t *lob)
|
132
134
|
{
|
133
135
|
if (lob->state == S_CLOSE) {
|
134
|
-
|
135
|
-
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
136
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
136
137
|
|
137
|
-
|
138
|
-
|
138
|
+
chker2(OCILobOpen_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, OCI_DEFAULT),
|
139
|
+
&svcctx->base);
|
139
140
|
lob->state = S_OPEN;
|
140
141
|
}
|
141
142
|
}
|
@@ -143,11 +144,10 @@ static void lob_open(oci8_lob_t *lob)
|
|
143
144
|
static void lob_close(oci8_lob_t *lob)
|
144
145
|
{
|
145
146
|
if (lob->state == S_OPEN) {
|
146
|
-
|
147
|
-
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
147
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
148
148
|
|
149
|
-
|
150
|
-
|
149
|
+
chker2(OCILobClose_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob),
|
150
|
+
&svcctx->base);
|
151
151
|
lob->state = S_CLOSE;
|
152
152
|
}
|
153
153
|
}
|
@@ -157,7 +157,8 @@ static void bfile_close(oci8_lob_t *lob)
|
|
157
157
|
if (lob->state == S_BFILE_OPEN) {
|
158
158
|
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
159
159
|
|
160
|
-
|
160
|
+
chker2(OCILobFileClose_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob),
|
161
|
+
&svcctx->base);
|
161
162
|
lob->state = S_BFILE_CLOSE;
|
162
163
|
}
|
163
164
|
}
|
@@ -192,15 +193,12 @@ static VALUE oci8_lob_do_initialize(int argc, VALUE *argv, VALUE self, ub1 csfrm
|
|
192
193
|
lob->state = S_NO_OPEN_CLOSE;
|
193
194
|
oci8_link_to_parent((oci8_base_t*)lob, (oci8_base_t*)DATA_PTR(svc));
|
194
195
|
if (!NIL_P(val)) {
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
} else {
|
202
|
-
rb_raise(rb_eRuntimeError, "creating a temporary lob is not supported on this Oracle version");
|
203
|
-
}
|
196
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(svc);
|
197
|
+
OCI8StringValue(val);
|
198
|
+
chker2(OCILobCreateTemporary_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, 0, csfrm, lobtype, TRUE, OCI_DURATION_SESSION),
|
199
|
+
&svcctx->base);
|
200
|
+
lob->svchp = oci8_get_oci_svcctx(svc);
|
201
|
+
oci8_lob_write(self, val);
|
204
202
|
}
|
205
203
|
return Qnil;
|
206
204
|
}
|
@@ -241,7 +239,8 @@ static VALUE oci8_lob_available_p(VALUE self)
|
|
241
239
|
oci8_lob_t *lob = DATA_PTR(self);
|
242
240
|
boolean is_initialized;
|
243
241
|
|
244
|
-
|
242
|
+
chker2(OCILobLocatorIsInit(oci8_envhp, oci8_errhp, lob->base.hp.lob, &is_initialized),
|
243
|
+
&lob->base);
|
245
244
|
return is_initialized ? Qtrue : Qfalse;
|
246
245
|
}
|
247
246
|
|
@@ -302,7 +301,8 @@ static VALUE oci8_lob_truncate(VALUE self, VALUE len)
|
|
302
301
|
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
303
302
|
|
304
303
|
lob_open(lob);
|
305
|
-
|
304
|
+
chker2(OCILobTrim_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, NUM2UINT(len)),
|
305
|
+
&svcctx->base);
|
306
306
|
return self;
|
307
307
|
}
|
308
308
|
|
@@ -354,11 +354,11 @@ static VALUE oci8_lob_read(int argc, VALUE *argv, VALUE self)
|
|
354
354
|
}
|
355
355
|
}
|
356
356
|
}
|
357
|
-
|
357
|
+
chker2(OCILobFileCloseAll_nb(svcctx, svcctx->base.hp.svc, oci8_errhp),
|
358
|
+
&svcctx->base);
|
358
359
|
continue;
|
359
360
|
}
|
360
|
-
|
361
|
-
oci8_raise(oci8_errhp, rv, NULL);
|
361
|
+
chker2(rv, &svcctx->base);
|
362
362
|
lob->state = S_BFILE_OPEN;
|
363
363
|
}
|
364
364
|
/* initialize buf in zeros everytime to check a nul characters. */
|
@@ -369,8 +369,9 @@ static VALUE oci8_lob_read(int argc, VALUE *argv, VALUE self)
|
|
369
369
|
if (lob->state == S_BFILE_CLOSE)
|
370
370
|
continue;
|
371
371
|
}
|
372
|
-
if (rv != OCI_SUCCESS && rv != OCI_NEED_DATA)
|
373
|
-
|
372
|
+
if (rv != OCI_SUCCESS && rv != OCI_NEED_DATA) {
|
373
|
+
chker2(rv, &svcctx->base);
|
374
|
+
}
|
374
375
|
|
375
376
|
/* Workaround when using Oracle 10.2.0.4 or 11.1.0.6 client and
|
376
377
|
* variable-length character set (e.g. AL32UTF8).
|
@@ -426,7 +427,8 @@ static VALUE oci8_lob_write(VALUE self, VALUE data)
|
|
426
427
|
}
|
427
428
|
RB_GC_GUARD(data);
|
428
429
|
amt = RSTRING_LEN(data);
|
429
|
-
|
430
|
+
chker2(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),
|
431
|
+
&svcctx->base);
|
430
432
|
lob->pos += amt;
|
431
433
|
return UINT2NUM(amt);
|
432
434
|
}
|
@@ -459,16 +461,13 @@ static VALUE oci8_lob_flush(VALUE self)
|
|
459
461
|
|
460
462
|
static VALUE oci8_lob_get_chunk_size(VALUE self)
|
461
463
|
{
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
ub4 len;
|
464
|
+
oci8_lob_t *lob = DATA_PTR(self);
|
465
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
466
|
+
ub4 len;
|
466
467
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
rb_notimplement();
|
471
|
-
}
|
468
|
+
chker2(OCILobGetChunkSize_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &len),
|
469
|
+
&svcctx->base);
|
470
|
+
return UINT2NUM(len);
|
472
471
|
}
|
473
472
|
|
474
473
|
static VALUE oci8_lob_clone(VALUE self)
|
@@ -476,21 +475,17 @@ static VALUE oci8_lob_clone(VALUE self)
|
|
476
475
|
oci8_lob_t *lob = DATA_PTR(self);
|
477
476
|
oci8_lob_t *newlob;
|
478
477
|
VALUE newobj;
|
479
|
-
sword rv;
|
480
478
|
boolean is_temporary;
|
481
479
|
|
482
480
|
newobj = rb_funcall(CLASS_OF(self), oci8_id_new, 1, lob->svc);
|
483
481
|
newlob = DATA_PTR(newobj);
|
484
|
-
if (
|
485
|
-
|
486
|
-
&& is_temporary) {
|
482
|
+
if (OCILobIsTemporary(oci8_envhp, oci8_errhp, lob->base.hp.lob, &is_temporary) == OCI_SUCCESS
|
483
|
+
&& is_temporary) {
|
487
484
|
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
488
|
-
|
485
|
+
chker2(OCILobLocatorAssign_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &newlob->base.hp.lob),
|
486
|
+
&svcctx->base);
|
489
487
|
} else {
|
490
|
-
|
491
|
-
}
|
492
|
-
if (rv != OCI_SUCCESS) {
|
493
|
-
oci8_raise(oci8_errhp, rv, NULL);
|
488
|
+
chker2(OCILobAssign(oci8_envhp, oci8_errhp, lob->base.hp.lob, &newlob->base.hp.lob), &lob->base);
|
494
489
|
}
|
495
490
|
return newobj;
|
496
491
|
}
|
@@ -517,7 +512,8 @@ static void oci8_bfile_get_name(VALUE self, VALUE *dir_alias_p, VALUE *filename_
|
|
517
512
|
VALUE dir_alias;
|
518
513
|
VALUE filename;
|
519
514
|
|
520
|
-
|
515
|
+
chker2(OCILobFileGetName(oci8_envhp, oci8_errhp, lob->base.hp.lob, TO_ORATEXT(d_buf), &d_length, TO_ORATEXT(f_buf), &f_length),
|
516
|
+
&lob->base);
|
521
517
|
dir_alias = rb_external_str_new_with_enc(d_buf, d_length, oci8_encoding);
|
522
518
|
filename = rb_external_str_new_with_enc(f_buf, f_length, oci8_encoding);
|
523
519
|
rb_ivar_set(self, id_dir_alias, dir_alias);
|
@@ -542,9 +538,10 @@ static void oci8_bfile_set_name(VALUE self, VALUE dir_alias, VALUE filename)
|
|
542
538
|
if (RSTRING_LEN(filename) > UB2MAXVAL) {
|
543
539
|
rb_raise(rb_eRuntimeError, "filename is too long.");
|
544
540
|
}
|
545
|
-
|
541
|
+
chker2(OCILobFileSetName(oci8_envhp, oci8_errhp, &lob->base.hp.lob,
|
546
542
|
RSTRING_ORATEXT(dir_alias), (ub2)RSTRING_LEN(dir_alias),
|
547
|
-
RSTRING_ORATEXT(filename), (ub2)RSTRING_LEN(filename))
|
543
|
+
RSTRING_ORATEXT(filename), (ub2)RSTRING_LEN(filename)),
|
544
|
+
&lob->base);
|
548
545
|
}
|
549
546
|
|
550
547
|
static VALUE oci8_bfile_initialize(int argc, VALUE *argv, VALUE self)
|
@@ -553,10 +550,14 @@ static VALUE oci8_bfile_initialize(int argc, VALUE *argv, VALUE self)
|
|
553
550
|
VALUE svc;
|
554
551
|
VALUE dir_alias;
|
555
552
|
VALUE filename;
|
553
|
+
int rv;
|
556
554
|
|
557
555
|
rb_scan_args(argc, argv, "12", &svc, &dir_alias, &filename);
|
558
556
|
TO_SVCCTX(svc); /* check argument type */
|
559
|
-
|
557
|
+
rv = OCIDescriptorAlloc(oci8_envhp, &lob->base.hp.ptr, OCI_DTYPE_LOB, 0, NULL);
|
558
|
+
if (rv != OCI_SUCCESS) {
|
559
|
+
oci8_env_raise(oci8_envhp, rv);
|
560
|
+
}
|
560
561
|
lob->base.type = OCI_DTYPE_LOB;
|
561
562
|
lob->svc = svc;
|
562
563
|
lob->pos = 0;
|
@@ -617,7 +618,8 @@ static VALUE oci8_bfile_exists_p(VALUE self)
|
|
617
618
|
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
618
619
|
boolean flag;
|
619
620
|
|
620
|
-
|
621
|
+
chker2(OCILobFileExists_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &flag),
|
622
|
+
&svcctx->base);
|
621
623
|
return flag ? Qtrue : Qfalse;
|
622
624
|
}
|
623
625
|
|
@@ -631,9 +633,9 @@ static VALUE oci8_bfile_error(VALUE self, VALUE dummy)
|
|
631
633
|
*/
|
632
634
|
|
633
635
|
typedef struct {
|
634
|
-
|
636
|
+
oci8_bind_vtable_t bind;
|
635
637
|
VALUE *klass;
|
636
|
-
}
|
638
|
+
} oci8_bind_lob_vtable_t;
|
637
639
|
|
638
640
|
static VALUE bind_lob_get(oci8_bind_t *obind, void *data, void *null_struct)
|
639
641
|
{
|
@@ -644,10 +646,10 @@ static VALUE bind_lob_get(oci8_bind_t *obind, void *data, void *null_struct)
|
|
644
646
|
static void bind_lob_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
645
647
|
{
|
646
648
|
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
|
647
|
-
const
|
649
|
+
const oci8_bind_lob_vtable_t *vptr = (const oci8_bind_lob_vtable_t *)obind->base.vptr;
|
648
650
|
oci8_base_t *h;
|
649
|
-
if (!rb_obj_is_kind_of(val, *
|
650
|
-
rb_raise(rb_eArgError, "Invalid argument: %s (expect %s)", rb_class2name(CLASS_OF(val)), rb_class2name(*
|
651
|
+
if (!rb_obj_is_kind_of(val, *vptr->klass))
|
652
|
+
rb_raise(rb_eArgError, "Invalid argument: %s (expect %s)", rb_class2name(CLASS_OF(val)), rb_class2name(*vptr->klass));
|
651
653
|
h = DATA_PTR(val);
|
652
654
|
oho->hp = h->hp.ptr;
|
653
655
|
oho->obj = val;
|
@@ -661,19 +663,27 @@ static void bind_lob_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length
|
|
661
663
|
|
662
664
|
static void bind_lob_init_elem(oci8_bind_t *obind, VALUE svc)
|
663
665
|
{
|
664
|
-
const
|
666
|
+
const oci8_bind_lob_vtable_t *vptr = (const oci8_bind_lob_vtable_t *)obind->base.vptr;
|
665
667
|
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
|
666
668
|
oci8_base_t *h;
|
667
669
|
ub4 idx = 0;
|
668
670
|
|
669
671
|
do {
|
670
|
-
oho[idx].obj = rb_funcall(*
|
672
|
+
oho[idx].obj = rb_funcall(*vptr->klass, oci8_id_new, 1, svc);
|
671
673
|
h = DATA_PTR(oho[idx].obj);
|
672
674
|
oho[idx].hp = h->hp.ptr;
|
673
675
|
} while (++idx < obind->maxar_sz);
|
674
676
|
}
|
675
677
|
|
676
|
-
static
|
678
|
+
static void bind_lob_post_bind_hook_for_nclob(oci8_bind_t *obind)
|
679
|
+
{
|
680
|
+
ub1 csfrm = SQLCS_NCHAR;
|
681
|
+
|
682
|
+
chker2(OCIAttrSet(obind->base.hp.ptr, obind->base.type, (void*)&csfrm, 0, OCI_ATTR_CHARSET_FORM, oci8_errhp),
|
683
|
+
&obind->base);
|
684
|
+
}
|
685
|
+
|
686
|
+
static const oci8_bind_lob_vtable_t bind_clob_vtable = {
|
677
687
|
{
|
678
688
|
{
|
679
689
|
oci8_bind_hp_obj_mark,
|
@@ -685,14 +695,12 @@ static const oci8_bind_lob_class_t bind_clob_class = {
|
|
685
695
|
bind_lob_init,
|
686
696
|
bind_lob_init_elem,
|
687
697
|
NULL,
|
688
|
-
NULL,
|
689
|
-
NULL,
|
690
698
|
SQLT_CLOB
|
691
699
|
},
|
692
700
|
&cOCI8CLOB
|
693
701
|
};
|
694
702
|
|
695
|
-
static const
|
703
|
+
static const oci8_bind_lob_vtable_t bind_nclob_vtable = {
|
696
704
|
{
|
697
705
|
{
|
698
706
|
oci8_bind_hp_obj_mark,
|
@@ -704,15 +712,13 @@ static const oci8_bind_lob_class_t bind_nclob_class = {
|
|
704
712
|
bind_lob_init,
|
705
713
|
bind_lob_init_elem,
|
706
714
|
NULL,
|
707
|
-
NULL,
|
708
|
-
NULL,
|
709
715
|
SQLT_CLOB,
|
710
|
-
|
716
|
+
bind_lob_post_bind_hook_for_nclob,
|
711
717
|
},
|
712
718
|
&cOCI8NCLOB
|
713
719
|
};
|
714
720
|
|
715
|
-
static const
|
721
|
+
static const oci8_bind_lob_vtable_t bind_blob_vtable = {
|
716
722
|
{
|
717
723
|
{
|
718
724
|
oci8_bind_hp_obj_mark,
|
@@ -724,14 +730,12 @@ static const oci8_bind_lob_class_t bind_blob_class = {
|
|
724
730
|
bind_lob_init,
|
725
731
|
bind_lob_init_elem,
|
726
732
|
NULL,
|
727
|
-
NULL,
|
728
|
-
NULL,
|
729
733
|
SQLT_BLOB
|
730
734
|
},
|
731
735
|
&cOCI8BLOB
|
732
736
|
};
|
733
737
|
|
734
|
-
static const
|
738
|
+
static const oci8_bind_lob_vtable_t bind_bfile_vtable = {
|
735
739
|
{
|
736
740
|
{
|
737
741
|
oci8_bind_hp_obj_mark,
|
@@ -743,8 +747,6 @@ static const oci8_bind_lob_class_t bind_bfile_class = {
|
|
743
747
|
bind_lob_init,
|
744
748
|
bind_lob_init_elem,
|
745
749
|
NULL,
|
746
|
-
NULL,
|
747
|
-
NULL,
|
748
750
|
SQLT_BFILE
|
749
751
|
},
|
750
752
|
&cOCI8BFILE
|
@@ -759,7 +761,7 @@ void Init_oci8_lob(VALUE cOCI8)
|
|
759
761
|
seek_cur = rb_eval_string("::IO::SEEK_CUR");
|
760
762
|
seek_end = rb_eval_string("::IO::SEEK_END");
|
761
763
|
|
762
|
-
cOCI8LOB = oci8_define_class_under(cOCI8, "LOB", &
|
764
|
+
cOCI8LOB = oci8_define_class_under(cOCI8, "LOB", &oci8_lob_vtable);
|
763
765
|
cOCI8CLOB = rb_define_class_under(cOCI8, "CLOB", cOCI8LOB);
|
764
766
|
cOCI8NCLOB = rb_define_class_under(cOCI8, "NCLOB", cOCI8LOB);
|
765
767
|
cOCI8BLOB = rb_define_class_under(cOCI8, "BLOB", cOCI8LOB);
|
@@ -796,8 +798,8 @@ void Init_oci8_lob(VALUE cOCI8)
|
|
796
798
|
rb_define_method(cOCI8BFILE, "size=", oci8_bfile_error, 1);
|
797
799
|
rb_define_method(cOCI8BFILE, "write", oci8_bfile_error, 1);
|
798
800
|
|
799
|
-
oci8_define_bind_class("CLOB", &
|
800
|
-
oci8_define_bind_class("NCLOB", &
|
801
|
-
oci8_define_bind_class("BLOB", &
|
802
|
-
oci8_define_bind_class("BFILE", &
|
801
|
+
oci8_define_bind_class("CLOB", &bind_clob_vtable.bind);
|
802
|
+
oci8_define_bind_class("NCLOB", &bind_nclob_vtable.bind);
|
803
|
+
oci8_define_bind_class("BLOB", &bind_blob_vtable.bind);
|
804
|
+
oci8_define_bind_class("BFILE", &bind_bfile_vtable.bind);
|
803
805
|
}
|
data/ext/oci8/metadata.c
CHANGED
@@ -40,7 +40,7 @@ VALUE oci8_metadata_create(OCIParam *parmhp, VALUE svc, VALUE parent)
|
|
40
40
|
|
41
41
|
p = oci8_get_handle(parent, oci8_cOCIHandle);
|
42
42
|
|
43
|
-
|
43
|
+
chker2(OCIAttrGet(parmhp, OCI_DTYPE_PARAM, &ptype, &size, OCI_ATTR_PTYPE, oci8_errhp), p);
|
44
44
|
klass = rb_hash_aref(ptype_to_class, INT2FIX(ptype));
|
45
45
|
if (NIL_P(klass))
|
46
46
|
rb_raise(rb_eRuntimeError, "unknown parameter type %d", ptype);
|
@@ -69,150 +69,16 @@ static VALUE metadata_s_register_ptype(VALUE klass, VALUE ptype)
|
|
69
69
|
return Qnil;
|
70
70
|
}
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
return INT2FIX(value);
|
83
|
-
}
|
84
|
-
|
85
|
-
static VALUE metadata_get_ub2(VALUE self, VALUE idx)
|
86
|
-
{
|
87
|
-
oci8_base_t *base = DATA_PTR(self);
|
88
|
-
ub2 value = 0;
|
89
|
-
ub4 size = sizeof(value);
|
90
|
-
|
91
|
-
oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
|
92
|
-
if (size != 2) {
|
93
|
-
rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 2, but %d", size);
|
94
|
-
}
|
95
|
-
return INT2FIX(value);
|
96
|
-
}
|
97
|
-
|
98
|
-
/* get ub2 without size check. */
|
99
|
-
static VALUE metadata_get_ub2_nc(VALUE self, VALUE idx)
|
100
|
-
{
|
101
|
-
oci8_base_t *base = DATA_PTR(self);
|
102
|
-
ub2 value = 0;
|
103
|
-
|
104
|
-
oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, 0, FIX2INT(idx), oci8_errhp));
|
105
|
-
return INT2FIX(value);
|
106
|
-
}
|
107
|
-
|
108
|
-
static VALUE metadata_get_ub4(VALUE self, VALUE idx)
|
109
|
-
{
|
110
|
-
oci8_base_t *base = DATA_PTR(self);
|
111
|
-
ub4 value = 0;
|
112
|
-
ub4 size = sizeof(value);
|
113
|
-
|
114
|
-
oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
|
115
|
-
if (size != 4) {
|
116
|
-
rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 4, but %d", size);
|
117
|
-
}
|
118
|
-
#if SIZEOF_LONG > 4
|
119
|
-
return INT2FIX(value);
|
120
|
-
#else
|
121
|
-
return UINT2NUM(value);
|
122
|
-
#endif
|
123
|
-
}
|
124
|
-
|
125
|
-
static VALUE metadata_get_sb1(VALUE self, VALUE idx)
|
126
|
-
{
|
127
|
-
oci8_base_t *base = DATA_PTR(self);
|
128
|
-
sb1 value = 0;
|
129
|
-
ub4 size = sizeof(value);
|
130
|
-
|
131
|
-
oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
|
132
|
-
if (size != 1) {
|
133
|
-
rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 1, but %d", size);
|
134
|
-
}
|
135
|
-
return INT2FIX(value);
|
136
|
-
}
|
137
|
-
|
138
|
-
static VALUE metadata_get_sb2(VALUE self, VALUE idx)
|
139
|
-
{
|
140
|
-
oci8_base_t *base = DATA_PTR(self);
|
141
|
-
sb2 value = 0;
|
142
|
-
ub4 size = sizeof(value);
|
143
|
-
|
144
|
-
oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
|
145
|
-
if (size != 2) {
|
146
|
-
rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 2, but %d", size);
|
147
|
-
}
|
148
|
-
return INT2FIX(value);
|
149
|
-
}
|
150
|
-
|
151
|
-
static VALUE metadata_get_sb4(VALUE self, VALUE idx)
|
152
|
-
{
|
153
|
-
oci8_base_t *base = DATA_PTR(self);
|
154
|
-
sb4 value = 0;
|
155
|
-
ub4 size = sizeof(value);
|
156
|
-
|
157
|
-
oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
|
158
|
-
if (size != 4) {
|
159
|
-
rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 4, but %d", size);
|
160
|
-
}
|
161
|
-
#if SIZEOF_LONG > 4
|
162
|
-
return INT2FIX(value);
|
163
|
-
#else
|
164
|
-
return INT2NUM(value);
|
165
|
-
#endif
|
166
|
-
}
|
167
|
-
|
168
|
-
static VALUE metadata_get_text(VALUE self, VALUE idx)
|
169
|
-
{
|
170
|
-
oci8_metadata_t *md = DATA_PTR(self);
|
171
|
-
oci8_svcctx_t *svcctx = oci8_get_svcctx(md->svc);
|
172
|
-
text *value;
|
173
|
-
ub4 size;
|
174
|
-
|
175
|
-
/* remote call sometimes? */
|
176
|
-
oci_lc(OCIAttrGet_nb(svcctx, md->base.hp.ptr, md->base.type, &value, &size, FIX2INT(idx), oci8_errhp));
|
177
|
-
return rb_external_str_new_with_enc(TO_CHARPTR(value), size, oci8_encoding);
|
178
|
-
}
|
179
|
-
|
180
|
-
static VALUE metadata_get_oradate(VALUE self, VALUE idx)
|
181
|
-
{
|
182
|
-
oci8_base_t *base = DATA_PTR(self);
|
183
|
-
ub1 *value;
|
184
|
-
ub4 size = 7;
|
185
|
-
static VALUE cOraDate = Qnil;
|
186
|
-
VALUE obj;
|
187
|
-
|
188
|
-
oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
|
189
|
-
if (size != 7) {
|
190
|
-
rb_raise(rb_eRuntimeError, "Invalid attribute size. expect 7, but %d", size);
|
191
|
-
}
|
192
|
-
if (NIL_P(cOraDate))
|
193
|
-
cOraDate = rb_eval_string("OraDate");
|
194
|
-
obj = rb_funcall(cOraDate, oci8_id_new, 0);
|
195
|
-
memcpy(DATA_PTR(obj), value, 7);
|
196
|
-
return obj;
|
197
|
-
}
|
198
|
-
|
199
|
-
static VALUE metadata_get_oraint(VALUE self, VALUE idx)
|
200
|
-
{
|
201
|
-
oci8_base_t *base = DATA_PTR(self);
|
202
|
-
ub1 *value;
|
203
|
-
ub4 size = 21;
|
204
|
-
OCINumber on;
|
205
|
-
|
206
|
-
oci_lc(OCIAttrGet(base->hp.ptr, base->type, &value, &size, FIX2INT(idx), oci8_errhp));
|
207
|
-
if (size >= 22) {
|
208
|
-
rb_raise(rb_eRuntimeError, "Invalid attribute size. expect less than 22, but %d", size);
|
209
|
-
}
|
210
|
-
memset(&on, 0, sizeof(on));
|
211
|
-
on.OCINumberPart[0] = size;
|
212
|
-
memcpy(&on.OCINumberPart[1], value, size);
|
213
|
-
return oci8_make_integer(&on, oci8_errhp);
|
214
|
-
}
|
215
|
-
|
72
|
+
/*
|
73
|
+
* call-seq:
|
74
|
+
* __param(attr_type) -> metadata information or nil
|
75
|
+
*
|
76
|
+
* Gets the value of the attribute specified by +attr_type+
|
77
|
+
* as an instance of an OCI8::Metadata::Base's subclass.
|
78
|
+
*
|
79
|
+
* <b>Caution:</b> If the specified attr_type's datatype is not a
|
80
|
+
* metadata, it causes a segmentation fault.
|
81
|
+
*/
|
216
82
|
static VALUE metadata_get_param(VALUE self, VALUE idx)
|
217
83
|
{
|
218
84
|
oci8_metadata_t *md = DATA_PTR(self);
|
@@ -220,11 +86,16 @@ static VALUE metadata_get_param(VALUE self, VALUE idx)
|
|
220
86
|
OCIParam *value;
|
221
87
|
ub4 size = sizeof(value);
|
222
88
|
|
223
|
-
|
224
|
-
|
89
|
+
Check_Type(idx, T_FIXNUM);
|
90
|
+
/* Is it remote call? */
|
91
|
+
chker2(OCIAttrGet_nb(svcctx, md->base.hp.ptr, md->base.type, &value, &size, FIX2INT(idx), oci8_errhp),
|
92
|
+
&svcctx->base);
|
225
93
|
if (size != sizeof(OCIParam *)) {
|
226
94
|
rb_raise(rb_eRuntimeError, "Invalid attribute size. expect %d, but %d", (sb4)sizeof(OCIParam *), size);
|
227
95
|
}
|
96
|
+
if (value == NULL) {
|
97
|
+
return Qnil;
|
98
|
+
}
|
228
99
|
return oci8_metadata_create(value, md->svc, self);
|
229
100
|
}
|
230
101
|
|
@@ -233,17 +104,11 @@ static VALUE metadata_get_param_at(VALUE self, VALUE idx)
|
|
233
104
|
oci8_metadata_t *md = DATA_PTR(self);
|
234
105
|
OCIParam *value;
|
235
106
|
|
236
|
-
|
107
|
+
chker2(OCIParamGet(md->base.hp.ptr, md->base.type, oci8_errhp, (dvoid *)&value, FIX2INT(idx)),
|
108
|
+
&md->base);
|
237
109
|
return oci8_metadata_create(value, md->svc, self);
|
238
110
|
}
|
239
111
|
|
240
|
-
static VALUE metadata_get_charset_name(VALUE self, VALUE charset_id)
|
241
|
-
{
|
242
|
-
oci8_metadata_t *md = DATA_PTR(self);
|
243
|
-
|
244
|
-
return oci8_charset_id2name(md->svc, charset_id);
|
245
|
-
}
|
246
|
-
|
247
112
|
static VALUE metadata_get_con(VALUE self)
|
248
113
|
{
|
249
114
|
oci8_metadata_t *md = DATA_PTR(self);
|
@@ -263,22 +128,29 @@ static VALUE oci8_do_describe(VALUE self, void *objptr, ub4 objlen, ub1 objtype,
|
|
263
128
|
VALUE type;
|
264
129
|
VALUE obj;
|
265
130
|
oci8_base_t *desc;
|
131
|
+
int rv;
|
266
132
|
|
267
133
|
/* make a describe handle object */
|
268
134
|
obj = rb_obj_alloc(oci8_cOCIHandle);
|
269
135
|
desc = DATA_PTR(obj);
|
270
|
-
|
136
|
+
rv = OCIHandleAlloc(oci8_envhp, (dvoid *)&desc->hp.dschp, OCI_HTYPE_DESCRIBE, 0, 0);
|
137
|
+
if (rv != OCI_SUCCESS) {
|
138
|
+
oci8_env_raise(oci8_envhp, rv);
|
139
|
+
}
|
271
140
|
desc->type = OCI_HTYPE_DESCRIBE;
|
272
141
|
|
273
142
|
type = rb_hash_aref(class_to_ptype, klass);
|
274
143
|
if (RTEST(check_public)) {
|
275
144
|
sb4 val = -1;
|
276
145
|
/* size of OCI_ATTR_DESC_PUBLIC is undocumented. */
|
277
|
-
|
146
|
+
chker2(OCIAttrSet(desc->hp.dschp, OCI_HTYPE_DESCRIBE, &val, 0, OCI_ATTR_DESC_PUBLIC, oci8_errhp),
|
147
|
+
&svcctx->base);
|
278
148
|
}
|
279
|
-
|
280
|
-
objtype, OCI_DEFAULT, (ub1)FIX2INT(type), desc->hp.dschp)
|
281
|
-
|
149
|
+
chker2(OCIDescribeAny_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, objptr, objlen,
|
150
|
+
objtype, OCI_DEFAULT, (ub1)FIX2INT(type), desc->hp.dschp),
|
151
|
+
&svcctx->base);
|
152
|
+
chker2(OCIAttrGet(desc->hp.dschp, OCI_HTYPE_DESCRIBE, &parmhp, 0, OCI_ATTR_PARAM, oci8_errhp),
|
153
|
+
&svcctx->base);
|
282
154
|
return oci8_metadata_create(parmhp, self, obj);
|
283
155
|
}
|
284
156
|
|
@@ -298,7 +170,8 @@ static VALUE metadata_get_type_metadata(VALUE self, VALUE klass)
|
|
298
170
|
OCIRef *ref = NULL;
|
299
171
|
|
300
172
|
/* remote call */
|
301
|
-
|
173
|
+
chker2(OCIAttrGet_nb(svcctx, md->base.hp.ptr, md->base.type, &ref, NULL, OCI_ATTR_REF_TDO, oci8_errhp),
|
174
|
+
&svcctx->base);
|
302
175
|
return oci8_do_describe(md->svc, ref, 0, OCI_OTYPE_REF, klass, Qfalse);
|
303
176
|
}
|
304
177
|
|
@@ -309,11 +182,14 @@ static VALUE metadata_get_tdo_id(VALUE self)
|
|
309
182
|
OCIRef *tdo_ref = NULL;
|
310
183
|
void *tdo;
|
311
184
|
|
312
|
-
|
185
|
+
chker2(OCIAttrGet_nb(svcctx, md->base.hp.ptr, md->base.type, &tdo_ref, NULL, OCI_ATTR_REF_TDO, oci8_errhp),
|
186
|
+
&svcctx->base);
|
313
187
|
if (tdo_ref == NULL)
|
314
188
|
return Qnil;
|
315
|
-
|
316
|
-
|
189
|
+
chker2(OCIObjectPin_nb(svcctx, oci8_envhp, oci8_errhp, tdo_ref, 0, OCI_PIN_ANY, OCI_DURATION_SESSION, OCI_LOCK_NONE, &tdo),
|
190
|
+
&svcctx->base);
|
191
|
+
chker2(OCIObjectUnpin(oci8_envhp, oci8_errhp, tdo),
|
192
|
+
&svcctx->base);
|
317
193
|
#if SIZEOF_LONG == SIZEOF_VOIDP
|
318
194
|
return ((VALUE)tdo | (VALUE)1);
|
319
195
|
#else
|
@@ -321,7 +197,7 @@ static VALUE metadata_get_tdo_id(VALUE self)
|
|
321
197
|
#endif
|
322
198
|
}
|
323
199
|
|
324
|
-
|
200
|
+
oci8_base_vtable_t oci8_metadata_vtable = {
|
325
201
|
oci8_metadata_mark,
|
326
202
|
NULL,
|
327
203
|
sizeof(oci8_metadata_t),
|
@@ -330,26 +206,15 @@ oci8_base_class_t oci8_metadata_class = {
|
|
330
206
|
void Init_oci8_metadata(VALUE cOCI8)
|
331
207
|
{
|
332
208
|
mOCI8Metadata = rb_define_module_under(cOCI8, "Metadata");
|
333
|
-
cOCI8MetadataBase = oci8_define_class_under(mOCI8Metadata, "Base", &
|
209
|
+
cOCI8MetadataBase = oci8_define_class_under(mOCI8Metadata, "Base", &oci8_metadata_vtable);
|
334
210
|
ptype_to_class = rb_hash_new();
|
335
211
|
class_to_ptype = rb_hash_new();
|
336
212
|
rb_global_variable(&ptype_to_class);
|
337
213
|
rb_global_variable(&class_to_ptype);
|
338
214
|
|
339
215
|
rb_define_singleton_method(cOCI8MetadataBase, "register_ptype", metadata_s_register_ptype, 1);
|
340
|
-
rb_define_private_method(cOCI8MetadataBase, "__ub1", metadata_get_ub1, 1);
|
341
|
-
rb_define_private_method(cOCI8MetadataBase, "__ub2", metadata_get_ub2, 1);
|
342
|
-
rb_define_private_method(cOCI8MetadataBase, "__ub2_nc", metadata_get_ub2_nc, 1);
|
343
|
-
rb_define_private_method(cOCI8MetadataBase, "__ub4", metadata_get_ub4, 1);
|
344
|
-
rb_define_private_method(cOCI8MetadataBase, "__sb1", metadata_get_sb1, 1);
|
345
|
-
rb_define_private_method(cOCI8MetadataBase, "__sb2", metadata_get_sb2, 1);
|
346
|
-
rb_define_private_method(cOCI8MetadataBase, "__sb4", metadata_get_sb4, 1);
|
347
|
-
rb_define_private_method(cOCI8MetadataBase, "__text", metadata_get_text, 1);
|
348
|
-
rb_define_private_method(cOCI8MetadataBase, "__oradate", metadata_get_oradate, 1);
|
349
|
-
rb_define_private_method(cOCI8MetadataBase, "__oraint", metadata_get_oraint, 1);
|
350
216
|
rb_define_private_method(cOCI8MetadataBase, "__param", metadata_get_param, 1);
|
351
217
|
rb_define_private_method(cOCI8MetadataBase, "__param_at", metadata_get_param_at, 1);
|
352
|
-
rb_define_private_method(cOCI8MetadataBase, "__charset_name", metadata_get_charset_name, 1);
|
353
218
|
rb_define_private_method(cOCI8MetadataBase, "__con", metadata_get_con, 0);
|
354
219
|
rb_define_private_method(cOCI8MetadataBase, "__is_implicit?", metadata_is_implicit_p, 0);
|
355
220
|
|