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