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