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
data/ext/oci8/param.c
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
/*
|
2
|
+
param.c - part of ruby-oci8
|
3
|
+
|
4
|
+
Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
|
5
|
+
|
6
|
+
=begin
|
7
|
+
== OCIParam
|
8
|
+
super class: ((<OCIDescriptor>))
|
9
|
+
=end
|
10
|
+
*/
|
11
|
+
#include "oci8.h"
|
12
|
+
|
13
|
+
void Init_oci8_param(void)
|
14
|
+
{
|
15
|
+
rb_define_method(cOCIParam, "paramGet", oci8_param_get, 1);
|
16
|
+
}
|
17
|
+
|
18
|
+
VALUE oci8_param_get(VALUE self, VALUE pos)
|
19
|
+
{
|
20
|
+
oci8_handle_t *h;
|
21
|
+
OCIParam *parmhp = NULL;
|
22
|
+
oci8_handle_t *parmh;
|
23
|
+
VALUE obj;
|
24
|
+
sword rv;
|
25
|
+
|
26
|
+
Get_Handle(self, h);
|
27
|
+
Check_Type(pos, T_FIXNUM);
|
28
|
+
rv = OCIParamGet(h->hp, h->type, h->errhp, (dvoid *)&parmhp, FIX2INT(pos));
|
29
|
+
if (rv != OCI_SUCCESS) {
|
30
|
+
oci8_raise(h->errhp, rv, NULL);
|
31
|
+
}
|
32
|
+
parmh = oci8_make_handle(OCI_DTYPE_PARAM, parmhp, h->errhp, h, 0);
|
33
|
+
parmh->u.param.is_implicit = (h->type == OCI_HTYPE_STMT) ? 1 : 0;
|
34
|
+
|
35
|
+
obj = parmh->self;
|
36
|
+
return obj;
|
37
|
+
}
|
data/ext/oci8/server.c
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
/*
|
2
|
+
server.c - part of ruby-oci8
|
3
|
+
|
4
|
+
Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
|
5
|
+
|
6
|
+
=begin
|
7
|
+
== OCIServer
|
8
|
+
If you use ((<OCIEnv#logon>)), you have no need to use this handle directly.
|
9
|
+
Because ((<OCIEnv#logon>)) create this handle implicitly and set it to ((<OCISvcCtx>)).
|
10
|
+
|
11
|
+
super class: ((<OCIHandle>))
|
12
|
+
|
13
|
+
correspond native OCI datatype: ((|OCIServer|))
|
14
|
+
=end
|
15
|
+
*/
|
16
|
+
#include "oci8.h"
|
17
|
+
|
18
|
+
/*
|
19
|
+
=begin
|
20
|
+
--- OCIServer#attach(dbname [, mode])
|
21
|
+
attach to the database.
|
22
|
+
:dbname
|
23
|
+
the name of database.
|
24
|
+
:mode
|
25
|
+
((|OCI_DEFAULT|)) or ((|OCI_CPOOL|))(Oracle 9i). Default value is ((|OCI_DEFAULT|)).
|
26
|
+
|
27
|
+
This ruby module doesn't support the connection pooling provided by OCI,
|
28
|
+
so ((|OCI_CPOOL|)) is invalid value for now.
|
29
|
+
|
30
|
+
correspond native OCI function: ((|OCIServerAttach|))
|
31
|
+
=end
|
32
|
+
*/
|
33
|
+
static VALUE oci8_server_attach(int argc, VALUE *argv, VALUE self)
|
34
|
+
{
|
35
|
+
VALUE vdbname, vmode;
|
36
|
+
oci8_handle_t *h;
|
37
|
+
oci8_string_t d;
|
38
|
+
ub4 mode;
|
39
|
+
sword rv;
|
40
|
+
|
41
|
+
rb_scan_args(argc, argv, "11", &vdbname, &vmode);
|
42
|
+
Get_Handle(self, h); /* 0 */
|
43
|
+
Get_String(vdbname, d); /* 1 */
|
44
|
+
Get_Int_With_Default(argc, 2, vmode, mode, OCI_DEFAULT); /* 2 */
|
45
|
+
|
46
|
+
rv = OCIServerAttach(h->hp, h->errhp, d.ptr, d.len, mode);
|
47
|
+
if (rv != OCI_SUCCESS)
|
48
|
+
oci8_raise(h->errhp, rv, NULL);
|
49
|
+
return self;
|
50
|
+
}
|
51
|
+
|
52
|
+
/*
|
53
|
+
=begin
|
54
|
+
--- OCIServer#detach([mode])
|
55
|
+
detach from the database.
|
56
|
+
|
57
|
+
:mode
|
58
|
+
((|OCI_DEFAULT|)) only valid. Default value is ((|OCI_DEFAULT|)).
|
59
|
+
|
60
|
+
correspond native OCI function: ((|OCIServerDetach|))
|
61
|
+
=end
|
62
|
+
*/
|
63
|
+
static VALUE oci8_server_detach(int argc, VALUE *argv, VALUE self)
|
64
|
+
{
|
65
|
+
VALUE vmode;
|
66
|
+
oci8_handle_t *h;
|
67
|
+
ub4 mode;
|
68
|
+
sword rv;
|
69
|
+
|
70
|
+
|
71
|
+
rb_scan_args(argc, argv, "01", &vmode);
|
72
|
+
Get_Handle(self, h); /* 0 */
|
73
|
+
Get_Int_With_Default(argc, 1, vmode, mode, OCI_DEFAULT); /* 1 */
|
74
|
+
|
75
|
+
rv = OCIServerDetach(h->hp, h->errhp, mode);
|
76
|
+
if (rv != OCI_SUCCESS)
|
77
|
+
oci8_raise(h->errhp, rv, NULL);
|
78
|
+
return self;
|
79
|
+
}
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
void Init_oci8_server(void)
|
84
|
+
{
|
85
|
+
rb_define_method(cOCIServer, "attach", oci8_server_attach, -1);
|
86
|
+
rb_define_method(cOCIServer, "detach", oci8_server_detach, -1);
|
87
|
+
rb_define_method(cOCIServer, "version", oci8_server_version, 0);
|
88
|
+
#ifdef HAVE_OCISERVERRELEASE
|
89
|
+
rb_define_method(cOCIServer, "release", oci8_server_release, 0);
|
90
|
+
#endif
|
91
|
+
rb_define_method(cOCIServer, "break", oci8_break, 0);
|
92
|
+
#ifdef HAVE_OCIRESET
|
93
|
+
rb_define_method(cOCIServer, "reset", oci8_reset, 0);
|
94
|
+
#endif
|
95
|
+
}
|
96
|
+
|
97
|
+
/*
|
98
|
+
=begin
|
99
|
+
--- OCIServer#version()
|
100
|
+
get server version.
|
101
|
+
|
102
|
+
:return value
|
103
|
+
string of server version. For example
|
104
|
+
Oracle8 Release 8.0.5.0.0 - Production
|
105
|
+
PL/SQL Release 8.0.5.0.0 - Production
|
106
|
+
|
107
|
+
correspond native OCI function: ((|OCIServerVersion|))
|
108
|
+
=end
|
109
|
+
*/
|
110
|
+
VALUE oci8_server_version(VALUE self)
|
111
|
+
{
|
112
|
+
oci8_handle_t *h;
|
113
|
+
OraText buf[1024];
|
114
|
+
sword rv;
|
115
|
+
|
116
|
+
Get_Handle(self, h); /* 0 */
|
117
|
+
rv = OCIServerVersion(h->hp, h->errhp, buf, sizeof(buf), h->type);
|
118
|
+
if (rv != OCI_SUCCESS)
|
119
|
+
oci8_raise(h->errhp, rv, NULL);
|
120
|
+
return rb_str_new2(TO_CHARPTR(buf));
|
121
|
+
}
|
122
|
+
|
123
|
+
/*
|
124
|
+
=begin
|
125
|
+
--- OCIServer#release()
|
126
|
+
get server version number and string
|
127
|
+
|
128
|
+
:return value
|
129
|
+
array of number and string. For example
|
130
|
+
|
131
|
+
version_number, version_str = srv.release()
|
132
|
+
version_number is 0x8005000.
|
133
|
+
version_str is
|
134
|
+
Oracle8 Release 8.0.5.0.0 - Production
|
135
|
+
PL/SQL Release 8.0.5.0.0 - Production
|
136
|
+
|
137
|
+
correspond native OCI function: ((|OCIServerVersion|))
|
138
|
+
|
139
|
+
Oracle 9i or later?
|
140
|
+
=end
|
141
|
+
*/
|
142
|
+
#ifdef HAVE_OCISERVERRELEASE
|
143
|
+
VALUE oci8_server_release(VALUE self)
|
144
|
+
{
|
145
|
+
oci8_handle_t *h;
|
146
|
+
OraText buf[1024];
|
147
|
+
ub4 version = 0;
|
148
|
+
sword rv;
|
149
|
+
|
150
|
+
Get_Handle(self, h); /* 0 */
|
151
|
+
rv = OCIServerRelease(h->hp, h->errhp, buf, sizeof(buf), h->type, &version);
|
152
|
+
if (rv != OCI_SUCCESS)
|
153
|
+
oci8_raise(h->errhp, rv, NULL);
|
154
|
+
return rb_ary_new3(2, INT2FIX(version), rb_str_new2(buf));
|
155
|
+
}
|
156
|
+
#endif
|
157
|
+
|
158
|
+
VALUE oci8_break(VALUE self)
|
159
|
+
{
|
160
|
+
oci8_handle_t *h;
|
161
|
+
sword rv;
|
162
|
+
|
163
|
+
Get_Handle(self, h); /* 0 */
|
164
|
+
rv = OCIBreak(h->hp, h->errhp);
|
165
|
+
if (rv != OCI_SUCCESS)
|
166
|
+
oci8_raise(h->errhp, rv, NULL);
|
167
|
+
return self;
|
168
|
+
}
|
169
|
+
|
170
|
+
#ifdef HAVE_OCIRESET
|
171
|
+
VALUE oci8_reset(VALUE self)
|
172
|
+
{
|
173
|
+
oci8_handle_t *h;
|
174
|
+
sword rv;
|
175
|
+
|
176
|
+
Get_Handle(self, h); /* 0 */
|
177
|
+
rv = OCIReset(h->hp, h->errhp);
|
178
|
+
if (rv != OCI_SUCCESS)
|
179
|
+
oci8_raise(h->errhp, rv, NULL);
|
180
|
+
return self;
|
181
|
+
}
|
182
|
+
#endif
|
data/ext/oci8/session.c
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
/*
|
2
|
+
session.c - part of ruby-oci8
|
3
|
+
|
4
|
+
Copyright (C) 2002 KUBO Takehiro <kubo@jiubao.org>
|
5
|
+
|
6
|
+
=begin
|
7
|
+
== OCISession
|
8
|
+
If you use ((<OCIEnv#logon>)), you have no need to use this handle directly.
|
9
|
+
Because ((<OCIEnv#logon>)) create this handle implicitly and set it to ((<OCISvcCtx>)).
|
10
|
+
|
11
|
+
super class: ((<OCIHandle>))
|
12
|
+
|
13
|
+
correspond native OCI datatype: ((|OCISession|))
|
14
|
+
=end
|
15
|
+
*/
|
16
|
+
#include "oci8.h"
|
17
|
+
|
18
|
+
/*
|
19
|
+
=begin
|
20
|
+
--- OCISession#begin(svc [, credt [, mode]])
|
21
|
+
start user session under the specified server context.
|
22
|
+
:svc
|
23
|
+
((<OCISvcCtx>)).
|
24
|
+
:credt
|
25
|
+
((|OCI_CRED_RDBMS|)) or ((|OCI_CRED_EXT|)).
|
26
|
+
Default value is ((|OCI_CRED_RDBMS|)).
|
27
|
+
|
28
|
+
If you use ((|OCI_CRED_RDBMS|)), set ((<OCI_ATTR_USERNAME>))
|
29
|
+
and ((<OCI_ATTR_PASSWORD>)) in advance.
|
30
|
+
|
31
|
+
:mode
|
32
|
+
((|OCI_DEFAULT|)), ((|OCI_MIGRATE|)), ((|OCI_SYSDBA|)), ((|OCI_SYSOPER|)),
|
33
|
+
(((|OCI_SYSDBA|)) | ((|OCI_PRELIM_AUTH|))), or (((|OCI_SYSOPER|)) | ((|OCI_PRELIM_AUTH|))).
|
34
|
+
Default value is ((|OCI_DEFAULT|)).
|
35
|
+
|
36
|
+
If you need SYSDBA or SYSOPER privilege, use
|
37
|
+
((|OCI_SYSDBA|)) or ((|OCI_SYSOPER|)) respectively.
|
38
|
+
|
39
|
+
correspond native OCI function: ((|OCISessionBegin|))
|
40
|
+
=end
|
41
|
+
*/
|
42
|
+
static VALUE oci8_session_begin(int argc, VALUE *argv, VALUE self)
|
43
|
+
{
|
44
|
+
VALUE vsvc, vcredt, vmode;
|
45
|
+
oci8_handle_t *h;
|
46
|
+
oci8_handle_t *svch;
|
47
|
+
ub4 credt;
|
48
|
+
ub4 mode;
|
49
|
+
sword rv;
|
50
|
+
|
51
|
+
rb_scan_args(argc, argv, "12", &vsvc, &vcredt, &vmode);
|
52
|
+
Get_Handle(self, h); /* 0 */
|
53
|
+
Check_Handle(vsvc, OCISvcCtx, svch); /* 1 */
|
54
|
+
Get_Int_With_Default(argc, 2, vcredt, credt, OCI_NTV_SYNTAX); /* 2 */
|
55
|
+
Get_Int_With_Default(argc, 3, vmode, mode, OCI_DEFAULT); /* 3 */
|
56
|
+
|
57
|
+
rv = OCISessionBegin(svch->hp, h->errhp, h->hp, credt, mode);
|
58
|
+
if (rv != OCI_SUCCESS)
|
59
|
+
oci8_raise(h->errhp, rv, NULL);
|
60
|
+
return self;
|
61
|
+
}
|
62
|
+
|
63
|
+
/*
|
64
|
+
=begin
|
65
|
+
--- OCISession#end(svc [, vmode])
|
66
|
+
terminate user Authentication Context
|
67
|
+
|
68
|
+
:svc
|
69
|
+
((<OCISvcCtx>)).
|
70
|
+
:mode
|
71
|
+
((|OCI_DEFAULT|)) only valid. Defalt value is ((|OCI_DEFAULT|)).
|
72
|
+
|
73
|
+
correspond native OCI function: ((|OCISessionEnd|))
|
74
|
+
=end
|
75
|
+
*/
|
76
|
+
static VALUE oci8_session_end(int argc, VALUE *argv, VALUE self)
|
77
|
+
{
|
78
|
+
VALUE vsvc, vmode;
|
79
|
+
oci8_handle_t *h;
|
80
|
+
oci8_handle_t *svch;
|
81
|
+
ub4 mode;
|
82
|
+
sword rv;
|
83
|
+
|
84
|
+
rb_scan_args(argc, argv, "11", &vsvc, &vmode);
|
85
|
+
Get_Handle(self, h); /* 0 */
|
86
|
+
Check_Handle(vsvc, OCISvcCtx, svch); /* 1 */
|
87
|
+
Get_Int_With_Default(argc, 2, vmode, mode, OCI_DEFAULT); /* 2 */
|
88
|
+
|
89
|
+
rv = OCISessionEnd(svch->hp, h->errhp, h->hp, mode);
|
90
|
+
if (rv != OCI_SUCCESS)
|
91
|
+
oci8_raise(h->errhp, rv, NULL);
|
92
|
+
return self;
|
93
|
+
}
|
94
|
+
|
95
|
+
void Init_oci8_session(void)
|
96
|
+
{
|
97
|
+
rb_define_method(cOCISession, "begin", oci8_session_begin, -1);
|
98
|
+
rb_define_method(cOCISession, "end", oci8_session_end, -1);
|
99
|
+
}
|
data/ext/oci8/stmt.c
ADDED
@@ -0,0 +1,624 @@
|
|
1
|
+
/*
|
2
|
+
stmt.c - part of ruby-oci8
|
3
|
+
implement the methods of OCIStmt.
|
4
|
+
|
5
|
+
Copyright (C) 2002-2006 KUBO Takehiro <kubo@jiubao.org>
|
6
|
+
|
7
|
+
=begin
|
8
|
+
== OCIStmt
|
9
|
+
Statemet handle identify a SQL or PL/SQL statement and its associated attributes.
|
10
|
+
|
11
|
+
Information about SQL or PL/SQL's input/output variables is managed by the
|
12
|
+
((<bind handle|OCIBind>)). Fetched data of select statement is managed by the
|
13
|
+
((<define handle|OCIDefine>)).
|
14
|
+
|
15
|
+
super class: ((<OCIHandle>))
|
16
|
+
|
17
|
+
correspond native OCI datatype: ((|OCIStmt|))
|
18
|
+
=end
|
19
|
+
*/
|
20
|
+
#include "oci8.h"
|
21
|
+
|
22
|
+
static ID id_alloc;
|
23
|
+
|
24
|
+
static void check_bind_type(ub4 type, oci8_handle_t *stmth, VALUE vtype, VALUE vlength, oci8_bind_handle_t **bhp, ub2 *dty)
|
25
|
+
{
|
26
|
+
enum oci8_bind_type bind_type;
|
27
|
+
oci8_bind_handle_t *bh;
|
28
|
+
sb4 value_sz;
|
29
|
+
VALUE klass = Qnil;
|
30
|
+
|
31
|
+
if (TYPE(vtype) == T_FIXNUM) {
|
32
|
+
switch (FIX2INT(vtype)) {
|
33
|
+
case SQLT_CHR: /* OCI_TYPECODE_VARCHAR */
|
34
|
+
bind_type = BIND_STRING;
|
35
|
+
*dty = SQLT_LVC;
|
36
|
+
if (NIL_P(vlength))
|
37
|
+
rb_raise(rb_eArgError, "the length of String is not specified.");
|
38
|
+
value_sz = NUM2INT(vlength) + 4;
|
39
|
+
if (value_sz < 5)
|
40
|
+
value_sz = 5; /* at least 5 bytes */
|
41
|
+
break;
|
42
|
+
case SQLT_LVB: /* OCI_TYPECODE_RAW */
|
43
|
+
case SQLT_BIN: /* OCI_TYPECODE_UNSIGNED8 */
|
44
|
+
bind_type = BIND_STRING;
|
45
|
+
*dty = SQLT_LVB;
|
46
|
+
if (NIL_P(vlength))
|
47
|
+
rb_raise(rb_eArgError, "the length of String is not specified.");
|
48
|
+
value_sz = NUM2INT(vlength) + 4;
|
49
|
+
if (value_sz < 5)
|
50
|
+
value_sz = 5; /* at least 5 bytes */
|
51
|
+
break;
|
52
|
+
case SQLT_DAT:
|
53
|
+
bind_type = BIND_ORA_DATE;
|
54
|
+
*dty = SQLT_DAT;
|
55
|
+
value_sz = sizeof(ora_date_t);
|
56
|
+
break;
|
57
|
+
case SQLT_CLOB: /* OCI_TYPECODE_CLOB */
|
58
|
+
case SQLT_BLOB: /* OCI_TYPECODE_BLOB */
|
59
|
+
bind_type = BIND_HANDLE;
|
60
|
+
*dty = FIX2INT(vtype);
|
61
|
+
value_sz = sizeof(bh->value.handle);
|
62
|
+
klass = cOCILobLocator;
|
63
|
+
break;
|
64
|
+
case SQLT_BFILE:
|
65
|
+
case SQLT_CFILE:
|
66
|
+
bind_type = BIND_HANDLE;
|
67
|
+
*dty = FIX2INT(vtype);
|
68
|
+
value_sz = sizeof(bh->value.handle);
|
69
|
+
klass = cOCIFileLocator;
|
70
|
+
break;
|
71
|
+
case SQLT_RDD:
|
72
|
+
bind_type = BIND_HANDLE;
|
73
|
+
*dty = SQLT_RDD;
|
74
|
+
value_sz = sizeof(bh->value.handle);
|
75
|
+
klass = cOCIRowid;
|
76
|
+
break;
|
77
|
+
case SQLT_RSET:
|
78
|
+
bind_type = BIND_HANDLE;
|
79
|
+
*dty = SQLT_RSET;
|
80
|
+
value_sz = sizeof(bh->value.handle);
|
81
|
+
klass = cOCIStmt;
|
82
|
+
break;
|
83
|
+
#ifdef SQLT_IBDOUBLE
|
84
|
+
case SQLT_IBDOUBLE:
|
85
|
+
bind_type = BIND_FLOAT;
|
86
|
+
*dty = SQLT_BDOUBLE;
|
87
|
+
value_sz = sizeof(double);
|
88
|
+
break;
|
89
|
+
#endif
|
90
|
+
default:
|
91
|
+
rb_raise(rb_eArgError, "Not supported type (%d)", FIX2INT(vtype));
|
92
|
+
}
|
93
|
+
} else if (vtype == rb_cFixnum) {
|
94
|
+
bind_type = BIND_FIXNUM;
|
95
|
+
*dty = SQLT_INT;
|
96
|
+
value_sz = sizeof(long);
|
97
|
+
} else if (vtype == rb_cInteger || vtype == rb_cBignum) {
|
98
|
+
bind_type = BIND_INTEGER_VIA_ORA_NUMBER;
|
99
|
+
*dty = SQLT_NUM;
|
100
|
+
value_sz = sizeof(ora_number_t);
|
101
|
+
} else if (vtype == rb_cTime) {
|
102
|
+
bind_type = BIND_TIME_VIA_ORA_DATE;
|
103
|
+
*dty = SQLT_DAT;
|
104
|
+
value_sz = sizeof(ora_date_t);
|
105
|
+
} else if (vtype == rb_cString) {
|
106
|
+
bind_type = BIND_STRING;
|
107
|
+
*dty = SQLT_LVC;
|
108
|
+
if (NIL_P(vlength))
|
109
|
+
rb_raise(rb_eArgError, "the length of String is not specified.");
|
110
|
+
value_sz = NUM2INT(vlength) + 4;
|
111
|
+
if (value_sz < 5)
|
112
|
+
value_sz = 5; /* at least 5 bytes */
|
113
|
+
} else if (vtype == rb_cFloat) {
|
114
|
+
bind_type = BIND_FLOAT;
|
115
|
+
*dty = SQLT_FLT;
|
116
|
+
value_sz = sizeof(double);
|
117
|
+
} else if (vtype == cOraDate) {
|
118
|
+
bind_type = BIND_ORA_DATE;
|
119
|
+
*dty = SQLT_DAT;
|
120
|
+
value_sz = sizeof(ora_date_t);
|
121
|
+
} else if (vtype == cOraNumber) {
|
122
|
+
bind_type = BIND_ORA_NUMBER;
|
123
|
+
*dty = SQLT_NUM;
|
124
|
+
value_sz = sizeof(ora_number_t);
|
125
|
+
} else {
|
126
|
+
if (SYMBOL_P(vtype)) {
|
127
|
+
rb_raise(rb_eArgError, "Not supported type (:%s)", rb_id2name(SYM2ID(vtype)));
|
128
|
+
} else {
|
129
|
+
rb_raise(rb_eArgError, "Not supported type (%s)", rb_class2name(vtype));
|
130
|
+
}
|
131
|
+
}
|
132
|
+
bh = (oci8_bind_handle_t *)oci8_make_handle(type, NULL, NULL, stmth, value_sz);
|
133
|
+
bh->bind_type = bind_type;
|
134
|
+
if (bind_type == BIND_HANDLE) {
|
135
|
+
if (NIL_P(vlength)) {
|
136
|
+
oci8_handle_t *envh;
|
137
|
+
for (envh = stmth; envh->type != OCI_HTYPE_ENV; envh = envh->parent);
|
138
|
+
vlength = rb_funcall(envh->self, id_alloc, 1, klass);
|
139
|
+
}
|
140
|
+
bh->value.handle.klass = klass;
|
141
|
+
oci8_set_value(bh, vlength);
|
142
|
+
}
|
143
|
+
*bhp = bh;
|
144
|
+
}
|
145
|
+
|
146
|
+
static VALUE oci8_each_value(VALUE hash)
|
147
|
+
{
|
148
|
+
return rb_funcall(hash, rb_intern("each_value"), 0);
|
149
|
+
}
|
150
|
+
|
151
|
+
/*
|
152
|
+
=begin
|
153
|
+
--- OCIStmt#prepare(stmt [, language [, mode]])
|
154
|
+
set and prepare SQL statement.
|
155
|
+
|
156
|
+
:stmt
|
157
|
+
SQL or PL/SQL statement
|
158
|
+
:language
|
159
|
+
((|OCI_NTV_SYNTAX|)), ((|OCI_V7_SYNTAX|)), or ((|OCI_V8_SYNTAX|)).
|
160
|
+
Default value is ((|OCI_NTV_SYNTAX|))
|
161
|
+
:mode
|
162
|
+
((|OCI_DEFAULT|)) or ((|OCI_NO_SHARING|)). Default value is ((|OCI_DEFAULT|)).
|
163
|
+
|
164
|
+
((|OCI_NO_SHARING|)) disables ((<Shared Data Mode>)) for this statement.
|
165
|
+
|
166
|
+
correspond native OCI function: ((|OCIStmtPrepare|))
|
167
|
+
=end
|
168
|
+
*/
|
169
|
+
static VALUE oci8_stmt_prepare(int argc, VALUE *argv, VALUE self)
|
170
|
+
{
|
171
|
+
VALUE vsql, vlanguage, vmode;
|
172
|
+
oci8_handle_t *h;
|
173
|
+
oci8_string_t s;
|
174
|
+
ub4 language;
|
175
|
+
ub4 mode;
|
176
|
+
sword rv;
|
177
|
+
VALUE ary;
|
178
|
+
VALUE hash;
|
179
|
+
int i;
|
180
|
+
|
181
|
+
rb_scan_args(argc, argv, "12", &vsql, &vlanguage, &vmode);
|
182
|
+
Get_Handle(self, h); /* 0 */
|
183
|
+
Get_String(vsql, s); /* 1 */
|
184
|
+
Get_Int_With_Default(argc, 2, vlanguage, language, OCI_NTV_SYNTAX); /* 2 */
|
185
|
+
Get_Int_With_Default(argc, 3, vmode, mode, OCI_DEFAULT); /* 3 */
|
186
|
+
|
187
|
+
/* when a new statement is prepared, OCI implicitly free the previous
|
188
|
+
* statement's define and bind handles.
|
189
|
+
* But ruby's object don't know it. So free these handles in advance.
|
190
|
+
*/
|
191
|
+
/* free define handles */
|
192
|
+
ary = rb_ivar_get(self, oci8_id_define_array);
|
193
|
+
if (ary != Qnil) {
|
194
|
+
for (i = 0;i < RARRAY_LEN(ary);i++) {
|
195
|
+
if (RARRAY_PTR(ary)[i] != Qnil)
|
196
|
+
oci8_handle_free(RARRAY_PTR(ary)[i]);
|
197
|
+
}
|
198
|
+
rb_ivar_set(self, oci8_id_define_array, Qnil);
|
199
|
+
}
|
200
|
+
/* free bind handles */
|
201
|
+
hash = rb_ivar_get(self, oci8_id_bind_hash);
|
202
|
+
if (hash != Qnil) {
|
203
|
+
rb_iterate(oci8_each_value, hash, oci8_handle_free, Qnil);
|
204
|
+
rb_ivar_set(self, oci8_id_bind_hash, Qnil);
|
205
|
+
}
|
206
|
+
|
207
|
+
rv = OCIStmtPrepare(h->hp, h->errhp, s.ptr, s.len, language, mode);
|
208
|
+
if (IS_OCI_ERROR(rv)) {
|
209
|
+
oci8_raise(h->errhp, rv, h->hp);
|
210
|
+
}
|
211
|
+
return self;
|
212
|
+
}
|
213
|
+
|
214
|
+
/*
|
215
|
+
=begin
|
216
|
+
--- OCIStmt#defineByPos(position, type [, length [, mode]])
|
217
|
+
define the datatype of fetched column.
|
218
|
+
You must define all column's datatype, before you fetch data.
|
219
|
+
|
220
|
+
:position
|
221
|
+
the position of the column. It starts from 1.
|
222
|
+
:type
|
223
|
+
the type of column.
|
224
|
+
((|String|)), ((|Fixnum|)), ((|Integer|)), ((|Float|)), ((|Time|)),
|
225
|
+
((<OraDate>)), ((<OraNumber>)), or ((|OCI_TYPECODE_RAW|))
|
226
|
+
:length
|
227
|
+
When the 2nd argument is
|
228
|
+
* ((|String|)) or ((|OCI_TYPECODE_RAW|)),
|
229
|
+
the max length of fetched data.
|
230
|
+
* otherwise,
|
231
|
+
its value is ignored.
|
232
|
+
:mode
|
233
|
+
((|OCI_DEFAULT|)), or ((|OCI_DYNAMIC_FETCH|)). But now available value is
|
234
|
+
((|OCI_DEFAULT|)) only. Default value is ((|OCI_DEFAULT|))
|
235
|
+
:return value
|
236
|
+
newly created ((<define handle|OCIDefine>))
|
237
|
+
|
238
|
+
correspond native OCI function: ((|OCIDefineByPos|))
|
239
|
+
=end
|
240
|
+
*/
|
241
|
+
static VALUE oci8_define_by_pos(int argc, VALUE *argv, VALUE self)
|
242
|
+
{
|
243
|
+
VALUE vposition;
|
244
|
+
VALUE vtype;
|
245
|
+
VALUE vlength;
|
246
|
+
VALUE vmode;
|
247
|
+
oci8_handle_t *h;
|
248
|
+
ub4 position;
|
249
|
+
oci8_bind_handle_t *bh;
|
250
|
+
ub2 dty;
|
251
|
+
ub4 mode;
|
252
|
+
dvoid *indp;
|
253
|
+
ub2 *rlenp;
|
254
|
+
dvoid *valuep;
|
255
|
+
OCIDefine *dfnhp = NULL;
|
256
|
+
sword status;
|
257
|
+
VALUE ary;
|
258
|
+
VALUE obj;
|
259
|
+
|
260
|
+
rb_scan_args(argc, argv, "22", &vposition, &vtype, &vlength, &vmode);
|
261
|
+
Get_Handle(self, h); /* 0 */
|
262
|
+
position = NUM2INT(vposition); /* 1 */
|
263
|
+
check_bind_type(OCI_HTYPE_DEFINE, h, vtype, vlength, &bh, &dty); /* 2, 3 */
|
264
|
+
Get_Int_With_Default(argc, 4, vmode, mode, OCI_DEFAULT); /* 4 */
|
265
|
+
|
266
|
+
if (mode & OCI_DYNAMIC_FETCH) {
|
267
|
+
indp = NULL;
|
268
|
+
rlenp = NULL;
|
269
|
+
} else {
|
270
|
+
indp = &(bh->ind);
|
271
|
+
rlenp = (bh->bind_type == BIND_STRING) ? NULL : &bh->rlen;
|
272
|
+
}
|
273
|
+
valuep = &bh->value;
|
274
|
+
status = OCIDefineByPos(h->hp, &dfnhp, h->errhp, position, valuep, bh->value_sz, dty, indp, rlenp, 0, mode);
|
275
|
+
if (status != OCI_SUCCESS) {
|
276
|
+
oci8_unlink((oci8_handle_t *)bh);
|
277
|
+
bh->type = 0;
|
278
|
+
oci8_raise(h->errhp, status, h->hp);
|
279
|
+
}
|
280
|
+
bh->type = OCI_HTYPE_DEFINE;
|
281
|
+
bh->hp = dfnhp;
|
282
|
+
bh->errhp = h->errhp;
|
283
|
+
obj = bh->self;
|
284
|
+
ary = rb_ivar_get(self, oci8_id_define_array);
|
285
|
+
if (ary == Qnil) {
|
286
|
+
ary = rb_ary_new();
|
287
|
+
rb_ivar_set(self, oci8_id_define_array, ary);
|
288
|
+
}
|
289
|
+
rb_ary_store(ary, position - 1, obj);
|
290
|
+
return obj;
|
291
|
+
}
|
292
|
+
|
293
|
+
/*
|
294
|
+
=begin
|
295
|
+
--- OCIStmt#bindByPos(position, type [, length [, mode]])
|
296
|
+
define the datatype of the bind variable by posision.
|
297
|
+
|
298
|
+
:position
|
299
|
+
the position of the bind variable.
|
300
|
+
:type
|
301
|
+
the type of the bind variable.
|
302
|
+
((|String|)), ((|Fixnum|)), ((|Integer|)), ((|Float|)), ((|Time|)),
|
303
|
+
((<OraDate>)), ((<OraNumber>)), or ((|OCI_TYPECODE_RAW|))
|
304
|
+
:length
|
305
|
+
When the 2nd argument is
|
306
|
+
* ((|String|)) or ((|OCI_TYPECODE_RAW|)),
|
307
|
+
the max length of fetched data.
|
308
|
+
* otherwise,
|
309
|
+
its value is ignored.
|
310
|
+
:mode
|
311
|
+
((|OCI_DEFAULT|)), or ((|OCI_DATA_AT_EXEC|)). But now available value is
|
312
|
+
((|OCI_DEFAULT|)) only. Default value is ((|OCI_DEFAULT|))
|
313
|
+
:return value
|
314
|
+
newly created ((<bind handle|OCIBind>))
|
315
|
+
|
316
|
+
correspond native OCI function: ((|OCIBindByPos|))
|
317
|
+
=end
|
318
|
+
*/
|
319
|
+
static VALUE oci8_bind_by_pos(int argc, VALUE *argv, VALUE self)
|
320
|
+
{
|
321
|
+
VALUE vposition;
|
322
|
+
VALUE vtype;
|
323
|
+
VALUE vlength;
|
324
|
+
VALUE vmode;
|
325
|
+
oci8_handle_t *h;
|
326
|
+
ub4 position;
|
327
|
+
oci8_bind_handle_t *bh;
|
328
|
+
ub2 dty;
|
329
|
+
ub4 mode;
|
330
|
+
dvoid *indp;
|
331
|
+
ub2 *rlenp;
|
332
|
+
dvoid *valuep;
|
333
|
+
OCIBind *bindhp = NULL;
|
334
|
+
sword status;
|
335
|
+
VALUE hash;
|
336
|
+
VALUE obj;
|
337
|
+
|
338
|
+
rb_scan_args(argc, argv, "22", &vposition, &vtype, &vlength, &vmode);
|
339
|
+
Get_Handle(self, h); /* 0 */
|
340
|
+
position = NUM2INT(vposition); /* 1 */
|
341
|
+
check_bind_type(OCI_HTYPE_BIND, h, vtype, vlength, &bh, &dty); /* 2, 3 */
|
342
|
+
Get_Int_With_Default(argc, 4, vmode, mode, OCI_DEFAULT); /* 4 */
|
343
|
+
|
344
|
+
if (mode & OCI_DATA_AT_EXEC) {
|
345
|
+
indp = NULL;
|
346
|
+
rlenp = NULL;
|
347
|
+
} else {
|
348
|
+
indp = &(bh->ind);
|
349
|
+
rlenp = (bh->bind_type == BIND_STRING) ? NULL : &bh->rlen;
|
350
|
+
}
|
351
|
+
valuep = &bh->value;
|
352
|
+
status = OCIBindByPos(h->hp, &bindhp, h->errhp, position, valuep, bh->value_sz, dty, indp, rlenp, 0, 0, 0, mode);
|
353
|
+
if (status != OCI_SUCCESS) {
|
354
|
+
oci8_unlink((oci8_handle_t *)bh);
|
355
|
+
bh->type = 0;
|
356
|
+
oci8_raise(h->errhp, status, h->hp);
|
357
|
+
}
|
358
|
+
bh->type = OCI_HTYPE_BIND;
|
359
|
+
bh->hp = bindhp;
|
360
|
+
bh->errhp = h->errhp;
|
361
|
+
obj = bh->self;
|
362
|
+
hash = rb_ivar_get(self, oci8_id_bind_hash);
|
363
|
+
if (hash == Qnil) {
|
364
|
+
hash = rb_hash_new();
|
365
|
+
rb_ivar_set(self, oci8_id_bind_hash, hash);
|
366
|
+
}
|
367
|
+
rb_hash_aset(hash, vposition, obj);
|
368
|
+
return obj;
|
369
|
+
}
|
370
|
+
|
371
|
+
/*
|
372
|
+
=begin
|
373
|
+
--- OCIStmt#bindByName(name, type [, length [, mode]])
|
374
|
+
define the datatype of the bind variable by name.
|
375
|
+
|
376
|
+
:name
|
377
|
+
the name of the bind variable including colon.
|
378
|
+
:type
|
379
|
+
the type of the bind variable.
|
380
|
+
((|String|)), ((|Fixnum|)), ((|Integer|)), ((|Float|)), ((|Time|)),
|
381
|
+
((<OraDate>)), ((<OraNumber>)), or ((|OCI_TYPECODE_RAW|))
|
382
|
+
:length
|
383
|
+
When the 2nd argument is
|
384
|
+
* ((|String|)) or ((|OCI_TYPECODE_RAW|)),
|
385
|
+
the max length of fetched data.
|
386
|
+
* otherwise,
|
387
|
+
its value is ignored.
|
388
|
+
:mode
|
389
|
+
((|OCI_DEFAULT|)), or ((|OCI_DATA_AT_EXEC|)). But now available value is
|
390
|
+
((|OCI_DEFAULT|)) only. Default value is ((|OCI_DEFAULT|))
|
391
|
+
:return value
|
392
|
+
newly created ((<bind handle|OCIBind>))
|
393
|
+
|
394
|
+
for example
|
395
|
+
stmt = env.alloc(OCIStmt)
|
396
|
+
stmt.prepare("SELECT * FROM EMP
|
397
|
+
WHERE ename = :ENAME
|
398
|
+
AND sal > :SAL
|
399
|
+
AND hiredate >= :HIREDATE")
|
400
|
+
b_ename = stmt.bindByName(":ENAME", String, 10)
|
401
|
+
b_sal = stmt.bindByName(":SAL", Fixnum)
|
402
|
+
b_hiredate = stmt.bindByName(":HIREDATE", OraDate)
|
403
|
+
|
404
|
+
correspond native OCI function: ((|OCIBindByName|))
|
405
|
+
=end
|
406
|
+
*/
|
407
|
+
static VALUE oci8_bind_by_name(int argc, VALUE *argv, VALUE self)
|
408
|
+
{
|
409
|
+
VALUE vplaceholder;
|
410
|
+
VALUE vtype;
|
411
|
+
VALUE vlength;
|
412
|
+
VALUE vmode;
|
413
|
+
oci8_handle_t *h;
|
414
|
+
oci8_string_t placeholder;
|
415
|
+
oci8_bind_handle_t *bh;
|
416
|
+
ub2 dty;
|
417
|
+
ub4 mode;
|
418
|
+
dvoid *indp;
|
419
|
+
ub2 *rlenp;
|
420
|
+
dvoid *valuep;
|
421
|
+
OCIBind *bindhp = NULL;
|
422
|
+
sword status;
|
423
|
+
VALUE hash;
|
424
|
+
VALUE obj;
|
425
|
+
|
426
|
+
rb_scan_args(argc, argv, "22", &vplaceholder, &vtype, &vlength, &vmode);
|
427
|
+
Get_Handle(self, h); /* 0 */
|
428
|
+
Get_String(vplaceholder, placeholder); /* 1 */
|
429
|
+
check_bind_type(OCI_HTYPE_BIND, h, vtype, vlength, &bh, &dty); /* 2, 3 */
|
430
|
+
Get_Int_With_Default(argc, 4, vmode, mode, OCI_DEFAULT); /* 4 */
|
431
|
+
|
432
|
+
if (mode & OCI_DATA_AT_EXEC) {
|
433
|
+
indp = NULL;
|
434
|
+
rlenp = NULL;
|
435
|
+
} else {
|
436
|
+
indp = &(bh->ind);
|
437
|
+
rlenp = (bh->bind_type == BIND_STRING) ? NULL : &bh->rlen;
|
438
|
+
}
|
439
|
+
valuep = &bh->value;
|
440
|
+
status = OCIBindByName(h->hp, &bindhp, h->errhp, placeholder.ptr, placeholder.len, valuep, bh->value_sz, dty, indp, rlenp, 0, 0, 0, mode);
|
441
|
+
if (status != OCI_SUCCESS) {
|
442
|
+
oci8_unlink((oci8_handle_t *)bh);
|
443
|
+
bh->type = 0;
|
444
|
+
oci8_raise(h->errhp, status, h->hp);
|
445
|
+
}
|
446
|
+
bh->type = OCI_HTYPE_BIND;
|
447
|
+
bh->hp = bindhp;
|
448
|
+
bh->errhp = h->errhp;
|
449
|
+
obj = bh->self;
|
450
|
+
hash = rb_ivar_get(self, oci8_id_bind_hash);
|
451
|
+
if (hash == Qnil) {
|
452
|
+
hash = rb_hash_new();
|
453
|
+
rb_ivar_set(self, oci8_id_bind_hash, hash);
|
454
|
+
}
|
455
|
+
rb_hash_aset(hash, vplaceholder, obj);
|
456
|
+
return obj;
|
457
|
+
}
|
458
|
+
|
459
|
+
/*
|
460
|
+
=begin
|
461
|
+
--- OCIStmt#execute(svc [, iters [, mode]])
|
462
|
+
execute statement at the ((<service context handle|OCISvcCtx>)).
|
463
|
+
|
464
|
+
:svc
|
465
|
+
((<service context handle|OCISvcCtx>))
|
466
|
+
:iters
|
467
|
+
the number of iterations to execute.
|
468
|
+
|
469
|
+
For select statement, if there are columns which is not defined
|
470
|
+
by ((<OCIStmt#defineByPos>)) and this value is positive, it
|
471
|
+
raises exception. If zero, no exception. In any case you must define
|
472
|
+
all columns before you call ((<OCIStmt#fetch>)).
|
473
|
+
|
474
|
+
For non-select statement, use positive value.
|
475
|
+
|
476
|
+
Default value is 0 for select statement, 1 for non-select statement.
|
477
|
+
|
478
|
+
note: Current implemantation doesn't support array fetch and batch mode, so
|
479
|
+
valid value is 0 or 1.
|
480
|
+
:mode
|
481
|
+
((|OCI_DEFAULT|)), ((|OCI_BATCH_ERRORS|)), ((|OCI_COMMIT_ON_SUCCESS|)),
|
482
|
+
((|OCI_DESCRIBE_ONLY|)), ((|OCI_EXACT_FETCH|)), ((|OCI_PARSE_ONLY|)),
|
483
|
+
any combinations of previous values, or ((|OCI_STMT_SCROLLABLE_READONLY|)).
|
484
|
+
Default value is ((|OCI_DEFAULT|)).
|
485
|
+
|
486
|
+
((|OCI_BATCH_ERRORS|)) and ((|OCI_STMT_SCROLLABLE_READONLY|)) are not
|
487
|
+
supported by current implementation.
|
488
|
+
|
489
|
+
correspond native OCI function: ((|OCIStmtExecute|))
|
490
|
+
=end
|
491
|
+
*/
|
492
|
+
static VALUE oci8_stmt_execute(int argc, VALUE *argv, VALUE self)
|
493
|
+
{
|
494
|
+
VALUE vsvc;
|
495
|
+
VALUE viters;
|
496
|
+
VALUE vmode;
|
497
|
+
oci8_handle_t *h;
|
498
|
+
oci8_handle_t *svch;
|
499
|
+
ub4 mode;
|
500
|
+
ub4 iters;
|
501
|
+
ub2 stmt_type;
|
502
|
+
sword rv;
|
503
|
+
|
504
|
+
rb_scan_args(argc, argv, "12", &vsvc, &viters, &vmode);
|
505
|
+
Get_Handle(self, h); /* 0 */
|
506
|
+
Check_Handle(vsvc, OCISvcCtx, svch); /* 1 */
|
507
|
+
if (argc >= 2) {
|
508
|
+
iters = NUM2UINT(viters); /* 2 */
|
509
|
+
} else {
|
510
|
+
rv = OCIAttrGet(h->hp, OCI_HTYPE_STMT, &stmt_type, 0, OCI_ATTR_STMT_TYPE, h->errhp);
|
511
|
+
if (rv != OCI_SUCCESS) {
|
512
|
+
oci8_raise(h->errhp, rv, h->hp);
|
513
|
+
}
|
514
|
+
if (stmt_type == OCI_STMT_SELECT) {
|
515
|
+
/* for select statement, default value 0. */
|
516
|
+
iters = 0;
|
517
|
+
} else {
|
518
|
+
/* for non-select statement, default value 0. */
|
519
|
+
iters = 1;
|
520
|
+
}
|
521
|
+
}
|
522
|
+
Get_Int_With_Default(argc, 3, vmode, mode, OCI_DEFAULT); /* 3 */
|
523
|
+
|
524
|
+
if (iters > 1) {
|
525
|
+
rb_raise(rb_eArgError, "current implementation doesn't support array fatch or batch mode");
|
526
|
+
}
|
527
|
+
|
528
|
+
rv = OCIStmtExecute(svch->hp, h->hp, h->errhp, iters, 0, NULL, NULL, mode);
|
529
|
+
if (rv == OCI_ERROR) {
|
530
|
+
sb4 errcode;
|
531
|
+
OCIErrorGet(h->errhp, 1, NULL, &errcode, NULL, 0, OCI_HTYPE_ERROR);
|
532
|
+
if (errcode == 1000) {
|
533
|
+
/* run GC to close unreferred cursors when ORA-01000 (maximum open cursors exceeded). */
|
534
|
+
rb_gc();
|
535
|
+
rv = OCIStmtExecute(svch->hp, h->hp, h->errhp, iters, 0, NULL, NULL, mode);
|
536
|
+
}
|
537
|
+
}
|
538
|
+
if (IS_OCI_ERROR(rv)) {
|
539
|
+
oci8_raise(h->errhp, rv, h->hp);
|
540
|
+
}
|
541
|
+
return self;
|
542
|
+
}
|
543
|
+
|
544
|
+
/*
|
545
|
+
=begin
|
546
|
+
--- OCIStmt#fetch([nrows [, orientation [, mode]]])
|
547
|
+
fetch data from select statement.
|
548
|
+
fetched data are stored to previously defined ((<define handle|OCIDefine>)).
|
549
|
+
|
550
|
+
:nrows
|
551
|
+
number of rows to fetch. If zero, cancel the cursor.
|
552
|
+
The default value is 1.
|
553
|
+
|
554
|
+
Because array fetch is not supported, valid value is 0 or 1.
|
555
|
+
|
556
|
+
:orientation
|
557
|
+
orientation to fetch. ((|OCI_FETCH_NEXT|)) only valid.
|
558
|
+
The default value is ((|OCI_FETCH_NEXT|)).
|
559
|
+
|
560
|
+
:mode
|
561
|
+
((|OCI_DEFULT|)) only valid.
|
562
|
+
The default value is ((|OCI_DEFAULT|)).
|
563
|
+
|
564
|
+
:return value
|
565
|
+
array of define handles, which are defined previously,
|
566
|
+
or nil when end of data.
|
567
|
+
|
568
|
+
correspond native OCI function: ((|OCIStmtFetch|))
|
569
|
+
=end
|
570
|
+
*/
|
571
|
+
static VALUE oci8_stmt_fetch(int argc, VALUE *argv, VALUE self)
|
572
|
+
{
|
573
|
+
VALUE vnrows;
|
574
|
+
VALUE vorientation;
|
575
|
+
VALUE vmode;
|
576
|
+
oci8_handle_t *h;
|
577
|
+
ub4 nrows;
|
578
|
+
ub2 orientation;
|
579
|
+
ub4 mode;
|
580
|
+
sword rv;
|
581
|
+
|
582
|
+
rb_scan_args(argc, argv, "03", &vnrows, &vorientation, &vmode);
|
583
|
+
Get_Handle(self, h); /* 0 */
|
584
|
+
Get_Int_With_Default(argc, 1, vnrows, nrows, 1); /* 1 */
|
585
|
+
Get_Int_With_Default(argc, 2, vorientation, orientation, OCI_FETCH_NEXT); /* 2 */
|
586
|
+
Get_Int_With_Default(argc, 3, vmode, mode, OCI_DEFAULT); /* 3 */
|
587
|
+
|
588
|
+
rv = OCIStmtFetch(h->hp, h->errhp, nrows, orientation, mode);
|
589
|
+
if (rv == OCI_NO_DATA) {
|
590
|
+
return Qnil;
|
591
|
+
}
|
592
|
+
if (IS_OCI_ERROR(rv)) {
|
593
|
+
oci8_raise(h->errhp, rv, h->hp);
|
594
|
+
}
|
595
|
+
return rb_ivar_get(self, oci8_id_define_array);
|
596
|
+
}
|
597
|
+
|
598
|
+
/*
|
599
|
+
implemented in param.c
|
600
|
+
=begin
|
601
|
+
--- OCIStmt#paramGet(position)
|
602
|
+
get column information of executed select statement.
|
603
|
+
See ((<Select a table whose column types are unknown.>))
|
604
|
+
|
605
|
+
:posision
|
606
|
+
the position of the column to get parameter. It starts from 1.
|
607
|
+
:return value
|
608
|
+
newly created ((<read-only parameter descriptor|OCIParam>))
|
609
|
+
|
610
|
+
correspond native OCI function: ((|OCIParamGet|))
|
611
|
+
=end
|
612
|
+
*/
|
613
|
+
|
614
|
+
void Init_oci8_stmt(void)
|
615
|
+
{
|
616
|
+
id_alloc = rb_intern("alloc");
|
617
|
+
rb_define_method(cOCIStmt, "prepare", oci8_stmt_prepare, -1);
|
618
|
+
rb_define_method(cOCIStmt, "defineByPos", oci8_define_by_pos, -1);
|
619
|
+
rb_define_method(cOCIStmt, "bindByPos", oci8_bind_by_pos, -1);
|
620
|
+
rb_define_method(cOCIStmt, "bindByName", oci8_bind_by_name, -1);
|
621
|
+
rb_define_method(cOCIStmt, "execute", oci8_stmt_execute, -1);
|
622
|
+
rb_define_method(cOCIStmt, "fetch", oci8_stmt_fetch, -1);
|
623
|
+
rb_define_method(cOCIStmt, "paramGet", oci8_param_get, 1);
|
624
|
+
}
|