ruby-oci8 2.0.4 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +158 -1
- data/Makefile +1 -3
- data/NEWS +70 -0
- data/VERSION +1 -1
- data/dist-files +1 -0
- data/ext/oci8/apiwrap.yml +284 -138
- data/ext/oci8/attr.c +1 -1
- data/ext/oci8/bind.c +36 -9
- data/ext/oci8/env.c +59 -33
- data/ext/oci8/error.c +4 -0
- data/ext/oci8/extconf.rb +15 -1
- data/ext/oci8/lob.c +44 -0
- data/ext/oci8/metadata.c +1 -1
- data/ext/oci8/object.c +55 -0
- data/ext/oci8/oci8.c +9 -14
- data/ext/oci8/oci8.h +39 -25
- data/ext/oci8/oci8lib.c +38 -3
- data/ext/oci8/ocidatetime.c +69 -80
- data/ext/oci8/ocihandle.c +9 -1
- data/ext/oci8/ocinumber.c +40 -18
- data/ext/oci8/oraconf.rb +126 -126
- data/ext/oci8/oradate.c +2 -2
- data/ext/oci8/oranumber_util.c +38 -1
- data/ext/oci8/stmt.c +28 -22
- data/ext/oci8/win32.c +9 -3
- data/lib/oci8.rb.in +13 -2
- data/lib/oci8/.document +1 -0
- data/lib/oci8/bindtype.rb +16 -3
- data/lib/oci8/datetime.rb +14 -6
- data/lib/oci8/encoding-init.rb +6 -1
- data/lib/oci8/encoding.yml +2 -2
- data/lib/oci8/object.rb +28 -9
- data/lib/oci8/oci8.rb +22 -6
- data/lib/oci8/properties.rb +50 -0
- data/test/test_break.rb +6 -7
- data/test/test_oranumber.rb +96 -5
- metadata +7 -4
data/ext/oci8/attr.c
CHANGED
data/ext/oci8/bind.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
* bind.c
|
4
4
|
*
|
5
5
|
* $Author: kubo $
|
6
|
-
* $Date:
|
6
|
+
* $Date: 2010-12-14 20:30:44 +0900 (火, 14 12月 2010) $
|
7
7
|
*
|
8
8
|
* Copyright (C) 2002-2008 KUBO Takehiro <kubo@jiubao.org>
|
9
9
|
*/
|
@@ -14,7 +14,7 @@ static ID id_bind_type;
|
|
14
14
|
static VALUE cOCI8BindTypeBase;
|
15
15
|
|
16
16
|
/*
|
17
|
-
*
|
17
|
+
* bind_char and bind_nchar
|
18
18
|
*/
|
19
19
|
static VALUE bind_string_get(oci8_bind_t *obind, void *data, void *null_struct)
|
20
20
|
{
|
@@ -54,7 +54,7 @@ static void bind_string_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE len
|
|
54
54
|
obind->alloc_sz = (sz + (sizeof(sb4) - 1)) & ~(sizeof(sb4) - 1);
|
55
55
|
}
|
56
56
|
|
57
|
-
static const oci8_bind_class_t
|
57
|
+
static const oci8_bind_class_t bind_char_class = {
|
58
58
|
{
|
59
59
|
NULL,
|
60
60
|
oci8_bind_free,
|
@@ -70,6 +70,23 @@ static const oci8_bind_class_t bind_string_class = {
|
|
70
70
|
SQLT_LVC
|
71
71
|
};
|
72
72
|
|
73
|
+
static const oci8_bind_class_t bind_nchar_class = {
|
74
|
+
{
|
75
|
+
NULL,
|
76
|
+
oci8_bind_free,
|
77
|
+
sizeof(oci8_bind_t)
|
78
|
+
},
|
79
|
+
bind_string_get,
|
80
|
+
bind_string_set,
|
81
|
+
bind_string_init,
|
82
|
+
NULL,
|
83
|
+
NULL,
|
84
|
+
NULL,
|
85
|
+
NULL,
|
86
|
+
SQLT_LVC,
|
87
|
+
SQLCS_NCHAR,
|
88
|
+
};
|
89
|
+
|
73
90
|
/*
|
74
91
|
* bind_raw
|
75
92
|
*/
|
@@ -79,6 +96,18 @@ static VALUE bind_raw_get(oci8_bind_t *obind, void *data, void *null_struct)
|
|
79
96
|
return rb_str_new(vstr->buf, vstr->size);
|
80
97
|
}
|
81
98
|
|
99
|
+
static void bind_raw_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
100
|
+
{
|
101
|
+
oci8_vstr_t *vstr = (oci8_vstr_t *)data;
|
102
|
+
|
103
|
+
StringValue(val);
|
104
|
+
if (RSTRING_LEN(val) > obind->value_sz - sizeof(vstr->size)) {
|
105
|
+
rb_raise(rb_eArgError, "too long String to set. (%ld for %d)", RSTRING_LEN(val), obind->value_sz - (sb4)sizeof(vstr->size));
|
106
|
+
}
|
107
|
+
memcpy(vstr->buf, RSTRING_PTR(val), RSTRING_LEN(val));
|
108
|
+
vstr->size = RSTRING_LEN(val);
|
109
|
+
}
|
110
|
+
|
82
111
|
static const oci8_bind_class_t bind_raw_class = {
|
83
112
|
{
|
84
113
|
NULL,
|
@@ -86,7 +115,7 @@ static const oci8_bind_class_t bind_raw_class = {
|
|
86
115
|
sizeof(oci8_bind_t)
|
87
116
|
},
|
88
117
|
bind_raw_get,
|
89
|
-
|
118
|
+
bind_raw_set,
|
90
119
|
bind_string_init,
|
91
120
|
NULL,
|
92
121
|
NULL,
|
@@ -303,10 +332,6 @@ static VALUE oci8_bind_get(VALUE self)
|
|
303
332
|
if (NIL_P(obind->tdo)) {
|
304
333
|
if (obind->u.inds[idx] != 0)
|
305
334
|
return Qnil;
|
306
|
-
} else {
|
307
|
-
null_structp = &obind->u.null_structs[idx];
|
308
|
-
if (*(OCIInd*)*null_structp != 0)
|
309
|
-
return Qnil;
|
310
335
|
}
|
311
336
|
return obc->get(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp);
|
312
337
|
}
|
@@ -350,6 +375,7 @@ static VALUE oci8_bind_set(VALUE self, VALUE val)
|
|
350
375
|
obind->u.inds[idx] = 0;
|
351
376
|
} else {
|
352
377
|
null_structp = &obind->u.null_structs[idx];
|
378
|
+
*(OCIInd*)obind->u.null_structs[idx] = 0;
|
353
379
|
}
|
354
380
|
obc->set(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp, val);
|
355
381
|
}
|
@@ -451,7 +477,8 @@ void Init_oci8_bind(VALUE klass)
|
|
451
477
|
rb_define_method(cOCI8BindTypeBase, "set", oci8_bind_set, 1);
|
452
478
|
|
453
479
|
/* register primitive data types. */
|
454
|
-
oci8_define_bind_class("
|
480
|
+
oci8_define_bind_class("CHAR", &bind_char_class);
|
481
|
+
oci8_define_bind_class("NCHAR", &bind_nchar_class);
|
455
482
|
oci8_define_bind_class("RAW", &bind_raw_class);
|
456
483
|
#ifdef USE_DYNAMIC_FETCH
|
457
484
|
oci8_define_bind_class("Long", &bind_long_class);
|
data/ext/oci8/env.c
CHANGED
@@ -2,28 +2,17 @@
|
|
2
2
|
/*
|
3
3
|
* env.c - part of ruby-oci8
|
4
4
|
*
|
5
|
-
* Copyright (C) 2002-
|
5
|
+
* Copyright (C) 2002-2011 KUBO Takehiro <kubo@jiubao.org>
|
6
6
|
*/
|
7
7
|
#include "oci8.h"
|
8
8
|
|
9
|
-
#if
|
10
|
-
/* ruby_setenv for workaround ruby 1.8.4 */
|
11
|
-
#include <util.h>
|
12
|
-
#endif
|
13
|
-
|
14
|
-
#ifdef _WIN32
|
15
|
-
#ifdef HAVE_RUBY_WIN32_H
|
16
|
-
#include <ruby/win32.h> /* for rb_w32_getenv() */
|
17
|
-
#else
|
18
|
-
#include <win32/win32.h> /* for rb_w32_getenv() */
|
19
|
-
#endif
|
20
|
-
#endif
|
21
|
-
|
22
|
-
#ifdef HAVE_RUBY_UTIL_H
|
9
|
+
#if defined(HAVE_RUBY_UTIL_H)
|
23
10
|
#include <ruby/util.h>
|
11
|
+
#elif defined(HAVE_UTIL_H)
|
12
|
+
#include <util.h>
|
24
13
|
#endif
|
25
14
|
|
26
|
-
#ifdef
|
15
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
27
16
|
ub4 oci8_env_mode = OCI_OBJECT | OCI_THREADED;
|
28
17
|
#else
|
29
18
|
ub4 oci8_env_mode = OCI_OBJECT;
|
@@ -42,23 +31,53 @@ OCIEnv *oci8_make_envhp(void)
|
|
42
31
|
return oci8_global_envhp;
|
43
32
|
}
|
44
33
|
|
45
|
-
#ifdef
|
34
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
46
35
|
/*
|
47
36
|
* oci8_errhp is a thread local object in ruby 1.9.
|
48
37
|
*/
|
49
38
|
|
50
39
|
oci8_tls_key_t oci8_tls_key; /* native thread key */
|
51
|
-
static ID id_thread_key; /* ruby's thread key */
|
52
40
|
|
53
|
-
|
41
|
+
/* This function is called on the native thread termination
|
42
|
+
* if the thread local errhp is not null.
|
43
|
+
*/
|
44
|
+
static void oci8_free_errhp(void *errhp)
|
54
45
|
{
|
55
46
|
OCIHandleFree(errhp, OCI_HTYPE_ERROR);
|
56
47
|
}
|
57
48
|
|
49
|
+
#ifdef _WIN32
|
50
|
+
static int dllmain_is_called;
|
51
|
+
|
52
|
+
__declspec(dllexport)
|
53
|
+
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
54
|
+
{
|
55
|
+
void *errhp;
|
56
|
+
|
57
|
+
switch (fdwReason) {
|
58
|
+
case DLL_PROCESS_ATTACH:
|
59
|
+
dllmain_is_called = 1;
|
60
|
+
break;
|
61
|
+
case DLL_THREAD_ATTACH:
|
62
|
+
/* do nothing */
|
63
|
+
break;
|
64
|
+
case DLL_THREAD_DETACH:
|
65
|
+
errhp = oci8_tls_get(oci8_tls_key);
|
66
|
+
if (errhp != NULL) {
|
67
|
+
oci8_free_errhp(errhp);
|
68
|
+
}
|
69
|
+
break;
|
70
|
+
case DLL_PROCESS_DETACH:
|
71
|
+
/* do nothing */
|
72
|
+
break;
|
73
|
+
}
|
74
|
+
return TRUE;
|
75
|
+
}
|
76
|
+
#endif
|
77
|
+
|
58
78
|
OCIError *oci8_make_errhp(void)
|
59
79
|
{
|
60
80
|
OCIError *errhp;
|
61
|
-
VALUE obj;
|
62
81
|
sword rv;
|
63
82
|
|
64
83
|
/* create a new errhp. */
|
@@ -66,15 +85,9 @@ OCIError *oci8_make_errhp(void)
|
|
66
85
|
if (rv != OCI_SUCCESS) {
|
67
86
|
oci8_env_raise(oci8_envhp, rv);
|
68
87
|
}
|
69
|
-
/*
|
70
|
-
*
|
88
|
+
/* Set the errhp to the thread local storage.
|
89
|
+
* It is freed by oci8_free_errhp().
|
71
90
|
*/
|
72
|
-
obj = Data_Wrap_Struct(rb_cObject, NULL, oci8_free_errhp, errhp);
|
73
|
-
/* set the ruby object to ruby's thread local storage to prevent
|
74
|
-
* it from being freed while the thread is available.
|
75
|
-
*/
|
76
|
-
rb_thread_local_aset(rb_thread_current(), id_thread_key, obj);
|
77
|
-
|
78
91
|
oci8_tls_set(oci8_tls_key, (void*)errhp);
|
79
92
|
return errhp;
|
80
93
|
}
|
@@ -97,11 +110,11 @@ OCIError *oci8_make_errhp(void)
|
|
97
110
|
|
98
111
|
void Init_oci8_env(void)
|
99
112
|
{
|
100
|
-
#ifdef
|
113
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
101
114
|
int error;
|
102
115
|
#endif
|
103
116
|
|
104
|
-
#if !defined(
|
117
|
+
#if !defined(HAVE_RB_THREAD_BLOCKING_REGION) && !defined(_WIN32)
|
105
118
|
/* workaround code.
|
106
119
|
*
|
107
120
|
* Some instant clients set the environment variables
|
@@ -147,9 +160,22 @@ void Init_oci8_env(void)
|
|
147
160
|
}
|
148
161
|
}
|
149
162
|
|
150
|
-
#ifdef
|
151
|
-
|
152
|
-
|
163
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
164
|
+
/* ruby 1.9 */
|
165
|
+
#if defined(_WIN32)
|
166
|
+
if (!dllmain_is_called) {
|
167
|
+
/* sanity check */
|
168
|
+
rb_raise(rb_eRuntimeError, "DllMain is not unexpectedly called. This causes resource leaks.");
|
169
|
+
}
|
170
|
+
oci8_tls_key = TlsAlloc();
|
171
|
+
if (oci8_tls_key == 0xFFFFFFFF) {
|
172
|
+
error = GetLastError();
|
173
|
+
} else {
|
174
|
+
error = 0;
|
175
|
+
}
|
176
|
+
#else
|
177
|
+
error = pthread_key_create(&oci8_tls_key, oci8_free_errhp);
|
178
|
+
#endif
|
153
179
|
if (error != 0) {
|
154
180
|
rb_raise(rb_eRuntimeError, "Cannot create thread local key (errno = %d)", error);
|
155
181
|
}
|
data/ext/oci8/error.c
CHANGED
data/ext/oci8/extconf.rb
CHANGED
@@ -105,12 +105,18 @@ have_func("localtime_r")
|
|
105
105
|
have_header("intern.h")
|
106
106
|
have_header("util.h")
|
107
107
|
# ruby 1.9 headers
|
108
|
+
have_header("ruby/util.h")
|
108
109
|
have_type('rb_encoding', ['ruby/ruby.h', 'ruby/encoding.h'])
|
109
110
|
|
110
111
|
# $! in C API
|
111
112
|
have_var("ruby_errinfo", "ruby.h") # ruby 1.8
|
112
113
|
have_func("rb_errinfo", "ruby.h") # ruby 1.9
|
113
114
|
|
115
|
+
have_type("rb_blocking_function_t", "ruby.h")
|
116
|
+
have_func("rb_set_end_proc", "ruby.h")
|
117
|
+
have_func("rb_class_superclass", "ruby.h")
|
118
|
+
have_func("rb_thread_blocking_region", "ruby.h")
|
119
|
+
|
114
120
|
# replace files
|
115
121
|
replace = {
|
116
122
|
'OCI8_CLIENT_VERSION' => oraconf.version,
|
@@ -120,14 +126,22 @@ replace = {
|
|
120
126
|
# make ruby script before running create_makefile.
|
121
127
|
replace_keyword(File.dirname(__FILE__) + '/../../lib/oci8.rb.in', '../../lib/oci8.rb', replace)
|
122
128
|
|
129
|
+
so_basename = 'oci8lib_'
|
130
|
+
if defined? RUBY_ENGINE and RUBY_ENGINE != 'ruby'
|
131
|
+
so_basename += RUBY_ENGINE
|
132
|
+
end
|
133
|
+
|
123
134
|
# Config::CONFIG["ruby_version"] indicates the ruby API version.
|
124
135
|
# 1.8 - ruby 1.8.x
|
125
136
|
# 1.9.1 - ruby 1.9.1 and 1.9.2
|
126
137
|
# 1.9.x - ruby 1.9.x future version which will break the API compatibility
|
127
|
-
so_basename
|
138
|
+
so_basename += Config::CONFIG["ruby_version"].gsub(/\W/, '')
|
128
139
|
|
129
140
|
$defs << "-DInit_oci8lib=Init_#{so_basename}"
|
130
141
|
$defs << "-Doci8lib=#{so_basename}"
|
142
|
+
if defined? RUBY_ENGINE and RUBY_ENGINE == 'rbx'
|
143
|
+
$defs << "-DCHAR_IS_NOT_A_SHORTCUT_TO_ID"
|
144
|
+
end
|
131
145
|
|
132
146
|
create_header()
|
133
147
|
|
data/ext/oci8/lob.c
CHANGED
@@ -64,15 +64,59 @@ VALUE oci8_make_bfile(oci8_svcctx_t *svcctx, OCILobLocator *s)
|
|
64
64
|
return oci8_make_lob(cOCI8BFILE, svcctx, s);
|
65
65
|
}
|
66
66
|
|
67
|
+
static void oci8_assign_lob(VALUE klass, oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
|
68
|
+
{
|
69
|
+
oci8_base_t *base = oci8_get_handle(lob, klass);
|
70
|
+
oci_lc(OCILobLocatorAssign_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, base->hp.lob, dest));
|
71
|
+
}
|
72
|
+
|
73
|
+
void oci8_assign_clob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
|
74
|
+
{
|
75
|
+
oci8_assign_lob(cOCI8CLOB, svcctx, lob, dest);
|
76
|
+
}
|
77
|
+
|
78
|
+
void oci8_assign_nclob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
|
79
|
+
{
|
80
|
+
oci8_assign_lob(cOCI8NCLOB, svcctx, lob, dest);
|
81
|
+
}
|
82
|
+
|
83
|
+
void oci8_assign_blob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
|
84
|
+
{
|
85
|
+
oci8_assign_lob(cOCI8BLOB, svcctx, lob, dest);
|
86
|
+
}
|
87
|
+
|
88
|
+
void oci8_assign_bfile(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
|
89
|
+
{
|
90
|
+
oci8_assign_lob(cOCI8BFILE, svcctx, lob, dest);
|
91
|
+
}
|
92
|
+
|
67
93
|
static void oci8_lob_mark(oci8_base_t *base)
|
68
94
|
{
|
69
95
|
oci8_lob_t *lob = (oci8_lob_t *)base;
|
70
96
|
rb_gc_mark(lob->svc);
|
71
97
|
}
|
72
98
|
|
99
|
+
static VALUE free_temp_lob(oci8_lob_t *lob)
|
100
|
+
{
|
101
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
|
102
|
+
|
103
|
+
OCILobFreeTemporary_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob);
|
104
|
+
return Qnil;
|
105
|
+
}
|
106
|
+
|
73
107
|
static void oci8_lob_free(oci8_base_t *base)
|
74
108
|
{
|
75
109
|
oci8_lob_t *lob = (oci8_lob_t *)base;
|
110
|
+
boolean is_temporary;
|
111
|
+
|
112
|
+
if (have_OCILobIsTemporary
|
113
|
+
&& OCILobIsTemporary(oci8_envhp, oci8_errhp, lob->base.hp.lob, &is_temporary) == OCI_SUCCESS
|
114
|
+
&& is_temporary) {
|
115
|
+
/* Exceptions in free_temp_lob() are ignored.
|
116
|
+
* oci8_lob_free() is called in GC. It must not raise an exception.
|
117
|
+
*/
|
118
|
+
rb_rescue(free_temp_lob, (VALUE)base, NULL, 0);
|
119
|
+
}
|
76
120
|
lob->svc = Qnil;
|
77
121
|
}
|
78
122
|
|
data/ext/oci8/metadata.c
CHANGED
@@ -38,7 +38,7 @@ VALUE oci8_metadata_create(OCIParam *parmhp, VALUE svc, VALUE parent)
|
|
38
38
|
VALUE klass;
|
39
39
|
VALUE obj;
|
40
40
|
|
41
|
-
|
41
|
+
p = oci8_get_handle(parent, oci8_cOCIHandle);
|
42
42
|
|
43
43
|
oci_lc(OCIAttrGet(parmhp, OCI_DTYPE_PARAM, &ptype, &size, OCI_ATTR_PTYPE, oci8_errhp));
|
44
44
|
klass = rb_hash_aref(ptype_to_class, INT2FIX(ptype));
|
data/ext/oci8/object.c
CHANGED
@@ -42,6 +42,10 @@ enum {
|
|
42
42
|
ATTR_BINARY_FLOAT,
|
43
43
|
ATTR_NAMED_TYPE,
|
44
44
|
ATTR_NAMED_COLLECTION,
|
45
|
+
ATTR_CLOB,
|
46
|
+
ATTR_NCLOB,
|
47
|
+
ATTR_BLOB,
|
48
|
+
ATTR_BFILE,
|
45
49
|
};
|
46
50
|
|
47
51
|
static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, OCIInd *ind);
|
@@ -198,6 +202,14 @@ static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *dat
|
|
198
202
|
rv = rb_funcall(tmp_obj, id_to_value, 0);
|
199
203
|
oci8_unlink_from_parent(&obj->base);
|
200
204
|
return rv;
|
205
|
+
case ATTR_CLOB:
|
206
|
+
return oci8_make_clob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
|
207
|
+
case ATTR_NCLOB:
|
208
|
+
return oci8_make_nclob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
|
209
|
+
case ATTR_BLOB:
|
210
|
+
return oci8_make_blob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
|
211
|
+
case ATTR_BFILE:
|
212
|
+
return oci8_make_bfile(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
|
201
213
|
default:
|
202
214
|
rb_raise(rb_eRuntimeError, "not supported datatype");
|
203
215
|
}
|
@@ -248,6 +260,25 @@ static VALUE oci8_named_type_set_attribute(VALUE self, VALUE datatype, VALUE typ
|
|
248
260
|
return Qnil;
|
249
261
|
}
|
250
262
|
|
263
|
+
static VALUE oci8_named_type_null_p(VALUE self)
|
264
|
+
{
|
265
|
+
void *data;
|
266
|
+
OCIInd *ind;
|
267
|
+
|
268
|
+
oci8_named_type_check_offset(self, INT2FIX(0), INT2FIX(0), sizeof(void*), &data, &ind);
|
269
|
+
return *ind ? Qtrue : Qfalse;
|
270
|
+
}
|
271
|
+
|
272
|
+
static VALUE oci8_named_type_set_null(VALUE self, VALUE val)
|
273
|
+
{
|
274
|
+
void *data;
|
275
|
+
OCIInd *ind;
|
276
|
+
|
277
|
+
oci8_named_type_check_offset(self, INT2FIX(0), INT2FIX(0), sizeof(void*), &data, &ind);
|
278
|
+
*ind = RTEST(val) ? -1 : 0;
|
279
|
+
return val;
|
280
|
+
}
|
281
|
+
|
251
282
|
typedef struct {
|
252
283
|
VALUE self;
|
253
284
|
VALUE datatype;
|
@@ -335,6 +366,11 @@ static VALUE oci8_named_coll_set_coll_element(VALUE self, VALUE datatype, VALUE
|
|
335
366
|
oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_NAMEDCOLLECTION, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr));
|
336
367
|
oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp));
|
337
368
|
break;
|
369
|
+
case ATTR_CLOB:
|
370
|
+
case ATTR_NCLOB:
|
371
|
+
case ATTR_BLOB:
|
372
|
+
case ATTR_BFILE:
|
373
|
+
rb_raise(rb_eRuntimeError, "Could not set LOB objects to collection types yet.");
|
338
374
|
default:
|
339
375
|
rb_raise(rb_eRuntimeError, "not supported datatype");
|
340
376
|
}
|
@@ -482,6 +518,18 @@ static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data
|
|
482
518
|
rb_funcall(tmp_obj, id_set_attributes, 1, val);
|
483
519
|
oci8_unlink_from_parent(&obj->base);
|
484
520
|
break;
|
521
|
+
case ATTR_CLOB:
|
522
|
+
oci8_assign_clob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
|
523
|
+
break;
|
524
|
+
case ATTR_NCLOB:
|
525
|
+
oci8_assign_nclob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
|
526
|
+
break;
|
527
|
+
case ATTR_BLOB:
|
528
|
+
oci8_assign_blob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
|
529
|
+
break;
|
530
|
+
case ATTR_BFILE:
|
531
|
+
oci8_assign_bfile(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
|
532
|
+
break;
|
485
533
|
default:
|
486
534
|
rb_raise(rb_eRuntimeError, "not supported datatype");
|
487
535
|
}
|
@@ -578,6 +626,7 @@ static void bind_named_type_init_elem(oci8_bind_t *obind, VALUE svc)
|
|
578
626
|
|
579
627
|
oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->base.hp.svc, tc, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, (dvoid**)obj->instancep));
|
580
628
|
oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, (dvoid*)*obj->instancep, (dvoid**)obj->null_structp));
|
629
|
+
*(OCIInd*)*obj->null_structp = -1;
|
581
630
|
} while (++idx < obind->maxar_sz);
|
582
631
|
}
|
583
632
|
|
@@ -615,6 +664,10 @@ void Init_oci_object(VALUE cOCI8)
|
|
615
664
|
rb_define_const(cOCI8TDO, "ATTR_BINARY_FLOAT", INT2FIX(ATTR_BINARY_FLOAT));
|
616
665
|
rb_define_const(cOCI8TDO, "ATTR_NAMED_TYPE", INT2FIX(ATTR_NAMED_TYPE));
|
617
666
|
rb_define_const(cOCI8TDO, "ATTR_NAMED_COLLECTION", INT2FIX(ATTR_NAMED_COLLECTION));
|
667
|
+
rb_define_const(cOCI8TDO, "ATTR_CLOB", INT2FIX(ATTR_CLOB));
|
668
|
+
rb_define_const(cOCI8TDO, "ATTR_NCLOB", INT2FIX(ATTR_NCLOB));
|
669
|
+
rb_define_const(cOCI8TDO, "ATTR_BLOB", INT2FIX(ATTR_BLOB));
|
670
|
+
rb_define_const(cOCI8TDO, "ATTR_BFILE", INT2FIX(ATTR_BFILE));
|
618
671
|
#define ALIGNMENT_OF(type) (size_t)&(((struct {char c; type t;}*)0)->t)
|
619
672
|
rb_define_const(cOCI8TDO, "SIZE_OF_POINTER", INT2FIX(sizeof(void *)));
|
620
673
|
rb_define_const(cOCI8TDO, "ALIGNMENT_OF_POINTER", INT2FIX(ALIGNMENT_OF(void *)));
|
@@ -633,6 +686,8 @@ void Init_oci_object(VALUE cOCI8)
|
|
633
686
|
rb_define_method(cOCI8NamedType, "tdo", oci8_named_type_tdo, 0);
|
634
687
|
rb_define_private_method(cOCI8NamedType, "get_attribute", oci8_named_type_get_attribute, 4);
|
635
688
|
rb_define_private_method(cOCI8NamedType, "set_attribute", oci8_named_type_set_attribute, 5);
|
689
|
+
rb_define_method(cOCI8NamedType, "null?", oci8_named_type_null_p, 0);
|
690
|
+
rb_define_method(cOCI8NamedType, "null=", oci8_named_type_set_null, 1);
|
636
691
|
|
637
692
|
/* OCI8::NamedCollection */
|
638
693
|
cOCI8NamedCollection = oci8_define_class_under(cOCI8, "NamedCollection", &oci8_named_type_class);
|