ruby-oci8 2.2.0.2 → 2.2.12
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|