ruby-oci8 1.0.7 → 2.0.0
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 +1254 -390
- data/Makefile +10 -13
- data/README +56 -385
- data/VERSION +1 -1
- data/dist-files +26 -27
- data/ext/oci8/.document +1 -0
- data/ext/oci8/MANIFEST +0 -4
- data/ext/oci8/apiwrap.c.tmpl +172 -0
- data/ext/oci8/apiwrap.h.tmpl +61 -0
- data/ext/oci8/apiwrap.rb +91 -0
- data/ext/oci8/apiwrap.yml +1243 -0
- data/ext/oci8/attr.c +124 -384
- data/ext/oci8/bind.c +472 -164
- data/ext/oci8/encoding.c +196 -0
- data/ext/oci8/env.c +84 -253
- data/ext/oci8/error.c +196 -127
- data/ext/oci8/extconf.rb +82 -59
- data/ext/oci8/lob.c +710 -370
- data/ext/oci8/metadata.c +359 -0
- data/ext/oci8/object.c +622 -0
- data/ext/oci8/oci8.c +577 -161
- data/ext/oci8/oci8.h +354 -258
- data/ext/oci8/oci8lib.c +493 -0
- data/ext/oci8/ocidatetime.c +473 -0
- data/ext/oci8/ocinumber.c +1123 -24
- data/ext/oci8/oraconf.rb +72 -106
- data/ext/oci8/oradate.c +511 -321
- data/ext/oci8/stmt.c +752 -572
- data/ext/oci8/win32.c +131 -0
- data/ext/oci8/xmldb.c +383 -0
- data/lib/.document +2 -0
- data/lib/dbd/OCI8.rb +2 -17
- data/lib/oci8.rb.in +41 -1622
- data/lib/oci8/.document +5 -0
- data/lib/oci8/compat.rb +108 -0
- data/lib/oci8/datetime.rb +489 -0
- data/lib/oci8/encoding-init.rb +40 -0
- data/lib/oci8/encoding.yml +537 -0
- data/lib/oci8/metadata.rb +2077 -0
- data/lib/oci8/object.rb +548 -0
- data/lib/oci8/oci8.rb +773 -0
- data/lib/oci8/oracle_version.rb +144 -0
- data/metaconfig +3 -3
- data/ruby-oci8.gemspec +5 -5
- data/setup.rb +4 -4
- data/test/config.rb +64 -84
- data/test/test_all.rb +14 -21
- data/test/test_array_dml.rb +317 -0
- data/test/test_bind_raw.rb +18 -25
- data/test/test_bind_time.rb +78 -91
- data/test/test_break.rb +37 -35
- data/test/test_clob.rb +33 -89
- data/test/test_connstr.rb +5 -4
- data/test/test_datetime.rb +469 -0
- data/test/test_dbi.rb +99 -60
- data/test/test_dbi_clob.rb +3 -8
- data/test/test_metadata.rb +65 -51
- data/test/test_oci8.rb +151 -55
- data/test/test_oracle_version.rb +70 -0
- data/test/test_oradate.rb +76 -83
- data/test/test_oranumber.rb +405 -71
- data/test/test_rowid.rb +6 -11
- metadata +31 -32
- data/NEWS +0 -420
- data/ext/oci8/const.c +0 -165
- data/ext/oci8/define.c +0 -53
- data/ext/oci8/describe.c +0 -81
- data/ext/oci8/descriptor.c +0 -39
- data/ext/oci8/handle.c +0 -273
- data/ext/oci8/oranumber.c +0 -445
- data/ext/oci8/param.c +0 -37
- data/ext/oci8/server.c +0 -182
- data/ext/oci8/session.c +0 -99
- data/ext/oci8/svcctx.c +0 -238
- data/ruby-oci8.spec +0 -62
- data/support/README +0 -4
- data/support/runit/assert.rb +0 -281
- data/support/runit/cui/testrunner.rb +0 -101
- data/support/runit/error.rb +0 -4
- data/support/runit/method_mappable.rb +0 -20
- data/support/runit/robserver.rb +0 -25
- data/support/runit/setuppable.rb +0 -15
- data/support/runit/teardownable.rb +0 -16
- data/support/runit/testcase.rb +0 -113
- data/support/runit/testfailure.rb +0 -25
- data/support/runit/testresult.rb +0 -121
- data/support/runit/testsuite.rb +0 -43
- data/support/runit/version.rb +0 -3
- data/test/test_describe.rb +0 -137
data/ext/oci8/stmt.c
CHANGED
@@ -1,624 +1,804 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
1
2
|
/*
|
2
|
-
|
3
|
-
|
3
|
+
* stmt.c - part of ruby-oci8
|
4
|
+
* implement the methods of OCIStmt.
|
5
|
+
*
|
6
|
+
* Copyright (C) 2002-2007 KUBO Takehiro <kubo@jiubao.org>
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
#include "oci8.h"
|
4
10
|
|
5
|
-
|
11
|
+
static VALUE oci8_sym_select_stmt;
|
12
|
+
static VALUE oci8_sym_update_stmt;
|
13
|
+
static VALUE oci8_sym_delete_stmt;
|
14
|
+
static VALUE oci8_sym_insert_stmt;
|
15
|
+
static VALUE oci8_sym_create_stmt;
|
16
|
+
static VALUE oci8_sym_drop_stmt;
|
17
|
+
static VALUE oci8_sym_alter_stmt;
|
18
|
+
static VALUE oci8_sym_begin_stmt;
|
19
|
+
static VALUE oci8_sym_declare_stmt;
|
20
|
+
static ID id_at_column_metadata;
|
21
|
+
static ID id_at_actual_array_size;
|
22
|
+
static ID id_at_max_array_size;
|
23
|
+
static ID id_each_value;
|
24
|
+
static ID id_at_names;
|
25
|
+
static ID id_empty_p;
|
26
|
+
static ID id_at_con;
|
27
|
+
static ID id_clear;
|
28
|
+
static ID id_set;
|
29
|
+
|
30
|
+
VALUE cOCIStmt;
|
31
|
+
|
32
|
+
typedef struct {
|
33
|
+
oci8_base_t base;
|
34
|
+
VALUE svc;
|
35
|
+
VALUE binds;
|
36
|
+
VALUE defns;
|
37
|
+
} oci8_stmt_t;
|
38
|
+
|
39
|
+
static void oci8_stmt_mark(oci8_base_t *base)
|
40
|
+
{
|
41
|
+
oci8_stmt_t *stmt = (oci8_stmt_t *)base;
|
42
|
+
rb_gc_mark(stmt->svc);
|
43
|
+
rb_gc_mark(stmt->binds);
|
44
|
+
rb_gc_mark(stmt->defns);
|
45
|
+
}
|
6
46
|
|
7
|
-
|
8
|
-
|
9
|
-
|
47
|
+
static void oci8_stmt_free(oci8_base_t *base)
|
48
|
+
{
|
49
|
+
oci8_stmt_t *stmt = (oci8_stmt_t *)base;
|
50
|
+
stmt->svc = Qnil;
|
51
|
+
stmt->binds = Qnil;
|
52
|
+
stmt->defns = Qnil;
|
53
|
+
}
|
10
54
|
|
11
|
-
|
12
|
-
|
13
|
-
|
55
|
+
static oci8_base_class_t oci8_stmt_class = {
|
56
|
+
oci8_stmt_mark,
|
57
|
+
oci8_stmt_free,
|
58
|
+
sizeof(oci8_stmt_t),
|
59
|
+
};
|
14
60
|
|
15
|
-
|
61
|
+
static VALUE oci8_stmt_initialize(int argc, VALUE *argv, VALUE self)
|
62
|
+
{
|
63
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
64
|
+
VALUE svc;
|
65
|
+
VALUE sql;
|
66
|
+
sword rv;
|
67
|
+
|
68
|
+
rb_scan_args(argc, argv, "11", &svc, &sql);
|
69
|
+
|
70
|
+
oci8_check_pid_consistency(oci8_get_svcctx(svc));
|
71
|
+
if (argc > 1)
|
72
|
+
OCI8SafeStringValue(sql);
|
73
|
+
|
74
|
+
rv = OCIHandleAlloc(oci8_envhp, &stmt->base.hp.ptr, OCI_HTYPE_STMT, 0, NULL);
|
75
|
+
if (rv != OCI_SUCCESS)
|
76
|
+
oci8_env_raise(oci8_envhp, rv);
|
77
|
+
stmt->base.type = OCI_HTYPE_STMT;
|
78
|
+
stmt->svc = svc;
|
79
|
+
stmt->binds = rb_hash_new();
|
80
|
+
stmt->defns = rb_ary_new();
|
81
|
+
rb_ivar_set(stmt->base.self, id_at_column_metadata, rb_ary_new());
|
82
|
+
rb_ivar_set(stmt->base.self, id_at_names, Qnil);
|
83
|
+
rb_ivar_set(stmt->base.self, id_at_con, svc);
|
84
|
+
rb_ivar_set(stmt->base.self, id_at_max_array_size, Qnil);
|
85
|
+
|
86
|
+
if (argc > 1) {
|
87
|
+
rv = OCIStmtPrepare(stmt->base.hp.stmt, oci8_errhp, RSTRING_ORATEXT(sql), RSTRING_LEN(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
|
88
|
+
if (IS_OCI_ERROR(rv)) {
|
89
|
+
oci8_raise(oci8_errhp, rv, stmt->base.hp.stmt);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
oci8_link_to_parent((oci8_base_t*)stmt, (oci8_base_t*)DATA_PTR(svc));
|
93
|
+
return Qnil;
|
94
|
+
}
|
16
95
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
96
|
+
static VALUE oci8_define_by_pos(VALUE self, VALUE vposition, VALUE vbindobj)
|
97
|
+
{
|
98
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
99
|
+
ub4 position;
|
100
|
+
oci8_bind_t *obind;
|
101
|
+
const oci8_bind_class_t *bind_class;
|
102
|
+
sword status;
|
103
|
+
ub4 mode;
|
104
|
+
|
105
|
+
position = NUM2INT(vposition); /* 1 */
|
106
|
+
obind = oci8_get_bind(vbindobj); /* 2 */
|
107
|
+
if (obind->base.hp.dfn != NULL) {
|
108
|
+
oci8_base_free(&obind->base); /* TODO: OK? */
|
109
|
+
}
|
110
|
+
bind_class = (const oci8_bind_class_t *)obind->base.klass;
|
111
|
+
if (bind_class->out == NULL) {
|
112
|
+
mode = OCI_DEFAULT;
|
113
|
+
} else {
|
114
|
+
mode = OCI_DYNAMIC_FETCH;
|
115
|
+
}
|
116
|
+
status = OCIDefineByPos(stmt->base.hp.stmt, &obind->base.hp.dfn, oci8_errhp, position, obind->valuep, obind->value_sz, bind_class->dty, NIL_P(obind->tdo) ? obind->u.inds : NULL, NULL, 0, mode);
|
117
|
+
if (status != OCI_SUCCESS) {
|
118
|
+
oci8_raise(oci8_errhp, status, stmt->base.hp.ptr);
|
119
|
+
}
|
120
|
+
obind->base.type = OCI_HTYPE_DEFINE;
|
121
|
+
if (NIL_P(obind->tdo) && obind->maxar_sz > 0) {
|
122
|
+
oci_lc(OCIDefineArrayOfStruct(obind->base.hp.dfn, oci8_errhp, obind->alloc_sz, sizeof(sb2), 0, 0));
|
123
|
+
}
|
124
|
+
if (RTEST(obind->tdo)) {
|
125
|
+
oci8_base_t *tdo = DATA_PTR(obind->tdo);
|
126
|
+
oci_lc(OCIDefineObject(obind->base.hp.dfn, oci8_errhp, tdo->hp.tdo,
|
127
|
+
obind->valuep, 0, obind->u.null_structs, 0));
|
128
|
+
}
|
129
|
+
if (position - 1 < RARRAY_LEN(stmt->defns)) {
|
130
|
+
VALUE old_value = RARRAY_PTR(stmt->defns)[position - 1];
|
131
|
+
if (!NIL_P(old_value)) {
|
132
|
+
oci8_base_free((oci8_base_t*)oci8_get_bind(old_value));
|
133
|
+
}
|
134
|
+
}
|
135
|
+
if (bind_class->csfrm != 0) {
|
136
|
+
oci_lc(OCIAttrSet(obind->base.hp.ptr, OCI_HTYPE_DEFINE, (void*)&bind_class->csfrm, 0, OCI_ATTR_CHARSET_FORM, oci8_errhp));
|
137
|
+
}
|
138
|
+
rb_ary_store(stmt->defns, position - 1, obind->base.self);
|
139
|
+
oci8_unlink_from_parent((oci8_base_t*)obind);
|
140
|
+
oci8_link_to_parent((oci8_base_t*)obind, (oci8_base_t*)stmt);
|
141
|
+
return obind->base.self;
|
142
|
+
}
|
21
143
|
|
22
|
-
static
|
144
|
+
static VALUE oci8_bind(VALUE self, VALUE vplaceholder, VALUE vbindobj)
|
145
|
+
{
|
146
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
147
|
+
char *placeholder_ptr = (char*)-1; /* initialize as an invalid value */
|
148
|
+
ub4 placeholder_len = 0;
|
149
|
+
ub4 position = 0;
|
150
|
+
oci8_bind_t *obind;
|
151
|
+
const oci8_bind_class_t *bind_class;
|
152
|
+
sword status;
|
153
|
+
VALUE old_value;
|
154
|
+
void *indp;
|
155
|
+
ub4 *curelep;
|
156
|
+
ub4 mode;
|
157
|
+
|
158
|
+
if (NIL_P(vplaceholder)) { /* 1 */
|
159
|
+
placeholder_ptr = NULL;
|
160
|
+
placeholder_len = 0;
|
161
|
+
} else if (SYMBOL_P(vplaceholder)) {
|
162
|
+
const char *symname = rb_id2name(SYM2ID(vplaceholder));
|
163
|
+
size_t len = strlen(symname);
|
164
|
+
placeholder_ptr = ALLOCA_N(char, len + 1);
|
165
|
+
placeholder_len = len + 1;
|
166
|
+
placeholder_ptr[0] = ':';
|
167
|
+
memcpy(placeholder_ptr + 1, symname, len);
|
168
|
+
} else if (FIXNUM_P(vplaceholder)) {
|
169
|
+
position = NUM2INT(vplaceholder);
|
170
|
+
} else {
|
171
|
+
OCI8StringValue(vplaceholder);
|
172
|
+
placeholder_ptr = RSTRING_PTR(vplaceholder);
|
173
|
+
placeholder_len = RSTRING_LEN(vplaceholder);
|
174
|
+
}
|
175
|
+
obind = oci8_get_bind(vbindobj); /* 2 */
|
176
|
+
if (obind->base.hp.bnd != NULL) {
|
177
|
+
oci8_base_free(&obind->base); /* TODO: OK? */
|
178
|
+
}
|
179
|
+
bind_class = (const oci8_bind_class_t *)obind->base.klass;
|
180
|
+
if (bind_class->in != NULL || bind_class->out != NULL) {
|
181
|
+
mode = OCI_DATA_AT_EXEC;
|
182
|
+
} else {
|
183
|
+
mode = OCI_DEFAULT;
|
184
|
+
}
|
23
185
|
|
24
|
-
|
186
|
+
indp = NIL_P(obind->tdo) ? obind->u.inds : NULL;
|
187
|
+
if (obind->maxar_sz == 0) {
|
188
|
+
curelep = NULL;
|
189
|
+
} else {
|
190
|
+
curelep = &obind->curar_sz;
|
191
|
+
}
|
192
|
+
if (placeholder_ptr == (char*)-1) {
|
193
|
+
status = OCIBindByPos(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, position, obind->valuep, obind->value_sz, bind_class->dty, indp, NULL, 0, 0, 0, mode);
|
194
|
+
} else {
|
195
|
+
status = OCIBindByName(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, TO_ORATEXT(placeholder_ptr), placeholder_len, obind->valuep, obind->value_sz, bind_class->dty, indp, NULL, 0, 0, 0, mode);
|
196
|
+
}
|
197
|
+
if (status != OCI_SUCCESS) {
|
198
|
+
oci8_raise(oci8_errhp, status, stmt->base.hp.stmt);
|
199
|
+
}
|
200
|
+
obind->base.type = OCI_HTYPE_BIND;
|
201
|
+
if (NIL_P(obind->tdo) && obind->maxar_sz > 0) {
|
202
|
+
oci_lc(OCIBindArrayOfStruct(obind->base.hp.bnd, oci8_errhp, obind->alloc_sz, sizeof(sb2), 0, 0));
|
203
|
+
}
|
204
|
+
if (!NIL_P(obind->tdo)) {
|
205
|
+
oci8_base_t *tdo = DATA_PTR(obind->tdo);
|
206
|
+
oci_lc(OCIBindObject(obind->base.hp.bnd, oci8_errhp, tdo->hp.tdo,
|
207
|
+
obind->valuep, 0, obind->u.null_structs, 0));
|
208
|
+
}
|
209
|
+
if (bind_class->csfrm != 0) {
|
210
|
+
oci_lc(OCIAttrSet(obind->base.hp.ptr, OCI_HTYPE_BIND, (void*)&bind_class->csfrm, 0, OCI_ATTR_CHARSET_FORM, oci8_errhp));
|
211
|
+
}
|
212
|
+
old_value = rb_hash_aref(stmt->binds, vplaceholder);
|
213
|
+
if (!NIL_P(old_value)) {
|
214
|
+
oci8_base_free((oci8_base_t*)oci8_get_bind(old_value));
|
215
|
+
}
|
216
|
+
rb_hash_aset(stmt->binds, vplaceholder, obind->base.self);
|
217
|
+
oci8_unlink_from_parent((oci8_base_t*)obind);
|
218
|
+
oci8_link_to_parent((oci8_base_t*)obind, (oci8_base_t*)stmt);
|
219
|
+
return obind->base.self;
|
220
|
+
}
|
221
|
+
|
222
|
+
static sword oci8_call_stmt_execute(oci8_svcctx_t *svcctx, oci8_stmt_t *stmt, ub4 iters, ub4 mode)
|
25
223
|
{
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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)));
|
224
|
+
sword rv;
|
225
|
+
|
226
|
+
rv = OCIStmtExecute_nb(svcctx, svcctx->base.hp.svc, stmt->base.hp.stmt, oci8_errhp, iters, 0, NULL, NULL, mode);
|
227
|
+
if (rv == OCI_ERROR) {
|
228
|
+
if (oci8_get_error_code(oci8_errhp) == 1000) {
|
229
|
+
/* run GC to close unreferred cursors
|
230
|
+
* when ORA-01000 (maximum open cursors exceeded).
|
231
|
+
*/
|
232
|
+
rb_gc();
|
233
|
+
rv = OCIStmtExecute_nb(svcctx, svcctx->base.hp.svc, stmt->base.hp.stmt, oci8_errhp, iters, 0, NULL, NULL, mode);
|
234
|
+
}
|
235
|
+
}
|
236
|
+
return rv;
|
237
|
+
}
|
238
|
+
|
239
|
+
static VALUE oci8_stmt_execute(VALUE self, VALUE iteration_count)
|
240
|
+
{
|
241
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
242
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(stmt->svc);
|
243
|
+
ub4 iters;
|
244
|
+
ub4 mode;
|
245
|
+
sword rv;
|
246
|
+
|
247
|
+
if (oci8_get_ub2_attr(&stmt->base, OCI_ATTR_STMT_TYPE) == INT2FIX(OCI_STMT_SELECT)) {
|
248
|
+
iters = 0;
|
249
|
+
mode = OCI_DEFAULT;
|
128
250
|
} else {
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
251
|
+
if(!NIL_P(iteration_count))
|
252
|
+
iters = NUM2INT(iteration_count);
|
253
|
+
else
|
254
|
+
iters = 1;
|
255
|
+
mode = svcctx->is_autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT;
|
256
|
+
}
|
257
|
+
rv = oci8_call_stmt_execute(svcctx, stmt, iters, mode);
|
258
|
+
#ifdef USE_DYNAMIC_FETCH
|
259
|
+
while (rv == OCI_NEED_DATA) {
|
260
|
+
oci8_bind_t *obind;
|
261
|
+
const oci8_bind_class_t *bind_class;
|
262
|
+
/* get piece info. */
|
263
|
+
dvoid *hp;
|
264
|
+
ub4 type;
|
265
|
+
ub1 in_out;
|
266
|
+
ub4 iter;
|
267
|
+
ub4 idx;
|
268
|
+
ub1 piece;
|
269
|
+
/* set piece info. */
|
270
|
+
void *valuep;
|
271
|
+
ub4 *alenp;
|
272
|
+
void *indp;
|
273
|
+
|
274
|
+
oci_lc(OCIStmtGetPieceInfo(stmt->base.hp.ptr, oci8_errhp, &hp, &type, &in_out, &iter, &idx, &piece));
|
275
|
+
obind = (oci8_bind_t*)stmt->base.children;
|
276
|
+
do {
|
277
|
+
if (obind->base.hp.ptr == hp) {
|
278
|
+
if (type != OCI_HTYPE_BIND)
|
279
|
+
rb_bug("ruby-oci8: expect OCI_HTYPE_BIND but %d", type);
|
280
|
+
bind_class = (const oci8_bind_class_t *)obind->base.klass;
|
281
|
+
switch (in_out) {
|
282
|
+
case OCI_PARAM_IN:
|
283
|
+
if (bind_class->in == NULL)
|
284
|
+
rb_bug("....");
|
285
|
+
piece = bind_class->in(obind, idx, piece, &valuep, &alenp, &indp);
|
286
|
+
break;
|
287
|
+
case OCI_PARAM_OUT:
|
288
|
+
if (bind_class->out == NULL)
|
289
|
+
rb_bug("....");
|
290
|
+
bind_class->out(obind, idx, piece, &valuep, &alenp, &indp);
|
291
|
+
break;
|
292
|
+
default:
|
293
|
+
rb_bug("ruby-oci8: expect OCI_PARAM_IN or OCI_PARAM_OUT but %d", in_out);
|
294
|
+
}
|
295
|
+
oci_lc(OCIStmtSetPieceInfo(obind->base.hp.ptr, OCI_HTYPE_BIND, oci8_errhp, valuep, alenp, 0, indp, NULL));
|
296
|
+
break;
|
297
|
+
}
|
298
|
+
obind = (oci8_bind_t*)obind->base.next;
|
299
|
+
} while (obind != (oci8_bind_t*)stmt->base.children);
|
300
|
+
if (obind == (oci8_bind_t*)stmt) {
|
301
|
+
rb_bug("ruby-oci8: No bind handle is found.");
|
302
|
+
}
|
303
|
+
rv = oci8_call_stmt_execute(svcctx, stmt, iters, mode);
|
304
|
+
}
|
305
|
+
#endif /* USE_DYNAMIC_FETCH */
|
306
|
+
if (IS_OCI_ERROR(rv)) {
|
307
|
+
oci8_raise(oci8_errhp, rv, stmt->base.hp.stmt);
|
308
|
+
}
|
309
|
+
return self;
|
310
|
+
}
|
311
|
+
|
312
|
+
static VALUE each_value(VALUE obj)
|
313
|
+
{
|
314
|
+
return rb_funcall(obj, id_each_value, 0);
|
315
|
+
}
|
316
|
+
|
317
|
+
static VALUE clear_binds_iterator_proc(VALUE val, VALUE arg)
|
318
|
+
{
|
319
|
+
if(!NIL_P(val)) {
|
320
|
+
oci8_base_free((oci8_base_t*)oci8_get_bind(val));
|
321
|
+
}
|
322
|
+
return Qnil;
|
144
323
|
}
|
145
324
|
|
146
|
-
static VALUE
|
325
|
+
static VALUE oci8_stmt_clear_binds(VALUE self)
|
147
326
|
{
|
148
|
-
|
327
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
328
|
+
|
329
|
+
if(!RTEST(rb_funcall(stmt->binds, id_empty_p, 0)))
|
330
|
+
{
|
331
|
+
rb_iterate(each_value, stmt->binds, clear_binds_iterator_proc, Qnil);
|
332
|
+
rb_funcall(stmt->binds,id_clear,0);
|
333
|
+
}
|
334
|
+
|
335
|
+
return self;
|
336
|
+
}
|
337
|
+
|
338
|
+
static VALUE oci8_stmt_do_fetch(oci8_stmt_t *stmt, oci8_svcctx_t *svcctx)
|
339
|
+
{
|
340
|
+
VALUE ary;
|
341
|
+
sword rv;
|
342
|
+
long idx;
|
343
|
+
oci8_bind_t *obind;
|
344
|
+
const oci8_bind_class_t *bind_class;
|
345
|
+
|
346
|
+
obind = (oci8_bind_t *)stmt->base.children;
|
347
|
+
do {
|
348
|
+
if (obind->base.type == OCI_HTYPE_DEFINE) {
|
349
|
+
bind_class = (const oci8_bind_class_t *)obind->base.klass;
|
350
|
+
if (bind_class->pre_fetch_hook != NULL) {
|
351
|
+
bind_class->pre_fetch_hook(obind, stmt->svc);
|
352
|
+
}
|
353
|
+
}
|
354
|
+
obind = (oci8_bind_t *)obind->base.next;
|
355
|
+
} while (obind != (oci8_bind_t*)stmt->base.children);
|
356
|
+
rv = OCIStmtFetch_nb(svcctx, stmt->base.hp.stmt, oci8_errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
|
357
|
+
#ifdef USE_DYNAMIC_FETCH
|
358
|
+
while (rv == OCI_NEED_DATA) {
|
359
|
+
/* get piece info. */
|
360
|
+
dvoid *hp;
|
361
|
+
ub4 type;
|
362
|
+
ub1 in_out;
|
363
|
+
ub4 iter;
|
364
|
+
ub4 idx;
|
365
|
+
ub1 piece;
|
366
|
+
/* set piece info. */
|
367
|
+
void *valuep;
|
368
|
+
ub4 *alenp;
|
369
|
+
void *indp;
|
370
|
+
|
371
|
+
oci_lc(OCIStmtGetPieceInfo(stmt->base.hp.ptr, oci8_errhp, &hp, &type, &in_out, &iter, &idx, &piece));
|
372
|
+
obind = (oci8_bind_t *)stmt->base.children;
|
373
|
+
do {
|
374
|
+
if (obind->base.hp.ptr == hp) {
|
375
|
+
if (type != OCI_HTYPE_DEFINE)
|
376
|
+
rb_bug("ruby-oci8: expect OCI_HTYPE_DEFINE but %d", type);
|
377
|
+
bind_class = (const oci8_bind_class_t *)obind->base.klass;
|
378
|
+
switch (in_out) {
|
379
|
+
case OCI_PARAM_OUT:
|
380
|
+
if (bind_class->out == NULL)
|
381
|
+
rb_bug("....");
|
382
|
+
bind_class->out(obind, idx, piece, &valuep, &alenp, &indp);
|
383
|
+
break;
|
384
|
+
default:
|
385
|
+
rb_bug("ruby-oci8: expect OCI_PARAM_OUT but %d", in_out);
|
386
|
+
}
|
387
|
+
oci_lc(OCIStmtSetPieceInfo(obind->base.hp.ptr, OCI_HTYPE_DEFINE, oci8_errhp, valuep, alenp, 0, indp, NULL));
|
388
|
+
break;
|
389
|
+
}
|
390
|
+
obind = (oci8_bind_t *)obind->base.next;
|
391
|
+
} while (obind != (oci8_bind_t*)stmt->base.children);
|
392
|
+
if (obind == (oci8_bind_t*)stmt) {
|
393
|
+
rb_bug("ruby-oci8: No define handle is found.");
|
394
|
+
}
|
395
|
+
rv = OCIStmtFetch_nb(svcctx, stmt->base.hp.stmt, oci8_errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
|
396
|
+
}
|
397
|
+
#endif /* USE_DYNAMIC_FETCH */
|
398
|
+
if (rv == OCI_NO_DATA) {
|
399
|
+
return Qnil;
|
400
|
+
}
|
401
|
+
if (IS_OCI_ERROR(rv)) {
|
402
|
+
oci8_raise(oci8_errhp, rv, stmt->base.hp.stmt);
|
403
|
+
}
|
404
|
+
#ifdef USE_DYNAMIC_FETCH
|
405
|
+
obind = (oci8_bind_t *)stmt->base.children;
|
406
|
+
do {
|
407
|
+
/* set piece info. */
|
408
|
+
void *valuep;
|
409
|
+
ub4 *alenp;
|
410
|
+
void *indp;
|
411
|
+
ub1 piece = OCI_LAST_PIECE;
|
412
|
+
|
413
|
+
if (obind->base.type == OCI_HTYPE_DEFINE) {
|
414
|
+
bind_class = (const oci8_bind_class_t *)obind->base.klass;
|
415
|
+
if (bind_class->out != NULL) {
|
416
|
+
if (obind->maxar_sz == 0) {
|
417
|
+
bind_class->out(obind, 0, piece, &valuep, &alenp, &indp);
|
418
|
+
} else {
|
419
|
+
ub4 idx;
|
420
|
+
for (idx = 0; idx < obind->curar_sz; idx++) {
|
421
|
+
bind_class->out(obind, idx, piece, &valuep, &alenp, &indp);
|
422
|
+
}
|
423
|
+
}
|
424
|
+
}
|
425
|
+
}
|
426
|
+
obind = (oci8_bind_t *)obind->base.next;
|
427
|
+
} while (obind != (oci8_bind_t*)stmt->base.children);
|
428
|
+
#endif /* USE_DYNAMIC_FETCH */
|
429
|
+
ary = rb_ary_new2(RARRAY_LEN(stmt->defns));
|
430
|
+
for (idx = 0; idx < RARRAY_LEN(stmt->defns); idx++) {
|
431
|
+
rb_ary_store(ary, idx, rb_funcall(RARRAY_PTR(stmt->defns)[idx], oci8_id_get, 0));
|
432
|
+
}
|
433
|
+
return ary;
|
149
434
|
}
|
150
435
|
|
151
436
|
/*
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
((|OCI_NO_SHARING|)) disables ((<Shared Data Mode>)) for this statement.
|
165
|
-
|
166
|
-
correspond native OCI function: ((|OCIStmtPrepare|))
|
167
|
-
=end
|
437
|
+
* Gets fetched data as array. This is available for select
|
438
|
+
* statement only.
|
439
|
+
*
|
440
|
+
* example:
|
441
|
+
* conn = OCI8.new('scott', 'tiger')
|
442
|
+
* cursor = conn.exec('SELECT * FROM emp')
|
443
|
+
* while r = cursor.fetch()
|
444
|
+
* puts r.join(',')
|
445
|
+
* end
|
446
|
+
* cursor.close
|
447
|
+
* conn.logoff
|
168
448
|
*/
|
169
|
-
static VALUE
|
449
|
+
static VALUE oci8_stmt_fetch(VALUE self)
|
450
|
+
{
|
451
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
452
|
+
oci8_svcctx_t *svcctx = oci8_get_svcctx(stmt->svc);
|
453
|
+
|
454
|
+
if (rb_block_given_p()) {
|
455
|
+
for (;;) {
|
456
|
+
VALUE rs = oci8_stmt_do_fetch(stmt, svcctx);
|
457
|
+
if (NIL_P(rs))
|
458
|
+
return self; /* NEED TO CHECK 0.1 behavior. */
|
459
|
+
rb_yield(rs);
|
460
|
+
}
|
461
|
+
} else {
|
462
|
+
return oci8_stmt_do_fetch(stmt, svcctx);
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
static VALUE oci8_stmt_get_param(VALUE self, VALUE pos)
|
170
467
|
{
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
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;
|
468
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
469
|
+
OCIParam *parmhp = NULL;
|
470
|
+
sword rv;
|
471
|
+
|
472
|
+
Check_Type(pos, T_FIXNUM); /* 1 */
|
473
|
+
rv = OCIParamGet(stmt->base.hp.stmt, OCI_HTYPE_STMT, oci8_errhp, (dvoid *)&parmhp, FIX2INT(pos));
|
474
|
+
if (rv != OCI_SUCCESS) {
|
475
|
+
oci8_raise(oci8_errhp, rv, NULL);
|
476
|
+
}
|
477
|
+
return oci8_metadata_create(parmhp, stmt->svc, self);
|
212
478
|
}
|
213
479
|
|
214
480
|
/*
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
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
|
481
|
+
* gets the type of SQL statement as follows.
|
482
|
+
* * OCI8::STMT_SELECT
|
483
|
+
* * OCI8::STMT_UPDATE
|
484
|
+
* * OCI8::STMT_DELETE
|
485
|
+
* * OCI8::STMT_INSERT
|
486
|
+
* * OCI8::STMT_CREATE
|
487
|
+
* * OCI8::STMT_DROP
|
488
|
+
* * OCI8::STMT_ALTER
|
489
|
+
* * OCI8::STMT_BEGIN (PL/SQL block which starts with a BEGIN keyword)
|
490
|
+
* * OCI8::STMT_DECLARE (PL/SQL block which starts with a DECLARE keyword)
|
491
|
+
* * Other Fixnum value undocumented in Oracle manuals.
|
492
|
+
*
|
493
|
+
* <em>Changes between ruby-oci8 1.0 and 2.0.</em>
|
494
|
+
*
|
495
|
+
* [ruby-oci8 2.0] OCI8::STMT_* are Symbols. (:select_stmt, :update_stmt, etc.)
|
496
|
+
* [ruby-oci8 1.0] OCI8::STMT_* are Fixnums. (1, 2, 3, etc.)
|
240
497
|
*/
|
241
|
-
static VALUE
|
498
|
+
static VALUE oci8_stmt_get_stmt_type(VALUE self)
|
242
499
|
{
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
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;
|
500
|
+
VALUE stmt_type = oci8_get_ub2_attr(DATA_PTR(self), OCI_ATTR_STMT_TYPE);
|
501
|
+
switch (FIX2INT(stmt_type)) {
|
502
|
+
case OCI_STMT_SELECT:
|
503
|
+
return oci8_sym_select_stmt;
|
504
|
+
case OCI_STMT_UPDATE:
|
505
|
+
return oci8_sym_update_stmt;
|
506
|
+
case OCI_STMT_DELETE:
|
507
|
+
return oci8_sym_delete_stmt;
|
508
|
+
case OCI_STMT_INSERT:
|
509
|
+
return oci8_sym_insert_stmt;
|
510
|
+
case OCI_STMT_CREATE:
|
511
|
+
return oci8_sym_create_stmt;
|
512
|
+
case OCI_STMT_DROP:
|
513
|
+
return oci8_sym_drop_stmt;
|
514
|
+
case OCI_STMT_ALTER:
|
515
|
+
return oci8_sym_alter_stmt;
|
516
|
+
case OCI_STMT_BEGIN:
|
517
|
+
return oci8_sym_begin_stmt;
|
518
|
+
case OCI_STMT_DECLARE:
|
519
|
+
return oci8_sym_declare_stmt;
|
520
|
+
default:
|
521
|
+
return stmt_type;
|
522
|
+
}
|
291
523
|
}
|
292
524
|
|
293
525
|
/*
|
294
|
-
|
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
|
526
|
+
* Returns the number of processed rows.
|
318
527
|
*/
|
319
|
-
static VALUE
|
528
|
+
static VALUE oci8_stmt_get_row_count(VALUE self)
|
320
529
|
{
|
321
|
-
|
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;
|
530
|
+
return oci8_get_ub4_attr(DATA_PTR(self), OCI_ATTR_ROW_COUNT);
|
369
531
|
}
|
370
532
|
|
371
533
|
/*
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
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
|
534
|
+
* Get the rowid of the last inserted/updated/deleted row.
|
535
|
+
* This cannot be used for select statements.
|
536
|
+
*
|
537
|
+
* example:
|
538
|
+
* cursor = conn.parse('INSERT INTO foo_table values(:1, :2)', 1, 2)
|
539
|
+
* cursor.exec
|
540
|
+
* cursor.rowid # => the inserted row's rowid
|
541
|
+
*
|
542
|
+
* <em>Changes between ruby-oci8 1.0.3 and 1.0.4.</em>
|
543
|
+
*
|
544
|
+
* [ruby-oci8 1.0.4 or upper] The return value is a String.
|
545
|
+
* [ruby-oci8 1.0.3 or lower] It returns an OCIRowid object.
|
406
546
|
*/
|
407
|
-
static VALUE
|
547
|
+
static VALUE oci8_stmt_get_rowid(VALUE self)
|
548
|
+
{
|
549
|
+
return oci8_get_rowid_attr(DATA_PTR(self), OCI_ATTR_ROWID);
|
550
|
+
}
|
551
|
+
|
552
|
+
static VALUE oci8_stmt_get_param_count(VALUE self)
|
408
553
|
{
|
409
|
-
|
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;
|
554
|
+
return oci8_get_ub4_attr(DATA_PTR(self), OCI_ATTR_PARAM_COUNT);
|
457
555
|
}
|
458
556
|
|
459
557
|
/*
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
558
|
+
* call-seq:
|
559
|
+
* [key]
|
560
|
+
*
|
561
|
+
* Gets the value of the bind variable.
|
562
|
+
*
|
563
|
+
* In case of binding explicitly, use same key with that of
|
564
|
+
* OCI8::Cursor#bind_param. A placeholder can be bound by
|
565
|
+
* name or position. If you bind by name, use that name. If you bind
|
566
|
+
* by position, use the position.
|
567
|
+
*
|
568
|
+
* example:
|
569
|
+
* cursor = conn.parse("BEGIN :out := 'BAR'; END;")
|
570
|
+
* cursor.bind_param(':out', 'FOO') # bind by name
|
571
|
+
* p cursor[':out'] # => 'FOO'
|
572
|
+
* p cursor[1] # => nil
|
573
|
+
* cursor.exec()
|
574
|
+
* p cursor[':out'] # => 'BAR'
|
575
|
+
* p cursor[1] # => nil
|
576
|
+
*
|
577
|
+
* example:
|
578
|
+
* cursor = conn.parse("BEGIN :out := 'BAR'; END;")
|
579
|
+
* cursor.bind_param(1, 'FOO') # bind by position
|
580
|
+
* p cursor[':out'] # => nil
|
581
|
+
* p cursor[1] # => 'FOO'
|
582
|
+
* cursor.exec()
|
583
|
+
* p cursor[':out'] # => nil
|
584
|
+
* p cursor[1] # => 'BAR'
|
585
|
+
*
|
586
|
+
* In case of binding by OCI8#exec or OCI8::Cursor#exec,
|
587
|
+
* get the value by position, which starts from 1.
|
588
|
+
*
|
589
|
+
* example:
|
590
|
+
* cursor = conn.exec("BEGIN :out := 'BAR'; END;", 'FOO')
|
591
|
+
* # 1st bind variable is bound as String with width 3. Its initial value is 'FOO'
|
592
|
+
* # After execute, the value become 'BAR'.
|
593
|
+
* p cursor[1] # => 'BAR'
|
594
|
+
*/
|
595
|
+
static VALUE oci8_stmt_aref(VALUE self, VALUE key)
|
493
596
|
{
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
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);
|
597
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
598
|
+
VALUE obj = rb_hash_aref(stmt->binds, key);
|
599
|
+
if (NIL_P(obj)) {
|
600
|
+
return Qnil;
|
513
601
|
}
|
514
|
-
|
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;
|
602
|
+
return rb_funcall(obj, oci8_id_get, 0);
|
542
603
|
}
|
543
604
|
|
544
605
|
/*
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
606
|
+
* call-seq:
|
607
|
+
* [key] = val
|
608
|
+
*
|
609
|
+
* Sets the value to the bind variable. The way to specify the
|
610
|
+
* +key+ is same with OCI8::Cursor#[]. This is available
|
611
|
+
* to replace the value and execute many times.
|
612
|
+
*
|
613
|
+
* example1:
|
614
|
+
* cursor = conn.parse("INSERT INTO test(col1) VALUES(:1)")
|
615
|
+
* cursor.bind_params(1, nil, String, 3)
|
616
|
+
* ['FOO', 'BAR', 'BAZ'].each do |key|
|
617
|
+
* cursor[1] = key
|
618
|
+
* cursor.exec
|
619
|
+
* end
|
620
|
+
* cursor.close()
|
621
|
+
*
|
622
|
+
* example2:
|
623
|
+
* ['FOO', 'BAR', 'BAZ'].each do |key|
|
624
|
+
* conn.exec("INSERT INTO test(col1) VALUES(:1)", key)
|
625
|
+
* end
|
626
|
+
*
|
627
|
+
* Both example's results are same. But the former will use less resources.
|
628
|
+
*/
|
629
|
+
static VALUE oci8_stmt_aset(VALUE self, VALUE key, VALUE val)
|
630
|
+
{
|
631
|
+
long max_array_size;
|
632
|
+
long actual_array_size;
|
633
|
+
long bind_array_size;
|
634
|
+
|
635
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
636
|
+
VALUE obj = rb_hash_aref(stmt->binds, key);
|
637
|
+
if (NIL_P(obj)) {
|
638
|
+
return Qnil; /* ?? MUST BE ERROR? */
|
639
|
+
}
|
549
640
|
|
550
|
-
|
551
|
-
|
552
|
-
|
641
|
+
if(TYPE(val) == T_ARRAY) {
|
642
|
+
max_array_size = NUM2INT(rb_ivar_get(self, id_at_max_array_size));
|
643
|
+
actual_array_size = NUM2INT(rb_ivar_get(self, id_at_actual_array_size));
|
644
|
+
bind_array_size = RARRAY_LEN(val);
|
553
645
|
|
554
|
-
|
646
|
+
if(actual_array_size > 0 && bind_array_size != actual_array_size) {
|
647
|
+
rb_raise(rb_eRuntimeError, "all binding arrays hould be the same size");
|
648
|
+
}
|
649
|
+
if(bind_array_size <= max_array_size && actual_array_size == 0) {
|
650
|
+
rb_ivar_set(self, id_at_actual_array_size, INT2NUM(bind_array_size));
|
651
|
+
}
|
652
|
+
}
|
555
653
|
|
556
|
-
|
557
|
-
|
558
|
-
The default value is ((|OCI_FETCH_NEXT|)).
|
654
|
+
return rb_funcall(obj, oci8_id_set, 1, val);
|
655
|
+
}
|
559
656
|
|
560
|
-
|
561
|
-
|
562
|
-
|
657
|
+
/*
|
658
|
+
* call-seq:
|
659
|
+
* keys -> an Array
|
660
|
+
*
|
661
|
+
* Returns the keys of bind variables as array.
|
662
|
+
*/
|
663
|
+
static VALUE oci8_stmt_keys(VALUE self)
|
664
|
+
{
|
665
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
666
|
+
return rb_funcall(stmt->binds, oci8_id_keys, 0);
|
667
|
+
}
|
563
668
|
|
564
|
-
|
565
|
-
|
566
|
-
|
669
|
+
static VALUE oci8_stmt_defined_p(VALUE self, VALUE pos)
|
670
|
+
{
|
671
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
672
|
+
long position = NUM2INT(pos);
|
673
|
+
|
674
|
+
if (position - 1 < RARRAY_LEN(stmt->defns)) {
|
675
|
+
VALUE value = RARRAY_PTR(stmt->defns)[position - 1];
|
676
|
+
if (!NIL_P(value)) {
|
677
|
+
return Qtrue;
|
678
|
+
}
|
679
|
+
}
|
680
|
+
return Qfalse;
|
681
|
+
}
|
567
682
|
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
683
|
+
/*
|
684
|
+
* call-seq:
|
685
|
+
* prefetch_rows = aFixnum
|
686
|
+
*
|
687
|
+
* Set number of rows to be prefetched.
|
688
|
+
* This can reduce the number of network round trips when fetching
|
689
|
+
* many rows. The default value is one.
|
690
|
+
*
|
691
|
+
* FYI: Rails oracle adaptor uses 100 by default.
|
692
|
+
*/
|
693
|
+
static VALUE oci8_stmt_set_prefetch_rows(VALUE self, VALUE rows)
|
572
694
|
{
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
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
|
-
}
|
695
|
+
oci8_stmt_t *stmt = DATA_PTR(self);
|
696
|
+
ub4 num = NUM2UINT(rows);
|
697
|
+
|
698
|
+
oci_lc(OCIAttrSet(stmt->base.hp.ptr, OCI_HTYPE_STMT, &num, 0, OCI_ATTR_PREFETCH_ROWS, oci8_errhp));
|
699
|
+
return Qfalse;
|
700
|
+
}
|
597
701
|
|
598
702
|
/*
|
599
|
-
|
600
|
-
|
601
|
-
|
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)
|
703
|
+
* bind_stmt
|
704
|
+
*/
|
705
|
+
VALUE oci8_stmt_get(oci8_bind_t *obind, void *data, void *null_struct)
|
615
706
|
{
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
707
|
+
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
|
708
|
+
rb_funcall(oho->obj, rb_intern("define_columns"), 0);
|
709
|
+
return oho->obj;
|
710
|
+
}
|
711
|
+
|
712
|
+
static void bind_stmt_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
713
|
+
{
|
714
|
+
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
|
715
|
+
oci8_base_t *h;
|
716
|
+
if (!rb_obj_is_instance_of(val, cOCIStmt))
|
717
|
+
rb_raise(rb_eArgError, "Invalid argument: %s (expect OCIStmt)", rb_class2name(CLASS_OF(val)));
|
718
|
+
h = DATA_PTR(val);
|
719
|
+
oho->hp = h->hp.ptr;
|
720
|
+
oho->obj = val;
|
721
|
+
}
|
722
|
+
|
723
|
+
static void bind_stmt_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
724
|
+
{
|
725
|
+
obind->value_sz = sizeof(void *);
|
726
|
+
obind->alloc_sz = sizeof(oci8_hp_obj_t);
|
727
|
+
}
|
728
|
+
|
729
|
+
static void bind_stmt_init_elem(oci8_bind_t *obind, VALUE svc)
|
730
|
+
{
|
731
|
+
oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
|
732
|
+
oci8_base_t *h;
|
733
|
+
ub4 idx = 0;
|
734
|
+
|
735
|
+
do {
|
736
|
+
oho[idx].obj = rb_funcall(cOCIStmt, oci8_id_new, 1, svc);
|
737
|
+
h = DATA_PTR(oho[idx].obj);
|
738
|
+
oho[idx].hp = h->hp.ptr;
|
739
|
+
} while (++idx < obind->maxar_sz);
|
740
|
+
}
|
741
|
+
|
742
|
+
static const oci8_bind_class_t bind_stmt_class = {
|
743
|
+
{
|
744
|
+
oci8_bind_hp_obj_mark,
|
745
|
+
oci8_bind_free,
|
746
|
+
sizeof(oci8_bind_t)
|
747
|
+
},
|
748
|
+
oci8_stmt_get,
|
749
|
+
bind_stmt_set,
|
750
|
+
bind_stmt_init,
|
751
|
+
bind_stmt_init_elem,
|
752
|
+
NULL,
|
753
|
+
NULL,
|
754
|
+
bind_stmt_init_elem,
|
755
|
+
SQLT_RSET
|
756
|
+
};
|
757
|
+
|
758
|
+
void Init_oci8_stmt(VALUE cOCI8)
|
759
|
+
{
|
760
|
+
#if 0
|
761
|
+
cOCIHandle = rb_define_class("OCIHandle", rb_cObject);
|
762
|
+
cOCI8 = rb_define_class("OCI8", cOCIHandle);
|
763
|
+
cOCIStmt = rb_define_class_under(cOCI8, "Cursor", cOCIHandle);
|
764
|
+
#endif
|
765
|
+
cOCIStmt = oci8_define_class_under(cOCI8, "Cursor", &oci8_stmt_class);
|
766
|
+
|
767
|
+
oci8_sym_select_stmt = ID2SYM(rb_intern("select_stmt"));
|
768
|
+
oci8_sym_update_stmt = ID2SYM(rb_intern("update_stmt"));
|
769
|
+
oci8_sym_delete_stmt = ID2SYM(rb_intern("delete_stmt"));
|
770
|
+
oci8_sym_insert_stmt = ID2SYM(rb_intern("insert_stmt"));
|
771
|
+
oci8_sym_create_stmt = ID2SYM(rb_intern("create_stmt"));
|
772
|
+
oci8_sym_drop_stmt = ID2SYM(rb_intern("drop_stmt"));
|
773
|
+
oci8_sym_alter_stmt = ID2SYM(rb_intern("alter_stmt"));
|
774
|
+
oci8_sym_begin_stmt = ID2SYM(rb_intern("begin_stmt"));
|
775
|
+
oci8_sym_declare_stmt = ID2SYM(rb_intern("declare_stmt"));
|
776
|
+
id_at_column_metadata = rb_intern("@column_metadata");
|
777
|
+
id_at_actual_array_size = rb_intern("@actual_array_size");
|
778
|
+
id_at_max_array_size = rb_intern("@max_array_size");
|
779
|
+
id_each_value = rb_intern("each_value");
|
780
|
+
id_at_names = rb_intern("@names");
|
781
|
+
id_at_con = rb_intern("@con");
|
782
|
+
id_empty_p = rb_intern("empty?");
|
783
|
+
id_clear = rb_intern("clear");
|
784
|
+
id_set = rb_intern("set");
|
785
|
+
|
786
|
+
rb_define_private_method(cOCIStmt, "initialize", oci8_stmt_initialize, -1);
|
787
|
+
rb_define_private_method(cOCIStmt, "__define", oci8_define_by_pos, 2);
|
788
|
+
rb_define_private_method(cOCIStmt, "__bind", oci8_bind, 2);
|
789
|
+
rb_define_private_method(cOCIStmt, "__execute", oci8_stmt_execute, 1);
|
790
|
+
rb_define_private_method(cOCIStmt, "__clearBinds", oci8_stmt_clear_binds, 0);
|
791
|
+
rb_define_method(cOCIStmt, "fetch", oci8_stmt_fetch, 0);
|
792
|
+
rb_define_private_method(cOCIStmt, "__paramGet", oci8_stmt_get_param, 1);
|
793
|
+
rb_define_method(cOCIStmt, "type", oci8_stmt_get_stmt_type, 0);
|
794
|
+
rb_define_method(cOCIStmt, "row_count", oci8_stmt_get_row_count, 0);
|
795
|
+
rb_define_method(cOCIStmt, "rowid", oci8_stmt_get_rowid, 0);
|
796
|
+
rb_define_private_method(cOCIStmt, "__param_count", oci8_stmt_get_param_count, 0);
|
797
|
+
rb_define_method(cOCIStmt, "[]", oci8_stmt_aref, 1);
|
798
|
+
rb_define_method(cOCIStmt, "[]=", oci8_stmt_aset, 2);
|
799
|
+
rb_define_method(cOCIStmt, "keys", oci8_stmt_keys, 0);
|
800
|
+
rb_define_private_method(cOCIStmt, "__defined?", oci8_stmt_defined_p, 1);
|
801
|
+
rb_define_method(cOCIStmt, "prefetch_rows=", oci8_stmt_set_prefetch_rows, 1);
|
802
|
+
|
803
|
+
oci8_define_bind_class("Cursor", &bind_stmt_class);
|
624
804
|
}
|