ruby-oci8 2.1.3 → 2.1.4
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 +50 -0
- data/NEWS +41 -0
- data/VERSION +1 -1
- data/docs/platform-specific-issues.md +19 -11
- data/ext/oci8/connection_pool.c +2 -2
- data/ext/oci8/encoding.c +13 -0
- data/ext/oci8/error.c +0 -27
- data/ext/oci8/extconf.rb +50 -7
- data/ext/oci8/lob.c +18 -6
- data/ext/oci8/metadata.c +13 -0
- data/ext/oci8/oci8.c +61 -29
- data/ext/oci8/oci8.h +1 -0
- data/ext/oci8/oci8lib.c +24 -23
- data/ext/oci8/oraconf.rb +1 -0
- data/lib/oci8.rb.in +42 -7
- data/lib/oci8/encoding-init.rb +20 -20
- data/lib/oci8/metadata.rb +71 -28
- data/lib/oci8/oci8.rb +68 -7
- data/lib/oci8/oracle_version.rb +1 -1
- data/lib/oci8/properties.rb +46 -12
- data/test/test_clob.rb +16 -0
- data/test/test_encoding.rb +7 -7
- metadata +3 -3
data/ChangeLog
CHANGED
@@ -1,3 +1,53 @@
|
|
1
|
+
2013-01-06 KUBO Takehiro <kubo@jiubao.org>
|
2
|
+
* NEWS: add changes between 2.1.4 and 2.1.3
|
3
|
+
* VERSION: change the version to 2.1.4.
|
4
|
+
* docs/platform-specific-issues.md: update solaris-specific document.
|
5
|
+
* ext/oci8/connection_pool.c, ext/oci8/encoding.c, ext/oci8/metadata.c,
|
6
|
+
ext/oci8/oci8.c,lib/oci8.rb.in, lib/oci8/metadata.rb, lib/oci8/oci8.rb,
|
7
|
+
lib/oci8/oracle_version.rb, lib/oci8/properties.rb: update comments for yard.
|
8
|
+
* test/test_clob.rb: change a lob size when ORA-24817 is raised to
|
9
|
+
pass tests on Windows.
|
10
|
+
|
11
|
+
2013-01-03 KUBO Takehiro <kubo@jiubao.org>
|
12
|
+
* ext/oci8/oci8.c, lib/oci8/properties.rb: add OCI8.properties[:events_mode]
|
13
|
+
to support Fast Application Notification (FAN).
|
14
|
+
|
15
|
+
2013-01-03 KUBO Takehiro <kubo@jiubao.org>
|
16
|
+
* ext/oci8/extconf.rb, lib/oci8.rb.in: add languange mode to the extension
|
17
|
+
library name when ths ruby engine is rubinius and explicitly claim that
|
18
|
+
jruby is not supported when it is jruby.
|
19
|
+
|
20
|
+
2013-01-03 KUBO Takehiro <kubo@jiubao.org>
|
21
|
+
* ext/oci8/encoding.c, lib/oci8/encoding-init.rb: delete an internal method
|
22
|
+
OCI8.nls_ratio= when the ruby is 1.9 or greater. nls_ratio is set by
|
23
|
+
OCI8.encoding=.
|
24
|
+
|
25
|
+
2012-12-23 KUBO Takehiro <kubo@jiubao.org>
|
26
|
+
* ext/oci8/lob.c, ext/oci8/oci8.h, ext/oci8/oci8lib.c, test/test_clob.rb:
|
27
|
+
fix SEGV when a temporary LOB is freed when OCILobRead returns OCI_NEED_DATA.
|
28
|
+
(github issue #20 reported by Edgars Beigarts)
|
29
|
+
|
30
|
+
2012-12-18 KUBO Takehiro <kubo@jiubao.org>
|
31
|
+
* ext/oci8/error.c, lib/oci8/oci8.rb: change the OCIError constructor to
|
32
|
+
accept an Oracle error code as the first parameter and create a message
|
33
|
+
which depends on NLS_LANG.
|
34
|
+
* lib/oci8/metadata.rb: fix OCI8.describe_table not to follow synonyms
|
35
|
+
until stack overflow. Now the recursive level is limited to 20.
|
36
|
+
(github issue #26 reported by Brian Henderson)
|
37
|
+
|
38
|
+
2012-12-16 KUBO Takehiro <kubo@jiubao.org>
|
39
|
+
* ext/oci8/extconf.rb, lib/oci8.rb.in: use RUBY_VERSION instead of
|
40
|
+
RbConfig::CONFIG['ruby_version'] to know the ruby ABI version.
|
41
|
+
The latter may be changed by the configure option --with-ruby-version.
|
42
|
+
(github issue #24 reported by suhrawardi)
|
43
|
+
|
44
|
+
2012-12-03 KUBO Takehiro <kubo@jiubao.org>
|
45
|
+
* ext/oci8/oraconf.rb: add a script encoding magic comment for ruby 2.0.0 preview2.
|
46
|
+
(github issue #25 reported by aboltart)
|
47
|
+
|
48
|
+
2012-12-02 KUBO Takehiro <kubo@jiubao.org>
|
49
|
+
* test/test_encoding.rb: fix to pass tests with ruby 2.0.0 preview2.
|
50
|
+
|
1
51
|
2012-11-11 KUBO Takehiro <kubo@jiubao.org>
|
2
52
|
* ext/oci8/lob.c: use OCILobLocatorAssign_nb (non-blocking version)
|
3
53
|
instead of OCILobLocatorAssign (blocking version).
|
data/NEWS
CHANGED
@@ -1,5 +1,46 @@
|
|
1
1
|
# @markup markdown
|
2
2
|
|
3
|
+
2.1.4
|
4
|
+
=====
|
5
|
+
|
6
|
+
New Features
|
7
|
+
------------
|
8
|
+
|
9
|
+
### Fast Application Notification (FAN) support
|
10
|
+
|
11
|
+
Look at {http://php.net/manual/en/oci8.connection.php} to know what is FAN.
|
12
|
+
[oci8.events](http://php.net/manual/en/oci8.configuration.php#ini.oci8.events) in PHP
|
13
|
+
corresponds to {OCI8.properties OCI8.properties[:events_mode]} in ruby-oci8.
|
14
|
+
|
15
|
+
Note: You need to set `OCI8.properties[:events_mode]` after `"require 'oci8'"` and before
|
16
|
+
any methods which call Oracle OCI functions.
|
17
|
+
|
18
|
+
Fixed Issues
|
19
|
+
------------
|
20
|
+
|
21
|
+
- fix SEGV when a temporary LOB is freed when `OCILobRead` returns `OCI_NEED_DATA`.
|
22
|
+
See: [github issue #20](https://github.com/kubo/ruby-oci8/issues/20)
|
23
|
+
|
24
|
+
(reported by Edgars Beigarts)
|
25
|
+
|
26
|
+
- use `RUBY_VERSION` instead of `RbConfig::CONFIG['ruby_version']` to know the
|
27
|
+
ruby ABI version. The latter may be changed by the configure option
|
28
|
+
--with-ruby-version.
|
29
|
+
See: [github issue #24](https://github.com/kubo/ruby-oci8/issues/24)
|
30
|
+
|
31
|
+
(reported by suhrawardi)
|
32
|
+
|
33
|
+
- add a script encoding magic comment for ruby 2.0.0 preview2.
|
34
|
+
See: [github issue #25](https://github.com/kubo/ruby-oci8/issues/25)
|
35
|
+
|
36
|
+
(reported by aboltart)
|
37
|
+
|
38
|
+
- fix {OCI8#describe_table} not to follow synonyms until stack overflow.
|
39
|
+
Now the recursive level is limited to 20.
|
40
|
+
See: [github issue #26](https://github.com/kubo/ruby-oci8/issues/26)
|
41
|
+
|
42
|
+
(reported by Brian Henderson)
|
43
|
+
|
3
44
|
2.1.3
|
4
45
|
=====
|
5
46
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.4
|
@@ -71,15 +71,23 @@ Solaris
|
|
71
71
|
=======
|
72
72
|
|
73
73
|
You need a same compiler which is used to make ruby itself.
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
74
|
+
For example, if the ruby is compiled by gcc, you need gcc. If it is compiled by Oracle Solaris Studio
|
75
|
+
(formerly called as Sun Studio), you need Oracle Solaris Studio.
|
76
|
+
|
77
|
+
If ruby is compiled by gcc and "require 'oci8'" raises "OCI Library Initialization Error",
|
78
|
+
you may need to recompile ruby as follows:
|
79
|
+
|
80
|
+
$ bzip2 -dc ruby-1.9.3-pxxx.tar.bz2 | tar xvf -
|
81
|
+
$ cd ruby-1.9.3-pxxx
|
82
|
+
$ vi main.c # <- Add RUBY_FUNC_EXPORTED just before "int main(..)" as follows:
|
83
|
+
-------------
|
84
|
+
RUBY_FUNC_EXPORTED /* Add this line */
|
85
|
+
int
|
86
|
+
main(int argc, char **argv)
|
87
|
+
-------------
|
88
|
+
$ ./configure
|
89
|
+
$ make
|
90
|
+
$ make install
|
83
91
|
|
84
92
|
If you use Blastwave.org's ruby and want not to install Sun Studio,
|
85
93
|
you can edit rbconfig.rb by your self. [(look at here)](http://forum.textdrive.com/viewtopic.php?id=12630)
|
@@ -91,8 +99,8 @@ If you use Sunfreeware.com's ruby and
|
|
91
99
|
prints "yes", you may need to edit rbconfig.rb distributed with the ruby
|
92
100
|
as follows:
|
93
101
|
|
94
|
-
|
95
|
-
|
102
|
+
from: CONFIG["LDFLAGS"] = "-L. -Wl,-E"
|
103
|
+
to: CONFIG["LDFLAGS"] = "-L. "
|
96
104
|
|
97
105
|
FreeBSD
|
98
106
|
=======
|
data/ext/oci8/connection_pool.c
CHANGED
@@ -174,9 +174,9 @@ static VALUE oci8_cpool_reinitialize(VALUE self, VALUE conn_min, VALUE conn_max,
|
|
174
174
|
* call-seq:
|
175
175
|
* pool_name -> string
|
176
176
|
*
|
177
|
-
* <b>internal use only</b>
|
178
|
-
*
|
179
177
|
* Retruns the pool name.
|
178
|
+
*
|
179
|
+
* @private
|
180
180
|
*/
|
181
181
|
static VALUE oci8_cpool_pool_name(VALUE self)
|
182
182
|
{
|
data/ext/oci8/encoding.c
CHANGED
@@ -185,12 +185,14 @@ static VALUE oci8_charset_name2id(VALUE svc, VALUE name)
|
|
185
185
|
*
|
186
186
|
* @return [Fixnum] NLS ratio
|
187
187
|
* @since 2.1.0
|
188
|
+
* @private
|
188
189
|
*/
|
189
190
|
static VALUE oci8_get_nls_ratio(VALUE klass)
|
190
191
|
{
|
191
192
|
return INT2NUM(oci8_nls_ratio);
|
192
193
|
}
|
193
194
|
|
195
|
+
#ifndef HAVE_TYPE_RB_ENCODING
|
194
196
|
/*
|
195
197
|
* call-seq:
|
196
198
|
* OCI8.nls_ratio = integer
|
@@ -201,6 +203,8 @@ static VALUE oci8_get_nls_ratio(VALUE klass)
|
|
201
203
|
*
|
202
204
|
* @param [Fixnum] integer NLS ratio
|
203
205
|
* @since 2.1.0
|
206
|
+
* @private
|
207
|
+
* @note ruby 1.8 only
|
204
208
|
*/
|
205
209
|
static VALUE oci8_set_nls_ratio(VALUE klass, VALUE val)
|
206
210
|
{
|
@@ -211,6 +215,7 @@ static VALUE oci8_set_nls_ratio(VALUE klass, VALUE val)
|
|
211
215
|
oci8_nls_ratio = v;
|
212
216
|
return val;
|
213
217
|
}
|
218
|
+
#endif
|
214
219
|
|
215
220
|
#ifdef HAVE_TYPE_RB_ENCODING
|
216
221
|
|
@@ -224,6 +229,7 @@ static VALUE oci8_set_nls_ratio(VALUE klass, VALUE val)
|
|
224
229
|
* are passed to Oracle, they are converted to +OCI8.encoding+
|
225
230
|
* in advance.
|
226
231
|
*
|
232
|
+
* @example
|
227
233
|
* # When OCI8.encoding is ISO-8859-1,
|
228
234
|
* conn.exec('insert into country_code values(:1, :2, :3)',
|
229
235
|
* 'AT', 'Austria', "\u00d6sterreichs")
|
@@ -243,6 +249,8 @@ static VALUE oci8_set_nls_ratio(VALUE klass, VALUE val)
|
|
243
249
|
*
|
244
250
|
* @return [Encoding]
|
245
251
|
* @since 2.0.0 and ruby 1.9
|
252
|
+
* @private
|
253
|
+
* @see OCI8.client_charset_name
|
246
254
|
*/
|
247
255
|
static VALUE oci8_get_encoding(VALUE klass)
|
248
256
|
{
|
@@ -259,13 +267,16 @@ static VALUE oci8_get_encoding(VALUE klass)
|
|
259
267
|
*
|
260
268
|
* @param [Encoding] enc
|
261
269
|
* @since 2.0.0 and ruby 1.9
|
270
|
+
* @private
|
262
271
|
*/
|
263
272
|
static VALUE oci8_set_encoding(VALUE klass, VALUE encoding)
|
264
273
|
{
|
265
274
|
if (NIL_P(encoding)) {
|
266
275
|
oci8_encoding = NULL;
|
276
|
+
oci8_nls_ratio = 1;
|
267
277
|
} else {
|
268
278
|
oci8_encoding = rb_to_encoding(encoding);
|
279
|
+
oci8_nls_ratio = rb_enc_mbmaxlen(oci8_encoding);
|
269
280
|
}
|
270
281
|
return encoding;
|
271
282
|
}
|
@@ -287,7 +298,9 @@ void Init_oci8_encoding(VALUE cOCI8)
|
|
287
298
|
rb_define_method(cOCI8, "charset_name2id", oci8_charset_name2id, 1);
|
288
299
|
rb_define_method(cOCI8, "charset_id2name", oci8_charset_id2name, 1);
|
289
300
|
rb_define_singleton_method(cOCI8, "nls_ratio", oci8_get_nls_ratio, 0);
|
301
|
+
#ifndef HAVE_TYPE_RB_ENCODING
|
290
302
|
rb_define_singleton_method(cOCI8, "nls_ratio=", oci8_set_nls_ratio, 1);
|
303
|
+
#endif
|
291
304
|
#ifdef HAVE_TYPE_RB_ENCODING
|
292
305
|
rb_define_singleton_method(cOCI8, "encoding", oci8_get_encoding, 0);
|
293
306
|
rb_define_singleton_method(cOCI8, "encoding=", oci8_set_encoding, 1);
|
data/ext/oci8/error.c
CHANGED
@@ -160,31 +160,6 @@ static VALUE set_backtrace(VALUE exc, const char *file, int line)
|
|
160
160
|
return exc;
|
161
161
|
}
|
162
162
|
|
163
|
-
/*
|
164
|
-
* call-seq:
|
165
|
-
* initialize(message, code = nil, sql = nil, parse_error_offset = nil)
|
166
|
-
*
|
167
|
-
* Creates a new OCIError object.
|
168
|
-
*
|
169
|
-
* @example
|
170
|
-
* OCIError.new("ORA-00001: unique constraint (%s.%s) violated", 1)
|
171
|
-
* # => #<OCIError: ORA-00001: unique constraint (%s.%s) violated>
|
172
|
-
*/
|
173
|
-
static VALUE oci8_error_initialize(int argc, VALUE *argv, VALUE self)
|
174
|
-
{
|
175
|
-
VALUE msg;
|
176
|
-
VALUE code;
|
177
|
-
VALUE sql;
|
178
|
-
VALUE parse_error_offset;
|
179
|
-
|
180
|
-
rb_scan_args(argc, argv, "04", &msg, &code, &sql, &parse_error_offset);
|
181
|
-
rb_call_super(argc > 1 ? 1 : argc, argv);
|
182
|
-
rb_ivar_set(self, oci8_id_at_code, code);
|
183
|
-
rb_ivar_set(self, oci8_id_at_sql, sql);
|
184
|
-
rb_ivar_set(self, oci8_id_at_parse_error_offset, parse_error_offset);
|
185
|
-
return Qnil;
|
186
|
-
}
|
187
|
-
|
188
163
|
sb4 oci8_get_error_code(OCIError *errhp)
|
189
164
|
{
|
190
165
|
sb4 errcode = -1;
|
@@ -214,8 +189,6 @@ void Init_oci8_error(void)
|
|
214
189
|
eOCIContinue = rb_define_class("OCIContinue", eOCIException);
|
215
190
|
eOCISuccessWithInfo = rb_define_class("OCISuccessWithInfo", eOCIError);
|
216
191
|
|
217
|
-
rb_define_method(eOCIError, "initialize", oci8_error_initialize, -1);
|
218
|
-
|
219
192
|
/*
|
220
193
|
* @attr_reader [Integer] code error code
|
221
194
|
*/
|
data/ext/oci8/extconf.rb
CHANGED
@@ -134,14 +134,57 @@ replace_keyword(File.dirname(__FILE__) + '/../../lib/oci8.rb.in', '../../lib/oci
|
|
134
134
|
ruby_engine = (defined? RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
135
135
|
|
136
136
|
so_basename = 'oci8lib_'
|
137
|
-
|
138
|
-
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
|
137
|
+
case ruby_engine
|
138
|
+
when 'ruby'
|
139
|
+
# The extension library name includes the ruby ABI (application binary interface)
|
140
|
+
# version. It is for binary gems which contain more than one extension library
|
141
|
+
# and use correct one depending on the ABI version.
|
142
|
+
#
|
143
|
+
# ruby version | ABI version
|
144
|
+
# --------------+--------------
|
145
|
+
# 1.8.6 | 1.8
|
146
|
+
# 1.8.7 | 1.8
|
147
|
+
# --------------+--------------
|
148
|
+
# 1.9.0 | 1.9.0
|
149
|
+
# 1.9.1 | 1.9.1
|
150
|
+
# 1.9.2 | 1.9.1
|
151
|
+
# 1.9.3 | 1.9.1
|
152
|
+
# --------------+--------------
|
153
|
+
# 2.0.0 | 2.0.0
|
154
|
+
# 2.0.1 | 2.0.1 (See: [ruby-core:49578])
|
155
|
+
# ... | ...
|
156
|
+
#
|
157
|
+
# Note: The ruby ABI version is same with RbConfig::CONFIG['ruby_version']
|
158
|
+
# if it wasn't explicitly changed by the configure option --with-ruby-version.
|
159
|
+
#
|
160
|
+
case RUBY_VERSION
|
161
|
+
when /^2\.0/
|
162
|
+
so_basename += RUBY_VERSION.gsub(/\W/, '')
|
163
|
+
when /^1\.9\.0/
|
164
|
+
raise 'unsupported ruby version: 1.9.0'
|
165
|
+
when /^1\.9/
|
166
|
+
so_basename += '191'
|
167
|
+
when /^1\.8/
|
168
|
+
so_basename += '18'
|
169
|
+
else
|
170
|
+
raise 'unsupported ruby version: ' + RUBY_VERSION
|
171
|
+
end
|
172
|
+
when 'rbx'
|
173
|
+
# "rbx -X18" and "rbx -X19" use different C header files.
|
174
|
+
case RUBY_VERSION
|
175
|
+
when /^2\.0/
|
176
|
+
so_basename += 'rbx20'
|
177
|
+
when /^1\.9/
|
178
|
+
so_basename += 'rbx19'
|
179
|
+
when /^1\.8/
|
180
|
+
so_basename += 'rbx18'
|
181
|
+
else
|
182
|
+
raise 'unsupported language mode: ' + RUBY_VERSION
|
183
|
+
end
|
184
|
+
when 'jruby'
|
185
|
+
raise "Ruby-oci8 doesn't support jruby because its C extension support is in development in jruby 1.6 and deprecated in jruby 1.7."
|
143
186
|
else
|
144
|
-
|
187
|
+
raise 'unsupported ruby engine: ' + RUBY_ENGINE
|
145
188
|
end
|
146
189
|
|
147
190
|
$defs << "-DInit_oci8lib=Init_#{so_basename}"
|
data/ext/oci8/lob.c
CHANGED
@@ -554,12 +554,24 @@ static VALUE oci8_lob_read(int argc, VALUE *argv, VALUE self)
|
|
554
554
|
/* initialize buf in zeros everytime to check a nul characters. */
|
555
555
|
memset(buf, 0, sizeof(buf));
|
556
556
|
rv = OCILobRead_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &amt, lob->pos + 1, buf, sizeof(buf), NULL, NULL, 0, lob->csfrm);
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
557
|
+
svcctx->suppress_free_temp_lobs = 0;
|
558
|
+
switch (rv) {
|
559
|
+
case OCI_SUCCESS:
|
560
|
+
break;
|
561
|
+
case OCI_NEED_DATA:
|
562
|
+
/* prevent OCILobFreeTemporary() from being called.
|
563
|
+
* See: https://github.com/kubo/ruby-oci8/issues/20
|
564
|
+
*/
|
565
|
+
svcctx->suppress_free_temp_lobs = 1;
|
566
|
+
break;
|
567
|
+
case OCI_ERROR:
|
568
|
+
if (oci8_get_error_code(oci8_errhp) == 22289) {
|
569
|
+
/* ORA-22289: cannot perform FILEREAD operation on an unopened file or LOB */
|
570
|
+
if (lob->state == S_BFILE_CLOSE)
|
571
|
+
continue;
|
572
|
+
}
|
573
|
+
/* FALLTHROUGH */
|
574
|
+
default:
|
563
575
|
chker2(rv, &svcctx->base);
|
564
576
|
}
|
565
577
|
|
data/ext/oci8/metadata.c
CHANGED
@@ -159,6 +159,19 @@ static VALUE oci8_do_describe(VALUE self, void *objptr, ub4 objlen, ub1 objtype,
|
|
159
159
|
return oci8_metadata_create(parmhp, self, obj);
|
160
160
|
}
|
161
161
|
|
162
|
+
/*
|
163
|
+
* call-seq:
|
164
|
+
* __describe(name, klass, check_public)
|
165
|
+
*
|
166
|
+
* @param [String] name object name
|
167
|
+
* @param [subclass of OCI8::Metadata::Base] klass
|
168
|
+
* @param [Boolean] check_public +true+ to look up the object as a public synonym when
|
169
|
+
* the object does not exist in the current schema and
|
170
|
+
* the name includes no dots.
|
171
|
+
* @return [subclass of OCI8::Metadata::Base]
|
172
|
+
*
|
173
|
+
* @private
|
174
|
+
*/
|
162
175
|
static VALUE oci8_describe(VALUE self, VALUE name, VALUE klass, VALUE check_public)
|
163
176
|
{
|
164
177
|
OCI8SafeStringValue(name);
|
data/ext/oci8/oci8.c
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
/*
|
3
3
|
* oci8.c - part of ruby-oci8
|
4
4
|
*
|
5
|
-
* Copyright (C) 2002-
|
5
|
+
* Copyright (C) 2002-2013 KUBO Takehiro <kubo@jiubao.org>
|
6
6
|
*
|
7
7
|
*/
|
8
8
|
#include "oci8.h"
|
@@ -171,25 +171,56 @@ static VALUE oci8_s_oracle_client_vernum(VALUE klass)
|
|
171
171
|
return oracle_client_vernum;
|
172
172
|
}
|
173
173
|
|
174
|
-
|
174
|
+
/*
|
175
|
+
* call-seq:
|
176
|
+
* OCI8.__get_prop(key)
|
177
|
+
*
|
178
|
+
* @param [Fixnum] key 1 or 2
|
179
|
+
*
|
180
|
+
* @private
|
181
|
+
*/
|
182
|
+
static VALUE oci8_s_get_prop(VALUE klass, VALUE key)
|
175
183
|
{
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
184
|
+
switch (NUM2INT(key)) {
|
185
|
+
case 1:
|
186
|
+
return oci8_float_conversion_type_is_ruby ? Qtrue : Qfalse;
|
187
|
+
case 2:
|
188
|
+
return UINT2NUM(oci8_env_mode);
|
189
|
+
default:
|
190
|
+
rb_raise(rb_eArgError, "Unknown prop %d", NUM2INT(key));
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
|
195
|
+
/*
|
196
|
+
* call-seq:
|
197
|
+
* OCI8.__set_prop(key, value)
|
198
|
+
*
|
199
|
+
* @param [Fixnum] key 1 or 2
|
200
|
+
* @param [Object] value depends on +key+.
|
201
|
+
*
|
202
|
+
* @private
|
203
|
+
*/
|
204
|
+
static VALUE oci8_s_set_prop(VALUE klass, VALUE key, VALUE val)
|
205
|
+
{
|
206
|
+
switch (NUM2INT(key)) {
|
207
|
+
case 1:
|
208
|
+
oci8_float_conversion_type_is_ruby = RTEST(val) ? 1 : 0;
|
209
|
+
break;
|
210
|
+
case 2:
|
211
|
+
/*
|
212
|
+
* Changes the OCI environment mode which will be passed to the second
|
213
|
+
* argument of the OCI function OCIEnvCreate.
|
214
|
+
*/
|
215
|
+
if (oci8_global_envhp != NULL) {
|
216
|
+
rb_raise(rb_eRuntimeError, "The OCI Environment has been alreadly initialized. It cannot be changed after even one OCI function is called.");
|
190
217
|
}
|
218
|
+
oci8_env_mode = NUM2UINT(val);
|
219
|
+
break;
|
220
|
+
default:
|
221
|
+
rb_raise(rb_eArgError, "Unknown prop %d", NUM2INT(key));
|
191
222
|
}
|
192
|
-
return
|
223
|
+
return klass;
|
193
224
|
}
|
194
225
|
|
195
226
|
/*
|
@@ -254,6 +285,7 @@ void oci8_do_parse_connect_string(VALUE conn_str, VALUE *user, VALUE *pass, VALU
|
|
254
285
|
* "scott/tiger@oradb.example.com" -> ["scott", "tiger", "oradb.example.com", nil]
|
255
286
|
* "sys/change_on_install as sysdba" -> ["sys", "change_on_install", nil, :SYSDBA]
|
256
287
|
*
|
288
|
+
* @private
|
257
289
|
*/
|
258
290
|
static VALUE oci8_parse_connect_string(VALUE self, VALUE conn_str)
|
259
291
|
{
|
@@ -365,9 +397,9 @@ static const oci8_logoff_strategy_t complex_logoff = {
|
|
365
397
|
* call-seq:
|
366
398
|
* logon2(username, password, dbname, mode) -> connection
|
367
399
|
*
|
368
|
-
* <b>internal use only</b>
|
369
|
-
*
|
370
400
|
* Creates a simple logon session by the OCI function OCILogon2().
|
401
|
+
*
|
402
|
+
* @private
|
371
403
|
*/
|
372
404
|
static VALUE oci8_logon2(VALUE self, VALUE username, VALUE password, VALUE dbname, VALUE mode)
|
373
405
|
{
|
@@ -417,10 +449,10 @@ static VALUE oci8_logon2(VALUE self, VALUE username, VALUE password, VALUE dbnam
|
|
417
449
|
* call-seq:
|
418
450
|
* allocate_handles()
|
419
451
|
*
|
420
|
-
* <b>internal use only</b>
|
421
|
-
*
|
422
452
|
* Allocates a service context handle, a session handle and a
|
423
453
|
* server handle to use explicit attach and begin-session calls.
|
454
|
+
*
|
455
|
+
* @private
|
424
456
|
*/
|
425
457
|
static VALUE oci8_allocate_handles(VALUE self)
|
426
458
|
{
|
@@ -457,9 +489,9 @@ static VALUE oci8_allocate_handles(VALUE self)
|
|
457
489
|
* call-seq:
|
458
490
|
* server_attach(dbname, mode)
|
459
491
|
*
|
460
|
-
* <b>internal use only</b>
|
461
|
-
*
|
462
492
|
* Attachs to the server by the OCI function OCIServerAttach().
|
493
|
+
*
|
494
|
+
* @private
|
463
495
|
*/
|
464
496
|
static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE attach_mode)
|
465
497
|
{
|
@@ -499,9 +531,9 @@ static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE attach_mode)
|
|
499
531
|
* call-seq:
|
500
532
|
* session_begin(cred, mode)
|
501
533
|
*
|
502
|
-
* <b>internal use only</b>
|
503
|
-
*
|
504
534
|
* Begins the session by the OCI function OCISessionBegin().
|
535
|
+
*
|
536
|
+
* @private
|
505
537
|
*/
|
506
538
|
static VALUE oci8_session_begin(VALUE self, VALUE cred, VALUE mode)
|
507
539
|
{
|
@@ -767,9 +799,9 @@ static VALUE oci8_set_prefetch_rows(VALUE self, VALUE val)
|
|
767
799
|
*
|
768
800
|
* Returns a numerical format of the Oracle server version.
|
769
801
|
*
|
770
|
-
*
|
771
|
-
*
|
802
|
+
* @see OCI8#oracle_server_version
|
772
803
|
* @since 2.0.1
|
804
|
+
* @private
|
773
805
|
*/
|
774
806
|
static VALUE oci8_oracle_server_vernum(VALUE self)
|
775
807
|
{
|
@@ -1121,7 +1153,8 @@ void Init_oci8(VALUE *out)
|
|
1121
1153
|
|
1122
1154
|
rb_define_const(cOCI8, "VERSION", rb_obj_freeze(rb_usascii_str_new_cstr(OCI8LIB_VERSION)));
|
1123
1155
|
rb_define_singleton_method_nodoc(cOCI8, "oracle_client_vernum", oci8_s_oracle_client_vernum, 0);
|
1124
|
-
|
1156
|
+
rb_define_singleton_method(cOCI8, "__get_prop", oci8_s_get_prop, 1);
|
1157
|
+
rb_define_singleton_method(cOCI8, "__set_prop", oci8_s_set_prop, 2);
|
1125
1158
|
rb_define_singleton_method(cOCI8, "error_message", oci8_s_error_message, 1);
|
1126
1159
|
rb_define_private_method(cOCI8, "parse_connect_string", oci8_parse_connect_string, 1);
|
1127
1160
|
rb_define_private_method(cOCI8, "logon2", oci8_logon2, 4);
|
@@ -1145,7 +1178,6 @@ void Init_oci8(VALUE *out)
|
|
1145
1178
|
rb_define_method(cOCI8, "module=", oci8_set_module, 1);
|
1146
1179
|
rb_define_method(cOCI8, "action=", oci8_set_action, 1);
|
1147
1180
|
rb_define_method(cOCI8, "client_info=", oci8_set_client_info, 1);
|
1148
|
-
rb_define_attr(cOCI8, "last_error", 1, 1);
|
1149
1181
|
*out = cOCI8;
|
1150
1182
|
}
|
1151
1183
|
|
data/ext/oci8/oci8.h
CHANGED
data/ext/oci8/oci8lib.c
CHANGED
@@ -229,44 +229,45 @@ static void *free_temp_lob(void *user_data)
|
|
229
229
|
/* ruby 1.9 */
|
230
230
|
sword oci8_call_without_gvl(oci8_svcctx_t *svcctx, void *(*func)(void *), void *data)
|
231
231
|
{
|
232
|
-
oci8_temp_lob_t *lob;
|
233
232
|
OCIError *errhp = oci8_errhp;
|
234
233
|
|
235
234
|
if (!NIL_P(svcctx->executing_thread)) {
|
236
235
|
rb_raise(rb_eRuntimeError /* FIXME */, "executing in another thread");
|
237
236
|
}
|
238
237
|
|
239
|
-
|
240
|
-
|
241
|
-
|
238
|
+
if (!svcctx->suppress_free_temp_lobs) {
|
239
|
+
oci8_temp_lob_t *lob = svcctx->temp_lobs;
|
240
|
+
while (lob != NULL) {
|
241
|
+
oci8_temp_lob_t *lob_next = lob->next;
|
242
242
|
|
243
|
-
|
244
|
-
|
245
|
-
|
243
|
+
if (svcctx->non_blocking) {
|
244
|
+
free_temp_lob_arg_t arg;
|
245
|
+
sword rv;
|
246
246
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
247
|
+
arg.svcctx = svcctx;
|
248
|
+
arg.svchp = svcctx->base.hp.svc;
|
249
|
+
arg.errhp = errhp;
|
250
|
+
arg.lob = lob->lob;
|
251
251
|
|
252
|
-
|
252
|
+
svcctx->executing_thread = rb_thread_current();
|
253
253
|
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
254
|
-
|
254
|
+
rv = (sword)(VALUE)rb_thread_call_without_gvl(free_temp_lob, &arg, oci8_unblock_func, svcctx);
|
255
255
|
#else
|
256
|
-
|
256
|
+
rv = (sword)rb_thread_blocking_region((VALUE(*)(void*))free_temp_lob, &arg, oci8_unblock_func, svcctx);
|
257
257
|
#endif
|
258
|
-
|
259
|
-
|
260
|
-
|
258
|
+
if (rv == OCI_ERROR) {
|
259
|
+
if (oci8_get_error_code(errhp) == 1013) {
|
260
|
+
rb_raise(eOCIBreak, "Canceled by user request.");
|
261
|
+
}
|
261
262
|
}
|
263
|
+
} else {
|
264
|
+
OCILobFreeTemporary(svcctx->base.hp.svc, errhp, lob->lob);
|
262
265
|
}
|
263
|
-
|
264
|
-
OCILobFreeTemporary(svcctx->base.hp.svc, errhp, lob->lob);
|
265
|
-
}
|
266
|
-
OCIDescriptorFree(lob->lob, OCI_DTYPE_LOB);
|
266
|
+
OCIDescriptorFree(lob->lob, OCI_DTYPE_LOB);
|
267
267
|
|
268
|
-
|
269
|
-
|
268
|
+
xfree(lob);
|
269
|
+
svcctx->temp_lobs = lob = lob_next;
|
270
|
+
}
|
270
271
|
}
|
271
272
|
|
272
273
|
if (svcctx->non_blocking) {
|
data/ext/oci8/oraconf.rb
CHANGED
data/lib/oci8.rb.in
CHANGED
@@ -26,14 +26,34 @@ end
|
|
26
26
|
ruby_engine = (defined? RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
27
27
|
|
28
28
|
so_basename = 'oci8lib_'
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
29
|
+
case ruby_engine
|
30
|
+
when 'ruby'
|
31
|
+
# The extension library name includes the ruby ABI (application binary interface)
|
32
|
+
# version. It is for binary gems which contain more than one extension library
|
33
|
+
# and use correct one depending on the ABI version.
|
34
|
+
#
|
35
|
+
# ruby version | ABI version
|
36
|
+
# --------------+--------------
|
37
|
+
# 1.8.6 | 1.8
|
38
|
+
# 1.8.7 | 1.8
|
39
|
+
# --------------+--------------
|
40
|
+
# 1.9.0 | 1.9.0
|
41
|
+
# 1.9.1 | 1.9.1
|
42
|
+
# 1.9.2 | 1.9.1
|
43
|
+
# 1.9.3 | 1.9.1
|
44
|
+
# --------------+--------------
|
45
|
+
# 2.0.0 | 2.0.0
|
46
|
+
# 2.0.1 | 2.0.1 (See: [ruby-core:49578])
|
47
|
+
# ... | ...
|
48
|
+
#
|
49
|
+
# Note: The ruby ABI version is same with RbConfig::CONFIG['ruby_version']
|
50
|
+
# if it wasn't explicitly changed by the configure option --with-ruby-version.
|
51
|
+
#
|
34
52
|
case RUBY_VERSION
|
35
53
|
when /^2\.0/
|
36
|
-
so_basename += '
|
54
|
+
so_basename += RUBY_VERSION.gsub(/\W/, '')
|
55
|
+
when /^1\.9\.0/
|
56
|
+
raise 'unsupported ruby version: 1.9.0'
|
37
57
|
when /^1\.9/
|
38
58
|
so_basename += '191'
|
39
59
|
when /^1\.8/
|
@@ -41,8 +61,22 @@ if ruby_engine == 'ruby'
|
|
41
61
|
else
|
42
62
|
raise 'unsupported ruby version: ' + RUBY_VERSION
|
43
63
|
end
|
64
|
+
when 'rbx'
|
65
|
+
# "rbx -X18" and "rbx -X19" use different C header files.
|
66
|
+
case RUBY_VERSION
|
67
|
+
when /^2\.0/
|
68
|
+
so_basename += 'rbx20'
|
69
|
+
when /^1\.9/
|
70
|
+
so_basename += 'rbx19'
|
71
|
+
when /^1\.8/
|
72
|
+
so_basename += 'rbx18'
|
73
|
+
else
|
74
|
+
raise 'unsupported language mode: ' + RUBY_VERSION
|
75
|
+
end
|
76
|
+
when 'jruby'
|
77
|
+
raise "Ruby-oci8 doesn't support jruby because its C extension support is in development in jruby 1.6 and deprecated in jruby 1.7."
|
44
78
|
else
|
45
|
-
|
79
|
+
raise 'unsupported ruby engine: ' + RUBY_ENGINE
|
46
80
|
end
|
47
81
|
require so_basename
|
48
82
|
|
@@ -89,6 +123,7 @@ class OCI8
|
|
89
123
|
# OCIClientVersion().
|
90
124
|
#
|
91
125
|
# @return [OCI8::OracleVersion] Oracle client version
|
126
|
+
# @see OCI8#oracle_server_version
|
92
127
|
def self.oracle_client_version
|
93
128
|
@@oracle_client_version
|
94
129
|
end
|
data/lib/oci8/encoding-init.rb
CHANGED
@@ -39,26 +39,6 @@ class OCI8
|
|
39
39
|
@@client_charset_name = 'US7ASCII'
|
40
40
|
end
|
41
41
|
|
42
|
-
# NLS ratio, maximum number of bytes per one chracter
|
43
|
-
case @@client_charset_name
|
44
|
-
when 'UTF8'
|
45
|
-
OCI8.nls_ratio = 3
|
46
|
-
when 'AL16UTF16'
|
47
|
-
OCI8.nls_ratio = 4
|
48
|
-
when /^[[:alpha:]]+(\d+)/
|
49
|
-
# convert maximum number of bits per one chracter to NLS ratio.
|
50
|
-
# charset name max bits max bytes
|
51
|
-
# ------------ -------- ---------
|
52
|
-
# US7ASCII 7 1
|
53
|
-
# WE8ISO8859P1 8 1
|
54
|
-
# JA16SJIS 16 2
|
55
|
-
# AL32UTF8 32 4
|
56
|
-
# ...
|
57
|
-
OCI8.nls_ratio = (($1.to_i + 7) >> 3)
|
58
|
-
else
|
59
|
-
raise "Unknown NLS character set name format: #{@@client_charset_name}"
|
60
|
-
end
|
61
|
-
|
62
42
|
# Ruby encoding name for ruby 1.9.
|
63
43
|
if OCI8.respond_to? :encoding
|
64
44
|
if defined? DEFAULT_OCI8_ENCODING
|
@@ -75,5 +55,25 @@ class OCI8
|
|
75
55
|
end
|
76
56
|
end
|
77
57
|
OCI8.encoding = enc
|
58
|
+
else
|
59
|
+
# NLS ratio, maximum number of bytes per one chracter
|
60
|
+
case @@client_charset_name
|
61
|
+
when 'UTF8'
|
62
|
+
OCI8.nls_ratio = 3
|
63
|
+
when 'AL16UTF16'
|
64
|
+
OCI8.nls_ratio = 4
|
65
|
+
when /^[[:alpha:]]+(\d+)/
|
66
|
+
# convert maximum number of bits per one chracter to NLS ratio.
|
67
|
+
# charset name max bits max bytes
|
68
|
+
# ------------ -------- ---------
|
69
|
+
# US7ASCII 7 1
|
70
|
+
# WE8ISO8859P1 8 1
|
71
|
+
# JA16SJIS 16 2
|
72
|
+
# AL32UTF8 32 4
|
73
|
+
# ...
|
74
|
+
OCI8.nls_ratio = (($1.to_i + 7) >> 3)
|
75
|
+
else
|
76
|
+
raise "Unknown NLS character set name format: #{@@client_charset_name}"
|
77
|
+
end
|
78
78
|
end
|
79
79
|
end
|
data/lib/oci8/metadata.rb
CHANGED
@@ -1985,72 +1985,115 @@ class OCI8
|
|
1985
1985
|
=end
|
1986
1986
|
end # OCI8::Metadata
|
1987
1987
|
|
1988
|
-
#
|
1989
|
-
#
|
1990
|
-
#
|
1991
|
-
#
|
1992
|
-
#
|
1993
|
-
#
|
1988
|
+
# Returns object information.
|
1989
|
+
#
|
1990
|
+
# The return type is depends on the object type.
|
1991
|
+
#
|
1992
|
+
# Oracle type:: Ruby type
|
1993
|
+
# Table:: {OCI8::Metadata::Table}
|
1994
|
+
# View:: {OCI8::Metadata::View}
|
1995
|
+
# Procedure:: {OCI8::Metadata::Procedure}
|
1996
|
+
# Function:: {OCI8::Metadata::Function}
|
1997
|
+
# Package:: {OCI8::Metadata::Package}
|
1998
|
+
# Type:: {OCI8::Metadata::Type}
|
1999
|
+
# Synonym:: {OCI8::Metadata::Synonym}
|
2000
|
+
# Sequence:: {OCI8::Metadata::Sequence}
|
2001
|
+
#
|
2002
|
+
# @param [String] object_name
|
2003
|
+
# @return [a subclass of OCI8::Metadata::Base]
|
1994
2004
|
def describe_any(object_name)
|
1995
2005
|
__describe(object_name, OCI8::Metadata::Unknown, true)
|
1996
2006
|
end
|
1997
|
-
#
|
1998
|
-
# name
|
1999
|
-
# it returns a OCI8::Metadata::Table or a OCI8::Metadata::View which
|
2007
|
+
# Returns table or view information. If the name is a current schema's synonym
|
2008
|
+
# name or a public synonym name, it returns table or view information which
|
2000
2009
|
# the synonym refers.
|
2001
2010
|
#
|
2002
|
-
# If
|
2003
|
-
#
|
2011
|
+
# If +table_only+ is true, it checks tables in the current schema.
|
2012
|
+
#
|
2013
|
+
# @param [String] table_name
|
2014
|
+
# @param [Boolean] table_only (default: false)
|
2015
|
+
# @return [OCI8::Metadata::Table or OCI8::Metadata::View]
|
2004
2016
|
def describe_table(table_name, table_only = false)
|
2005
2017
|
if table_only
|
2006
2018
|
# check my own tables only.
|
2007
2019
|
__describe(table_name, OCI8::Metadata::Table, false)
|
2008
2020
|
else
|
2009
2021
|
# check tables, views, synonyms and public synonyms.
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
metadata
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2022
|
+
recursive_level = 20
|
2023
|
+
recursive_level.times do
|
2024
|
+
metadata = __describe(table_name, OCI8::Metadata::Unknown, true)
|
2025
|
+
case metadata
|
2026
|
+
when OCI8::Metadata::Table, OCI8::Metadata::View
|
2027
|
+
return metadata
|
2028
|
+
when OCI8::Metadata::Synonym
|
2029
|
+
table_name = metadata.translated_name
|
2030
|
+
else
|
2031
|
+
raise OCIError.new(4043, table_name) # ORA-04043: object %s does not exist
|
2032
|
+
end
|
2018
2033
|
end
|
2034
|
+
raise OCIError.new(36, recursive_level) # ORA-00036: maximum number of recursive SQL levels (%s) exceeded
|
2019
2035
|
end
|
2020
2036
|
end
|
2021
|
-
#
|
2037
|
+
# Returns view information
|
2038
|
+
#
|
2039
|
+
# @param [String] view_name
|
2040
|
+
# @return [OCI8::Metadata::View]
|
2022
2041
|
def describe_view(view_name)
|
2023
2042
|
__describe(view_name, OCI8::Metadata::View, false)
|
2024
2043
|
end
|
2025
|
-
#
|
2044
|
+
# Returns procedure information
|
2045
|
+
#
|
2046
|
+
# @param [String] procedure_name
|
2047
|
+
# @return [OCI8::Metadata::Procedure]
|
2026
2048
|
def describe_procedure(procedure_name)
|
2027
2049
|
__describe(procedure_name, OCI8::Metadata::Procedure, false)
|
2028
2050
|
end
|
2029
|
-
#
|
2051
|
+
# Returns function information
|
2052
|
+
#
|
2053
|
+
# @param [String] function_name
|
2054
|
+
# @return [OCI8::Metadata::Function]
|
2030
2055
|
def describe_function(function_name)
|
2031
2056
|
__describe(function_name, OCI8::Metadata::Function, false)
|
2032
2057
|
end
|
2033
|
-
#
|
2058
|
+
# Returns package information
|
2059
|
+
#
|
2060
|
+
# @param [String] package_name
|
2061
|
+
# @return [OCI8::Metadata::Package]
|
2034
2062
|
def describe_package(package_name)
|
2035
2063
|
__describe(package_name, OCI8::Metadata::Package, false)
|
2036
2064
|
end
|
2037
|
-
#
|
2065
|
+
# Returns type information
|
2066
|
+
#
|
2067
|
+
# @param [String] type_name
|
2068
|
+
# @return [OCI8::Metadata::Type]
|
2038
2069
|
def describe_type(type_name)
|
2039
2070
|
__describe(type_name, OCI8::Metadata::Type, false)
|
2040
2071
|
end
|
2041
|
-
#
|
2072
|
+
# Returns synonym information
|
2073
|
+
#
|
2074
|
+
# @param [String] synonym_name
|
2075
|
+
# @return [OCI8::Metadata::Synonym]
|
2042
2076
|
def describe_synonym(synonym_name, check_public_also = true)
|
2043
2077
|
__describe(synonym_name, OCI8::Metadata::Synonym, check_public_also)
|
2044
2078
|
end
|
2045
|
-
#
|
2079
|
+
# Returns sequence information
|
2080
|
+
#
|
2081
|
+
# @param [String] sequence_name
|
2082
|
+
# @return [OCI8::Metadata::Sequence]
|
2046
2083
|
def describe_sequence(sequence_name)
|
2047
2084
|
__describe(sequence_name, OCI8::Metadata::Sequence, false)
|
2048
2085
|
end
|
2049
|
-
#
|
2086
|
+
# Returns schema information
|
2087
|
+
#
|
2088
|
+
# @param [String] schema_name
|
2089
|
+
# @return [OCI8::Metadata::Schema]
|
2050
2090
|
def describe_schema(schema_name)
|
2051
2091
|
__describe(schema_name, OCI8::Metadata::Schema, false)
|
2052
2092
|
end
|
2053
|
-
#
|
2093
|
+
# Returns database information
|
2094
|
+
#
|
2095
|
+
# @param [String] database_name
|
2096
|
+
# @return [OCI8::Metadata::Database]
|
2054
2097
|
def describe_database(database_name)
|
2055
2098
|
__describe(database_name, OCI8::Metadata::Database, false)
|
2056
2099
|
end
|
data/lib/oci8/oci8.rb
CHANGED
@@ -26,8 +26,10 @@ require 'yaml'
|
|
26
26
|
# value_for_the_second_parameter)
|
27
27
|
class OCI8
|
28
28
|
|
29
|
-
#
|
30
|
-
|
29
|
+
# @return [OCIError]
|
30
|
+
attr_accessor :last_error
|
31
|
+
|
32
|
+
# @overload initialize(username, password, dbname = nil, privilege = nil)
|
31
33
|
#
|
32
34
|
# Connects to an Oracle database server by +username+ and +password+
|
33
35
|
# at +dbname+ as +privilege+.
|
@@ -337,14 +339,14 @@ class OCI8
|
|
337
339
|
end
|
338
340
|
end
|
339
341
|
|
342
|
+
# @private
|
340
343
|
def inspect
|
341
344
|
"#<OCI8:#{username}>"
|
342
345
|
end
|
343
346
|
|
344
|
-
# Returns
|
345
|
-
#
|
346
|
-
# See also: OCI8.oracle_client_version
|
347
|
+
# Returns the Oracle server version.
|
347
348
|
#
|
349
|
+
# @see OCI8.oracle_client_version
|
348
350
|
# @return [OCI8::OracleVersion]
|
349
351
|
def oracle_server_version
|
350
352
|
unless defined? @oracle_server_version
|
@@ -365,7 +367,7 @@ class OCI8
|
|
365
367
|
@oracle_server_version
|
366
368
|
end
|
367
369
|
|
368
|
-
# Returns the Oracle database character set name.
|
370
|
+
# Returns the Oracle database character set name such as AL32UTF8.
|
369
371
|
#
|
370
372
|
# @since 2.1.0
|
371
373
|
# @return [String] Oracle database character set name
|
@@ -373,15 +375,74 @@ class OCI8
|
|
373
375
|
charset_id2name(@server_handle.send(:attr_get_ub2, OCI_ATTR_CHARSET_ID))
|
374
376
|
end
|
375
377
|
|
376
|
-
# Returns the client-side Oracle character set name.
|
378
|
+
# Returns the client-side Oracle character set name such as AL32UTF8.
|
377
379
|
#
|
378
380
|
# @since 2.1.0
|
379
381
|
# @return [String] client-side character set name
|
382
|
+
# @private
|
383
|
+
# @see OCI8.encoding
|
380
384
|
def self.client_charset_name
|
381
385
|
@@client_charset_name
|
382
386
|
end
|
383
387
|
end
|
384
388
|
|
389
|
+
class OCIError
|
390
|
+
|
391
|
+
# @overload initialize(message, error_code = nil, sql_stmt = nil, parse_error_offset = nil)
|
392
|
+
# Creates a new OCIError object with specified parameters.
|
393
|
+
#
|
394
|
+
# @param [String] message error message
|
395
|
+
# @param [Integer] error_code Oracle error code
|
396
|
+
# @param [String] sql_stmt SQL statement
|
397
|
+
# @param [Integer] parse_error_offset
|
398
|
+
#
|
399
|
+
# @example
|
400
|
+
# OCIError.new("ORA-00001: unique constraint (%s.%s) violated", 1, 'insert into table_name values (1)', )
|
401
|
+
# # => #<OCIError: ORA-00001: unique constraint (%s.%s) violated>
|
402
|
+
# #<OCIError: ORA-00923: FROM keyword not found where expected>
|
403
|
+
# "select sysdate"
|
404
|
+
# 923
|
405
|
+
# 14
|
406
|
+
#
|
407
|
+
# @overload initialize(error_code, *params)
|
408
|
+
# Creates a new OCIError object with the error message which corresponds to the specified
|
409
|
+
# Oracle error code.
|
410
|
+
#
|
411
|
+
# @param [Integer] error_code Oracle error code
|
412
|
+
# @param [String, ...] params parameters which replace '%s'
|
413
|
+
#
|
414
|
+
# @example
|
415
|
+
# # without parameters
|
416
|
+
# OCIError.new(4043)
|
417
|
+
# # When NLS_LANG=american_america.AL32UTF8
|
418
|
+
# # => #<OCIError: ORA-04043: object %s does not exist>
|
419
|
+
# # When NLS_LANG=german_germany.AL32UTF8
|
420
|
+
# # => #<OCIError: ORA-04043: Objekt %s ist nicht vorhanden>
|
421
|
+
#
|
422
|
+
# # with one parameter
|
423
|
+
# OCIError.new(4043, 'table_name')
|
424
|
+
# # When NLS_LANG=american_america.AL32UTF8
|
425
|
+
# # => #<OCIError: ORA-04043: object table_name does not exist>
|
426
|
+
# # When NLS_LANG=german_germany.AL32UTF8
|
427
|
+
# # => #<OCIError: ORA-04043: Objekt table_name ist nicht vorhanden>
|
428
|
+
#
|
429
|
+
def initialize(*args)
|
430
|
+
if args.length > 0
|
431
|
+
if args[0].is_a? Fixnum
|
432
|
+
@code = args.shift
|
433
|
+
super(OCI8.error_message(@code).gsub('%s') {|s| args.empty? ? '%s' : args.shift})
|
434
|
+
@sql = nil
|
435
|
+
@parse_error_offset = nil
|
436
|
+
else
|
437
|
+
msg, @code, @sql, @parse_error_offset = args
|
438
|
+
super(msg)
|
439
|
+
end
|
440
|
+
else
|
441
|
+
super()
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
385
446
|
class OraDate
|
386
447
|
|
387
448
|
# Returns a Time object which denotes self.
|
data/lib/oci8/oracle_version.rb
CHANGED
data/lib/oci8/properties.rb
CHANGED
@@ -1,26 +1,30 @@
|
|
1
1
|
# properties.rb -- implements OCI8.properties
|
2
2
|
#
|
3
|
-
# Copyright (C) 2010-
|
3
|
+
# Copyright (C) 2010-2013 KUBO Takehiro <kubo@jiubao.org>
|
4
4
|
|
5
5
|
#
|
6
6
|
class OCI8
|
7
7
|
|
8
|
+
# @private
|
8
9
|
@@properties = {
|
9
10
|
:length_semantics => :byte,
|
10
11
|
:bind_string_as_nchar => false,
|
11
|
-
:float_conversion_type => :ruby,
|
12
|
+
:float_conversion_type => OCI8.__get_prop(1) ? :ruby : :oracle,
|
12
13
|
:statement_cache_size => 0,
|
14
|
+
:events_mode => ((OCI8.__get_prop(2) & 4) != 0) # 4 <- OCI_EVENTS in oci.h
|
13
15
|
}
|
14
16
|
|
15
17
|
if OCI8.oracle_client_version < OCI8::ORAVER_9_2
|
16
18
|
@@properties[:statement_cache_size] = nil
|
17
19
|
end
|
18
20
|
|
21
|
+
# @private
|
19
22
|
def @@properties.[](name)
|
20
23
|
raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
|
21
24
|
super(name)
|
22
25
|
end
|
23
26
|
|
27
|
+
# @private
|
24
28
|
def @@properties.[]=(name, val)
|
25
29
|
raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
|
26
30
|
case name
|
@@ -31,23 +35,31 @@ class OCI8
|
|
31
35
|
when :bind_string_as_nchar
|
32
36
|
val = val ? true : false
|
33
37
|
when :float_conversion_type
|
34
|
-
|
35
|
-
|
38
|
+
case val
|
39
|
+
when :ruby
|
40
|
+
OCI8.__set_prop(1, true)
|
41
|
+
when :oracle
|
42
|
+
OCI8.__set_prop(1, false)
|
43
|
+
else
|
44
|
+
raise ArgumentError, "float_conversion_type's value should be either :ruby or :oracle."
|
45
|
+
end
|
36
46
|
when :statement_cache_size
|
37
47
|
if OCI8.oracle_client_version < OCI8::ORAVER_9_2
|
38
48
|
raise RuntimeError, ":statement_cache_size is disabled on Oracle 9iR1 client."
|
39
49
|
end
|
40
50
|
val = val.to_i
|
41
51
|
raise ArgumentError, "The property value for :statement_cache_size must not be negative." if val < 0
|
52
|
+
when :events_mode
|
53
|
+
val = val ? true : false
|
54
|
+
if val
|
55
|
+
OCI8.__set_prop(2, OCI8.__get_prop(2) | 4) # set OCI_EVENTS
|
56
|
+
else
|
57
|
+
OCI8.__set_prop(2, OCI8.__get_prop(2) & ~4) # unset OCI_EVENTS
|
58
|
+
end
|
42
59
|
end
|
43
60
|
super(name, val)
|
44
61
|
end
|
45
62
|
|
46
|
-
# call-seq:
|
47
|
-
# OCI8.properties -> a customized Hash
|
48
|
-
#
|
49
|
-
# (new in 2.0.5)
|
50
|
-
#
|
51
63
|
# Returns a Hash which ruby-oci8 global settings.
|
52
64
|
# The hash's setter and getter methods are customized to check
|
53
65
|
# property names and values.
|
@@ -63,19 +75,20 @@ class OCI8
|
|
63
75
|
# Supported properties are listed below:
|
64
76
|
#
|
65
77
|
# [:length_semantics]
|
66
|
-
# (new in 2.1.0)
|
67
78
|
#
|
68
79
|
# +:char+ when Oracle character length is counted by the number of characters.
|
69
80
|
# +:byte+ when it is counted by the number of bytes.
|
70
81
|
# The default setting is +:byte+ because +:char+ causes unexpected behaviour on
|
71
82
|
# Oracle 9i.
|
83
|
+
#
|
84
|
+
# *Since:* 2.1.0
|
72
85
|
#
|
73
86
|
# [:bind_string_as_nchar]
|
87
|
+
#
|
74
88
|
# +true+ when string bind variables are bound as NCHAR,
|
75
89
|
# otherwise +false+. The default value is +false+.
|
76
90
|
#
|
77
91
|
# [:float_conversion_type]
|
78
|
-
# (new in 2.1.0)
|
79
92
|
#
|
80
93
|
# +:ruby+ when Oracle decimal numbers are converted to ruby Float values
|
81
94
|
# same as Float#to_s does. (default)
|
@@ -85,14 +98,35 @@ class OCI8
|
|
85
98
|
# the Oracle function OCINumberToReal() makes a string representation
|
86
99
|
# 15.700000000000001 by Float#to_s.
|
87
100
|
# See: http://rubyforge.org/forum/forum.php?thread_id=50030&forum_id=1078
|
101
|
+
#
|
102
|
+
# *Since:* 2.1.0
|
88
103
|
#
|
89
104
|
# [:statement_cache_size]
|
90
|
-
# (new in 2.1.1)
|
91
105
|
#
|
92
106
|
# The statement cache size per each session. The default size is 0, which
|
93
107
|
# means no statement cache, since 2.1.2. It was 20 in 2.1.1.
|
94
108
|
# This feature is available on Oracle 9iR2 or later.
|
95
109
|
# See: http://docs.oracle.com/cd/E11882_01/appdev.112/e10646/oci09adv.htm#i471377
|
110
|
+
#
|
111
|
+
# *Since:* 2.1.1
|
112
|
+
#
|
113
|
+
# [:events_mode]
|
114
|
+
#
|
115
|
+
# +true+ when Fast Application Notification (FAN) Support is enabled.
|
116
|
+
# +false+ when it is disabled. The default value is +false+.
|
117
|
+
# This corresponds to {http://php.net/manual/en/oci8.configuration.php#ini.oci8.events +oci8.events+ in PHP}.
|
118
|
+
#
|
119
|
+
# This parameter can be changed only when no OCI methods are called.
|
120
|
+
#
|
121
|
+
# require 'oci8'
|
122
|
+
# OCI8.properties[:events_mode] = true # works fine.
|
123
|
+
# ... call some OCI methods ...
|
124
|
+
# OCI8.properties[:events_mode] = true # raises a runtime error.
|
125
|
+
#
|
126
|
+
# *Since:* 2.1.4
|
127
|
+
#
|
128
|
+
# @return [a customized Hash]
|
129
|
+
# @since 2.0.5
|
96
130
|
#
|
97
131
|
def self.properties
|
98
132
|
@@properties
|
data/test/test_clob.rb
CHANGED
@@ -75,6 +75,22 @@ class TestCLob < Test::Unit::TestCase
|
|
75
75
|
lob.close
|
76
76
|
end
|
77
77
|
|
78
|
+
# https://github.com/kubo/ruby-oci8/issues/20
|
79
|
+
def test_github_issue_20
|
80
|
+
lob1 = OCI8::CLOB.new(@conn, ' ' * (1024 * 1024))
|
81
|
+
begin
|
82
|
+
lob2 = OCI8::CLOB.new(@conn, ' ' * (128 * 1024 * 1024))
|
83
|
+
rescue OCIError
|
84
|
+
raise if $!.code != 24817
|
85
|
+
# ORA-24817: Unable to allocate the given chunk for current lob operation
|
86
|
+
GC.start
|
87
|
+
# allocate smaller size
|
88
|
+
lob2 = OCI8::CLOB.new(@conn, ' ' * (16 * 1024 * 1024))
|
89
|
+
end
|
90
|
+
lob1 = nil # lob1's value will be freed in GC.
|
91
|
+
lob2.read # GC must run here to reproduce the issue.
|
92
|
+
end
|
93
|
+
|
78
94
|
def teardown
|
79
95
|
drop_table('test_table')
|
80
96
|
@conn.logoff
|
data/test/test_encoding.rb
CHANGED
@@ -25,7 +25,7 @@ STORAGE (
|
|
25
25
|
MAXEXTENTS UNLIMITED
|
26
26
|
PCTINCREASE 0)
|
27
27
|
EOS
|
28
|
-
ascii_8bit =
|
28
|
+
ascii_8bit = "\xab\xcd".force_encoding('ASCII-8BIT')
|
29
29
|
@conn.exec(<<EOS)
|
30
30
|
INSERT INTO test_table VALUES ('abcd', 'abcd', 'abcd', 'abcd', 'abcd', 'abcd', 'abcd')
|
31
31
|
EOS
|
@@ -34,16 +34,16 @@ EOS
|
|
34
34
|
assert_equal(OCI8.encoding, row[0].encoding);
|
35
35
|
assert_equal('abcd', row[1], 'VARCHAR2(10)')
|
36
36
|
assert_equal(OCI8.encoding, row[1].encoding);
|
37
|
-
assert_equal(
|
38
|
-
assert_equal(ascii_8bit, row[2].encoding);
|
39
|
-
assert_equal(
|
40
|
-
assert_equal(ascii_8bit, row[3].encoding);
|
37
|
+
assert_equal(ascii_8bit, row[2], 'RAW(10)')
|
38
|
+
assert_equal(ascii_8bit.encoding, row[2].encoding);
|
39
|
+
assert_equal(ascii_8bit, row[3], 'LONG RAW')
|
40
|
+
assert_equal(ascii_8bit.encoding, row[3].encoding);
|
41
41
|
assert_equal('abcd', (data = row[4].read), 'CLOB')
|
42
42
|
assert_equal(OCI8.encoding, data.encoding);
|
43
43
|
assert_equal('abcd', (data = row[5].read), 'NCLOB')
|
44
44
|
assert_equal(OCI8.encoding, data.encoding);
|
45
|
-
assert_equal(
|
46
|
-
assert_equal(ascii_8bit, data.encoding);
|
45
|
+
assert_equal(ascii_8bit, (data = row[6].read), 'BLOB')
|
46
|
+
assert_equal(ascii_8bit.encoding, data.encoding);
|
47
47
|
|
48
48
|
if OCI8.encoding.name == "UTF-8" and ['WE8ISO8859P1', 'WE8ISO8859P15', 'AL32UTF8', 'UTF8'].include? @conn.database_charset_name
|
49
49
|
utf_8 = "\u00A1\u00A2\u00A3\u00A5\u00A7\u00A9"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-oci8
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-06 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'ruby-oci8 is a ruby interface for Oracle using OCI8 API. It is available
|
15
15
|
with Oracle8, Oracle8i, Oracle9i, Oracle10g and Oracle Instant Client.
|
@@ -135,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
135
|
version: '0'
|
136
136
|
requirements: []
|
137
137
|
rubyforge_project: ruby-oci8
|
138
|
-
rubygems_version: 1.8.
|
138
|
+
rubygems_version: 1.8.11
|
139
139
|
signing_key:
|
140
140
|
specification_version: 3
|
141
141
|
summary: Ruby interface for Oracle using OCI8 API
|