ruby-oci8 2.1.3 → 2.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|