ruby-oci8 1.0.2
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 +569 -0
- data/Makefile +51 -0
- data/NEWS +322 -0
- data/README +415 -0
- data/VERSION +1 -0
- data/dist-files +70 -0
- data/doc/api.en.html +527 -0
- data/doc/api.en.rd +554 -0
- data/doc/api.ja.html +525 -0
- data/doc/api.ja.rd +557 -0
- data/doc/manual.css +35 -0
- data/ext/oci8/MANIFEST +22 -0
- data/ext/oci8/attr.c +415 -0
- data/ext/oci8/bind.c +194 -0
- data/ext/oci8/const.c +165 -0
- data/ext/oci8/define.c +53 -0
- data/ext/oci8/describe.c +81 -0
- data/ext/oci8/descriptor.c +39 -0
- data/ext/oci8/env.c +276 -0
- data/ext/oci8/error.c +234 -0
- data/ext/oci8/extconf.rb +118 -0
- data/ext/oci8/handle.c +262 -0
- data/ext/oci8/lob.c +386 -0
- data/ext/oci8/oci8.c +137 -0
- data/ext/oci8/oci8.h +345 -0
- data/ext/oci8/ocinumber.c +117 -0
- data/ext/oci8/oraconf.rb +1026 -0
- data/ext/oci8/oradate.c +426 -0
- data/ext/oci8/oranumber.c +445 -0
- data/ext/oci8/param.c +37 -0
- data/ext/oci8/post-config.rb +5 -0
- data/ext/oci8/server.c +182 -0
- data/ext/oci8/session.c +99 -0
- data/ext/oci8/stmt.c +624 -0
- data/ext/oci8/svcctx.c +229 -0
- data/lib/DBD/OCI8/OCI8.rb +549 -0
- data/lib/oci8.rb.in +1605 -0
- data/metaconfig +142 -0
- data/pre-distclean.rb +7 -0
- data/ruby-oci8.gemspec +54 -0
- data/ruby-oci8.spec +62 -0
- data/setup.rb +1331 -0
- data/support/README +4 -0
- data/support/runit/assert.rb +281 -0
- data/support/runit/cui/testrunner.rb +101 -0
- data/support/runit/error.rb +4 -0
- data/support/runit/method_mappable.rb +20 -0
- data/support/runit/robserver.rb +25 -0
- data/support/runit/setuppable.rb +15 -0
- data/support/runit/teardownable.rb +16 -0
- data/support/runit/testcase.rb +113 -0
- data/support/runit/testfailure.rb +25 -0
- data/support/runit/testresult.rb +121 -0
- data/support/runit/testsuite.rb +43 -0
- data/support/runit/version.rb +3 -0
- data/test/README +4 -0
- data/test/config.rb +129 -0
- data/test/test_all.rb +43 -0
- data/test/test_bind_raw.rb +53 -0
- data/test/test_bind_time.rb +191 -0
- data/test/test_break.rb +81 -0
- data/test/test_clob.rb +101 -0
- data/test/test_connstr.rb +80 -0
- data/test/test_dbi.rb +317 -0
- data/test/test_dbi_clob.rb +56 -0
- data/test/test_describe.rb +137 -0
- data/test/test_metadata.rb +243 -0
- data/test/test_oci8.rb +273 -0
- data/test/test_oradate.rb +263 -0
- data/test/test_oranumber.rb +149 -0
- metadata +118 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
/*
|
2
|
+
descriptor.c - part of ruby-oci8
|
3
|
+
|
4
|
+
Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
|
5
|
+
|
6
|
+
=begin
|
7
|
+
== OCIDescriptor
|
8
|
+
The abstract class of OCI descriptors.
|
9
|
+
=end
|
10
|
+
*/
|
11
|
+
#include "oci8.h"
|
12
|
+
|
13
|
+
/*
|
14
|
+
=begin
|
15
|
+
--- OCIDescriptor#attrGet(type)
|
16
|
+
:type
|
17
|
+
the type of attribute.
|
18
|
+
:return value
|
19
|
+
depends on argument ((|type|)).
|
20
|
+
|
21
|
+
See also ((<Attributes of Handles and Descriptors>)).
|
22
|
+
=end
|
23
|
+
*/
|
24
|
+
|
25
|
+
/*
|
26
|
+
=begin
|
27
|
+
--- OCIDescriptor#free()
|
28
|
+
explicitly free the OCI's data structure associated with this object.
|
29
|
+
This call will not free ruby's object itself, which wrap the OCI's data structure.
|
30
|
+
=end
|
31
|
+
*/
|
32
|
+
|
33
|
+
void Init_oci8_descriptor(void)
|
34
|
+
{
|
35
|
+
rb_define_method(cOCIDescriptor, "attrGet", oci8_attr_get, 1);
|
36
|
+
rb_define_method(cOCIDescriptor, "attrSet", oci8_attr_set, 2);
|
37
|
+
rb_define_method(cOCIDescriptor, "free", oci8_handle_free, 0);
|
38
|
+
rb_define_singleton_method(cOCIDescriptor, "new", oci8_s_new, 0);
|
39
|
+
}
|
data/ext/oci8/env.c
ADDED
@@ -0,0 +1,276 @@
|
|
1
|
+
/*
|
2
|
+
env.c - part of ruby-oci8
|
3
|
+
|
4
|
+
Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
|
5
|
+
|
6
|
+
=begin
|
7
|
+
== OCIEnv
|
8
|
+
The environment handle is the source of all OCI objects.
|
9
|
+
Usually there is one instance per one application.
|
10
|
+
|
11
|
+
super class: ((<OCIHandle>))
|
12
|
+
|
13
|
+
correspond native OCI datatype: ((|OCIEnv|))
|
14
|
+
=end
|
15
|
+
*/
|
16
|
+
#include "oci8.h"
|
17
|
+
#include <util.h> /* ruby_setenv */
|
18
|
+
|
19
|
+
RBOCI_NORETURN(static void oci8_raise_init_error(void));
|
20
|
+
|
21
|
+
static void oci8_raise_init_error(void)
|
22
|
+
{
|
23
|
+
VALUE msg = rb_str_new2("OCI Library Initialization Error");
|
24
|
+
VALUE exc = rb_funcall(eOCIError, oci8_id_new, 1, msg);
|
25
|
+
rb_ivar_set(exc, oci8_id_code, rb_ary_new3(1, INT2FIX(-1)));
|
26
|
+
rb_ivar_set(exc, oci8_id_message, rb_ary_new3(1, msg));
|
27
|
+
rb_exc_raise(exc);
|
28
|
+
}
|
29
|
+
|
30
|
+
static VALUE oci8_env_s_initialize(int argc, VALUE *argv, VALUE klass)
|
31
|
+
{
|
32
|
+
VALUE vmode;
|
33
|
+
ub4 mode;
|
34
|
+
sword rv;
|
35
|
+
|
36
|
+
#ifndef WIN32
|
37
|
+
/* workaround code.
|
38
|
+
*
|
39
|
+
* Some instant clients set the environment variables
|
40
|
+
* ORA_NLS_PROFILE33, ORA_NLS10 and ORACLE_HOME if they aren't
|
41
|
+
* set. It causes problems on some platforms.
|
42
|
+
*/
|
43
|
+
if (RTEST(rb_eval_string("RUBY_VERSION == \"1.8.4\""))) {
|
44
|
+
if (getenv("ORA_NLS_PROFILE33") == NULL) {
|
45
|
+
ruby_setenv("ORA_NLS_PROFILE33", "");
|
46
|
+
}
|
47
|
+
if (getenv("ORA_NLS10") == NULL) {
|
48
|
+
ruby_setenv("ORA_NLS10", "");
|
49
|
+
}
|
50
|
+
if (getenv("ORACLE_HOME") == NULL) {
|
51
|
+
ruby_setenv("ORACLE_HOME", ".");
|
52
|
+
}
|
53
|
+
}
|
54
|
+
#endif /* WIN32 */
|
55
|
+
|
56
|
+
rb_scan_args(argc, argv, "01", &vmode);
|
57
|
+
Get_Int_With_Default(argc, 1, vmode, mode, OCI_DEFAULT); /* 1 */
|
58
|
+
|
59
|
+
rv = OCIInitialize(mode, NULL, NULL, NULL, NULL);
|
60
|
+
return INT2FIX(rv);
|
61
|
+
}
|
62
|
+
|
63
|
+
static VALUE oci8_env_s_init(int argc, VALUE *argv, VALUE klass)
|
64
|
+
{
|
65
|
+
VALUE vmode;
|
66
|
+
ub4 mode;
|
67
|
+
OCIEnv *envhp = NULL;
|
68
|
+
OCIError *errhp;
|
69
|
+
oci8_handle_t *h;
|
70
|
+
sword rv;
|
71
|
+
|
72
|
+
rb_scan_args(argc, argv, "01", &vmode);
|
73
|
+
Get_Int_With_Default(argc, 1, vmode, mode, OCI_DEFAULT); /* 1 */
|
74
|
+
|
75
|
+
rv = OCIEnvInit(&envhp, OCI_DEFAULT, 0, NULL);
|
76
|
+
if (envhp == NULL) {
|
77
|
+
oci8_raise_init_error();
|
78
|
+
}
|
79
|
+
if (rv != OCI_SUCCESS)
|
80
|
+
oci8_env_raise(envhp, rv);
|
81
|
+
rv = OCIHandleAlloc(envhp, (dvoid *)&errhp, OCI_HTYPE_ERROR, 0, NULL);
|
82
|
+
if (rv != OCI_SUCCESS)
|
83
|
+
oci8_env_raise(envhp, rv);
|
84
|
+
h = oci8_make_handle(OCI_HTYPE_ENV, envhp, errhp, NULL, 0);
|
85
|
+
return h->self;
|
86
|
+
}
|
87
|
+
|
88
|
+
/*
|
89
|
+
=begin
|
90
|
+
--- OCIEnv.create([mode])
|
91
|
+
create the environment handle. Don't call `new'.
|
92
|
+
|
93
|
+
:mode
|
94
|
+
((|OCI_DEFAULT|)), ((|OCI_THREADED|)), ((|OCI_OBJECT|)), ((|OCI_SHARED|))
|
95
|
+
or these combination.
|
96
|
+
But I test only ((|OCI_DEFAULT|)). Default value is ((|OCI_DEFAULT|)).
|
97
|
+
|
98
|
+
((|OCI_THREADED|)): if your application use native thread(not ruby's thread), use this.
|
99
|
+
|
100
|
+
((|OCI_OBJECT|)): for OCI objects. But current implementation doesn't support OCI Object-Relational functions.
|
101
|
+
This is for ((*far future*)) extension, because my plan doesn't include `OCI object support'.
|
102
|
+
|
103
|
+
((|OCI_SHARED|))(Oracle 8i or later): for ((<Shared Data Mode>)).
|
104
|
+
|
105
|
+
:return value
|
106
|
+
A instance of ((<OCIEnv>)).
|
107
|
+
|
108
|
+
correspond native OCI function: ((|OCIEnvCreate|)) (if ((|OCIEnvCreate|)) is not found, the combination of ((|OCIInitialize|)) and ((|OCIEnvInit|)).)
|
109
|
+
=end
|
110
|
+
*/
|
111
|
+
#ifdef HAVE_OCIENVCREATE
|
112
|
+
static VALUE oci8_env_s_create(int argc, VALUE *argv, VALUE klass)
|
113
|
+
{
|
114
|
+
VALUE vmode;
|
115
|
+
ub4 mode;
|
116
|
+
OCIEnv *envhp = NULL;
|
117
|
+
OCIError *errhp;
|
118
|
+
oci8_handle_t *h;
|
119
|
+
sword rv;
|
120
|
+
|
121
|
+
rb_scan_args(argc, argv, "01", &vmode);
|
122
|
+
Get_Int_With_Default(argc, 1, vmode, mode, OCI_DEFAULT); /* 1 */
|
123
|
+
|
124
|
+
rv = OCIEnvCreate(&envhp, mode, NULL, NULL, NULL, NULL, 0, NULL);
|
125
|
+
if (envhp == NULL) {
|
126
|
+
oci8_raise_init_error();
|
127
|
+
}
|
128
|
+
if (rv != OCI_SUCCESS)
|
129
|
+
oci8_env_raise(envhp, rv);
|
130
|
+
rv = OCIHandleAlloc(envhp, (dvoid *)&errhp, OCI_HTYPE_ERROR, 0, NULL);
|
131
|
+
if (rv != OCI_SUCCESS)
|
132
|
+
oci8_env_raise(envhp, rv);
|
133
|
+
h = oci8_make_handle(OCI_HTYPE_ENV, envhp, errhp, NULL, 0);
|
134
|
+
return h->self;
|
135
|
+
}
|
136
|
+
#endif
|
137
|
+
|
138
|
+
/*
|
139
|
+
=begin
|
140
|
+
--- OCIEnv.terminate([mode])
|
141
|
+
:mode
|
142
|
+
((|OCI_DEFAULT|)) only valid. Default value is ((|OCI__DEFAULT|)).
|
143
|
+
|
144
|
+
correspond native OCI function: ((|OCITerminate|))
|
145
|
+
=end
|
146
|
+
*/
|
147
|
+
#ifdef HAVE_OCITERMINATE
|
148
|
+
static VALUE oci8_env_s_terminate(int argc, VALUE *argv, VALUE klass)
|
149
|
+
{
|
150
|
+
VALUE vmode;
|
151
|
+
ub4 mode;
|
152
|
+
|
153
|
+
if (rb_scan_args(argc, argv, "01", &vmode) == 1) {
|
154
|
+
Check_Type(vmode, T_FIXNUM);
|
155
|
+
mode = FIX2INT(vmode);
|
156
|
+
} else {
|
157
|
+
mode = OCI_DEFAULT;
|
158
|
+
}
|
159
|
+
|
160
|
+
OCITerminate(mode);
|
161
|
+
return Qnil;
|
162
|
+
}
|
163
|
+
#endif
|
164
|
+
|
165
|
+
/*
|
166
|
+
=begin
|
167
|
+
--- OCIEnv#alloc(handle)
|
168
|
+
create a new OCI handle.
|
169
|
+
:handle
|
170
|
+
The valid values are ((<OCISvcCtx>)), ((<OCIStmt>)),
|
171
|
+
((<OCIServer>)), ((<OCISession>)), and ((<OCIDescribe>)).
|
172
|
+
:return value
|
173
|
+
A newly created handle.
|
174
|
+
|
175
|
+
correspond native OCI function: ((|OCIHandleAlloc|))
|
176
|
+
=end
|
177
|
+
*/
|
178
|
+
typedef sword (*alloc_func_t)(CONST dvoid *, dvoid **, CONST ub4, CONST size_t, dvoid **);
|
179
|
+
static VALUE oci8_handle_alloc(VALUE self, VALUE klass)
|
180
|
+
{
|
181
|
+
sword rv;
|
182
|
+
dvoid *hp;
|
183
|
+
oci8_handle_t *envh;
|
184
|
+
oci8_handle_t *h;
|
185
|
+
int i;
|
186
|
+
struct {
|
187
|
+
VALUE *klass;
|
188
|
+
ub4 type;
|
189
|
+
alloc_func_t alloc_func;
|
190
|
+
} alloc_map[] = {
|
191
|
+
{&cOCISvcCtx, OCI_HTYPE_SVCCTX, (alloc_func_t)OCIHandleAlloc},
|
192
|
+
{&cOCIStmt, OCI_HTYPE_STMT, (alloc_func_t)OCIHandleAlloc},
|
193
|
+
{&cOCIServer, OCI_HTYPE_SERVER, (alloc_func_t)OCIHandleAlloc},
|
194
|
+
{&cOCISession, OCI_HTYPE_SESSION, (alloc_func_t)OCIHandleAlloc},
|
195
|
+
{&cOCIDescribe, OCI_HTYPE_DESCRIBE, (alloc_func_t)OCIHandleAlloc},
|
196
|
+
{&cOCILobLocator, OCI_DTYPE_LOB, (alloc_func_t)OCIDescriptorAlloc},
|
197
|
+
{&cOCIFileLocator, OCI_DTYPE_FILE, (alloc_func_t)OCIDescriptorAlloc},
|
198
|
+
};
|
199
|
+
#define ALLOC_MAP_SIZE (sizeof(alloc_map) / sizeof(alloc_map[0]))
|
200
|
+
|
201
|
+
Get_Handle(self, envh);
|
202
|
+
for (i = 0;i < ALLOC_MAP_SIZE;i++) {
|
203
|
+
if (alloc_map[i].klass[0] == klass)
|
204
|
+
break;
|
205
|
+
}
|
206
|
+
if (i == ALLOC_MAP_SIZE) {
|
207
|
+
rb_raise(rb_eTypeError, "not valid handle type %s", rb_class2name(CLASS_OF(klass)));
|
208
|
+
}
|
209
|
+
|
210
|
+
rv = alloc_map[i].alloc_func(envh->hp, &hp, alloc_map[i].type, 0, NULL);
|
211
|
+
if (rv != OCI_SUCCESS)
|
212
|
+
oci8_env_raise(envh->hp, rv);
|
213
|
+
h = oci8_make_handle(alloc_map[i].type, hp, envh->errhp, envh, 0);
|
214
|
+
return h->self;
|
215
|
+
}
|
216
|
+
|
217
|
+
/*
|
218
|
+
=begin
|
219
|
+
--- OCIEnv#logon(username, password, dbname)
|
220
|
+
Logon to the Oracle server.
|
221
|
+
|
222
|
+
See ((<Simplified Logon>)) and ((<Explicit Attach and Begin Session>))
|
223
|
+
|
224
|
+
:username
|
225
|
+
the username.
|
226
|
+
:password
|
227
|
+
the user's password.
|
228
|
+
:dbname
|
229
|
+
the name of the database, or nil.
|
230
|
+
:return value
|
231
|
+
A instance of ((<OCISvcCtx>))
|
232
|
+
For example:
|
233
|
+
env = OCIEnv.create()
|
234
|
+
svc = env.logon("SCOTT", "TIGER", nil)
|
235
|
+
or
|
236
|
+
svc = env.logon("SCOTT", "TIGER", "ORCL.WORLD")
|
237
|
+
|
238
|
+
correspond native OCI function: ((|OCILogon|))
|
239
|
+
=end
|
240
|
+
*/
|
241
|
+
static VALUE oci8_logon(VALUE self, VALUE username, VALUE password, VALUE dbname)
|
242
|
+
{
|
243
|
+
oci8_handle_t *envh;
|
244
|
+
oci8_handle_t *svch;
|
245
|
+
OCISvcCtx *svchp;
|
246
|
+
oci8_string_t u, p, d;
|
247
|
+
VALUE obj;
|
248
|
+
sword rv;
|
249
|
+
|
250
|
+
Get_Handle(self, envh);
|
251
|
+
Get_String(username, u);
|
252
|
+
Get_String(password, p);
|
253
|
+
Get_String(dbname, d);
|
254
|
+
rv = OCILogon(envh->hp, envh->errhp, &svchp,
|
255
|
+
u.ptr, u.len, p.ptr, p.len, d.ptr, d.len);
|
256
|
+
if (rv != OCI_SUCCESS) {
|
257
|
+
oci8_raise(envh->errhp, rv, NULL);
|
258
|
+
}
|
259
|
+
svch = oci8_make_handle(OCI_HTYPE_SVCCTX, svchp, envh->errhp, envh, 0);
|
260
|
+
obj = svch->self;
|
261
|
+
return obj;
|
262
|
+
}
|
263
|
+
|
264
|
+
void Init_oci8_env(void)
|
265
|
+
{
|
266
|
+
rb_define_singleton_method(cOCIEnv, "initialise", oci8_env_s_initialize, -1);
|
267
|
+
rb_define_singleton_method(cOCIEnv, "init", oci8_env_s_init, -1);
|
268
|
+
#ifdef HAVE_OCIENVCREATE
|
269
|
+
rb_define_singleton_method(cOCIEnv, "create", oci8_env_s_create, -1);
|
270
|
+
#endif
|
271
|
+
#ifdef HAVE_OCITERMINATE
|
272
|
+
rb_define_singleton_method(cOCIEnv, "terminate", oci8_env_s_terminate, -1);
|
273
|
+
#endif
|
274
|
+
rb_define_method(cOCIEnv, "alloc", oci8_handle_alloc, 1);
|
275
|
+
rb_define_method(cOCIEnv, "logon", oci8_logon, 3);
|
276
|
+
}
|
data/ext/oci8/error.c
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
/*
|
2
|
+
error.c - part of ruby-oci8
|
3
|
+
|
4
|
+
Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
|
5
|
+
|
6
|
+
=begin
|
7
|
+
== OCIError
|
8
|
+
=end
|
9
|
+
*/
|
10
|
+
#include "oci8.h"
|
11
|
+
|
12
|
+
static ID oci8_id_caller;
|
13
|
+
static ID oci8_id_set_backtrace;
|
14
|
+
|
15
|
+
RBOCI_NORETURN(static void oci8_raise2(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp, const char *file, int line));
|
16
|
+
|
17
|
+
static void oci8_raise2(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp, const char *file, int line)
|
18
|
+
{
|
19
|
+
VALUE vcodes = Qnil;
|
20
|
+
VALUE vmessages = Qnil;
|
21
|
+
VALUE exc;
|
22
|
+
char errmsg[1024];
|
23
|
+
sb4 errcode;
|
24
|
+
ub4 recodeno;
|
25
|
+
VALUE msg;
|
26
|
+
#ifdef OCI_ATTR_PARSE_ERROR_OFFSET
|
27
|
+
VALUE vparse_error_offset = Qnil;
|
28
|
+
#endif
|
29
|
+
#ifdef OCI_ATTR_STATEMENT
|
30
|
+
VALUE vsql = Qnil;
|
31
|
+
#endif
|
32
|
+
int i;
|
33
|
+
int rv;
|
34
|
+
VALUE backtrace;
|
35
|
+
#if defined(_WIN32) || defined(WIN32)
|
36
|
+
char *p = strrchr(file, '\\');
|
37
|
+
if (p != NULL)
|
38
|
+
file = p + 1;
|
39
|
+
#endif
|
40
|
+
|
41
|
+
switch (status) {
|
42
|
+
case OCI_ERROR:
|
43
|
+
case OCI_SUCCESS_WITH_INFO:
|
44
|
+
vcodes = rb_ary_new();
|
45
|
+
vmessages = rb_ary_new();
|
46
|
+
for (recodeno = 1;;recodeno++) {
|
47
|
+
/* get error string */
|
48
|
+
rv = OCIErrorGet(errhp, recodeno, NULL, &errcode, TO_ORATEXT(errmsg), sizeof(errmsg), type);
|
49
|
+
if (rv != OCI_SUCCESS) {
|
50
|
+
break;
|
51
|
+
}
|
52
|
+
/* chop error string */
|
53
|
+
for (i = strlen(errmsg) - 1;i >= 0;i--) {
|
54
|
+
if (errmsg[i] == '\n' || errmsg[i] == '\r') {
|
55
|
+
errmsg[i] = '\0';
|
56
|
+
} else {
|
57
|
+
break;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
rb_ary_push(vcodes, INT2FIX(errcode));
|
61
|
+
rb_ary_push(vmessages, rb_str_new2(errmsg));
|
62
|
+
}
|
63
|
+
if (RARRAY_LEN(vmessages) > 0) {
|
64
|
+
msg = RARRAY_PTR(vmessages)[0];
|
65
|
+
} else {
|
66
|
+
msg = rb_str_new2("ERROR");
|
67
|
+
}
|
68
|
+
if (status == OCI_ERROR) {
|
69
|
+
exc = eOCIError;
|
70
|
+
} else {
|
71
|
+
exc = eOCISuccessWithInfo;
|
72
|
+
}
|
73
|
+
break;
|
74
|
+
case OCI_NO_DATA:
|
75
|
+
exc = eOCINoData;
|
76
|
+
msg = rb_str_new2("No Data");
|
77
|
+
break;
|
78
|
+
case OCI_INVALID_HANDLE:
|
79
|
+
exc = eOCIInvalidHandle;
|
80
|
+
msg = rb_str_new2("Invalid Handle");
|
81
|
+
break;
|
82
|
+
case OCI_NEED_DATA:
|
83
|
+
exc = eOCINeedData;
|
84
|
+
msg = rb_str_new2("Need Data");
|
85
|
+
break;
|
86
|
+
case OCI_STILL_EXECUTING:
|
87
|
+
exc = eOCIStillExecuting;
|
88
|
+
msg = rb_str_new2("Still Executing");
|
89
|
+
break;
|
90
|
+
case OCI_CONTINUE:
|
91
|
+
exc = eOCIContinue;
|
92
|
+
msg = rb_str_new2("Continue");
|
93
|
+
break;
|
94
|
+
default:
|
95
|
+
sprintf(errmsg, "Unknown error (%d)", status);
|
96
|
+
exc = rb_eStandardError;
|
97
|
+
msg = rb_str_new2(errmsg);
|
98
|
+
}
|
99
|
+
exc = rb_funcall(exc, oci8_id_new, 1, msg);
|
100
|
+
if (!NIL_P(vcodes)) {
|
101
|
+
rb_ivar_set(exc, oci8_id_code, vcodes);
|
102
|
+
}
|
103
|
+
if (!NIL_P(vmessages)) {
|
104
|
+
rb_ivar_set(exc, oci8_id_message, vmessages);
|
105
|
+
}
|
106
|
+
#ifdef OCI_ATTR_PARSE_ERROR_OFFSET
|
107
|
+
if (!NIL_P(vparse_error_offset)) {
|
108
|
+
rb_ivar_set(exc, oci8_id_parse_error_offset, vparse_error_offset);
|
109
|
+
}
|
110
|
+
#endif
|
111
|
+
#ifdef OCI_ATTR_STATEMENT
|
112
|
+
if (!NIL_P(vsql)) {
|
113
|
+
rb_ivar_set(exc, oci8_id_sql, vsql);
|
114
|
+
}
|
115
|
+
#endif
|
116
|
+
/*
|
117
|
+
* make error line in C code.
|
118
|
+
*/
|
119
|
+
backtrace = rb_funcall(rb_cObject, rb_intern("caller"), 0);
|
120
|
+
sprintf(errmsg, "%s:%d:in oci8lib.so", file, line);
|
121
|
+
rb_ary_unshift(backtrace, rb_str_new2(errmsg));
|
122
|
+
rb_funcall(exc, rb_intern("set_backtrace"), 1, backtrace);
|
123
|
+
rb_exc_raise(exc);
|
124
|
+
}
|
125
|
+
|
126
|
+
static VALUE oci8_error_initialize(int argc, VALUE *argv, VALUE self)
|
127
|
+
{
|
128
|
+
VALUE msg;
|
129
|
+
VALUE code;
|
130
|
+
|
131
|
+
rb_scan_args(argc, argv, "02", &msg, &code);
|
132
|
+
rb_call_super(argc > 1 ? 1 : argc, argv);
|
133
|
+
if (!NIL_P(code)) {
|
134
|
+
rb_ivar_set(self, oci8_id_code, rb_ary_new3(1, code));
|
135
|
+
}
|
136
|
+
return Qnil;
|
137
|
+
}
|
138
|
+
|
139
|
+
|
140
|
+
/*
|
141
|
+
=begin
|
142
|
+
--- OCIError#code()
|
143
|
+
=end
|
144
|
+
*/
|
145
|
+
static VALUE oci8_error_code(VALUE self)
|
146
|
+
{
|
147
|
+
VALUE ary = rb_ivar_get(self, oci8_id_code);
|
148
|
+
if (NIL_P(ary)) {
|
149
|
+
return Qnil;
|
150
|
+
}
|
151
|
+
Check_Type(ary, T_ARRAY);
|
152
|
+
if (RARRAY_LEN(ary) == 0) {
|
153
|
+
return Qnil;
|
154
|
+
}
|
155
|
+
return RARRAY_PTR(ary)[0];
|
156
|
+
}
|
157
|
+
|
158
|
+
/*
|
159
|
+
=begin
|
160
|
+
--- OCIError#codes()
|
161
|
+
=end
|
162
|
+
*/
|
163
|
+
static VALUE oci8_error_code_array(VALUE self)
|
164
|
+
{
|
165
|
+
return rb_ivar_get(self, oci8_id_code);
|
166
|
+
}
|
167
|
+
|
168
|
+
/*
|
169
|
+
=begin
|
170
|
+
--- OCIError#message()
|
171
|
+
=end
|
172
|
+
*/
|
173
|
+
|
174
|
+
/*
|
175
|
+
=begin
|
176
|
+
--- OCIError#messages()
|
177
|
+
=end
|
178
|
+
*/
|
179
|
+
static VALUE oci8_error_message_array(VALUE self)
|
180
|
+
{
|
181
|
+
return rb_ivar_get(self, oci8_id_message);
|
182
|
+
}
|
183
|
+
|
184
|
+
#ifdef OCI_ATTR_PARSE_ERROR_OFFSET
|
185
|
+
/*
|
186
|
+
=begin
|
187
|
+
--- OCIError#parseErrorOffset()
|
188
|
+
=end
|
189
|
+
*/
|
190
|
+
static VALUE oci8_error_parse_error_offset(VALUE self)
|
191
|
+
{
|
192
|
+
return rb_ivar_get(self, oci8_id_parse_error_offset);
|
193
|
+
}
|
194
|
+
#endif
|
195
|
+
|
196
|
+
#ifdef OCI_ATTR_STATEMENT
|
197
|
+
/*
|
198
|
+
=begin
|
199
|
+
--- OCIError#sql()
|
200
|
+
(Oracle 8.1.6 or later)
|
201
|
+
=end
|
202
|
+
*/
|
203
|
+
static VALUE oci8_error_sql(VALUE self)
|
204
|
+
{
|
205
|
+
return rb_ivar_get(self, oci8_id_sql);
|
206
|
+
}
|
207
|
+
#endif
|
208
|
+
|
209
|
+
void Init_oci8_error(void)
|
210
|
+
{
|
211
|
+
oci8_id_caller = rb_intern("caller");
|
212
|
+
oci8_id_set_backtrace = rb_intern("set_backtrace");
|
213
|
+
|
214
|
+
rb_define_method(eOCIError, "initialize", oci8_error_initialize, -1);
|
215
|
+
rb_define_method(eOCIError, "code", oci8_error_code, 0);
|
216
|
+
rb_define_method(eOCIError, "codes", oci8_error_code_array, 0);
|
217
|
+
rb_define_method(eOCIError, "messages", oci8_error_message_array, 0);
|
218
|
+
#ifdef OCI_ATTR_PARSE_ERROR_OFFSET
|
219
|
+
rb_define_method(eOCIError, "parseErrorOffset", oci8_error_parse_error_offset, 0);
|
220
|
+
#endif
|
221
|
+
#ifdef OCI_ATTR_STATEMENT
|
222
|
+
rb_define_method(eOCIError, "sql", oci8_error_sql, 0);
|
223
|
+
#endif
|
224
|
+
}
|
225
|
+
|
226
|
+
void oci8_do_raise(OCIError *errhp, sword status, OCIStmt *stmthp, const char *file, int line)
|
227
|
+
{
|
228
|
+
oci8_raise2(errhp, status, OCI_HTYPE_ERROR, stmthp, file, line);
|
229
|
+
}
|
230
|
+
|
231
|
+
void oci8_do_env_raise(OCIEnv *envhp, sword status, const char *file, int line)
|
232
|
+
{
|
233
|
+
oci8_raise2(envhp, status, OCI_HTYPE_ENV, NULL, file, line);
|
234
|
+
}
|