ruby-oci8 2.2.0.2 → 2.2.12
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.
- checksums.yaml +7 -0
- data/.yardopts +1 -6
- data/ChangeLog +600 -0
- data/NEWS +426 -35
- data/README.md +27 -9
- data/dist-files +13 -2
- data/docs/bind-array-to-in_cond.md +38 -0
- data/docs/conflicts-local-connections-and-processes.md +98 -0
- data/docs/hanging-after-inactivity.md +63 -0
- data/docs/install-binary-package.md +15 -11
- data/docs/install-full-client.md +18 -21
- data/docs/install-instant-client.md +45 -27
- data/docs/install-on-osx.md +31 -117
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/docs/platform-specific-issues.md +17 -50
- data/docs/report-installation-issue.md +11 -8
- data/docs/timeout-parameters.md +94 -0
- data/ext/oci8/apiwrap.c.tmpl +2 -5
- data/ext/oci8/apiwrap.rb +6 -1
- data/ext/oci8/apiwrap.yml +39 -143
- data/ext/oci8/attr.c +4 -2
- data/ext/oci8/bind.c +421 -9
- data/ext/oci8/connection_pool.c +3 -3
- data/ext/oci8/encoding.c +5 -5
- data/ext/oci8/env.c +8 -2
- data/ext/oci8/error.c +24 -16
- data/ext/oci8/extconf.rb +35 -63
- data/ext/oci8/hook_funcs.c +274 -61
- data/ext/oci8/lob.c +31 -75
- data/ext/oci8/metadata.c +8 -6
- data/ext/oci8/object.c +119 -29
- data/ext/oci8/oci8.c +46 -133
- data/ext/oci8/oci8.h +40 -123
- data/ext/oci8/oci8lib.c +178 -46
- data/ext/oci8/ocihandle.c +37 -37
- data/ext/oci8/ocinumber.c +24 -35
- data/ext/oci8/oraconf.rb +168 -337
- data/ext/oci8/oradate.c +19 -19
- data/ext/oci8/plthook.h +10 -0
- data/ext/oci8/plthook_elf.c +433 -268
- data/ext/oci8/plthook_osx.c +40 -9
- data/ext/oci8/plthook_win32.c +16 -1
- data/ext/oci8/stmt.c +52 -17
- data/ext/oci8/win32.c +4 -22
- data/lib/oci8/bindtype.rb +10 -17
- data/lib/oci8/check_load_error.rb +57 -10
- data/lib/oci8/compat.rb +5 -1
- data/lib/oci8/connection_pool.rb +74 -3
- data/lib/oci8/cursor.rb +70 -31
- data/lib/oci8/metadata.rb +9 -1
- data/lib/oci8/object.rb +14 -1
- data/lib/oci8/oci8.rb +184 -58
- data/lib/oci8/ocihandle.rb +0 -16
- data/lib/oci8/oracle_version.rb +11 -1
- data/lib/oci8/properties.rb +55 -0
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8.rb +48 -4
- data/lib/ruby-oci8.rb +1 -0
- data/pre-distclean.rb +1 -3
- data/ruby-oci8.gemspec +4 -9
- data/setup.rb +11 -2
- data/test/README.md +37 -0
- data/test/config.rb +8 -1
- data/test/setup_test_object.sql +42 -14
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +4 -0
- data/test/test_bind_array.rb +70 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_bind_integer.rb +47 -0
- data/test/test_break.rb +11 -9
- data/test/test_clob.rb +5 -17
- data/test/test_connstr.rb +142 -0
- data/test/test_datetime.rb +8 -3
- data/test/test_metadata.rb +2 -1
- data/test/test_object.rb +99 -18
- data/test/test_oci8.rb +170 -46
- data/test/test_oranumber.rb +12 -6
- data/test/test_package_type.rb +17 -3
- data/test/test_properties.rb +17 -0
- metadata +45 -55
- data/docs/osx-install-dev-tools.png +0 -0
- data/test/README +0 -42
data/ext/oci8/bind.c
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
#endif
|
12
12
|
|
13
13
|
static ID id_bind_type;
|
14
|
+
static ID id_charset_form;
|
14
15
|
static VALUE sym_length;
|
15
16
|
static VALUE sym_length_semantics;
|
16
17
|
static VALUE sym_char;
|
@@ -25,6 +26,29 @@ typedef struct {
|
|
25
26
|
ub1 csfrm;
|
26
27
|
} oci8_bind_string_t;
|
27
28
|
|
29
|
+
static ub4 initial_chunk_size = 32 * 1024;
|
30
|
+
static ub4 max_chunk_size = 8 * 1024 * 1024;
|
31
|
+
|
32
|
+
typedef struct chunk {
|
33
|
+
struct chunk *next;
|
34
|
+
ub4 alloc_len;
|
35
|
+
ub4 used_len;
|
36
|
+
char buf[1];
|
37
|
+
} chunk_t;
|
38
|
+
|
39
|
+
typedef struct {
|
40
|
+
chunk_t *head;
|
41
|
+
chunk_t **tail;
|
42
|
+
chunk_t **inpos;
|
43
|
+
} chunk_buf_t;
|
44
|
+
|
45
|
+
typedef struct {
|
46
|
+
oci8_bind_t obind;
|
47
|
+
ub1 csfrm;
|
48
|
+
} oci8_bind_long_t;
|
49
|
+
|
50
|
+
#define IS_BIND_LONG(obind) (((oci8_bind_data_type_t*)obind->base.data_type)->dty == SQLT_CHR)
|
51
|
+
|
28
52
|
const oci8_handle_data_type_t oci8_bind_data_type = {
|
29
53
|
{
|
30
54
|
"OCI8::BindType::Base",
|
@@ -61,7 +85,7 @@ static void bind_string_set(oci8_bind_t *obind, void *data, void **null_structp,
|
|
61
85
|
rb_raise(rb_eArgError, "too long String to set. (%ld for %d)", RSTRING_LEN(val), obs->bytelen);
|
62
86
|
}
|
63
87
|
memcpy(vstr->buf, RSTRING_PTR(val), RSTRING_LEN(val));
|
64
|
-
vstr->size =
|
88
|
+
vstr->size = RSTRING_LENINT(val);
|
65
89
|
}
|
66
90
|
|
67
91
|
static void bind_string_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE param)
|
@@ -171,7 +195,7 @@ static void bind_raw_set(oci8_bind_t *obind, void *data, void **null_structp, VA
|
|
171
195
|
rb_raise(rb_eArgError, "too long String to set. (%ld for %d)", RSTRING_LEN(val), obs->bytelen);
|
172
196
|
}
|
173
197
|
memcpy(vstr->buf, RSTRING_PTR(val), RSTRING_LEN(val));
|
174
|
-
vstr->size =
|
198
|
+
vstr->size = RSTRING_LENINT(val);
|
175
199
|
}
|
176
200
|
|
177
201
|
static const oci8_bind_data_type_t bind_raw_data_type = {
|
@@ -224,9 +248,6 @@ static void bind_binary_double_init(oci8_bind_t *obind, VALUE svc, VALUE val, VA
|
|
224
248
|
obind->alloc_sz = sizeof(double);
|
225
249
|
}
|
226
250
|
|
227
|
-
#ifndef SQLT_BDOUBLE
|
228
|
-
#define SQLT_BDOUBLE 22
|
229
|
-
#endif
|
230
251
|
static const oci8_bind_data_type_t bind_binary_double_data_type = {
|
231
252
|
{
|
232
253
|
{
|
@@ -257,6 +278,347 @@ static VALUE bind_binary_double_alloc(VALUE klass)
|
|
257
278
|
return oci8_allocate_typeddata(klass, &bind_binary_double_data_type.base);
|
258
279
|
}
|
259
280
|
|
281
|
+
/*
|
282
|
+
* bind_boolean
|
283
|
+
*/
|
284
|
+
static VALUE bind_boolean_get(oci8_bind_t *obind, void *data, void *null_struct)
|
285
|
+
{
|
286
|
+
return *(int*)data ? Qtrue : Qfalse;
|
287
|
+
}
|
288
|
+
|
289
|
+
static void bind_boolean_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
290
|
+
{
|
291
|
+
*(int*)data = RTEST(val) ? -1 : 0;
|
292
|
+
}
|
293
|
+
|
294
|
+
static void bind_boolean_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
295
|
+
{
|
296
|
+
obind->value_sz = sizeof(int);
|
297
|
+
obind->alloc_sz = sizeof(int);
|
298
|
+
}
|
299
|
+
|
300
|
+
#ifndef SQLT_BOL
|
301
|
+
#define SQLT_BOL 252
|
302
|
+
#endif
|
303
|
+
static const oci8_bind_data_type_t bind_boolean_data_type = {
|
304
|
+
{
|
305
|
+
{
|
306
|
+
"OCI8::BindType::Boolean",
|
307
|
+
{
|
308
|
+
NULL,
|
309
|
+
oci8_handle_cleanup,
|
310
|
+
oci8_handle_size,
|
311
|
+
},
|
312
|
+
&oci8_bind_data_type.rb_data_type, NULL,
|
313
|
+
#ifdef RUBY_TYPED_WB_PROTECTED
|
314
|
+
RUBY_TYPED_WB_PROTECTED,
|
315
|
+
#endif
|
316
|
+
},
|
317
|
+
oci8_bind_free,
|
318
|
+
sizeof(oci8_bind_t)
|
319
|
+
},
|
320
|
+
bind_boolean_get,
|
321
|
+
bind_boolean_set,
|
322
|
+
bind_boolean_init,
|
323
|
+
NULL,
|
324
|
+
NULL,
|
325
|
+
SQLT_BOL,
|
326
|
+
};
|
327
|
+
|
328
|
+
static VALUE bind_boolean_alloc(VALUE klass)
|
329
|
+
{
|
330
|
+
return oci8_allocate_typeddata(klass, &bind_boolean_data_type.base);
|
331
|
+
}
|
332
|
+
|
333
|
+
/*
|
334
|
+
* bind_long
|
335
|
+
*/
|
336
|
+
static chunk_t *next_chunk(chunk_buf_t *cb)
|
337
|
+
{
|
338
|
+
chunk_t *chunk;
|
339
|
+
|
340
|
+
if (*cb->tail != NULL) {
|
341
|
+
chunk = *cb->tail;
|
342
|
+
} else {
|
343
|
+
ub4 alloc_len;
|
344
|
+
if (cb->head == NULL) {
|
345
|
+
alloc_len = initial_chunk_size;
|
346
|
+
} else {
|
347
|
+
alloc_len = ((chunk_t*)((size_t)cb->tail - offsetof(chunk_t, next)))->alloc_len * 2;
|
348
|
+
if (alloc_len > max_chunk_size) {
|
349
|
+
alloc_len = max_chunk_size;
|
350
|
+
}
|
351
|
+
}
|
352
|
+
chunk = xmalloc(offsetof(chunk_t, buf) + alloc_len);
|
353
|
+
chunk->next = NULL;
|
354
|
+
chunk->alloc_len = alloc_len;
|
355
|
+
*cb->tail = chunk;
|
356
|
+
}
|
357
|
+
cb->tail = &chunk->next;
|
358
|
+
return chunk;
|
359
|
+
}
|
360
|
+
|
361
|
+
static sb4 define_callback(void *octxp, OCIDefine *defnp, ub4 iter, void **bufpp, ub4 **alenp, ub1 *piecep, void **indp, ub2 **rcodep)
|
362
|
+
{
|
363
|
+
oci8_bind_t *obind = (oci8_bind_t *)octxp;
|
364
|
+
chunk_buf_t *cb = ((chunk_buf_t*)obind->valuep) + iter;
|
365
|
+
chunk_t *chunk;
|
366
|
+
|
367
|
+
if (*piecep == OCI_FIRST_PIECE) {
|
368
|
+
cb->tail = &cb->head;
|
369
|
+
}
|
370
|
+
chunk = next_chunk(cb);
|
371
|
+
chunk->used_len = chunk->alloc_len;
|
372
|
+
*bufpp = chunk->buf;
|
373
|
+
*alenp = &chunk->used_len;
|
374
|
+
*indp = (void*)&obind->u.inds[iter];
|
375
|
+
*rcodep = NULL;
|
376
|
+
return OCI_CONTINUE;
|
377
|
+
}
|
378
|
+
|
379
|
+
static sb4 in_bind_callback(void *ictxp, OCIBind *bindp, ub4 iter, ub4 index, void **bufpp, ub4 *alenp, ub1 *piecep, void **indp)
|
380
|
+
{
|
381
|
+
oci8_bind_t *obind = (oci8_bind_t *)ictxp;
|
382
|
+
chunk_buf_t *cb = ((chunk_buf_t*)obind->valuep) + iter;
|
383
|
+
|
384
|
+
if (cb->tail == &cb->head) {
|
385
|
+
/* empty string */
|
386
|
+
*bufpp = (void *)"";
|
387
|
+
*alenp = 0;
|
388
|
+
*piecep = OCI_ONE_PIECE;
|
389
|
+
} else {
|
390
|
+
chunk_t *chunk = *cb->inpos;
|
391
|
+
*bufpp = chunk->buf;
|
392
|
+
*alenp = chunk->used_len;
|
393
|
+
if (cb->tail == &cb->head->next) {
|
394
|
+
*piecep = OCI_ONE_PIECE;
|
395
|
+
} else if (cb->inpos == &cb->head) {
|
396
|
+
*piecep = OCI_FIRST_PIECE;
|
397
|
+
cb->inpos = &chunk->next;
|
398
|
+
} else if (&chunk->next != cb->tail) {
|
399
|
+
*piecep = OCI_NEXT_PIECE;
|
400
|
+
cb->inpos = &chunk->next;
|
401
|
+
} else {
|
402
|
+
*piecep = OCI_LAST_PIECE;
|
403
|
+
cb->inpos = &cb->head;
|
404
|
+
}
|
405
|
+
}
|
406
|
+
*indp = (void*)&obind->u.inds[iter];
|
407
|
+
return OCI_CONTINUE;
|
408
|
+
}
|
409
|
+
|
410
|
+
static sb4 out_bind_callback(void *octxp, OCIBind *bindp, ub4 iter, ub4 index, void **bufpp, ub4 **alenp, ub1 *piecep, void **indp, ub2 **rcodep)
|
411
|
+
{
|
412
|
+
oci8_bind_t *obind = (oci8_bind_t *)octxp;
|
413
|
+
chunk_buf_t *cb = ((chunk_buf_t*)obind->valuep) + iter;
|
414
|
+
chunk_t *chunk;
|
415
|
+
|
416
|
+
if (*piecep == OCI_ONE_PIECE) {
|
417
|
+
*piecep = OCI_FIRST_PIECE;
|
418
|
+
cb->tail = &cb->head;
|
419
|
+
}
|
420
|
+
chunk = next_chunk(cb);
|
421
|
+
chunk->used_len = chunk->alloc_len;
|
422
|
+
*bufpp = chunk->buf;
|
423
|
+
*alenp = &chunk->used_len;
|
424
|
+
*indp = (void*)&obind->u.inds[iter];
|
425
|
+
*rcodep = NULL;
|
426
|
+
return OCI_CONTINUE;
|
427
|
+
}
|
428
|
+
|
429
|
+
static void bind_long_free(oci8_base_t *base)
|
430
|
+
{
|
431
|
+
oci8_bind_t *obind = (oci8_bind_t *)base;
|
432
|
+
chunk_buf_t *cb = (chunk_buf_t *)obind->valuep;
|
433
|
+
|
434
|
+
if (cb != NULL) {
|
435
|
+
ub4 idx = 0;
|
436
|
+
do {
|
437
|
+
chunk_t *chunk, *chunk_next;
|
438
|
+
for (chunk = cb[idx].head; chunk != NULL; chunk = chunk_next) {
|
439
|
+
chunk_next = chunk->next;
|
440
|
+
xfree(chunk);
|
441
|
+
}
|
442
|
+
} while (++idx < obind->maxar_sz);
|
443
|
+
}
|
444
|
+
oci8_bind_free(base);
|
445
|
+
}
|
446
|
+
|
447
|
+
static VALUE bind_long_get(oci8_bind_t *obind, void *data, void *null_struct)
|
448
|
+
{
|
449
|
+
chunk_buf_t *cb = (chunk_buf_t *)data;
|
450
|
+
chunk_t *chunk;
|
451
|
+
long len = 0;
|
452
|
+
VALUE str;
|
453
|
+
char *buf;
|
454
|
+
|
455
|
+
for (chunk = cb->head; chunk != *cb->tail; chunk = chunk->next) {
|
456
|
+
len += chunk->used_len;
|
457
|
+
}
|
458
|
+
str = rb_str_buf_new(len);
|
459
|
+
buf = RSTRING_PTR(str);
|
460
|
+
for (chunk = cb->head; chunk != *cb->tail; chunk = chunk->next) {
|
461
|
+
memcpy(buf, chunk->buf, chunk->used_len);
|
462
|
+
buf += chunk->used_len;
|
463
|
+
}
|
464
|
+
rb_str_set_len(str, len);
|
465
|
+
if (IS_BIND_LONG(obind)) {
|
466
|
+
rb_encoding *enc = rb_default_internal_encoding();
|
467
|
+
|
468
|
+
rb_enc_associate(str, oci8_encoding);
|
469
|
+
if (enc != NULL) {
|
470
|
+
str = rb_str_conv_enc(str, oci8_encoding, enc);
|
471
|
+
}
|
472
|
+
}
|
473
|
+
return str;
|
474
|
+
}
|
475
|
+
|
476
|
+
static void bind_long_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
477
|
+
{
|
478
|
+
chunk_buf_t *cb = (chunk_buf_t *)data;
|
479
|
+
ub4 len;
|
480
|
+
const char *buf;
|
481
|
+
|
482
|
+
if (IS_BIND_LONG(obind)) {
|
483
|
+
OCI8StringValue(val);
|
484
|
+
} else {
|
485
|
+
StringValue(val);
|
486
|
+
}
|
487
|
+
len = (ub4)RSTRING_LEN(val);
|
488
|
+
buf = RSTRING_PTR(val);
|
489
|
+
cb->tail = &cb->head;
|
490
|
+
while (1) {
|
491
|
+
chunk_t *chunk = next_chunk(cb);
|
492
|
+
if (len <= chunk->alloc_len) {
|
493
|
+
memcpy(chunk->buf, buf, len);
|
494
|
+
chunk->used_len = len;
|
495
|
+
break;
|
496
|
+
}
|
497
|
+
memcpy(chunk->buf, buf, chunk->alloc_len);
|
498
|
+
chunk->used_len = chunk->alloc_len;
|
499
|
+
len -= chunk->alloc_len;
|
500
|
+
buf += chunk->alloc_len;
|
501
|
+
}
|
502
|
+
}
|
503
|
+
|
504
|
+
static void bind_long_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE param)
|
505
|
+
{
|
506
|
+
if (IS_BIND_LONG(obind)) {
|
507
|
+
oci8_bind_long_t *obl = (oci8_bind_long_t *)obind;
|
508
|
+
VALUE nchar;
|
509
|
+
|
510
|
+
if (rb_respond_to(param, id_charset_form)) {
|
511
|
+
VALUE csfrm = rb_funcall(param, id_charset_form, 0);
|
512
|
+
nchar = (csfrm == sym_nchar) ? Qtrue : Qfalse;
|
513
|
+
} else {
|
514
|
+
Check_Type(param, T_HASH);
|
515
|
+
nchar = rb_hash_aref(param, sym_nchar);
|
516
|
+
}
|
517
|
+
|
518
|
+
if (RTEST(nchar)) {
|
519
|
+
obl->csfrm = SQLCS_NCHAR; /* bind as NCHAR/NVARCHAR2 */
|
520
|
+
} else {
|
521
|
+
obl->csfrm = SQLCS_IMPLICIT; /* bind as CHAR/VARCHAR2 */
|
522
|
+
}
|
523
|
+
}
|
524
|
+
obind->value_sz = SB4MAXVAL;
|
525
|
+
obind->alloc_sz = sizeof(chunk_buf_t);
|
526
|
+
}
|
527
|
+
|
528
|
+
static void bind_long_init_elem(oci8_bind_t *obind, VALUE svc)
|
529
|
+
{
|
530
|
+
chunk_buf_t *cb = (chunk_buf_t *)obind->valuep;
|
531
|
+
ub4 idx = 0;
|
532
|
+
|
533
|
+
do {
|
534
|
+
cb[idx].tail = &cb[idx].head;
|
535
|
+
cb[idx].inpos = &cb[idx].head;
|
536
|
+
} while (++idx < obind->maxar_sz);
|
537
|
+
}
|
538
|
+
|
539
|
+
static void bind_long_post_bind_hook(oci8_bind_t *obind)
|
540
|
+
{
|
541
|
+
oci8_bind_long_t *ds = (oci8_bind_long_t *)obind;
|
542
|
+
|
543
|
+
if (IS_BIND_LONG(obind)) {
|
544
|
+
chker2(OCIAttrSet(obind->base.hp.ptr, obind->base.type, (void*)&ds->csfrm, 0, OCI_ATTR_CHARSET_FORM, oci8_errhp),
|
545
|
+
&obind->base);
|
546
|
+
}
|
547
|
+
switch (obind->base.type) {
|
548
|
+
case OCI_HTYPE_DEFINE:
|
549
|
+
chker2(OCIDefineDynamic(obind->base.hp.dfn, oci8_errhp, obind, define_callback),
|
550
|
+
&obind->base);
|
551
|
+
break;
|
552
|
+
case OCI_HTYPE_BIND:
|
553
|
+
chker2(OCIBindDynamic(obind->base.hp.bnd, oci8_errhp, obind, in_bind_callback,
|
554
|
+
obind, out_bind_callback),
|
555
|
+
&obind->base);
|
556
|
+
break;
|
557
|
+
}
|
558
|
+
}
|
559
|
+
|
560
|
+
static const oci8_bind_data_type_t bind_long_data_type = {
|
561
|
+
{
|
562
|
+
{
|
563
|
+
"OCI8::BindType::Long",
|
564
|
+
{
|
565
|
+
NULL,
|
566
|
+
oci8_handle_cleanup,
|
567
|
+
oci8_handle_size,
|
568
|
+
},
|
569
|
+
&oci8_bind_data_type.rb_data_type, NULL,
|
570
|
+
#ifdef RUBY_TYPED_WB_PROTECTED
|
571
|
+
RUBY_TYPED_WB_PROTECTED,
|
572
|
+
#endif
|
573
|
+
},
|
574
|
+
bind_long_free,
|
575
|
+
sizeof(oci8_bind_long_t)
|
576
|
+
},
|
577
|
+
bind_long_get,
|
578
|
+
bind_long_set,
|
579
|
+
bind_long_init,
|
580
|
+
bind_long_init_elem,
|
581
|
+
NULL,
|
582
|
+
SQLT_CHR,
|
583
|
+
bind_long_post_bind_hook,
|
584
|
+
};
|
585
|
+
|
586
|
+
static VALUE bind_long_alloc(VALUE klass)
|
587
|
+
{
|
588
|
+
return oci8_allocate_typeddata(klass, &bind_long_data_type.base);
|
589
|
+
}
|
590
|
+
|
591
|
+
static const oci8_bind_data_type_t bind_long_raw_data_type = {
|
592
|
+
{
|
593
|
+
{
|
594
|
+
"OCI8::BindType::LongRaw",
|
595
|
+
{
|
596
|
+
NULL,
|
597
|
+
oci8_handle_cleanup,
|
598
|
+
oci8_handle_size,
|
599
|
+
},
|
600
|
+
&oci8_bind_data_type.rb_data_type, NULL,
|
601
|
+
#ifdef RUBY_TYPED_WB_PROTECTED
|
602
|
+
RUBY_TYPED_WB_PROTECTED,
|
603
|
+
#endif
|
604
|
+
},
|
605
|
+
bind_long_free,
|
606
|
+
sizeof(oci8_bind_long_t)
|
607
|
+
},
|
608
|
+
bind_long_get,
|
609
|
+
bind_long_set,
|
610
|
+
bind_long_init,
|
611
|
+
bind_long_init_elem,
|
612
|
+
NULL,
|
613
|
+
SQLT_BIN,
|
614
|
+
bind_long_post_bind_hook,
|
615
|
+
};
|
616
|
+
|
617
|
+
static VALUE bind_long_raw_alloc(VALUE klass)
|
618
|
+
{
|
619
|
+
return oci8_allocate_typeddata(klass, &bind_long_raw_data_type.base);
|
620
|
+
}
|
621
|
+
|
260
622
|
static VALUE oci8_bind_get(VALUE self)
|
261
623
|
{
|
262
624
|
oci8_bind_t *obind = TO_BIND(self);
|
@@ -271,11 +633,20 @@ static VALUE oci8_bind_get(VALUE self)
|
|
271
633
|
return data_type->get(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp);
|
272
634
|
}
|
273
635
|
|
274
|
-
static VALUE oci8_bind_get_data(VALUE self)
|
636
|
+
static VALUE oci8_bind_get_data(int argc, VALUE *argv, VALUE self)
|
275
637
|
{
|
276
638
|
oci8_bind_t *obind = TO_BIND(self);
|
639
|
+
VALUE index;
|
277
640
|
|
278
|
-
|
641
|
+
rb_scan_args(argc, argv, "01", &index);
|
642
|
+
if (!NIL_P(index)) {
|
643
|
+
ub4 idx = NUM2UINT(index);
|
644
|
+
if (idx >= obind->maxar_sz) {
|
645
|
+
rb_raise(rb_eRuntimeError, "data index is too big. (%u for %u)", idx, obind->maxar_sz);
|
646
|
+
}
|
647
|
+
obind->curar_idx = idx;
|
648
|
+
return rb_funcall(self, oci8_id_get, 0);
|
649
|
+
} else if (obind->maxar_sz == 0) {
|
279
650
|
obind->curar_idx = 0;
|
280
651
|
return rb_funcall(self, oci8_id_get, 0);
|
281
652
|
} else {
|
@@ -329,7 +700,7 @@ static VALUE oci8_bind_set_data(VALUE self, VALUE val)
|
|
329
700
|
ub4 idx;
|
330
701
|
Check_Type(val, T_ARRAY);
|
331
702
|
|
332
|
-
size =
|
703
|
+
size = RARRAY_LENINT(val);
|
333
704
|
if (size > obind->maxar_sz) {
|
334
705
|
rb_raise(rb_eRuntimeError, "over the max array size");
|
335
706
|
}
|
@@ -342,6 +713,36 @@ static VALUE oci8_bind_set_data(VALUE self, VALUE val)
|
|
342
713
|
return self;
|
343
714
|
}
|
344
715
|
|
716
|
+
static VALUE get_initial_chunk_size(VALUE klass)
|
717
|
+
{
|
718
|
+
return UINT2NUM(initial_chunk_size);
|
719
|
+
}
|
720
|
+
|
721
|
+
static VALUE set_initial_chunk_size(VALUE klass, VALUE arg)
|
722
|
+
{
|
723
|
+
ub4 size = NUM2UINT(arg);
|
724
|
+
if (size == 0) {
|
725
|
+
rb_raise(rb_eArgError, "Could not set zero");
|
726
|
+
}
|
727
|
+
initial_chunk_size = size;
|
728
|
+
return arg;
|
729
|
+
}
|
730
|
+
|
731
|
+
static VALUE get_max_chunk_size(VALUE klass)
|
732
|
+
{
|
733
|
+
return UINT2NUM(max_chunk_size);
|
734
|
+
}
|
735
|
+
|
736
|
+
static VALUE set_max_chunk_size(VALUE klass, VALUE arg)
|
737
|
+
{
|
738
|
+
ub4 size = NUM2UINT(arg);
|
739
|
+
if (size == 0) {
|
740
|
+
rb_raise(rb_eArgError, "Could not set zero");
|
741
|
+
}
|
742
|
+
max_chunk_size = size;
|
743
|
+
return arg;
|
744
|
+
}
|
745
|
+
|
345
746
|
static VALUE oci8_bind_initialize(VALUE self, VALUE svc, VALUE val, VALUE length, VALUE max_array_size)
|
346
747
|
{
|
347
748
|
oci8_bind_t *obind = TO_BIND(self);
|
@@ -407,6 +808,7 @@ void Init_oci8_bind(VALUE klass)
|
|
407
808
|
{
|
408
809
|
cOCI8BindTypeBase = klass;
|
409
810
|
id_bind_type = rb_intern("bind_type");
|
811
|
+
id_charset_form = rb_intern("charset_form");
|
410
812
|
sym_length = ID2SYM(rb_intern("length"));
|
411
813
|
sym_length_semantics = ID2SYM(rb_intern("length_semantics"));
|
412
814
|
sym_char = ID2SYM(rb_intern("char"));
|
@@ -415,11 +817,21 @@ void Init_oci8_bind(VALUE klass)
|
|
415
817
|
rb_define_method(cOCI8BindTypeBase, "initialize", oci8_bind_initialize, 4);
|
416
818
|
rb_define_method(cOCI8BindTypeBase, "get", oci8_bind_get, 0);
|
417
819
|
rb_define_method(cOCI8BindTypeBase, "set", oci8_bind_set, 1);
|
418
|
-
rb_define_private_method(cOCI8BindTypeBase, "get_data", oci8_bind_get_data,
|
820
|
+
rb_define_private_method(cOCI8BindTypeBase, "get_data", oci8_bind_get_data, -1);
|
419
821
|
rb_define_private_method(cOCI8BindTypeBase, "set_data", oci8_bind_set_data, 1);
|
420
822
|
|
823
|
+
rb_define_singleton_method(klass, "initial_chunk_size", get_initial_chunk_size, 0);
|
824
|
+
rb_define_singleton_method(klass, "initial_chunk_size=", set_initial_chunk_size, 1);
|
825
|
+
rb_define_singleton_method(klass, "max_chunk_size", get_max_chunk_size, 0);
|
826
|
+
rb_define_singleton_method(klass, "max_chunk_size=", set_max_chunk_size, 1);
|
827
|
+
|
421
828
|
/* register primitive data types. */
|
422
829
|
oci8_define_bind_class("String", &bind_string_data_type, bind_string_alloc);
|
423
830
|
oci8_define_bind_class("RAW", &bind_raw_data_type, bind_raw_alloc);
|
424
831
|
oci8_define_bind_class("BinaryDouble", &bind_binary_double_data_type, bind_binary_double_alloc);
|
832
|
+
if (oracle_client_version >= ORAVER_12_1) {
|
833
|
+
oci8_define_bind_class("Boolean", &bind_boolean_data_type, bind_boolean_alloc);
|
834
|
+
}
|
835
|
+
klass = oci8_define_bind_class("Long", &bind_long_data_type, bind_long_alloc);
|
836
|
+
klass = oci8_define_bind_class("LongRaw", &bind_long_data_type, bind_long_raw_alloc);
|
425
837
|
}
|
data/ext/oci8/connection_pool.c
CHANGED
@@ -144,13 +144,13 @@ static VALUE oci8_cpool_initialize(int argc, VALUE *argv, VALUE self)
|
|
144
144
|
chker2(OCIConnectionPoolCreate(oci8_envhp, oci8_errhp, cpool->base.hp.poolhp,
|
145
145
|
&pool_name, &pool_name_len,
|
146
146
|
NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname),
|
147
|
-
NIL_P(dbname) ? 0 :
|
147
|
+
NIL_P(dbname) ? 0 : RSTRING_LENINT(dbname),
|
148
148
|
FIX2UINT(conn_min), FIX2UINT(conn_max),
|
149
149
|
FIX2UINT(conn_incr),
|
150
150
|
NIL_P(username) ? NULL : RSTRING_ORATEXT(username),
|
151
|
-
NIL_P(username) ? 0 :
|
151
|
+
NIL_P(username) ? 0 : RSTRING_LENINT(username),
|
152
152
|
NIL_P(password) ? NULL : RSTRING_ORATEXT(password),
|
153
|
-
NIL_P(password) ? 0 :
|
153
|
+
NIL_P(password) ? 0 : RSTRING_LENINT(password),
|
154
154
|
OCI_DEFAULT),
|
155
155
|
&cpool->base);
|
156
156
|
RB_OBJ_WRITE(cpool->base.self, &cpool->pool_name, rb_str_new(TO_CHARPTR(pool_name), pool_name_len));
|
data/ext/oci8/encoding.c
CHANGED
@@ -23,7 +23,7 @@ rb_encoding *oci8_encoding;
|
|
23
23
|
* Returns the Oracle character set name from the specified
|
24
24
|
* character set ID if it is valid. Otherwise, +nil+ is returned.
|
25
25
|
*
|
26
|
-
* @param [
|
26
|
+
* @param [Integer] charset_id Oracle character set id
|
27
27
|
* @return [String] Oracle character set name or nil
|
28
28
|
* @since 2.2.0
|
29
29
|
*/
|
@@ -48,7 +48,7 @@ VALUE oci8_s_charset_id2name(VALUE klass, VALUE csid)
|
|
48
48
|
* character set name if it is valid. Othewise, +nil+ is returned.
|
49
49
|
*
|
50
50
|
* @param [String] charset_name Oracle character set name
|
51
|
-
* @return [
|
51
|
+
* @return [Integer] Oracle character set id or nil
|
52
52
|
* @since 2.2.0
|
53
53
|
*/
|
54
54
|
static VALUE oci8_s_charset_name2id(VALUE klass, VALUE name)
|
@@ -71,7 +71,7 @@ static VALUE oci8_s_charset_name2id(VALUE klass, VALUE name)
|
|
71
71
|
* internal buffer size of a string bind variable whose nls length
|
72
72
|
* semantics is char.
|
73
73
|
*
|
74
|
-
* @return [
|
74
|
+
* @return [Integer] NLS ratio
|
75
75
|
* @since 2.1.0
|
76
76
|
* @private
|
77
77
|
*/
|
@@ -150,7 +150,7 @@ static VALUE oci8_set_encoding(VALUE klass, VALUE encoding)
|
|
150
150
|
* character set name if it is valid. Othewise, +nil+ is returned.
|
151
151
|
*
|
152
152
|
* @param [String] charset_name Oracle character set name
|
153
|
-
* @return [
|
153
|
+
* @return [Integer] Oracle character set id or nil
|
154
154
|
* @since 2.0.0
|
155
155
|
* @deprecated Use {OCI8.charset_name2id} instead.
|
156
156
|
*/
|
@@ -167,7 +167,7 @@ static VALUE oci8_charset_name2id(VALUE svc, VALUE name)
|
|
167
167
|
* Returns the Oracle character set name from the specified
|
168
168
|
* character set ID if it is valid. Otherwise, +nil+ is returned.
|
169
169
|
*
|
170
|
-
* @param [
|
170
|
+
* @param [Integer] charset_id Oracle character set id
|
171
171
|
* @return [String] Oracle character set name or nil
|
172
172
|
* @since 2.0.0
|
173
173
|
* @deprecated Use {OCI8.charset_id2name} instead.
|
data/ext/oci8/env.c
CHANGED
@@ -14,11 +14,17 @@ OCIEnv *oci8_global_envhp;
|
|
14
14
|
OCIEnv *oci8_make_envhp(void)
|
15
15
|
{
|
16
16
|
sword rv;
|
17
|
+
OCIEnv *envhp = NULL;
|
17
18
|
|
18
|
-
rv = OCIEnvCreate(&
|
19
|
+
rv = OCIEnvCreate(&envhp, oci8_env_mode, NULL, NULL, NULL, NULL, 0, NULL);
|
19
20
|
if (rv != OCI_SUCCESS) {
|
20
|
-
|
21
|
+
if (envhp != NULL) {
|
22
|
+
oci8_env_free_and_raise(envhp, rv);
|
23
|
+
} else {
|
24
|
+
oci8_raise_init_error();
|
25
|
+
}
|
21
26
|
}
|
27
|
+
oci8_global_envhp = envhp;
|
22
28
|
return oci8_global_envhp;
|
23
29
|
}
|
24
30
|
|
data/ext/oci8/error.c
CHANGED
@@ -75,6 +75,21 @@ retry:
|
|
75
75
|
return rb_external_str_new_with_enc(errbuf, len, oci8_encoding);
|
76
76
|
}
|
77
77
|
|
78
|
+
/*
|
79
|
+
* Don't call rb_class_new_instance() with more than one argument in this function.
|
80
|
+
* This may be called before OCIError#initialize is defined in lib/oci8/oci8.rb.
|
81
|
+
*/
|
82
|
+
static VALUE oci_exception_new(VALUE klass, VALUE msg, VALUE code, VALUE sql, VALUE parse_error_offset)
|
83
|
+
{
|
84
|
+
VALUE obj = rb_class_new_instance(NIL_P(msg) ? 0 : 1, &msg, klass);
|
85
|
+
if (rb_obj_is_kind_of(obj, eOCIError)) {
|
86
|
+
rb_ivar_set(obj, oci8_id_at_code, code);
|
87
|
+
rb_ivar_set(obj, oci8_id_at_sql, sql);
|
88
|
+
rb_ivar_set(obj, oci8_id_at_parse_error_offset, parse_error_offset);
|
89
|
+
}
|
90
|
+
return obj;
|
91
|
+
}
|
92
|
+
|
78
93
|
static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp, const char *file, int line)
|
79
94
|
{
|
80
95
|
VALUE exc;
|
@@ -84,24 +99,19 @@ static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp
|
|
84
99
|
VALUE parse_error_offset = Qnil;
|
85
100
|
VALUE sql = Qnil;
|
86
101
|
int rv;
|
87
|
-
VALUE args[4];
|
88
|
-
int numarg = 1;
|
89
102
|
|
90
103
|
switch (status) {
|
91
104
|
case OCI_ERROR:
|
92
105
|
exc = eOCIError;
|
93
106
|
msg = get_error_msg(errhp, type, "Error", &errcode);
|
94
|
-
numarg = 4;
|
95
107
|
break;
|
96
108
|
case OCI_SUCCESS_WITH_INFO:
|
97
109
|
exc = eOCISuccessWithInfo;
|
98
110
|
msg = get_error_msg(errhp, type, "Error", &errcode);
|
99
|
-
numarg = 4;
|
100
111
|
break;
|
101
112
|
case OCI_NO_DATA:
|
102
113
|
exc = eOCINoData;
|
103
114
|
msg = get_error_msg(errhp, type, "No Data", &errcode);
|
104
|
-
numarg = 4;
|
105
115
|
break;
|
106
116
|
case OCI_INVALID_HANDLE:
|
107
117
|
exc = eOCIInvalidHandle;
|
@@ -138,11 +148,7 @@ static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp
|
|
138
148
|
sql = rb_external_str_new_with_enc(TO_CHARPTR(text), size, oci8_encoding);
|
139
149
|
}
|
140
150
|
}
|
141
|
-
|
142
|
-
args[1] = INT2FIX(errcode);
|
143
|
-
args[2] = sql;
|
144
|
-
args[3] = parse_error_offset;
|
145
|
-
exc = rb_class_new_instance(numarg, args, exc);
|
151
|
+
exc = oci_exception_new(exc, msg, INT2FIX(errcode), sql, parse_error_offset);
|
146
152
|
return set_backtrace(exc, file, line);
|
147
153
|
}
|
148
154
|
|
@@ -208,9 +214,13 @@ void oci8_do_raise(OCIError *errhp, sword status, OCIStmt *stmthp, const char *f
|
|
208
214
|
rb_exc_raise(oci8_make_exc(errhp, status, OCI_HTYPE_ERROR, stmthp, file, line));
|
209
215
|
}
|
210
216
|
|
211
|
-
void oci8_do_env_raise(OCIEnv *envhp, sword status, const char *file, int line)
|
217
|
+
void oci8_do_env_raise(OCIEnv *envhp, sword status, int free_envhp, const char *file, int line)
|
212
218
|
{
|
213
|
-
|
219
|
+
VALUE exc = oci8_make_exc(envhp, status, OCI_HTYPE_ENV, NULL, file, line);
|
220
|
+
if (free_envhp) {
|
221
|
+
OCIHandleFree(envhp, OCI_HTYPE_ENV);
|
222
|
+
}
|
223
|
+
rb_exc_raise(exc);
|
214
224
|
}
|
215
225
|
|
216
226
|
void oci8_do_raise_init_error(const char *file, int line)
|
@@ -255,11 +265,9 @@ VALUE oci8_get_error_message(ub4 msgno, const char *default_msg)
|
|
255
265
|
void oci8_do_raise_by_msgno(ub4 msgno, const char *default_msg, const char *file, int line)
|
256
266
|
{
|
257
267
|
VALUE msg = oci8_get_error_message(msgno, default_msg);
|
258
|
-
VALUE
|
259
|
-
args[0] = msg;
|
260
|
-
args[1] = INT2FIX(-1);
|
268
|
+
VALUE exc = oci_exception_new(eOCIError, msg, INT2FIX(-1), Qnil, Qnil);
|
261
269
|
|
262
|
-
rb_exc_raise(set_backtrace(
|
270
|
+
rb_exc_raise(set_backtrace(exc, file, line));
|
263
271
|
}
|
264
272
|
|
265
273
|
void oci8_check_error_(sword status, oci8_base_t *base, OCIStmt *stmthp, const char *file, int line)
|