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.
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
  }