ruby-oci8 2.0.6 → 2.1.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 +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
|
|