ruby-oci8 2.2.4.1 → 2.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ChangeLog CHANGED
@@ -1,7 +1,57 @@
1
+ 2017-10-21 Kubo Takehiro <kubo@jiubao.org>
2
+ * NEWS: Add changes between 2.2.4.1 and 2.2.5
3
+ * lib/oci8/version.rb: Update to 2.2.5
4
+ * docs/number-type-mapping.md: minor fix
5
+ * dist-files: Add files.
6
+
7
+ 2017-10-18 Kubo Takehiro <kubo@jiubao.org>
8
+ * docs/number-type-mapping.md, README.md, dist-files: Add document
9
+ about the mapping between Oracle number types and Ruby classes.
10
+
11
+ 2017-10-17 Kubo Takehiro <kubo@jiubao.org>
12
+ * lib/oci8/check_load_error.rb: Check error reason when loading
13
+ failed with 'The specified module could not be found' on Windows.
14
+
15
+ 2017-10-17 Kubo Takehiro <kubo@jiubao.org>
16
+ * lib/oci8/check_load_error.rb: Fix LoadError while trying to check
17
+ errors in "require 'oci8lib_230.so'" on cygwin 2.8 or later.
18
+ (related to github issue #176)
19
+
20
+ 2017-10-17 Kubo Takehiro <kubo@jiubao.org>
21
+ * ext/oci8/ocinumber.c, test/test_oranumber.rb:
22
+ Add OraNumber#has_fractional_part?.
23
+
24
+ 2017-10-01 Kubo Takehiro <kubo@jiubao.org>
25
+ * ext/oci8/plthook_elf.c: Update plthook to use prelinked
26
+ libclntsh.so on Linux.
27
+ (github issue #172)
28
+
29
+ 2017-09-27 Kubo Takehiro <kubo@jiubao.org>
30
+ * ext/oci8/oci8lib.c: Change order to load libclntsh when runtime
31
+ api check is enabled on Unix.
32
+
33
+ 2017-09-24 Kubo Takehiro <kubo@jiubao.org>
34
+ * ext/oci8/oci8lib.c: Try to load $ORACLE_HOME/lib/libclntsh.so also
35
+ when runtime api check is enabled on Unix.
36
+
37
+ 2017-09-23 Kubo Takehiro <kubo@jiubao.org>
38
+ * lib/oci8/cursor.rb: Don't call unnecessary __paramGet(i) when a
39
+ cursor is executed more than once.
40
+ (pointed by OMOTO Kenji at github issue #171)
41
+
42
+ 2017-07-09 Kubo Takehiro <kubo@jiubao.org>
43
+ * ext/oci8/apiwrap.yml, ext/oci8/oci8.c, lib/oci8/oci8.rb:
44
+ Delete unused code using OCILogon2 and OCILogoff.
45
+
46
+ 2017-07-09 Kubo Takehiro <kubo@jiubao.org>
47
+ * ext/oci8/error.c: Delete OCIError#initialize defined by C code
48
+ to suppress warning: method redefined; discarding old initialize.
49
+ (github issue #168)
50
+
1
51
  2017-06-17 Kubo Takehiro <kubo@jiubao.org>
2
52
  * NEWS: Add changes between 2.2.4 and 2.2.4.1
3
53
  * lib/oci8/version.rb: Update to 2.2.4.1
4
- * lib/oci8/version.rb: Fix URL links
54
+ * lib/oci8/properties.rb: Fix URL links
5
55
  * docs/hanging-after-inactivity.md: Revised
6
56
 
7
57
  2017-06-16 Kubo Takehiro <kubo@jiubao.org>
data/NEWS CHANGED
@@ -1,5 +1,63 @@
1
1
  # @markup markdown
2
2
 
3
+ 2.2.5
4
+ =====
5
+
6
+ New Features
7
+ ------------
8
+
9
+ ### Try to load $ORACLE_HOME/lib/libclntsh.so also when runtime api check is enabled on Unix.
10
+
11
+ When ruby-oci8 is configured with `--with-runtime-check`, it loads Oracle client
12
+ library and checks available functions in the library at runtime. This feature was
13
+ added to release Windows binary gems which cannot know Oracle version at compile time.
14
+ This is available also on Unix. However it tries to load libraries in LD_LIBRARY_PATH only.
15
+ From this version, it tries to load $ORACLE_HOME/lib/libclntsh.so also.
16
+
17
+ ### Check error reasons when loading failed with 'The specified module could not be found' on Windows.
18
+
19
+ The error messages are same when OCI.DLL isn't found and when Visual
20
+ C++ runtime library depended on by OCI.DLL isn't found. From this
21
+ version, ruby-oci8 distinguishes the difference and prints other message
22
+ for the latter case.
23
+
24
+ Fixed issue
25
+ -----------
26
+
27
+ ### Fix segmentation fault when Oracle client library is prelinked.
28
+
29
+ When Oracle instant client rpm package is used on RHEL5 or RHEL6,
30
+ Oracle client library is modified by [prelink][] and ruby-oci8 crashed
31
+ with segmentation fault. This is not due to Oracle, but due to
32
+ plthook used by ruby-oci8. The plthook was fixed to work with
33
+ prelinked libraries.
34
+ (github issue #172)
35
+
36
+ [prelink]: https://en.wikipedia.org/wiki/Prelink#Linux
37
+
38
+ ### Fix not to hide the original error message of LoadError on recent cygwin.
39
+
40
+ Ruby-oci8 tries to check error messages when `require 'oci8lib_xxx.so` fails.
41
+ However the message was hidden by an exception while checking on cygwin.
42
+ (github issue #176)
43
+
44
+ ### Don't call unnecessary __paramGet(i) when a cursor is executed more than once.
45
+
46
+ pointed by OMOTO Kenji
47
+ (github issue #171)
48
+
49
+ ### Suppress warning: method redefined; discarding old initialize.
50
+
51
+ (github issue #168)
52
+
53
+ Other Changes
54
+ -------------
55
+
56
+ ### Add document about the mapping between Oracle number types and Ruby classes.
57
+
58
+ See {file:docs/number-type-mapping.md Number Type Mapping between Oracle and Ruby}.
59
+ (github issue #173)
60
+
3
61
  2.2.4.1
4
62
  =======
5
63
 
data/README.md CHANGED
@@ -24,7 +24,9 @@ See {file:NEWS}.
24
24
  Sample one-liner
25
25
  ----------------
26
26
 
27
- Connect to scott/tiger, select `emp` and print as CSV format.
27
+ When you have an Oracle database server to which `sqlplus scott/tiger` can connect
28
+ and `scott` user has `emp` table, you can select `emp` and print rows
29
+ as CSV by the followig one liner.
28
30
 
29
31
  ruby -r oci8 -e "OCI8.new('scott', 'tiger').exec('select * from emp') do |r| puts r.join(','); end"
30
32
 
@@ -50,6 +52,7 @@ Report issues
50
52
  Other documents
51
53
  ---------------
52
54
 
55
+ * {file:docs/number-type-mapping.md Number Type Mapping between Oracle and Ruby}
53
56
  * {file:docs/timeout-parameters.md Timeout Parameters}
54
57
  * {file:docs/conflicts-local-connections-and-processes.md Conflicts between Local Connections and Child Process Handling on Unix}
55
58
  * {file:docs/hanging-after-inactivity.md Hanging After a Long Period of Inactivity}
data/dist-files CHANGED
@@ -11,12 +11,14 @@ pre-distclean.rb
11
11
  ruby-oci8.gemspec
12
12
  setup.rb
13
13
  docs/bind-array-to-in_cond.md
14
+ docs/conflicts-local-connections-and-processes.md
15
+ docs/hanging-after-inactivity.md
14
16
  docs/install-binary-package.md
15
17
  docs/install-full-client.md
16
18
  docs/install-instant-client.md
17
19
  docs/install-on-osx.md
18
- docs/conflicts-local-connections-and-processes.md
19
- docs/hanging-after-inactivity.md
20
+ docs/ldap-auth-and-function-interposition.md
21
+ docs/number-type-mapping.md
20
22
  docs/osx-install-dev-tools.png
21
23
  docs/platform-specific-issues.md
22
24
  docs/report-installation-issue.md
@@ -81,10 +83,12 @@ lib/ruby-oci8.rb
81
83
  test/README
82
84
  test/config.rb
83
85
  test/setup_test_object.sql
86
+ test/setup_test_package.sql
84
87
  test/test_all.rb
85
88
  test/test_appinfo.rb
86
89
  test/test_array_dml.rb
87
90
  test/test_bind_array.rb
91
+ test/test_bind_boolean.rb
88
92
  test/test_bind_raw.rb
89
93
  test/test_bind_string.rb
90
94
  test/test_bind_time.rb
@@ -27,7 +27,7 @@ The above code is rewritten as follows:
27
27
 
28
28
  ids = [ ... ] # an arbitrary-length array containing user IDs.
29
29
 
30
- in_cond = OCI8::in_cond(:id, ids)]
30
+ in_cond = OCI8::in_cond(:id, ids)
31
31
  cursor = conn.exec("select * from users where id in (#{in_cond.names})", *in_cond.values)
32
32
 
33
33
  or
@@ -0,0 +1,123 @@
1
+ # @title LDAP Authentication and Function Interposition
2
+
3
+ LDAP Authentication and Function Interposition
4
+ ==============================================
5
+
6
+ Problems
7
+ --------
8
+
9
+ The following code may trigger segmentation faults or unexpected behaviours.
10
+
11
+ require 'pg' # or any modules using LDAP such as ActiveLdap
12
+ require 'oci8'
13
+
14
+ conn = OCI8.new('username/password@dbname.example.com')
15
+ ...
16
+
17
+ It happens when all the following conditions are satisfied.
18
+
19
+ * The platform is Unix
20
+ * The PostgreSQL client library, which `pg` depends, was compiled with LDAP support.
21
+ * LDAP authentication is used to connect to an Oracle server.
22
+
23
+ It is caused by function interposition as follows:
24
+
25
+ * The ruby process loads `pq` and its depending libraries such as
26
+ `libpq.so`(PostgreSQL client library) and `libldap_r.so`(LDAP library).
27
+ * Then it loads `oci8` and its depending libraries such as
28
+ `libclntsh.so`(Oracle client library).
29
+ * When LDAP authentication is used, `libclntsh.so` tries to use
30
+ LDAP functions in the library.
31
+ * However it uses LDAP functions in `libldap_r.so` because the function
32
+ in the firstly loaded library is used when more than one library exports
33
+ functions whose names are same.
34
+ * It triggers segmentation faults or unexpected behaviours because
35
+ implementations of LDAP functions are different even though their names
36
+ are same.
37
+
38
+ The reverse may cause same results by the following code.
39
+
40
+ require 'oci8'
41
+ require 'pg'
42
+
43
+ ... connect to PostgreSQL using LDAP ...
44
+
45
+ ### Note for macOS
46
+
47
+ Libraries in two-level namespaces are free from function interposition on macOS.
48
+ See the second paragraph of [this document][mach-o]. If `TWOLEVEL` is
49
+ found in the output of `otool -hV /path/to/library`, it is in a
50
+ two-level namespace. Otherwise it is in a single-level (flat) namespace.
51
+
52
+ Oracle client library (`libclntsh.dylib.12.1`) is in a flat namespace.
53
+ It suffers from function interposition.
54
+
55
+ $ otool -hV libclntsh.dylib.12.1
56
+ Mach header
57
+ magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
58
+ MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 19 2360 DYLDLINK NO_REEXPORTED_DYLIBS MH_HAS_TLV_DESCRIPTORS
59
+
60
+ PostgreSQL client library (`libpq.5.dylib`) installed by [brew][] depends on an OS-supplied LDAP library.
61
+
62
+ $ otool -L libpq.5.dylib
63
+ libpq.5.dylib:
64
+ /usr/local/opt/postgresql/lib/libpq.5.dylib (compatibility version 5.0.0, current version 5.9.0)
65
+ /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
66
+ /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
67
+ /System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos (compatibility version 5.0.0, current version 6.0.0)
68
+ /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP (compatibility version 1.0.0, current version 2.4.0)
69
+ /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
70
+
71
+ The OS-supplied LDAP library is in a two-level namespace.
72
+
73
+ $ otool -hV /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP
74
+ Mach header
75
+ magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
76
+ MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 22 2528 NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS APP_EXTENSION_SAFE
77
+
78
+ As a result, the PostgreSQL client library is free from function interposition.
79
+
80
+ Solution 1
81
+ ----------
82
+
83
+ If you don't connect to PostgreSQL using LDAP, use the following code.
84
+
85
+ require 'oci8' # This must be before "require 'pg'".
86
+ require 'pg'
87
+
88
+ conn = OCI8.new('username/password@dbname.example.com')
89
+ ...
90
+ ... connect to a PostgreSQL server ...
91
+
92
+ Oracle client library uses LDAP functions in `libclntsh.so` because `libclntsh.so`
93
+ is loaded before `libldap_r.so`.
94
+
95
+ Don't connect to PostgreSQL using LDAP because `libpq.so` tries to use
96
+ LDAP functions in `libldap_r.so` but faultily uses functions in `libclntsh.so`.
97
+
98
+ Note for macOS: This fixes all function interposition issues if the LDAP library
99
+ in a two-level namespace.
100
+
101
+ Solution 2
102
+ ----------
103
+
104
+ If LDAP is used to connect to both Oracle and PostgreSQL and the platform
105
+ is Linux or macOS, use ruby-oci8 2.2.4 or later and use the following code.
106
+
107
+ require 'pg'
108
+ require 'oci8' # This must be after "require 'pg'".
109
+
110
+ conn = OCI8.new('username/password@dbname.example.com')
111
+ ...
112
+ ... connect to a PostgreSQL server using LDAP ...
113
+
114
+ PostgreSQL client library uses LDAP functions in `libldap_r.so` because `libldap_r.so`
115
+ is loaded before `libclntsh.so`.
116
+
117
+ Oracle client library uses LDAP functions in `libclntsh.so` because ruby-oci8
118
+ forcedly modifies PLT (Procedure Linkage Table) entries to point to
119
+ functions in `libclntsh.so` if they point to functions in other libraries.
120
+ (PLT is equivalent to IAT (Import Address Table) on Windows.)
121
+
122
+ [mach-o]: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/executing_files.html
123
+ [brew]: http://brew.sh/
@@ -0,0 +1,79 @@
1
+ # @title Number Type Mapping between Oracle and Ruby
2
+
3
+ Number Type Mapping between Oracle and Ruby
4
+ ===========================================
5
+
6
+ Default mapping
7
+ ---------------
8
+
9
+ Oracle numbers in select statements are fetched as followings by default:
10
+
11
+ | Oracle Data Type | Ruby Class |
12
+ |---|---|
13
+ | NUMBER(prec) or NUMBER(prec, 0) | Integer |
14
+ | NUMBER(prec, scale) where prec < 15 and scale != 0 | Float |
15
+ | NUMBER(prec, scale) where prec >= 15 and scale != 0 | BigDecimal |
16
+ | FLOAT or FLOAT(prec) | Float |
17
+ | NUMBER without precision and scale | BigDecimal |
18
+ | number type returned by functions or calculated number | BigDecimal |
19
+ | BINARY_FLOAT | Float |
20
+ | BINARY_DOUBLE | Float |
21
+
22
+ When the data type is within Integer or Float class, it is fetched
23
+ as Integer or Float. Otherwise, BigDecimal.
24
+
25
+ Note that the mapping is determined by the column definition in
26
+ select statements, not by the actual value fetched.
27
+ For example the column in `select count(*) from table_name` is
28
+ fetched as BigDecimal because it is returned from `count` function.
29
+
30
+ The mapping is customizable by `OCI8::BindType::Mapping`.
31
+ The default values of Oracle number data type mapping are:
32
+
33
+ # NUMBER or FLOAT data type, used for the first six rows in the above table
34
+ OCI8::BindType::Mapping[:number] = OCI8::BindType::Number
35
+ # BINARY_FLOAT data type, used for the seventh row in the above table
36
+ OCI8::BindType::Mapping[:binary_float] = OCI8::BindType::BinaryDouble
37
+ # BINARY_DOUBLE data type, used for the eighth row in the above table
38
+ OCI8::BindType::Mapping[:binary_double] = OCI8::BindType::BinaryDouble
39
+
40
+ `OCI8::BindType::Number` checks precision and scale to determine
41
+ ruby class. The first four rows in the above table are hard-coded.
42
+ The fifth and sixth rows are, however, customizable by
43
+ `OCI8::BindType::Mapping[:number_no_prec_setting]` and
44
+ `OCI8::BindType::Mapping[:number_unknown_prec]` respectively.
45
+
46
+ The default values are:
47
+
48
+ OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::BigDecimal
49
+ OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::BigDecimal
50
+
51
+ The mapping may be changed as follows in future.
52
+
53
+ | Oracle Data Type | Ruby Class |
54
+ |---|---|
55
+ | NUMBER(prec) or NUMBER(prec, 0) | Integer |
56
+ | other NUMBER | OraNumber |
57
+ | BINARY_FLOAT | Float |
58
+ | BINARY_DOUBLE | Float |
59
+
60
+ Customize mapping
61
+ -----------------
62
+
63
+ Add the following code to fetch all number or float columns as {OraNumber}.
64
+
65
+ OCI8::BindType::Mapping[:number] = OCI8::BindType::OraNumber
66
+
67
+ Otherwise, add the following code to customize the fifth and sixth rows only
68
+ in the above table.
69
+
70
+ OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::OraNumber
71
+ OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::OraNumber
72
+
73
+ If you want to fetch numbers as Integer or Float by its actual value, use
74
+ the following code:
75
+
76
+ # Fetch numbers as Integer when their fractional part is zero.
77
+ # Otherwise, Float. For example when a column contains 10 and
78
+ # 10.1, they are fetched as Integer and Float respectively.
79
+ OCI8::BindType::Mapping[:number] = OCI8::BindType::BasicNumberType
@@ -321,13 +321,6 @@ OCILobLocatorIsInit:
321
321
  - CONST OCILobLocator *locp
322
322
  - boolean *is_initialized
323
323
 
324
- # round trip: 1
325
- OCILogoff:
326
- :version: 800
327
- :args:
328
- - OCISvcCtx *svchp
329
- - OCIError *errhp
330
-
331
324
  # round trip: 0
332
325
  OCINumberAbs:
333
326
  :version: 800
@@ -1149,21 +1142,6 @@ OCIIntervalSetYearMonth:
1149
1142
  - sb4 mnth
1150
1143
  - OCIInterval *result
1151
1144
 
1152
- # round trip: 1
1153
- OCILogon2_nb:
1154
- :version: 900
1155
- :args:
1156
- - OCIEnv *envhp
1157
- - OCIError *errhp
1158
- - OCISvcCtx **svchp
1159
- - CONST text *username
1160
- - ub4 uname_len
1161
- - CONST text *password
1162
- - ub4 passwd_len
1163
- - CONST text *dbname
1164
- - ub4 dbname_len
1165
- - ub4 mode
1166
-
1167
1145
  # round trip: 0 (not docmented. I guess.)
1168
1146
  OCIRowidToChar:
1169
1147
  :version: 900
@@ -75,6 +75,21 @@ retry:
75
75
  return rb_external_str_new_with_enc(errbuf, len, oci8_encoding);
76
76
  }
77
77
 
78
+ /*
79
+ * Don't call rb_class_new_instance() with more than one argument in this function.
80
+ * This may be called before OCIError#initialize is defined in lib/oci8/oci8.rb.
81
+ */
82
+ static VALUE oci_exception_new(VALUE klass, VALUE msg, VALUE code, VALUE sql, VALUE parse_error_offset)
83
+ {
84
+ VALUE obj = rb_class_new_instance(NIL_P(msg) ? 0 : 1, &msg, klass);
85
+ if (rb_obj_is_kind_of(obj, eOCIError)) {
86
+ rb_ivar_set(obj, oci8_id_at_code, code);
87
+ rb_ivar_set(obj, oci8_id_at_sql, sql);
88
+ rb_ivar_set(obj, oci8_id_at_parse_error_offset, parse_error_offset);
89
+ }
90
+ return obj;
91
+ }
92
+
78
93
  static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp, const char *file, int line)
79
94
  {
80
95
  VALUE exc;
@@ -84,24 +99,19 @@ static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp
84
99
  VALUE parse_error_offset = Qnil;
85
100
  VALUE sql = Qnil;
86
101
  int rv;
87
- VALUE args[4];
88
- int numarg = 1;
89
102
 
90
103
  switch (status) {
91
104
  case OCI_ERROR:
92
105
  exc = eOCIError;
93
106
  msg = get_error_msg(errhp, type, "Error", &errcode);
94
- numarg = 4;
95
107
  break;
96
108
  case OCI_SUCCESS_WITH_INFO:
97
109
  exc = eOCISuccessWithInfo;
98
110
  msg = get_error_msg(errhp, type, "Error", &errcode);
99
- numarg = 4;
100
111
  break;
101
112
  case OCI_NO_DATA:
102
113
  exc = eOCINoData;
103
114
  msg = get_error_msg(errhp, type, "No Data", &errcode);
104
- numarg = 4;
105
115
  break;
106
116
  case OCI_INVALID_HANDLE:
107
117
  exc = eOCIInvalidHandle;
@@ -138,11 +148,7 @@ static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp
138
148
  sql = rb_external_str_new_with_enc(TO_CHARPTR(text), size, oci8_encoding);
139
149
  }
140
150
  }
141
- args[0] = msg;
142
- args[1] = INT2FIX(errcode);
143
- args[2] = sql;
144
- args[3] = parse_error_offset;
145
- exc = rb_class_new_instance(numarg, args, exc);
151
+ exc = oci_exception_new(exc, msg, INT2FIX(errcode), sql, parse_error_offset);
146
152
  return set_backtrace(exc, file, line);
147
153
  }
148
154
 
@@ -172,22 +178,6 @@ sb4 oci8_get_error_code(OCIError *errhp)
172
178
  return errcode;
173
179
  }
174
180
 
175
- /* This is overwritten by lib/oci8/oci8.rb. */
176
- static VALUE oci8_error_initialize(int argc, VALUE *argv, VALUE self)
177
- {
178
- VALUE msg;
179
- VALUE code;
180
- VALUE sql;
181
- VALUE parse_error_offset;
182
-
183
- rb_scan_args(argc, argv, "04", &msg, &code, &sql, &parse_error_offset);
184
- rb_call_super(argc ? 1 : 0, &msg);
185
- rb_ivar_set(self, oci8_id_at_code, code);
186
- rb_ivar_set(self, oci8_id_at_sql, sql);
187
- rb_ivar_set(self, oci8_id_at_parse_error_offset, parse_error_offset);
188
- return Qnil;
189
- }
190
-
191
181
  void Init_oci8_error(void)
192
182
  {
193
183
  errbufsiz = ERRBUF_EXPAND_LEN;
@@ -217,9 +207,6 @@ void Init_oci8_error(void)
217
207
  rb_define_attr(eOCIError, "sql", 1, 0);
218
208
  rb_define_attr(eOCIError, "parse_error_offset", 1, 0);
219
209
  rb_define_alias(eOCIError, "parseErrorOffset", "parse_error_offset");
220
-
221
- /* This is overwritten by lib/oci8/oci8.rb. */
222
- rb_define_method_nodoc(eOCIError, "initialize", oci8_error_initialize, -1);
223
210
  }
224
211
 
225
212
  void oci8_do_raise(OCIError *errhp, sword status, OCIStmt *stmthp, const char *file, int line)
@@ -278,11 +265,9 @@ VALUE oci8_get_error_message(ub4 msgno, const char *default_msg)
278
265
  void oci8_do_raise_by_msgno(ub4 msgno, const char *default_msg, const char *file, int line)
279
266
  {
280
267
  VALUE msg = oci8_get_error_message(msgno, default_msg);
281
- VALUE args[2];
282
- args[0] = msg;
283
- args[1] = INT2FIX(-1);
268
+ VALUE exc = oci_exception_new(eOCIError, msg, INT2FIX(-1), Qnil, Qnil);
284
269
 
285
- rb_exc_raise(set_backtrace(rb_class_new_instance(2, args, eOCIError), file, line));
270
+ rb_exc_raise(set_backtrace(exc, file, line));
286
271
  }
287
272
 
288
273
  void oci8_check_error_(sword status, oci8_base_t *base, OCIStmt *stmthp, const char *file, int line)