ruby-oci8 2.0.4 → 2.0.5
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 +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);
|