ruby-oci8 2.0.6 → 2.1.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 (59) hide show
  1. data/ChangeLog +366 -19
  2. data/Makefile +2 -8
  3. data/NEWS +111 -0
  4. data/README +4 -85
  5. data/VERSION +1 -1
  6. data/dist-files +9 -2
  7. data/ext/oci8/.document +1 -0
  8. data/ext/oci8/apiwrap.c.tmpl +12 -2
  9. data/ext/oci8/apiwrap.yml +37 -21
  10. data/ext/oci8/attr.c +23 -74
  11. data/ext/oci8/bind.c +93 -225
  12. data/ext/oci8/connection_pool.c +201 -0
  13. data/ext/oci8/encoding.c +117 -24
  14. data/ext/oci8/env.c +5 -10
  15. data/ext/oci8/error.c +171 -189
  16. data/ext/oci8/extconf.rb +6 -2
  17. data/ext/oci8/lob.c +81 -79
  18. data/ext/oci8/metadata.c +42 -177
  19. data/ext/oci8/object.c +55 -28
  20. data/ext/oci8/oci8.c +426 -294
  21. data/ext/oci8/oci8.h +84 -51
  22. data/ext/oci8/oci8lib.c +75 -53
  23. data/ext/oci8/ocidatetime.c +67 -88
  24. data/ext/oci8/ocihandle.c +78 -37
  25. data/ext/oci8/ocinumber.c +166 -109
  26. data/ext/oci8/oraconf.rb +68 -157
  27. data/ext/oci8/oradate.c +2 -7
  28. data/ext/oci8/stmt.c +40 -183
  29. data/ext/oci8/thread_util.c +85 -0
  30. data/ext/oci8/thread_util.h +30 -0
  31. data/lib/oci8.rb.in +19 -13
  32. data/lib/oci8/.document +2 -0
  33. data/lib/oci8/bindtype.rb +62 -45
  34. data/lib/oci8/connection_pool.rb +118 -0
  35. data/lib/oci8/datetime.rb +304 -320
  36. data/lib/oci8/encoding-init.rb +62 -30
  37. data/lib/oci8/encoding.yml +3 -3
  38. data/lib/oci8/metadata.rb +552 -497
  39. data/lib/oci8/object.rb +9 -9
  40. data/lib/oci8/oci8.rb +161 -2
  41. data/lib/oci8/ocihandle.rb +427 -0
  42. data/lib/oci8/properties.rb +31 -1
  43. data/ruby-oci8.gemspec +10 -3
  44. data/test/README +41 -3
  45. data/test/config.rb +16 -0
  46. data/test/test_all.rb +3 -0
  47. data/test/test_bind_string.rb +106 -0
  48. data/test/test_break.rb +33 -7
  49. data/test/test_clob.rb +13 -10
  50. data/test/test_connection_pool.rb +125 -0
  51. data/test/test_connstr.rb +2 -2
  52. data/test/test_datetime.rb +26 -66
  53. data/test/test_encoding.rb +7 -3
  54. data/test/test_error.rb +88 -0
  55. data/test/test_metadata.rb +1356 -204
  56. data/test/test_oci8.rb +27 -8
  57. data/test/test_oranumber.rb +41 -0
  58. metadata +34 -9
  59. data/ext/oci8/xmldb.c +0 -383
data/NEWS CHANGED
@@ -1,3 +1,114 @@
1
+ 2.1.0:
2
+
3
+ *** Ruby-oci8 2.1.0 doesn't support Oracle 8 (8.0) and Oracle 8i (8.1) anymore. ***
4
+
5
+ * New Features
6
+
7
+ - OCI connection pooling
8
+
9
+ See: http://docs.oracle.com/cd/E11882_01/appdev.112/e10646/oci09adv.htm#sthref1479
10
+ and http://docs.oracle.com/cd/E11882_01/java.112/e16548/ociconpl.htm#JJDBC28789
11
+
12
+ Example:
13
+
14
+ # Create a connection pool.
15
+ # username and password are required to establish an implicit primary session.
16
+ cpool = OCI8::ConnectionPool.new(1, 5, 2, username, password, database)
17
+
18
+ # Get a session from the pool.
19
+ # Pass the connection pool to the third argument.
20
+ conn1 = OCI8.new(username, password, cpool)
21
+
22
+ # Get another session.
23
+ conn2 = OCI8.new(username, password, cpool)
24
+
25
+ - Daylight saving time aware if TZ is set.
26
+
27
+ You should set the environment variable TZ if your applications run
28
+ in a time zone with daylight saving time transitions.
29
+ Otherwise, Oracle session time zone is set with current constant
30
+ offset from GMT.
31
+ (reported by Yasuo Honda)
32
+
33
+ - connect as sysasm (Oracle 11g only)
34
+
35
+ OCI8.new('username/password as sysasm')
36
+ or
37
+ OCI8.new('username', 'password', nil, :SYSASM)
38
+
39
+ - Oracle number is converted to ruby float exactly same as ruby does.
40
+
41
+ From ruby 1.9.2, a float value converted from Oracle number 15.7 by
42
+ the Oracle function OCINumberToReal() makes a string representation
43
+ 15.700000000000001 by Float#to_s. (See: http://redmine.ruby-lang.org/issues/4656)
44
+ To avoid this issue, any Oracle number is converted to a float as
45
+ ruby's String#to_f does.
46
+
47
+ The behavior is customizable by OCI8.properties[:float_conversion_type].
48
+
49
+ OCI8.properties[:float_conversion_type] = :oracle # => Use OCINumberToReal()
50
+ OCI8.properties[:float_conversion_type] = :ruby # => Use String#to_f
51
+
52
+ The default value is :ruby.
53
+
54
+ - OCI_SUCCESS_WITH_INFO handling is changed.
55
+
56
+ Ruby-oci8 2.0 treats OCI_SUCCESS_WITH_INFO in OCI layer as an error
57
+ and raise an exception OCISuccessWithInfo such as "ORA-24347: Warning of
58
+ a NULL column in an aggregate function" and "ORA-28002: the password will
59
+ expire within xx days."
60
+
61
+ From 2.1.0, it is treated as a warning and the exception is set
62
+ to OCI8#last_error.
63
+
64
+ - OCI8#last_error
65
+
66
+ The last error or warning associated with the session is set to
67
+ OCI8#last_error. The usecase is to detect OCI_SUCCESS_WITH_INFO.
68
+ It is reset by OCI8#exec and OCI8#parse.
69
+
70
+ - Experimental support of character length semantics
71
+
72
+ This is enabled when :char is set to OCI8.properties[:length_semantics].
73
+
74
+ - OCI8.client_charset_name and OCI8#database_charset_name is added.
75
+
76
+ They return Oracle charset name such as WE8ISO8859P15.
77
+
78
+ * Specification changes
79
+
80
+ - The parent class OCINoData was changed from OCIException to OCIError.
81
+
82
+ * Fixed Issues
83
+
84
+ - Fix a bug that an array is always bound as null.
85
+ This bug was introduced in ruby-oci8 2.0.5.
86
+ (reported by Leoš Bitto)
87
+
88
+ - Avoid a gcc internal compiler error when using ruby1.9.2-p290 on
89
+ ubuntu 11.10 (64bit). (reported by Bob Saveland.)
90
+
91
+ - Fix compilation problems on Solaris.
92
+ (Reported by Sanjiv Patel.)
93
+
94
+ - Fix compilation problems on Linux.
95
+ (Reported by Edgars Beigarts.)
96
+
97
+ - Connections are released by GC without explicit logoff.
98
+
99
+ - Set ruby encoding CP950 for oracle characterset ZHT16MSWIN950 and
100
+ CP951 for ZHT16HKSCS and ZHT16HKSCS31 when the ruby is 1.9.3.
101
+
102
+ - Clear an executuing thread information in a connection when a SQL
103
+ executions is canceled by Thread#kill or Timeout::timeout.
104
+ (reported by Aaron Qian)
105
+
106
+ - Fix some test cases for object type and TZ issues.
107
+ (reported by Yasuo Honda)
108
+
109
+ - Use Gem::Command.build_args to get arguments after '--'.
110
+ (reported by jbirdjavi)
111
+
1
112
  2.0.6:
2
113
 
3
114
  * Fixed issues
data/README CHANGED
@@ -1,86 +1,5 @@
1
- = How to make
1
+ Ruby-oci8 is a ruby interface for Oracle using OCI8 API.
2
+ The latest version (2.1.x) works with Oracle9i or later.
3
+ Use ruby-oci8 2.0.6 or earlier for Oracle 8.
2
4
 
3
- * <tt>ruby</tt> and <tt>make</tt> (or nmake on MSVC) commands in the environment variable <tt>PATH</tt>?
4
- * <tt>ruby</tt> is 1.8.0 or later? (Use ruby-oci8 0.1.x for ruby 1.6.x.)
5
-
6
- == For OCI installed by Oracle Universal Installer
7
- make sure the environment variable ORACLE_HOME (or registry on Windows)
8
- is set correctly. run the the following commands.
9
-
10
- make (or nmake on MSVC)
11
-
12
- == For OCI installed by Oracle Instant Installer
13
-
14
- linux:
15
- ruby setup.rb config -- --with-instant-client
16
- make
17
-
18
- others:
19
- ruby setup.rb config -- --with-instant-client=/path/to/instantclient10_1
20
- make (or nmake on MSVC)
21
-
22
- = On compilation failure
23
-
24
- Please report the following information to kubo@jiubao.org.
25
-
26
- * last 100 lines of 'ext/oci8/mkmf.log'.
27
- * the results of the following commands:
28
- ruby -r rbconfig -e "p Config::CONFIG['host']"
29
- ruby -r rbconfig -e "p Config::CONFIG['CC']"
30
- ruby -r rbconfig -e "p Config::CONFIG['CFLAGS']"
31
- ruby -r rbconfig -e "p Config::CONFIG['LDSHARED']"
32
- ruby -r rbconfig -e "p Config::CONFIG['LDFLAGS']"
33
- ruby -r rbconfig -e "p Config::CONFIG['LIBS']"
34
- ruby -r rbconfig -e "p Config::CONFIG['GNU_LD']"
35
- * if you use gcc:
36
- gcc --print-prog-name=ld
37
- gcc --print-prog-name=as
38
- * on platforms which can use both 32bit/64bit binaries:
39
- file $ORACLE_HOME/bin/oracle
40
- file `which ruby`
41
- echo $LD_LIBRARY_PATH
42
-
43
- = How to run unit test
44
-
45
- before runing unit test,
46
- 1. connect to Oracle as system:
47
-
48
- $ sqlplus system/<password_of_system>
49
-
50
- 2. create user ruby:
51
-
52
- SQL> CREATE USER ruby IDENTIFIED BY oci8;
53
-
54
- or
55
-
56
- SQL> CREATE USER ruby IDENTIFIED BY oci8
57
- 2 DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
58
-
59
- 3. grant the privilege to connect and execute.
60
-
61
- SQL> GRANT connect, resource TO ruby;
62
-
63
- 4. If the Oracle version is 8i or later:
64
-
65
- SQL> CREATE TABLE ruby.test_clob (filename VARCHAR2(40), content CLOB);
66
-
67
- 5. connect to Oracle as sys
68
-
69
- $ sqlplus 'sys/<password_of_sys> as sysdba'
70
-
71
- 6. grant the privilege for the unittest of blocking-mode.
72
-
73
- SQL> GRANT EXECUTE ON dbms_lock TO ruby;
74
-
75
- 7. change test/config.rb as you like
76
-
77
- Then you can run:
78
- $ make check
79
- or
80
- $ nmake check (If your compiler is MS Visual C++.)
81
-
82
- = TODO
83
-
84
- * more proper handling of OCI_SUCCESS_WITH_INFO.
85
- * more proper handling of NUMBER without its scale values.
86
- * support Timestamp.
5
+ See: http://ruby-oci8.rubyforge.org
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.6
1
+ 2.1.0
data/dist-files CHANGED
@@ -21,12 +21,14 @@ ext/oci8/apiwrap.rb
21
21
  ext/oci8/apiwrap.yml
22
22
  ext/oci8/attr.c
23
23
  ext/oci8/bind.c
24
+ ext/oci8/connection_pool.c
24
25
  ext/oci8/encoding.c
25
26
  ext/oci8/env.c
26
27
  ext/oci8/error.c
27
28
  ext/oci8/extconf.rb
28
29
  ext/oci8/lob.c
29
30
  ext/oci8/metadata.c
31
+ ext/oci8/object.c
30
32
  ext/oci8/oci8.c
31
33
  ext/oci8/oci8.h
32
34
  ext/oci8/oci8lib.c
@@ -39,21 +41,23 @@ ext/oci8/oranumber_util.c
39
41
  ext/oci8/oranumber_util.h
40
42
  ext/oci8/post-config.rb
41
43
  ext/oci8/stmt.c
42
- ext/oci8/object.c
44
+ ext/oci8/thread_util.c
45
+ ext/oci8/thread_util.h
43
46
  ext/oci8/win32.c
44
- ext/oci8/xmldb.c
45
47
  lib/.document
46
48
  lib/oci8.rb.in
47
49
  lib/dbd/OCI8.rb
48
50
  lib/oci8/.document
49
51
  lib/oci8/bindtype.rb
50
52
  lib/oci8/compat.rb
53
+ lib/oci8/connection_pool.rb
51
54
  lib/oci8/datetime.rb
52
55
  lib/oci8/encoding-init.rb
53
56
  lib/oci8/encoding.yml
54
57
  lib/oci8/metadata.rb
55
58
  lib/oci8/object.rb
56
59
  lib/oci8/oci8.rb
60
+ lib/oci8/ocihandle.rb
57
61
  lib/oci8/oracle_version.rb
58
62
  lib/oci8/properties.rb
59
63
  test/README
@@ -62,14 +66,17 @@ test/test_all.rb
62
66
  test/test_appinfo.rb
63
67
  test/test_array_dml.rb
64
68
  test/test_bind_raw.rb
69
+ test/test_bind_string.rb
65
70
  test/test_bind_time.rb
66
71
  test/test_break.rb
67
72
  test/test_clob.rb
73
+ test/test_connection_pool.rb
68
74
  test/test_connstr.rb
69
75
  test/test_encoding.rb
70
76
  test/test_datetime.rb
71
77
  test/test_dbi.rb
72
78
  test/test_dbi_clob.rb
79
+ test/test_error.rb
73
80
  test/test_metadata.rb
74
81
  test/test_oci8.rb
75
82
  test/test_oracle_version.rb
@@ -15,3 +15,4 @@ ocinumber.c
15
15
  ocidatetime.c
16
16
  oradate.c
17
17
  object.c
18
+ connection_pool.c
@@ -4,6 +4,12 @@
4
4
  %>
5
5
  #define API_WRAP_C 1
6
6
  #include "apiwrap.h"
7
+ #ifdef HAVE_RB_THREAD_BLOCKING_REGION
8
+ #define BLOCKING_FUNCTION_EPILOGUE(svcctx) do { (svcctx)->executing_thread = Qnil; } while (0)
9
+ #else
10
+ #define BLOCKING_FUNCTION_EPILOGUE(svcctx) do { } while (0)
11
+ #endif
12
+
7
13
  <%
8
14
  prev_name = ''
9
15
  funcs.each do |f|
@@ -33,6 +39,7 @@ funcs.each do |f|
33
39
  * <%=f.name%>_nb
34
40
  */
35
41
  typedef struct {
42
+ oci8_svcctx_t *svcctx;
36
43
  <%
37
44
  f.ret != 'void'
38
45
  %> <%= f.ret %> rv;
@@ -56,9 +63,11 @@ static VALUE oci8_<%=f.name%>_cb(void *user_data)
56
63
  %> data->rv = <%=f.name%>(<%= f.args.collect do |a| 'data->' + a.name; end.join(', ') %>);
57
64
  <% end %>
58
65
  <% if f.ret == 'sword'
59
- %> return (VALUE)data->rv;
66
+ %> BLOCKING_FUNCTION_EPILOGUE(data->svcctx);
67
+ return (VALUE)data->rv;
60
68
  <% else
61
- %> return (VALUE)0;
69
+ %> BLOCKING_FUNCTION_EPILOGUE(data->svcctx);
70
+ return (VALUE)0;
62
71
  <% end %>
63
72
  }
64
73
  #else
@@ -69,6 +78,7 @@ static VALUE oci8_<%=f.name%>_cb(void *user_data)
69
78
  {
70
79
  if (have_<%=f.name%>_nb) {
71
80
  oci8_<%=f.name%>_data_t data;
81
+ data.svcctx = svcctx;
72
82
  <% f.args.each do |a|
73
83
  %> data.<%=a.name%> = <%=a.name%>;
74
84
  <% end
@@ -220,14 +220,6 @@ OCIDescriptorFree:
220
220
  - dvoid *descp
221
221
  - ub4 type
222
222
 
223
- OCIEnvInit:
224
- :version: 800
225
- :args:
226
- - OCIEnv **envp
227
- - ub4 mode
228
- - size_t xtramem_sz
229
- - dvoid **usrmempp
230
-
231
223
  OCIErrorGet:
232
224
  :version: 800
233
225
  :args:
@@ -254,16 +246,6 @@ OCIHandleFree:
254
246
  - dvoid *hndlp
255
247
  - ub4 type
256
248
 
257
- # round trip: 0
258
- OCIInitialize:
259
- :version: 800
260
- :args:
261
- - ub4 mode
262
- - dvoid *ctxp
263
- - dvoid *(*malocfp)(dvoid *ctxp, size_t size)
264
- - dvoid *(*ralocfp)(dvoid *ctxp, dvoid *memptr, size_t newsize)
265
- - void (*mfreefp)(dvoid *ctxp, dvoid *memptr)
266
-
267
249
  # round trip: 0
268
250
  OCILobAssign:
269
251
  :version: 800
@@ -391,7 +373,7 @@ OCILobWrite_nb:
391
373
  - ub1 csfrm
392
374
 
393
375
  # round trip: 1
394
- OCILogoff_nb:
376
+ OCILogoff:
395
377
  :version: 800
396
378
  :args:
397
379
  - OCISvcCtx *svchp
@@ -835,7 +817,7 @@ OCIRawSize:
835
817
  - CONST OCIRaw *raw
836
818
 
837
819
  # round trip: 1
838
- OCISessionEnd_nb:
820
+ OCISessionEnd:
839
821
  :version: 800
840
822
  :args:
841
823
  - OCISvcCtx *svchp
@@ -854,7 +836,7 @@ OCIServerAttach_nb:
854
836
  - ub4 mode
855
837
 
856
838
  # round trip: 1
857
- OCIServerDetach_nb:
839
+ OCIServerDetach:
858
840
  :version: 800
859
841
  :args:
860
842
  - OCIServer *srvhp
@@ -962,6 +944,14 @@ OCITransCommit_nb:
962
944
  - OCIError *errhp
963
945
  - ub4 flags
964
946
 
947
+ # round trip: 1
948
+ OCITransRollback:
949
+ :version: 800
950
+ :args:
951
+ - OCISvcCtx *svchp
952
+ - OCIError *errhp
953
+ - ub4 flags
954
+
965
955
  # round trip: 1
966
956
  OCITransRollback_nb:
967
957
  :version: 800
@@ -1179,6 +1169,32 @@ OCIReset:
1179
1169
  # Oracle 9.0
1180
1170
  #
1181
1171
 
1172
+ OCIConnectionPoolCreate:
1173
+ :version: 900
1174
+ :args:
1175
+ - OCIEnv *envhp
1176
+ - OCIError *errhp
1177
+ - OCICPool *poolhp
1178
+ - OraText **poolName
1179
+ - sb4 *poolNameLen
1180
+ - const OraText *dblink
1181
+ - sb4 dblinkLen
1182
+ - ub4 connMin
1183
+ - ub4 connMax
1184
+ - ub4 connIncr
1185
+ - const OraText *poolUserName
1186
+ - sb4 poolUserLen
1187
+ - const OraText *poolPassword
1188
+ - sb4 poolPassLen
1189
+ - ub4 mode
1190
+
1191
+ OCIConnectionPoolDestroy:
1192
+ :version: 900
1193
+ :args:
1194
+ - OCICPool *poolhp
1195
+ - OCIError *errhp
1196
+ - ub4 mode
1197
+
1182
1198
  # round trip: 0 (not docmented. I guess.)
1183
1199
  OCIDateTimeConstruct:
1184
1200
  :version: 900
@@ -2,54 +2,43 @@
2
2
  /*
3
3
  * attr.c
4
4
  *
5
- * $Author: kubo $
6
- * $Date: 2009-05-17 19:08:39 +0900 (Sun, 17 May 2009) $
7
- *
8
5
  * Copyright (C) 2002-2007 KUBO Takehiro <kubo@jiubao.org>
9
6
  */
10
7
  #include "oci8.h"
11
8
 
12
- VALUE oci8_get_sb1_attr(oci8_base_t *base, ub4 attrtype)
9
+ VALUE oci8_get_sb1_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
13
10
  {
14
11
  sb1 val;
15
- sword rv;
16
12
 
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);
13
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp),
14
+ base, stmtp);
20
15
  return INT2FIX(val);
21
16
  }
22
17
 
23
- VALUE oci8_get_ub2_attr(oci8_base_t *base, ub4 attrtype)
18
+ VALUE oci8_get_ub2_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
24
19
  {
25
20
  ub2 val;
26
- sword rv;
27
21
 
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);
22
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp),
23
+ base, stmtp);
31
24
  return INT2FIX(val);
32
25
  }
33
26
 
34
- VALUE oci8_get_sb2_attr(oci8_base_t *base, ub4 attrtype)
27
+ VALUE oci8_get_sb2_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
35
28
  {
36
29
  sb2 val;
37
- sword rv;
38
30
 
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);
31
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp),
32
+ base, stmtp);
42
33
  return INT2FIX(val);
43
34
  }
44
35
 
45
- VALUE oci8_get_ub4_attr(oci8_base_t *base, ub4 attrtype)
36
+ VALUE oci8_get_ub4_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
46
37
  {
47
38
  ub4 val;
48
- sword rv;
49
39
 
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);
40
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp),
41
+ base, stmtp);
53
42
  #if SIZEOF_LONG > 4
54
43
  return LONG2FIX(val);
55
44
  #else
@@ -57,15 +46,13 @@ VALUE oci8_get_ub4_attr(oci8_base_t *base, ub4 attrtype)
57
46
  #endif
58
47
  }
59
48
 
60
- VALUE oci8_get_string_attr(oci8_base_t *base, ub4 attrtype)
49
+ VALUE oci8_get_string_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
61
50
  {
62
51
  text *val;
63
52
  ub4 size;
64
- sword rv;
65
53
 
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);
54
+ chker3(OCIAttrGet(base->hp.ptr, base->type, &val, &size, attrtype, oci8_errhp),
55
+ base, stmtp);
69
56
  return rb_external_str_new_with_enc(TO_CHARPTR(val), size, oci8_encoding);
70
57
  }
71
58
 
@@ -73,6 +60,7 @@ VALUE oci8_get_string_attr(oci8_base_t *base, ub4 attrtype)
73
60
 
74
61
  typedef struct {
75
62
  oci8_base_t *base;
63
+ OCIStmt *stmtp;
76
64
  ub4 attrtype;
77
65
  OCIRowid *ridp;
78
66
  } rowid_arg_t;
@@ -89,52 +77,12 @@ static VALUE get_rowid_attr(rowid_arg_t *arg)
89
77
  rv = OCIDescriptorAlloc(oci8_envhp, (dvoid*)&arg->ridp, OCI_DTYPE_ROWID, 0, NULL);
90
78
  if (rv != OCI_SUCCESS)
91
79
  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
- }
80
+ chker3(OCIAttrGet(base->hp.ptr, base->type, arg->ridp, 0, attrtype, oci8_errhp),
81
+ base, arg->stmtp);
96
82
  /* 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 define_var;
110
- oci8_exec_sql_var_t bind_var;
111
-
112
- /* search a connection from the handle */
113
- svc = base;
114
- while (svc->type != OCI_HTYPE_SVCCTX) {
115
- svc = svc->parent;
116
- if (svc == NULL) {
117
- rb_raise(rb_eRuntimeError, "No connection is found!!");
118
- }
119
- }
120
- /* :strval */
121
- define_var.valuep = buf;
122
- define_var.value_sz = sizeof(buf);
123
- define_var.dty = SQLT_CHR;
124
- define_var.indp = NULL;
125
- define_var.alenp = &buflen;
126
- /* :rowid */
127
- bind_var.valuep = &arg->ridp;
128
- bind_var.value_sz = sizeof(void *);
129
- bind_var.dty = SQLT_RDD;
130
- bind_var.indp = NULL;
131
- bind_var.alenp = NULL;
132
- /* convert the rowid descriptor to a string value by querying Oracle server. */
133
- oci8_exec_sql((oci8_svcctx_t*)svc, "SELECT :rid FROM dual", 1, &define_var, 1, &bind_var, 1);
134
- if (buflen == 0) {
135
- return Qnil;
136
- }
137
- }
83
+ buflen = MAX_ROWID_LEN;
84
+ chker3(OCIRowidToChar(arg->ridp, TO_ORATEXT(buf), &buflen, oci8_errhp),
85
+ base, arg->stmtp);
138
86
  return rb_external_str_new_with_enc(buf, buflen, rb_usascii_encoding());
139
87
  }
140
88
 
@@ -146,10 +94,11 @@ static VALUE rowid_ensure(rowid_arg_t *arg)
146
94
  return Qnil;
147
95
  }
148
96
 
149
- VALUE oci8_get_rowid_attr(oci8_base_t *base, ub4 attrtype)
97
+ VALUE oci8_get_rowid_attr(oci8_base_t *base, ub4 attrtype, OCIStmt *stmtp)
150
98
  {
151
99
  rowid_arg_t arg;
152
100
  arg.base = base;
101
+ arg.stmtp = stmtp;
153
102
  arg.attrtype = attrtype;
154
103
  arg.ridp = NULL;
155
104
  return rb_ensure(get_rowid_attr, (VALUE)&arg, rowid_ensure, (VALUE)&arg);