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