ruby-oci8 2.1.7 → 2.1.8
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 +136 -0
- data/NEWS +61 -0
- data/README.md +2 -2
- data/VERSION +1 -1
- data/dist-files +5 -0
- data/docs/install-instant-client.md +2 -0
- data/ext/oci8/attr.c +0 -9
- data/ext/oci8/bind.c +86 -28
- data/ext/oci8/connection_pool.c +32 -17
- data/ext/oci8/extconf.rb +21 -0
- data/ext/oci8/hook_funcs.c +215 -0
- data/ext/oci8/lob.c +363 -168
- data/ext/oci8/metadata.c +43 -26
- data/ext/oci8/object.c +115 -36
- data/ext/oci8/oci8.c +392 -269
- data/ext/oci8/oci8.h +88 -33
- data/ext/oci8/oci8lib.c +59 -28
- data/ext/oci8/ocidatetime.c +100 -36
- data/ext/oci8/ocihandle.c +288 -286
- data/ext/oci8/ocinumber.c +172 -112
- data/ext/oci8/oradate.c +129 -87
- data/ext/oci8/plthook.h +56 -0
- data/ext/oci8/plthook_elf.c +537 -0
- data/ext/oci8/plthook_osx.c +474 -0
- data/ext/oci8/plthook_win32.c +376 -0
- data/ext/oci8/stmt.c +112 -75
- data/lib/oci8/cursor.rb +1 -1
- data/lib/oci8/oci8.rb +71 -0
- data/lib/oci8/properties.rb +18 -3
- metadata +10 -16
data/ext/oci8/oci8.h
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
/*
|
3
3
|
* oci8.h - part of ruby-oci8
|
4
4
|
*
|
5
|
-
* Copyright (C) 2002-
|
5
|
+
* Copyright (C) 2002-2014 Kubo Takehiro <kubo@jiubao.org>
|
6
6
|
*/
|
7
7
|
#ifndef _RUBY_OCI_H_
|
8
8
|
#define _RUBY_OCI_H_ 1
|
@@ -40,6 +40,7 @@ extern "C"
|
|
40
40
|
#define ORAVER_10_1 ORAVERNUM(10, 1, 0, 0, 0)
|
41
41
|
#define ORAVER_10_2 ORAVERNUM(10, 2, 0, 0, 0)
|
42
42
|
#define ORAVER_11_1 ORAVERNUM(11, 1, 0, 0, 0)
|
43
|
+
#define ORAVER_12_1 ORAVERNUM(12, 1, 0, 0, 0)
|
43
44
|
|
44
45
|
#include "extconf.h"
|
45
46
|
#ifdef HAVE_TYPE_RB_ENCODING
|
@@ -116,6 +117,13 @@ typedef struct OCICPool OCICPool;
|
|
116
117
|
#define RARRAY_LEN(obj) RARRAY(obj)->len
|
117
118
|
#endif
|
118
119
|
|
120
|
+
#ifndef HAVE_RB_STR_SET_LEN
|
121
|
+
#define rb_str_set_len(s, l) do { \
|
122
|
+
RSTRING(s)->len = (l); \
|
123
|
+
RSTRING(s)->ptr[l] = '\0'; \
|
124
|
+
} while (0)
|
125
|
+
#endif
|
126
|
+
|
119
127
|
/* new macros in ruby 1.9.
|
120
128
|
* define compatible macros for ruby 1.8 or lower.
|
121
129
|
*/
|
@@ -173,6 +181,46 @@ static inline volatile VALUE *rb_gc_guarded_ptr(volatile VALUE *ptr) {return ptr
|
|
173
181
|
#endif
|
174
182
|
#endif
|
175
183
|
|
184
|
+
/*
|
185
|
+
* Use TypedData on ruby 1.9.3 and later.
|
186
|
+
*/
|
187
|
+
#ifndef HAVE_RB_DATA_TYPE_T_FUNCTION
|
188
|
+
|
189
|
+
/*
|
190
|
+
* Don't use TypedData even though ruby 1.9.2 has it because the
|
191
|
+
* definitions are slightly different from ruby 1.9.3 and later.
|
192
|
+
*/
|
193
|
+
#define rb_data_type_t oci8_data_type_t
|
194
|
+
#undef TypedData_Make_Struct
|
195
|
+
#undef TypedData_Wrap_Struct
|
196
|
+
#undef TypedData_Get_Struct
|
197
|
+
#undef RTYPEDDATA_DATA
|
198
|
+
#undef RUBY_DEFAULT_FREE
|
199
|
+
|
200
|
+
/*
|
201
|
+
* To pass compilation on ruby 1.9.2 and earlier.
|
202
|
+
*/
|
203
|
+
typedef struct oci8_data_type_struct rb_data_type_t;
|
204
|
+
struct oci8_data_type_struct {
|
205
|
+
const char *wrap_struct_name;
|
206
|
+
struct {
|
207
|
+
void (*dmark)(void*);
|
208
|
+
void (*dfree)(void*);
|
209
|
+
size_t (*dsize)(const void *);
|
210
|
+
} function;
|
211
|
+
const rb_data_type_t *parent;
|
212
|
+
void *data;
|
213
|
+
};
|
214
|
+
#define TypedData_Make_Struct(klass, type, data_type, sval) \
|
215
|
+
Data_Make_Struct((klass), type, (data_type)->function.dmark, (data_type)->function.dfree, (sval))
|
216
|
+
#define TypedData_Wrap_Struct(klass, data_type, sval) \
|
217
|
+
Data_Wrap_Struct((klass), (data_type)->function.dmark, (data_type)->function.dfree, (sval))
|
218
|
+
#define TypedData_Get_Struct(obj, type, data_type, sval) \
|
219
|
+
Data_Get_Struct((obj), type, (sval))
|
220
|
+
#define RTYPEDDATA_DATA(obj) DATA_PTR(obj)
|
221
|
+
#define RUBY_DEFAULT_FREE xfree
|
222
|
+
#endif
|
223
|
+
|
176
224
|
/* a new function in ruby 1.9.3.
|
177
225
|
* define a compatible macro for ruby 1.9.2 or lower.
|
178
226
|
*/
|
@@ -184,6 +232,21 @@ static inline volatile VALUE *rb_gc_guarded_ptr(volatile VALUE *ptr) {return ptr
|
|
184
232
|
#endif
|
185
233
|
#endif
|
186
234
|
|
235
|
+
/* new macros in ruby 2.1.0
|
236
|
+
*/
|
237
|
+
#ifndef RARRAY_AREF
|
238
|
+
#define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
|
239
|
+
#endif
|
240
|
+
#ifndef RARRAY_CONST_PTR
|
241
|
+
#define RARRAY_CONST_PTR(a) RARRAY_PTR(a)
|
242
|
+
#endif
|
243
|
+
#ifndef RB_OBJ_WRITE
|
244
|
+
#define RB_OBJ_WRITE(a, slot, b) do {*(slot) = (b);} while (0)
|
245
|
+
#endif
|
246
|
+
#ifndef RB_OBJ_WRITTEN
|
247
|
+
#define RB_OBJ_WRITTEN(a, oldv, b) do {(void)oldv;} while (0)
|
248
|
+
#endif
|
249
|
+
|
187
250
|
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) || defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
188
251
|
#define NATIVE_THREAD_WITH_GVL 1
|
189
252
|
#endif
|
@@ -270,6 +333,8 @@ static ALWAYS_INLINE char *to_charptr(OraText *c)
|
|
270
333
|
#define RSTRING_ORATEXT(obj) TO_ORATEXT(RSTRING_PTR(obj))
|
271
334
|
#define rb_str_new2_ora(str) rb_str_new2(TO_CHARPTR(str))
|
272
335
|
|
336
|
+
#define TO_BIND(obj) ((oci8_bind_t *)oci8_check_typeddata((obj), &oci8_bind_data_type, 1))
|
337
|
+
|
273
338
|
/*
|
274
339
|
* prevent rdoc from gathering the specified method.
|
275
340
|
*/
|
@@ -282,23 +347,22 @@ typedef struct {
|
|
282
347
|
char buf[1];
|
283
348
|
} oci8_vstr_t;
|
284
349
|
|
285
|
-
typedef struct
|
286
|
-
typedef struct
|
350
|
+
typedef struct oci8_handle_data_type oci8_handle_data_type_t;
|
351
|
+
typedef struct oci8_bind_data_type oci8_bind_data_type_t;
|
287
352
|
|
288
353
|
typedef struct oci8_base oci8_base_t;
|
289
354
|
typedef struct oci8_bind oci8_bind_t;
|
290
355
|
|
291
356
|
/* The virtual method table of oci8_base_t */
|
292
|
-
struct
|
293
|
-
|
357
|
+
struct oci8_handle_data_type {
|
358
|
+
rb_data_type_t rb_data_type;
|
294
359
|
void (*free)(oci8_base_t *base);
|
295
360
|
size_t size;
|
296
|
-
void (*init)(oci8_base_t *base);
|
297
361
|
};
|
298
362
|
|
299
363
|
/* The virtual method table of oci8_bind_t */
|
300
|
-
struct
|
301
|
-
|
364
|
+
struct oci8_bind_data_type {
|
365
|
+
oci8_handle_data_type_t base;
|
302
366
|
VALUE (*get)(oci8_bind_t *obind, void *data, void *null_struct);
|
303
367
|
void (*set)(oci8_bind_t *obind, void *data, void **null_structp, VALUE val);
|
304
368
|
void (*init)(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length);
|
@@ -311,12 +375,11 @@ struct oci8_bind_vtable {
|
|
311
375
|
/* Class structure implemented by C language.
|
312
376
|
* oci8_base_t represents OCIHandle and its subclasses.
|
313
377
|
*
|
314
|
-
* The vptr member points to a virtual method table.
|
315
|
-
* See: http://en.wikipedia.org/wiki/Virtual_method_table
|
316
378
|
*/
|
317
379
|
struct oci8_base {
|
318
|
-
const
|
380
|
+
const oci8_handle_data_type_t *data_type;
|
319
381
|
ub4 type;
|
382
|
+
ub1 closed;
|
320
383
|
union {
|
321
384
|
dvoid *ptr;
|
322
385
|
OCISvcCtx *svc;
|
@@ -397,19 +460,6 @@ typedef struct {
|
|
397
460
|
ub2 *alenp;
|
398
461
|
} oci8_exec_sql_var_t;
|
399
462
|
|
400
|
-
#define Check_Handle(obj, klass, hp) do { \
|
401
|
-
if (!rb_obj_is_kind_of(obj, klass)) { \
|
402
|
-
rb_raise(rb_eTypeError, "invalid argument %s (expect %s)", rb_class2name(CLASS_OF(obj)), rb_class2name(klass)); \
|
403
|
-
} \
|
404
|
-
Data_Get_Struct(obj, oci8_base_t, hp); \
|
405
|
-
} while (0)
|
406
|
-
|
407
|
-
#define Check_Object(obj, klass) do {\
|
408
|
-
if (!rb_obj_is_kind_of(obj, klass)) { \
|
409
|
-
rb_raise(rb_eTypeError, "invalid argument %s (expect %s)", rb_class2name(CLASS_OF(obj)), rb_class2name(klass)); \
|
410
|
-
} \
|
411
|
-
} while (0)
|
412
|
-
|
413
463
|
#define oci8_raise(err, status, stmt) oci8_do_raise(err, status, stmt, __FILE__, __LINE__)
|
414
464
|
#define oci8_env_raise(err, status) oci8_do_env_raise(err, status, __FILE__, __LINE__)
|
415
465
|
#define oci8_raise_init_error() oci8_do_raise_init_error(__FILE__, __LINE__)
|
@@ -462,7 +512,6 @@ void Init_oci8_env(void);
|
|
462
512
|
extern ID oci8_id_at_last_error;
|
463
513
|
extern ID oci8_id_get;
|
464
514
|
extern ID oci8_id_set;
|
465
|
-
extern ID oci8_id_oci8_vtable;
|
466
515
|
#ifdef CHAR_IS_NOT_A_SHORTCUT_TO_ID
|
467
516
|
extern ID oci8_id_add_op; /* ID of the addition operator '+' */
|
468
517
|
extern ID oci8_id_sub_op; /* ID of the subtraction operator '-' */
|
@@ -477,9 +526,9 @@ extern ID oci8_id_div_op; /* ID of the division operator '/' */
|
|
477
526
|
extern int oci8_in_finalizer;
|
478
527
|
extern VALUE oci8_cOCIHandle;
|
479
528
|
void oci8_base_free(oci8_base_t *base);
|
480
|
-
VALUE oci8_define_class(const char *name,
|
481
|
-
VALUE oci8_define_class_under(VALUE outer, const char *name,
|
482
|
-
VALUE oci8_define_bind_class(const char *name, const
|
529
|
+
VALUE oci8_define_class(const char *name, const oci8_handle_data_type_t *data_type, VALUE (*alloc_func)(VALUE));
|
530
|
+
VALUE oci8_define_class_under(VALUE outer, const char *name, const oci8_handle_data_type_t *data_type, VALUE (*alloc_func)(VALUE));
|
531
|
+
VALUE oci8_define_bind_class(const char *name, const oci8_bind_data_type_t *data_type, VALUE (*alloc_func)(VALUE));
|
483
532
|
void oci8_link_to_parent(oci8_base_t *base, oci8_base_t *parent);
|
484
533
|
void oci8_unlink_from_parent(oci8_base_t *base);
|
485
534
|
sword oci8_call_without_gvl(oci8_svcctx_t *svcctx, void *(*func)(void *), void *data);
|
@@ -487,7 +536,7 @@ sword oci8_exec_sql(oci8_svcctx_t *svcctx, const char *sql_text, ub4 num_define_
|
|
487
536
|
#if defined RUNTIME_API_CHECK
|
488
537
|
void *oci8_find_symbol(const char *symbol_name);
|
489
538
|
#endif
|
490
|
-
|
539
|
+
void *oci8_check_typeddata(VALUE obj, const oci8_handle_data_type_t *data_type, int error_if_closed);
|
491
540
|
|
492
541
|
/* error.c */
|
493
542
|
extern VALUE eOCIException;
|
@@ -501,7 +550,11 @@ NORETURN(void oci8_do_raise_by_msgno(ub4 msgno, const char *default_msg, const c
|
|
501
550
|
void oci8_check_error_(sword status, oci8_base_t *base, OCIStmt *stmthp, const char *file, int line);
|
502
551
|
|
503
552
|
/* ocihandle.c */
|
553
|
+
extern const oci8_handle_data_type_t oci8_handle_data_type;
|
504
554
|
void Init_oci8_handle(void);
|
555
|
+
VALUE oci8_allocate_typeddata(VALUE klass, const oci8_handle_data_type_t *data_type);
|
556
|
+
void oci8_handle_cleanup(void *ptr);
|
557
|
+
size_t oci8_handle_size(const void *ptr);
|
505
558
|
|
506
559
|
/* oci8.c */
|
507
560
|
void Init_oci8(VALUE *out);
|
@@ -515,7 +568,6 @@ void oci8_check_pid_consistency(oci8_svcctx_t *svcctx);
|
|
515
568
|
void Init_oci8_connection_pool(VALUE cOCI8);
|
516
569
|
|
517
570
|
/* stmt.c */
|
518
|
-
extern VALUE cOCIStmt;
|
519
571
|
void Init_oci8_stmt(VALUE cOCI8);
|
520
572
|
|
521
573
|
/* bind.c */
|
@@ -523,13 +575,13 @@ typedef struct {
|
|
523
575
|
void *hp;
|
524
576
|
VALUE obj;
|
525
577
|
} oci8_hp_obj_t;
|
578
|
+
extern const oci8_handle_data_type_t oci8_bind_data_type;
|
526
579
|
void oci8_bind_free(oci8_base_t *base);
|
527
580
|
void oci8_bind_hp_obj_mark(oci8_base_t *base);
|
528
581
|
void Init_oci8_bind(VALUE cOCI8BindTypeBase);
|
529
|
-
oci8_bind_t *oci8_get_bind(VALUE obj);
|
530
582
|
|
531
583
|
/* metadata.c */
|
532
|
-
extern
|
584
|
+
extern const oci8_handle_data_type_t oci8_metadata_base_data_type;
|
533
585
|
void Init_oci8_metadata(VALUE cOCI8);
|
534
586
|
VALUE oci8_metadata_create(OCIParam *parmhp, VALUE svc, VALUE parent);
|
535
587
|
|
@@ -580,7 +632,6 @@ VALUE oci8_make_interval_ds(OCIInterval *s);
|
|
580
632
|
void Init_oci_object(VALUE mOCI);
|
581
633
|
|
582
634
|
/* attr.c */
|
583
|
-
VALUE oci8_get_ub2_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp);
|
584
635
|
VALUE oci8_get_rowid_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp);
|
585
636
|
|
586
637
|
/* encoding.c */
|
@@ -591,6 +642,10 @@ extern int oci8_nls_ratio;
|
|
591
642
|
/* win32.c */
|
592
643
|
void Init_oci8_win32(VALUE cOCI8);
|
593
644
|
|
645
|
+
/* hook_funcs.c */
|
646
|
+
void oci8_install_hook_functions(void);
|
647
|
+
void oci8_shutdown_sockets(void);
|
648
|
+
|
594
649
|
#ifdef HAVE_TYPE_RB_ENCODING
|
595
650
|
extern rb_encoding *oci8_encoding;
|
596
651
|
|
data/ext/oci8/oci8lib.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2002-
|
3
|
+
* Copyright (C) 2002-2015 Kubo Takehiro <kubo@jiubao.org>
|
4
4
|
*/
|
5
5
|
|
6
6
|
#include "oci8.h"
|
@@ -11,7 +11,6 @@
|
|
11
11
|
ID oci8_id_at_last_error;
|
12
12
|
ID oci8_id_get;
|
13
13
|
ID oci8_id_set;
|
14
|
-
ID oci8_id_oci8_vtable;
|
15
14
|
#ifdef CHAR_IS_NOT_A_SHORTCUT_TO_ID
|
16
15
|
ID oci8_id_add_op;
|
17
16
|
ID oci8_id_sub_op;
|
@@ -39,8 +38,8 @@ void oci8_base_free(oci8_base_t *base)
|
|
39
38
|
oci8_base_free(base->children);
|
40
39
|
}
|
41
40
|
oci8_unlink_from_parent(base);
|
42
|
-
if (base->
|
43
|
-
base->
|
41
|
+
if (base->data_type->free != NULL)
|
42
|
+
base->data_type->free(base);
|
44
43
|
if (base->type >= OCI_DTYPE_FIRST) {
|
45
44
|
OCIDescriptorFree(base->hp.ptr, base->type);
|
46
45
|
} else if (base->type == OCI_HTYPE_BIND || base->type == OCI_HTYPE_DEFINE) {
|
@@ -51,6 +50,7 @@ void oci8_base_free(oci8_base_t *base)
|
|
51
50
|
OCIHandleFree(base->hp.ptr, base->type);
|
52
51
|
}
|
53
52
|
base->type = 0;
|
53
|
+
base->closed = 1;
|
54
54
|
base->hp.ptr = NULL;
|
55
55
|
}
|
56
56
|
|
@@ -58,9 +58,17 @@ void oci8_base_free(oci8_base_t *base)
|
|
58
58
|
static void at_exit_func(VALUE val)
|
59
59
|
{
|
60
60
|
oci8_in_finalizer = 1;
|
61
|
+
#ifdef HAVE_PLTHOOK
|
62
|
+
oci8_shutdown_sockets();
|
63
|
+
#endif
|
61
64
|
}
|
62
65
|
#endif
|
63
66
|
|
67
|
+
static VALUE bind_base_alloc(VALUE klass)
|
68
|
+
{
|
69
|
+
rb_raise(rb_eNameError, "private method `new' called for %s:Class", rb_class2name(klass));
|
70
|
+
}
|
71
|
+
|
64
72
|
#ifdef _WIN32
|
65
73
|
__declspec(dllexport)
|
66
74
|
#endif
|
@@ -88,7 +96,6 @@ Init_oci8lib()
|
|
88
96
|
oci8_id_at_last_error = rb_intern("@last_error");
|
89
97
|
oci8_id_get = rb_intern("get");
|
90
98
|
oci8_id_set = rb_intern("set");
|
91
|
-
oci8_id_oci8_vtable = rb_intern("__oci8_vtable__");
|
92
99
|
#ifdef CHAR_IS_NOT_A_SHORTCUT_TO_ID
|
93
100
|
oci8_id_add_op = rb_intern("+");
|
94
101
|
oci8_id_sub_op = rb_intern("-");
|
@@ -115,7 +122,7 @@ Init_oci8lib()
|
|
115
122
|
/* OCI8::BindType module */
|
116
123
|
mOCI8BindType = rb_define_module_under(cOCI8, "BindType");
|
117
124
|
/* OCI8::BindType::Base class */
|
118
|
-
cOCI8BindTypeBase =
|
125
|
+
cOCI8BindTypeBase = oci8_define_class_under(mOCI8BindType, "Base", &oci8_bind_data_type, bind_base_alloc);
|
119
126
|
|
120
127
|
/* Handle */
|
121
128
|
Init_oci8_bind(cOCI8BindTypeBase);
|
@@ -149,33 +156,39 @@ Init_oci8lib()
|
|
149
156
|
#endif
|
150
157
|
}
|
151
158
|
|
152
|
-
VALUE oci8_define_class(const char *name,
|
159
|
+
VALUE oci8_define_class(const char *name, const oci8_handle_data_type_t *data_type, VALUE (*alloc_func)(VALUE))
|
153
160
|
{
|
154
|
-
VALUE
|
155
|
-
VALUE
|
156
|
-
|
161
|
+
VALUE parent_class = rb_eval_string(data_type->rb_data_type.parent->wrap_struct_name);
|
162
|
+
VALUE klass = rb_define_class(name, parent_class);
|
163
|
+
|
164
|
+
rb_define_alloc_func(klass, alloc_func);
|
157
165
|
return klass;
|
158
166
|
}
|
159
167
|
|
160
|
-
VALUE oci8_define_class_under(VALUE outer, const char *name,
|
168
|
+
VALUE oci8_define_class_under(VALUE outer, const char *name, const oci8_handle_data_type_t *data_type, VALUE (*alloc_func)(VALUE))
|
161
169
|
{
|
162
|
-
VALUE
|
163
|
-
VALUE
|
164
|
-
|
170
|
+
VALUE parent_class = rb_eval_string(data_type->rb_data_type.parent->wrap_struct_name);
|
171
|
+
VALUE klass = rb_define_class_under(outer, name, parent_class);
|
172
|
+
|
173
|
+
rb_define_alloc_func(klass, alloc_func);
|
165
174
|
return klass;
|
166
175
|
}
|
167
176
|
|
168
|
-
VALUE oci8_define_bind_class(const char *name, const
|
177
|
+
VALUE oci8_define_bind_class(const char *name, const oci8_bind_data_type_t *data_type, VALUE (*alloc_func)(VALUE))
|
169
178
|
{
|
170
|
-
VALUE
|
171
|
-
VALUE
|
172
|
-
|
179
|
+
VALUE parent_class = rb_eval_string(data_type->base.rb_data_type.parent->wrap_struct_name);
|
180
|
+
VALUE klass = rb_define_class_under(mOCI8BindType, name, parent_class);
|
181
|
+
|
182
|
+
rb_define_alloc_func(klass, alloc_func);
|
173
183
|
return klass;
|
174
184
|
}
|
175
185
|
|
176
186
|
void oci8_link_to_parent(oci8_base_t *base, oci8_base_t *parent)
|
177
187
|
{
|
188
|
+
VALUE old_parent = Qundef;
|
189
|
+
|
178
190
|
if (base->parent != NULL) {
|
191
|
+
old_parent = base->parent->self;
|
179
192
|
oci8_unlink_from_parent(base);
|
180
193
|
}
|
181
194
|
if (parent->children == NULL) {
|
@@ -187,6 +200,8 @@ void oci8_link_to_parent(oci8_base_t *base, oci8_base_t *parent)
|
|
187
200
|
parent->children->prev = base;
|
188
201
|
}
|
189
202
|
base->parent = parent;
|
203
|
+
RB_OBJ_WRITTEN(parent->self, Qundef, base->self);
|
204
|
+
RB_OBJ_WRITTEN(base->self, old_parent, parent->self);
|
190
205
|
}
|
191
206
|
|
192
207
|
void oci8_unlink_from_parent(oci8_base_t *base)
|
@@ -246,7 +261,7 @@ static VALUE protected_call(VALUE data)
|
|
246
261
|
if (!NIL_P(parg->svcctx->executing_thread)) {
|
247
262
|
rb_raise(rb_eRuntimeError, "executing in another thread");
|
248
263
|
}
|
249
|
-
parg->svcctx->executing_thread
|
264
|
+
RB_OBJ_WRITE(parg->svcctx->base.self, &parg->svcctx->executing_thread, rb_thread_current());
|
250
265
|
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
251
266
|
rv = (VALUE)rb_thread_call_without_gvl(parg->func, parg->data, oci8_unblock_func, parg->svcctx);
|
252
267
|
#else
|
@@ -527,7 +542,7 @@ void *oci8_find_symbol(const char *symbol_name)
|
|
527
542
|
};
|
528
543
|
#define NUM_SONAMES (sizeof(sonames)/sizeof(sonames[0]))
|
529
544
|
size_t idx;
|
530
|
-
VALUE err = rb_ary_new();
|
545
|
+
volatile VALUE err = rb_ary_new();
|
531
546
|
|
532
547
|
#ifdef _AIX
|
533
548
|
#define DLOPEN_FLAG (RTLD_LAZY|RTLD_GLOBAL|RTLD_MEMBER)
|
@@ -543,10 +558,11 @@ void *oci8_find_symbol(const char *symbol_name)
|
|
543
558
|
}
|
544
559
|
if (handle == NULL) {
|
545
560
|
VALUE msg;
|
561
|
+
const char *ary = RARRAY_CONST_PTR(err);
|
546
562
|
|
547
563
|
msg = rb_str_buf_new(NUM_SONAMES * 50);
|
548
564
|
for (idx = 0; idx < NUM_SONAMES; idx++) {
|
549
|
-
const char *errmsg = RSTRING_PTR(
|
565
|
+
const char *errmsg = RSTRING_PTR(arr[idx]);
|
550
566
|
if (idx != 0) {
|
551
567
|
rb_str_buf_cat2(msg, " ");
|
552
568
|
}
|
@@ -557,7 +573,7 @@ void *oci8_find_symbol(const char *symbol_name)
|
|
557
573
|
rb_str_buf_cat2(msg, sonames[idx]);
|
558
574
|
rb_str_buf_cat2(msg, ": ");
|
559
575
|
}
|
560
|
-
rb_str_buf_append(msg,
|
576
|
+
rb_str_buf_append(msg, arr[idx]);
|
561
577
|
rb_str_buf_cat2(msg, ";");
|
562
578
|
}
|
563
579
|
rb_exc_raise(rb_exc_new3(rb_eLoadError, msg));
|
@@ -568,16 +584,31 @@ void *oci8_find_symbol(const char *symbol_name)
|
|
568
584
|
}
|
569
585
|
#endif /* RUNTIME_API_CHECK */
|
570
586
|
|
571
|
-
|
587
|
+
void *oci8_check_typeddata(VALUE obj, const oci8_handle_data_type_t *data_type, int error_if_closed)
|
572
588
|
{
|
589
|
+
#ifdef HAVE_RB_DATA_TYPE_T_FUNCTION
|
590
|
+
oci8_base_t *hp = Check_TypedStruct(obj, &data_type->rb_data_type);
|
591
|
+
#else
|
573
592
|
oci8_base_t *hp;
|
593
|
+
const char *expected_type_name = data_type->rb_data_type.wrap_struct_name;
|
594
|
+
const rb_data_type_t *rb_data_type;
|
595
|
+
const rb_data_type_t *expected_rb_data_type = &data_type->rb_data_type;
|
574
596
|
|
575
|
-
if (!rb_obj_is_kind_of(obj,
|
576
|
-
rb_raise(rb_eTypeError, "
|
577
|
-
rb_obj_classname(obj),
|
597
|
+
if (TYPE(obj) != T_DATA || !rb_obj_is_kind_of(obj, oci8_cOCIHandle)) {
|
598
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
|
599
|
+
rb_obj_classname(obj), expected_type_name);
|
578
600
|
}
|
579
|
-
|
580
|
-
|
601
|
+
hp = DATA_PTR(obj);
|
602
|
+
rb_data_type = &hp->data_type->rb_data_type;
|
603
|
+
while (rb_data_type != expected_rb_data_type) {
|
604
|
+
if (rb_data_type == NULL) {
|
605
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
|
606
|
+
rb_obj_classname(obj), expected_type_name);
|
607
|
+
}
|
608
|
+
rb_data_type = rb_data_type->parent;
|
609
|
+
}
|
610
|
+
#endif
|
611
|
+
if (error_if_closed && hp->closed) {
|
581
612
|
rb_raise(eOCIException, "%s was already closed.",
|
582
613
|
rb_obj_classname(obj));
|
583
614
|
}
|