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.
Files changed (89) hide show
  1. data/ChangeLog +1254 -390
  2. data/Makefile +10 -13
  3. data/README +56 -385
  4. data/VERSION +1 -1
  5. data/dist-files +26 -27
  6. data/ext/oci8/.document +1 -0
  7. data/ext/oci8/MANIFEST +0 -4
  8. data/ext/oci8/apiwrap.c.tmpl +172 -0
  9. data/ext/oci8/apiwrap.h.tmpl +61 -0
  10. data/ext/oci8/apiwrap.rb +91 -0
  11. data/ext/oci8/apiwrap.yml +1243 -0
  12. data/ext/oci8/attr.c +124 -384
  13. data/ext/oci8/bind.c +472 -164
  14. data/ext/oci8/encoding.c +196 -0
  15. data/ext/oci8/env.c +84 -253
  16. data/ext/oci8/error.c +196 -127
  17. data/ext/oci8/extconf.rb +82 -59
  18. data/ext/oci8/lob.c +710 -370
  19. data/ext/oci8/metadata.c +359 -0
  20. data/ext/oci8/object.c +622 -0
  21. data/ext/oci8/oci8.c +577 -161
  22. data/ext/oci8/oci8.h +354 -258
  23. data/ext/oci8/oci8lib.c +493 -0
  24. data/ext/oci8/ocidatetime.c +473 -0
  25. data/ext/oci8/ocinumber.c +1123 -24
  26. data/ext/oci8/oraconf.rb +72 -106
  27. data/ext/oci8/oradate.c +511 -321
  28. data/ext/oci8/stmt.c +752 -572
  29. data/ext/oci8/win32.c +131 -0
  30. data/ext/oci8/xmldb.c +383 -0
  31. data/lib/.document +2 -0
  32. data/lib/dbd/OCI8.rb +2 -17
  33. data/lib/oci8.rb.in +41 -1622
  34. data/lib/oci8/.document +5 -0
  35. data/lib/oci8/compat.rb +108 -0
  36. data/lib/oci8/datetime.rb +489 -0
  37. data/lib/oci8/encoding-init.rb +40 -0
  38. data/lib/oci8/encoding.yml +537 -0
  39. data/lib/oci8/metadata.rb +2077 -0
  40. data/lib/oci8/object.rb +548 -0
  41. data/lib/oci8/oci8.rb +773 -0
  42. data/lib/oci8/oracle_version.rb +144 -0
  43. data/metaconfig +3 -3
  44. data/ruby-oci8.gemspec +5 -5
  45. data/setup.rb +4 -4
  46. data/test/config.rb +64 -84
  47. data/test/test_all.rb +14 -21
  48. data/test/test_array_dml.rb +317 -0
  49. data/test/test_bind_raw.rb +18 -25
  50. data/test/test_bind_time.rb +78 -91
  51. data/test/test_break.rb +37 -35
  52. data/test/test_clob.rb +33 -89
  53. data/test/test_connstr.rb +5 -4
  54. data/test/test_datetime.rb +469 -0
  55. data/test/test_dbi.rb +99 -60
  56. data/test/test_dbi_clob.rb +3 -8
  57. data/test/test_metadata.rb +65 -51
  58. data/test/test_oci8.rb +151 -55
  59. data/test/test_oracle_version.rb +70 -0
  60. data/test/test_oradate.rb +76 -83
  61. data/test/test_oranumber.rb +405 -71
  62. data/test/test_rowid.rb +6 -11
  63. metadata +31 -32
  64. data/NEWS +0 -420
  65. data/ext/oci8/const.c +0 -165
  66. data/ext/oci8/define.c +0 -53
  67. data/ext/oci8/describe.c +0 -81
  68. data/ext/oci8/descriptor.c +0 -39
  69. data/ext/oci8/handle.c +0 -273
  70. data/ext/oci8/oranumber.c +0 -445
  71. data/ext/oci8/param.c +0 -37
  72. data/ext/oci8/server.c +0 -182
  73. data/ext/oci8/session.c +0 -99
  74. data/ext/oci8/svcctx.c +0 -238
  75. data/ruby-oci8.spec +0 -62
  76. data/support/README +0 -4
  77. data/support/runit/assert.rb +0 -281
  78. data/support/runit/cui/testrunner.rb +0 -101
  79. data/support/runit/error.rb +0 -4
  80. data/support/runit/method_mappable.rb +0 -20
  81. data/support/runit/robserver.rb +0 -25
  82. data/support/runit/setuppable.rb +0 -15
  83. data/support/runit/teardownable.rb +0 -16
  84. data/support/runit/testcase.rb +0 -113
  85. data/support/runit/testfailure.rb +0 -25
  86. data/support/runit/testresult.rb +0 -121
  87. data/support/runit/testsuite.rb +0 -43
  88. data/support/runit/version.rb +0 -3
  89. data/test/test_describe.rb +0 -137
@@ -1,415 +1,155 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * attr.c
4
+ *
5
+ * $Author: kubo $
6
+ * $Date: 2009-01-12 00:11:09 +0900 (Mon, 12 Jan 2009) $
7
+ *
8
+ * Copyright (C) 2002-2007 KUBO Takehiro <kubo@jiubao.org>
9
+ */
1
10
  #include "oci8.h"
2
11
 
3
- #define ENTRY(name, type, setter, getter) \
4
- {"OCI_ATTR_" #name, OCI_ATTR_##name, type, setter, getter}
5
-
6
- static VALUE get_param(oci8_handle_t *hp, ub4 attr);
7
- static VALUE get_ub4(oci8_handle_t *hp, ub4 attr);
8
- static VALUE get_ub2(oci8_handle_t *hp, ub4 attr);
9
- static VALUE get_ub1(oci8_handle_t *hp, ub4 attr);
10
- static VALUE get_sb1(oci8_handle_t *hp, ub4 attr);
11
- static VALUE get_boolean(oci8_handle_t *hp, ub4 attr);
12
- static VALUE get_precision(oci8_handle_t *hp, ub4 attr);
13
- static VALUE get_string(oci8_handle_t *hp, ub4 attr);
14
- static VALUE get_rowid(oci8_handle_t *hp, ub4 attr);
15
- static VALUE get_oranum_as_int(oci8_handle_t *hp, ub4 attr);
16
- static VALUE get_server(oci8_handle_t *hp, ub4 attr);
17
-
18
- static void set_server(oci8_handle_t *hp, ub4 attr, VALUE value);
19
- static void set_session(oci8_handle_t *hp, ub4 attr, VALUE value);
20
- static void set_ub4(oci8_handle_t *hp, ub4 attr, VALUE value);
21
- static void set_ub2(oci8_handle_t *hp, ub4 attr, VALUE value);
22
- static void set_ub1(oci8_handle_t *hp, ub4 attr, VALUE value);
23
- static void set_no_arg(oci8_handle_t *hp, ub4 attr, VALUE value);
24
- static void set_string(oci8_handle_t *hp, ub4 attr, VALUE value);
25
-
26
- oci8_attr_t oci8_attr_list[] = {
27
- /* Attribute Types */
28
- ENTRY(NONBLOCKING_MODE, ATTR_FOR_HNDL, get_boolean, set_no_arg), /* 3 */
29
- ENTRY(SERVER, ATTR_FOR_HNDL, get_server, set_server), /* 6 */
30
- ENTRY(SESSION, ATTR_FOR_HNDL, NULL, set_session), /* 7 */
31
- ENTRY(ROW_COUNT, ATTR_FOR_HNDL, get_ub4, NULL), /* 9 */
32
- ENTRY(PREFETCH_ROWS, ATTR_FOR_HNDL, NULL, set_ub4), /* 11 */
33
- ENTRY(PREFETCH_MEMORY, ATTR_FOR_HNDL, NULL, set_ub4), /* 13 */
34
- #ifdef OCI_ATTR_FSPRECISION
35
- ENTRY(FSPRECISION, ATTR_FOR_DESC, get_ub1, NULL), /* 16 */
36
- #endif
37
- #ifdef OCI_ATTR_LFPRECISION
38
- ENTRY(LFPRECISION, ATTR_FOR_DESC, get_ub1, NULL), /* 17 */
39
- #endif
40
- ENTRY(PARAM_COUNT, ATTR_FOR_HNDL, get_ub4, NULL), /* 18 */
41
- ENTRY(ROWID, ATTR_FOR_HNDL, get_rowid, NULL), /* 19 */
42
- ENTRY(USERNAME, ATTR_FOR_HNDL, NULL, set_string), /* 22 */
43
- ENTRY(PASSWORD, ATTR_FOR_HNDL, NULL, set_string), /* 23 */
44
- ENTRY(STMT_TYPE, ATTR_FOR_HNDL, get_ub2, NULL), /* 24 */
45
- ENTRY(CHARSET_ID, ATTR_FOR_BOTH, get_ub2, set_ub2), /* 31 */
46
- ENTRY(CHARSET_FORM, ATTR_FOR_BOTH, get_ub1, set_ub1), /* 32 */
47
- ENTRY(MAXDATA_SIZE, ATTR_FOR_HNDL, get_ub2, NULL), /* 33 */
48
- ENTRY(ROWS_RETURNED, ATTR_FOR_HNDL, get_ub4, NULL), /* 42 */
49
- ENTRY(LOBEMPTY, ATTR_FOR_DESC, NULL, set_ub4), /* 45 */
50
- ENTRY(NUM_COLS, ATTR_FOR_DESC, get_ub2, NULL), /* 102 */
51
- ENTRY(LIST_COLUMNS, ATTR_FOR_DESC, get_param, NULL), /* 103 */
52
- ENTRY(CLUSTERED, ATTR_FOR_DESC, get_boolean, NULL), /* 105 */
53
- ENTRY(PARTITIONED, ATTR_FOR_DESC, get_boolean, NULL), /* 106 */
54
- ENTRY(INDEX_ONLY, ATTR_FOR_DESC, get_boolean, NULL), /* 107 */
55
- ENTRY(LIST_ARGUMENTS, ATTR_FOR_DESC, get_param, NULL), /* 108 */
56
- ENTRY(LIST_SUBPROGRAMS, ATTR_FOR_DESC, get_param, NULL), /* 109 */
57
- ENTRY(LINK, ATTR_FOR_DESC, get_string, NULL), /* 111 */
58
- ENTRY(MIN, ATTR_FOR_DESC, get_oranum_as_int, NULL), /* 112 */
59
- ENTRY(MAX, ATTR_FOR_DESC, get_oranum_as_int, NULL), /* 113 */
60
- ENTRY(INCR, ATTR_FOR_DESC, get_oranum_as_int, NULL), /* 114 */
61
- ENTRY(CACHE, ATTR_FOR_DESC, get_oranum_as_int, NULL), /* 115 */
62
- ENTRY(ORDER, ATTR_FOR_DESC, get_boolean, NULL), /* 116 */
63
- ENTRY(HW_MARK, ATTR_FOR_DESC, get_oranum_as_int, NULL), /* 117 */
64
- ENTRY(NUM_PARAMS, ATTR_FOR_DESC, get_ub2, NULL), /* 121 */
65
- ENTRY(OBJID, ATTR_FOR_DESC, get_ub4, NULL), /* 121 */
66
- ENTRY(PTYPE, ATTR_FOR_DESC, get_ub1, NULL), /* 123 */
67
- ENTRY(PARAM, ATTR_FOR_HNDL, get_param, NULL), /* 124 */
68
- /* ENTRY(PARSE_ERROR_OFFSET, ATTR_FOR_HNDL, get_ub2, NULL), */ /* 129 */
69
- #ifdef OCI_ATTR_IS_TEMPORARY
70
- ENTRY(IS_TEMPORARY, ATTR_FOR_DESC, get_boolean, NULL), /* 130 */
71
- #endif
72
- #ifdef OCI_ATTR_IS_INVOKER_RIGHTS
73
- ENTRY(IS_INVOKER_RIGHTS, ATTR_FOR_DESC, get_boolean, NULL), /* 133 */
74
- #endif
75
- #ifdef OCI_ATTR_OBJ_NAME
76
- ENTRY(OBJ_NAME, ATTR_FOR_DESC, get_string, NULL), /* 134 */
77
- #endif
78
- #ifdef OCI_ATTR_OBJ_SCHEMA
79
- ENTRY(OBJ_SCHEMA, ATTR_FOR_DESC, get_string, NULL), /* 135 */
80
- #endif
81
- #ifdef OCI_ATTR_OBJ_ID
82
- ENTRY(OBJ_ID, ATTR_FOR_DESC, get_ub4, NULL), /* 136 */
83
- #endif
84
- #ifdef OCI_ATTR_STATEMENT
85
- ENTRY(STATEMENT, ATTR_FOR_HNDL, get_string, NULL), /* 144 */
86
- #endif
87
- #ifdef OCI_ATTR_MAXCHAR_SIZE
88
- ENTRY(MAXCHAR_SIZE, ATTR_FOR_HNDL, get_ub2, set_ub2), /* 163 */
89
- #endif
90
- #ifdef OCI_ATTR_CURRENT_POSITION
91
- ENTRY(CURRENT_POSITION, ATTR_FOR_HNDL, get_ub4, NULL), /* 164 */
92
- #endif
93
- #ifdef OCI_ATTR_ROWS_FETCHED
94
- ENTRY(ROWS_FETCHED, ATTR_FOR_HNDL, get_ub4, NULL), /* 197 */
95
- #endif
96
- ENTRY(DESC_PUBLIC, ATTR_FOR_HNDL, NULL, set_ub4), /* 250 */
97
-
98
- /* Describe Handle Parameter Attributes */
99
- ENTRY(DATA_SIZE, ATTR_FOR_DESC, get_ub2, NULL), /* 1 */
100
- ENTRY(DATA_TYPE, ATTR_FOR_DESC, get_ub2, NULL), /* 2 */
101
- ENTRY(NAME, ATTR_FOR_DESC, get_string, NULL), /* 4 */
102
- ENTRY(PRECISION, ATTR_FOR_DESC, get_precision, NULL), /* 5 */
103
- ENTRY(SCALE, ATTR_FOR_DESC, get_sb1, NULL), /* 6 */
104
- ENTRY(IS_NULL, ATTR_FOR_DESC, get_boolean, NULL), /* 7 */
105
- ENTRY(TYPE_NAME, ATTR_FOR_DESC, get_string, NULL), /* 8 */
106
- ENTRY(SCHEMA_NAME, ATTR_FOR_DESC, get_string, NULL), /* 9 */
107
- #ifdef OCI_ATTR_CHAR_USED
108
- ENTRY(CHAR_USED, ATTR_FOR_DESC, get_boolean, NULL), /* 285 */
109
- #endif
110
- #ifdef OCI_ATTR_CHAR_SIZE
111
- ENTRY(CHAR_SIZE, ATTR_FOR_DESC, get_ub2, NULL), /* 286 */
112
- #endif
113
- };
114
- size_t oci8_attr_size = sizeof(oci8_attr_list) / sizeof(oci8_attr_list[0]);
115
-
116
- static VALUE get_param(oci8_handle_t *hp, ub4 attr)
117
- {
118
- OCIParam *parmhp;
119
- ub4 as = 0;
120
- oci8_handle_t *parmh;
121
- oci8_handle_t *parenth;
122
- sword rv;
123
-
124
- rv = OCIAttrGet(hp->hp, hp->type, &parmhp, &as, attr, hp->errhp);
125
- if (rv != OCI_SUCCESS)
126
- oci8_raise(hp->errhp, rv, NULL);
127
-
128
- for (parenth = hp;parenth->type == OCI_DTYPE_PARAM;parenth = parenth->parent);
129
- parmh = oci8_make_handle(OCI_DTYPE_PARAM, parmhp, hp->errhp, parenth, 0);
130
- return parmh->self;
131
- }
132
-
133
- #if 0
134
- #define DEFINE_GETTER_FUNC_FOR_NUMBER(attrtype) \
135
- static VALUE get_##attrtype(oci8_handle_t *h, ub4 attr) \
136
- { \
137
- attrtype av;
138
- ub4 as = 0; \
139
- sword rv; \
140
- \
141
- rv = OCIAttrGet(h->hp, h->type, &av, &as, attr, h->errhp); \
142
- if (rv != OCI_SUCCESS) \
143
- oci8_raise(h->errhp, rv, NULL); \
144
- return INT2FIX(av); \
145
- }
146
- #else
147
- #define MARKER_1 0xFE
148
- #define MARKER_2 0xEF
149
- #define DEFINE_GETTER_FUNC_FOR_NUMBER(attrtype) \
150
- static VALUE get_##attrtype(oci8_handle_t *h, ub4 attr) \
151
- { \
152
- union { \
153
- attrtype v; \
154
- unsigned char s[sizeof(attrtype) + 1]; \
155
- } av; \
156
- ub4 as = 0; \
157
- sword rv; \
158
- \
159
- memset(&av, MARKER_1, sizeof(av)); \
160
- rv = OCIAttrGet(h->hp, h->type, &av, &as, attr, h->errhp); \
161
- if (rv != OCI_SUCCESS) \
162
- oci8_raise(h->errhp, rv, NULL); \
163
- if (av.s[sizeof(attrtype)] != MARKER_1) \
164
- rb_bug("overwrite in get_" #attrtype " for %d", attr); \
165
- if (av.s[sizeof(attrtype) -1] == MARKER_1) { \
166
- /* if not overwrited, set another value and retry */ \
167
- av.s[sizeof(attrtype) -1] = MARKER_2; \
168
- rv = OCIAttrGet(h->hp, h->type, &av, &as, attr, h->errhp); \
169
- if (av.s[sizeof(attrtype) -1] == MARKER_2) \
170
- rb_bug("specified size is too small in get_" #attrtype " for %d", attr); \
171
- } \
172
- return INT2FIX(av.v); \
173
- }
174
- #endif
175
-
176
- DEFINE_GETTER_FUNC_FOR_NUMBER(ub4)
177
- DEFINE_GETTER_FUNC_FOR_NUMBER(ub2)
178
- DEFINE_GETTER_FUNC_FOR_NUMBER(ub1)
179
- DEFINE_GETTER_FUNC_FOR_NUMBER(sb1)
180
-
181
- static VALUE get_boolean(oci8_handle_t *h, ub4 attr)
12
+ VALUE oci8_get_sb1_attr(oci8_base_t *base, ub4 attrtype)
182
13
  {
183
- sb1 av;
184
- ub4 as = 0;
185
- sword rv;
14
+ sb1 val;
15
+ sword rv;
186
16
 
187
- rv = OCIAttrGet(h->hp, h->type, &av, &as, attr, h->errhp);
188
- if (rv != OCI_SUCCESS)
189
- oci8_raise(h->errhp, rv, NULL);
190
- return av ? Qtrue : Qfalse;
17
+ rv = OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp);
18
+ if (rv != OCI_SUCCESS)
19
+ oci8_raise(oci8_errhp, rv, NULL);
20
+ return INT2FIX(val);
191
21
  }
192
22
 
193
- static VALUE get_precision(oci8_handle_t *h, ub4 attr)
23
+ VALUE oci8_get_ub2_attr(oci8_base_t *base, ub4 attrtype)
194
24
  {
195
- union {
196
- sb1 _sb1;
197
- sb2 _sb2;
198
- unsigned char s[sizeof(sb2) + 1];
199
- } av;
200
- ub4 as = 0;
201
- int size = sizeof(sb1);
202
- int is_implicit = 0;
203
- sword rv;
204
-
205
- if (h->type == OCI_DTYPE_PARAM) {
206
- if (h->u.param.is_implicit) {
207
- is_implicit = 1;
208
- size = sizeof(sb2);
209
- }
210
- }
25
+ ub2 val;
26
+ sword rv;
211
27
 
212
- /* runtime check */
213
- memset(&av, MARKER_1, sizeof(av));
214
- rv = OCIAttrGet(h->hp, h->type, &av, &as, attr, h->errhp);
215
- if (rv != OCI_SUCCESS)
216
- oci8_raise(h->errhp, rv, NULL);
217
- if (av.s[size] != MARKER_1)
218
- rb_bug("overwrite in get_precision for %d(%s)", attr, is_implicit ? "implicit" : "explicit");
219
- if (av.s[size -1] == MARKER_1) {
220
- /* if not overwrited, set another value and retry */
221
- av.s[size -1] = MARKER_2;
222
- rv = OCIAttrGet(h->hp, h->type, &av, &as, attr, h->errhp);
223
- if (av.s[size -1] == MARKER_2)
224
- rb_bug("specified size is too small in get_precision for %d(%s)", attr, is_implicit ? "implicit" : "explicit");
225
- }
226
- if (!is_implicit) {
227
- return INT2FIX(av._sb1);
228
- } else {
229
- return INT2FIX(av._sb2);
230
- }
28
+ rv = OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp);
29
+ if (rv != OCI_SUCCESS)
30
+ oci8_raise(oci8_errhp, rv, NULL);
31
+ return INT2FIX(val);
231
32
  }
232
33
 
233
- static VALUE get_string(oci8_handle_t *h, ub4 attr)
34
+ VALUE oci8_get_sb2_attr(oci8_base_t *base, ub4 attrtype)
234
35
  {
235
- text *txt;
236
- ub4 size;
237
- sword rv;
36
+ sb2 val;
37
+ sword rv;
238
38
 
239
- rv = OCIAttrGet(h->hp, h->type, &txt, &size, attr, h->errhp);
240
- if (rv != OCI_SUCCESS)
241
- oci8_raise(h->errhp, rv, NULL);
242
- return rb_str_new(TO_CHARPTR(txt), size);
39
+ rv = OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp);
40
+ if (rv != OCI_SUCCESS)
41
+ oci8_raise(oci8_errhp, rv, NULL);
42
+ return INT2FIX(val);
243
43
  }
244
44
 
245
- static VALUE get_rowid(oci8_handle_t *h, ub4 attr)
45
+ VALUE oci8_get_ub4_attr(oci8_base_t *base, ub4 attrtype)
246
46
  {
247
- OCIRowid *rowidhp;
248
- oci8_handle_t *rowidh;
249
- oci8_handle_t *envh;
250
- sword rv;
251
-
252
- /* get environment handle */
253
- for (envh = h; envh->type != OCI_HTYPE_ENV; envh = envh->parent);
254
- rv = OCIDescriptorAlloc(envh->hp, (void *)&rowidhp, OCI_DTYPE_ROWID, 0, NULL);
255
- if (rv != OCI_SUCCESS) {
256
- oci8_env_raise(envh->hp, rv);
257
- }
258
- rv = OCIAttrGet(h->hp, h->type, rowidhp, 0, attr, h->errhp);
259
- if (rv != OCI_SUCCESS) {
260
- OCIDescriptorFree(rowidhp, OCI_DTYPE_ROWID);
261
- oci8_raise(h->errhp, rv, NULL);
262
- }
263
- rowidh = oci8_make_handle(OCI_DTYPE_ROWID, rowidhp, h->errhp, envh, 0);
264
- return rowidh->self;
265
- }
266
-
267
- static VALUE get_oranum_as_int(oci8_handle_t *h, ub4 attr) {
268
- ora_number_t *av;
269
- ub4 as = 0;
270
- sword rv;
271
- char buf[ORA_NUMBER_BUF_SIZE];
272
- size_t len;
273
-
274
- rv = OCIAttrGet(h->hp, h->type, &av, &as, attr, h->errhp);
275
- if (rv != OCI_SUCCESS)
276
- oci8_raise(h->errhp, rv, NULL);
277
- ora_number_to_str(TO_ORATEXT(buf), &len, av, as);
278
- return rb_cstr2inum(buf, 10);
279
- }
280
-
281
- static VALUE get_server(oci8_handle_t *h, ub4 attr)
282
- {
283
- oci8_handle_t *hv;
284
- void *hp;
285
- sword rv;
286
-
287
- rv = OCIAttrGet(h->hp, h->type, &hp, 0, attr, h->errhp);
288
- if (rv != OCI_SUCCESS)
289
- oci8_raise(h->errhp, rv, NULL);
290
- hv = oci8_make_handle(OCI_HTYPE_SERVER, hp, h->errhp, h, 0);
291
- return hv->self;
292
- }
293
-
294
- static void set_server(oci8_handle_t *h, ub4 attr, VALUE value)
295
- {
296
- oci8_handle_t *hv;
297
- sword rv;
298
-
299
- Check_Handle(value, OCIServer, hv);
300
- rv = OCIAttrSet(h->hp, h->type, hv->hp, 0, attr, h->errhp);
301
- if (rv != OCI_SUCCESS)
302
- oci8_raise(h->errhp, rv, NULL);
47
+ ub4 val;
48
+ sword rv;
49
+
50
+ rv = OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp);
51
+ if (rv != OCI_SUCCESS)
52
+ oci8_raise(oci8_errhp, rv, NULL);
53
+ #if SIZEOF_LONG > 4
54
+ return LONG2FIX(val);
55
+ #else
56
+ return ULONG2NUM(val);
57
+ #endif
303
58
  }
304
59
 
305
- static void set_session(oci8_handle_t *h, ub4 attr, VALUE value)
60
+ VALUE oci8_get_string_attr(oci8_base_t *base, ub4 attrtype)
306
61
  {
307
- oci8_handle_t *hv;
308
- sword rv;
62
+ text *val;
63
+ ub4 size;
64
+ sword rv;
309
65
 
310
- Check_Handle(value, OCISession, hv);
311
- rv = OCIAttrSet(h->hp, h->type, hv->hp, 0, attr, h->errhp);
312
- if (rv != OCI_SUCCESS)
313
- oci8_raise(h->errhp, rv, NULL);
66
+ rv = OCIAttrGet(base->hp.ptr, base->type, &val, &size, attrtype, oci8_errhp);
67
+ if (rv != OCI_SUCCESS)
68
+ oci8_raise(oci8_errhp, rv, NULL);
69
+ return rb_external_str_new_with_enc(TO_CHARPTR(val), size, oci8_encoding);
314
70
  }
315
71
 
316
- #define DEFINE_SETTER_FUNC_FOR_NUMBER(attrtype) \
317
- static void set_##attrtype(oci8_handle_t *h, ub4 attr, VALUE value) \
318
- { \
319
- attrtype hv; \
320
- sword rv; \
321
- \
322
- hv = NUM2INT(value); \
323
- rv = OCIAttrSet(h->hp, h->type, &hv, sizeof(attrtype), attr, h->errhp); \
324
- if (rv != OCI_SUCCESS) \
325
- oci8_raise(h->errhp, rv, NULL); \
326
- }
72
+ #define MAX_ROWID_LEN 128
327
73
 
328
- DEFINE_SETTER_FUNC_FOR_NUMBER(ub4)
329
- DEFINE_SETTER_FUNC_FOR_NUMBER(ub2)
330
- DEFINE_SETTER_FUNC_FOR_NUMBER(ub1)
74
+ typedef struct {
75
+ oci8_base_t *base;
76
+ ub4 attrtype;
77
+ OCIRowid *ridp;
78
+ } rowid_arg_t;
331
79
 
332
- static void set_no_arg(oci8_handle_t *h, ub4 attr, VALUE value)
80
+ static VALUE get_rowid_attr(rowid_arg_t *arg)
333
81
  {
334
- sword rv;
335
-
336
- if (!NIL_P(value)) {
337
- rb_raise(rb_eArgError, "invalid argument %s (expect nil: this attribute value is ignored, so set nil)", rb_class2name(CLASS_OF(value)));
338
- }
339
- rv = OCIAttrSet(h->hp, h->type, 0, 0, attr, h->errhp);
340
- if (rv != OCI_SUCCESS)
341
- oci8_raise(h->errhp, rv, NULL);
342
- }
343
-
344
- static void set_string(oci8_handle_t *h, ub4 attr, VALUE value)
345
- {
346
- sword rv;
347
-
348
- Check_Type(value, T_STRING);
349
- rv = OCIAttrSet(h->hp, h->type, RSTRING_PTR(value), RSTRING_LEN(value), attr, h->errhp);
350
- if (rv != OCI_SUCCESS)
351
- oci8_raise(h->errhp, rv, NULL);
82
+ oci8_base_t *base = arg->base;
83
+ ub4 attrtype = arg->attrtype;
84
+ char buf[MAX_ROWID_LEN];
85
+ ub2 buflen;
86
+ sword rv;
87
+
88
+ /* get a rowid descriptor from OCIHandle */
89
+ rv = OCIDescriptorAlloc(oci8_envhp, (dvoid*)&arg->ridp, OCI_DTYPE_ROWID, 0, NULL);
90
+ if (rv != OCI_SUCCESS)
91
+ oci8_env_raise(oci8_envhp, rv);
92
+ rv = OCIAttrGet(base->hp.ptr, base->type, arg->ridp, 0, attrtype, oci8_errhp);
93
+ if (rv != OCI_SUCCESS) {
94
+ oci8_raise(oci8_errhp, rv, NULL);
95
+ }
96
+ /* convert the rowid descriptor to a string. */
97
+ if (have_OCIRowidToChar) {
98
+ /* If OCIRowidToChar is available, use it. */
99
+ buflen = MAX_ROWID_LEN;
100
+ rv = OCIRowidToChar(arg->ridp, TO_ORATEXT(buf), &buflen, oci8_errhp);
101
+ if (rv != OCI_SUCCESS) {
102
+ oci8_raise(oci8_errhp, rv, NULL);
103
+ }
104
+ } else {
105
+ /* If OCIRowidToChar is not available, convert it on
106
+ * Oracle Server.
107
+ */
108
+ oci8_base_t *svc;
109
+ oci8_exec_sql_var_t bind_vars[2];
110
+
111
+ /* search a connection from the handle */
112
+ svc = base;
113
+ while (svc->type != OCI_HTYPE_SVCCTX) {
114
+ svc = svc->parent;
115
+ if (svc == NULL) {
116
+ rb_raise(rb_eRuntimeError, "No connection is found!!");
117
+ }
118
+ }
119
+ /* :strval */
120
+ bind_vars[0].valuep = buf;
121
+ bind_vars[0].value_sz = sizeof(buf);
122
+ bind_vars[0].dty = SQLT_CHR;
123
+ bind_vars[0].indp = NULL;
124
+ bind_vars[0].alenp = &buflen;
125
+ /* :rowid */
126
+ bind_vars[1].valuep = &arg->ridp;
127
+ bind_vars[1].value_sz = sizeof(void *);
128
+ bind_vars[1].dty = SQLT_RDD;
129
+ bind_vars[1].indp = NULL;
130
+ bind_vars[1].alenp = NULL;
131
+ /* convert the rowid descriptor to a string value by querying Oracle server. */
132
+ oci8_exec_sql((oci8_svcctx_t*)svc, "BEGIN :strval := :rowid; END;", 0, NULL, 2, bind_vars, 1);
133
+ if (buflen == 0) {
134
+ return Qnil;
135
+ }
136
+ }
137
+ return rb_external_str_new_with_enc(buf, buflen, rb_usascii_encoding());
352
138
  }
353
139
 
354
- VALUE oci8_attr_set(VALUE self, VALUE vtype, VALUE value)
140
+ static VALUE rowid_ensure(rowid_arg_t *arg)
355
141
  {
356
- oci8_handle_t *h;
357
- ub4 type;
358
- char attr_type_flag;
359
-
360
- Get_Handle(self, h); /* 0 */
361
- type = NUM2UINT(vtype); /* 1 */
362
-
363
- /* check range. */
364
- if (oci8_attr_size <= type)
365
- rb_raise(rb_eArgError, "invalid OCI_ATTR_ type");
366
-
367
- /* check attribute type */
368
- if (h->type < OCI_DTYPE_FIRST)
369
- attr_type_flag = ATTR_FOR_HNDL;
370
- else
371
- attr_type_flag = ATTR_FOR_DESC;
372
- if (!(oci8_attr_list[type].attr_type & attr_type_flag))
373
- rb_raise(rb_eArgError, "invalid OCI_ATTR_ type");
374
-
375
- if (oci8_attr_list[type].set == NULL)
376
- rb_raise(rb_eArgError, "attrSet is not permitted for %s", oci8_attr_list[type].name);
377
-
378
- oci8_attr_list[type].set(h, oci8_attr_list[type].attr, value);
379
-
380
- switch (oci8_attr_list[type].attr) {
381
- case OCI_ATTR_SERVER:
382
- rb_ivar_set(self, oci8_id_server, value);
383
- break;
384
- case OCI_ATTR_SESSION:
385
- rb_ivar_set(self, oci8_id_session, value);
386
- break;
387
- }
388
- return self;
142
+ if (arg->ridp != NULL) {
143
+ OCIDescriptorFree(arg->ridp, OCI_DTYPE_ROWID);
144
+ }
145
+ return Qnil;
389
146
  }
390
147
 
391
- VALUE oci8_attr_get(VALUE self, VALUE vtype)
148
+ VALUE oci8_get_rowid_attr(oci8_base_t *base, ub4 attrtype)
392
149
  {
393
- oci8_handle_t *h;
394
- ub4 type;
395
- char attr_type_flag;
396
-
397
- Get_Handle(self, h); /* 0 */
398
- type = NUM2UINT(vtype); /* 1 */
399
-
400
- /* check range. */
401
- if (oci8_attr_size <= type)
402
- rb_raise(rb_eArgError, "invalid OCI_ATTR_ type");
403
-
404
- /* check attribute type */
405
- if (h->type < OCI_DTYPE_FIRST)
406
- attr_type_flag = ATTR_FOR_HNDL;
407
- else
408
- attr_type_flag = ATTR_FOR_DESC;
409
- if (!(oci8_attr_list[type].attr_type & attr_type_flag))
410
- rb_raise(rb_eArgError, "invalid OCI_ATTR_ type");
411
-
412
- if (oci8_attr_list[type].get == NULL)
413
- rb_raise(rb_eArgError, "attrGet is not permitted for %s", oci8_attr_list[type].name);
414
- return oci8_attr_list[type].get(h, oci8_attr_list[type].attr);
150
+ rowid_arg_t arg;
151
+ arg.base = base;
152
+ arg.attrtype = attrtype;
153
+ arg.ridp = NULL;
154
+ return rb_ensure(get_rowid_attr, (VALUE)&arg, rowid_ensure, (VALUE)&arg);
415
155
  }