ruby-oci8 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +58 -1
- data/NEWS +39 -1
- data/VERSION +1 -1
- data/dist-files +2 -1
- data/ext/oci8/const.c +2 -2
- data/ext/oci8/extconf.rb +2 -0
- data/ext/oci8/handle.c +18 -7
- data/ext/oci8/oci8.c +41 -0
- data/ext/oci8/oci8.h +11 -0
- data/ext/oci8/oraconf.rb +133 -4
- data/ext/oci8/svcctx.c +9 -0
- data/lib/{DBD/OCI8 → dbd}/OCI8.rb +27 -1
- data/lib/oci8.rb.in +25 -3
- data/metaconfig +2 -2
- data/test/test_all.rb +1 -0
- data/test/test_dbi.rb +20 -10
- data/test/test_dbi_clob.rb +7 -5
- data/test/test_rowid.rb +38 -0
- metadata +5 -4
data/ChangeLog
CHANGED
@@ -1,3 +1,60 @@
|
|
1
|
+
2009-02-08 KUBO Takehiro <kubo@jiubao.org>
|
2
|
+
* NEWS: add changes between 1.0.3 and 1.0.4.
|
3
|
+
* VERSION: change version to 1.0.4.
|
4
|
+
* dist-files: add newly added file names which must be included
|
5
|
+
in gem or tar.gz packages.
|
6
|
+
|
7
|
+
2009-02-01 KUBO Takehiro <kubo@jiubao.org>
|
8
|
+
* lib/dbd/OCI8.rb: add code for ruby-dbi 0.4 type conversion.
|
9
|
+
* test/test_dbi.rb: suppress deprecated warnings while running
|
10
|
+
test_bind_dbi_data_type.
|
11
|
+
* test/test_dbi_clob.rb: fix a problem when running this
|
12
|
+
file directly.
|
13
|
+
|
14
|
+
2009-01-31 KUBO Takehiro <kubo@jiubao.org>
|
15
|
+
* ext/oci8/oraconf.rb: fix for Oracle 11.1.0.7.0 instant
|
16
|
+
client rpm package. The directory tree is a bit different
|
17
|
+
with that of 11.1.0.6.0 or earlier.
|
18
|
+
(reported by Luis Parravicini.)
|
19
|
+
|
20
|
+
2009-01-31 KUBO Takehiro <kubo@jiubao.org>
|
21
|
+
* lib/DBD/OCI8/OCI8.rb: renamed to lib/dbd/OCI8.rb.
|
22
|
+
* lib/dbd/OCI8.rb: 1. renamed from lib/DBD/OCI8/OCI8.rb
|
23
|
+
2. fix USED_DBD_VERSION from 0.2 to 0.4.
|
24
|
+
3. add DBI::DBD::OCI8.driver_name
|
25
|
+
(changes for ruby-dbi 0.4 contributed by James Cao.)
|
26
|
+
|
27
|
+
2008-12-30 KUBO Takehiro <kubo@jiubao.org>
|
28
|
+
* ext/oci8/handle.c, ext/oci8/oci8.h, ext/oci8/svcctx.c: add
|
29
|
+
OCISvcCtx.pid, which returns id of the process where the
|
30
|
+
OCISvcCtx is created.
|
31
|
+
* lib/oci8.rb.in: add check code to ensure that the process id
|
32
|
+
is not changed.
|
33
|
+
|
34
|
+
2008-12-30 KUBO Takehiro <kubo@jiubao.org>
|
35
|
+
* ext/oci8/const.c, ext/oci8/handle.c: suppress compilation warnings.
|
36
|
+
(contributed by Daniel Berger)
|
37
|
+
|
38
|
+
2008-12-30 KUBO Takehiro <kubo@jiubao.org>
|
39
|
+
* ext/oci8/oraconf.rb: add code to check the cpu type of Mac OS X
|
40
|
+
libclntsh.dylib.
|
41
|
+
|
42
|
+
2008-12-14 KUBO Takehiro <kubo@jiubao.org>
|
43
|
+
* lib/oci8.rb.in:
|
44
|
+
1. fix to fetch a rowid column as s String.
|
45
|
+
2. change the return type of OCI8::Cursor#rowid from OCIRowid
|
46
|
+
to String. It is a local call on Oracle 9.0 or upper.
|
47
|
+
But on Oracle 8.x client, it needs one network roundtrip
|
48
|
+
to convert OCIRowid to String on server side.
|
49
|
+
3. fix OCI8#describe_table to prevent OCIStillExecuting when
|
50
|
+
non-blocking mode is enabled and it needs a time to
|
51
|
+
retrieve table information.
|
52
|
+
* ext/oci8/extconf.rb, ext/oci8/oci8.c: add OCIRowid#to_s
|
53
|
+
when OCIRowidToChar() is available.
|
54
|
+
* test/test_all.rb, test/test_rowid.rb: add a rowid test case.
|
55
|
+
* test/test_dbi_clob.rb: fix to pass tests when the test directory
|
56
|
+
path is too long.
|
57
|
+
|
1
58
|
2008-08-10 KUBO Takehiro <kubo@jiubao.org>
|
2
59
|
* NEWS: add changes between 1.0.2 and 1.0.3.
|
3
60
|
* VERSION: change version to 1.0.3.
|
@@ -12,7 +69,7 @@
|
|
12
69
|
2008-08-09 KUBO Takehiro <kubo@jiubao.org>
|
13
70
|
* ext/oci8/lob.c: fix OCILobLocator#getLength for a lob over 1GB,
|
14
71
|
which affect OCI8::LOB#size and OCI8::LOB#read. fix
|
15
|
-
OCILobLocator#read and OCILobLocator#write to set offset over
|
72
|
+
OCILobLocator#read and OCILobLocator#write to set offset over 2GB,
|
16
73
|
which affect OCI8::LOB#read and OCI8::LOB#write.
|
17
74
|
(This probmem was reported by Jonathan Hadders.)
|
18
75
|
|
data/NEWS
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
+
1.0.4:
|
2
|
+
|
3
|
+
1. [dbi] support ruby-dbi 0.4
|
4
|
+
(Thanks to James Cao and Peter Zingg.)
|
5
|
+
|
6
|
+
Ruby-dbi 0.4 is supported by DBD::OCI8 after 6 months from the
|
7
|
+
release of 0.4.
|
8
|
+
|
9
|
+
If you are using ruby-dbi 0.1.1, you need to copy dbd/OCI8.rb
|
10
|
+
to DBD/OCI8/OCI8.rb. The file itself works fine with ruby-dbi
|
11
|
+
0.1.1, but the dbi cannot find the file by default.
|
12
|
+
|
13
|
+
2. Rowid column data are fetched as a String by default.
|
14
|
+
|
15
|
+
3. The return type of OCI8::Cursor#rowid is changed from OCIRowid
|
16
|
+
to String.
|
17
|
+
|
18
|
+
Note: It needs one network roundtrip to convert OCIRowid to
|
19
|
+
String on server side when using Oracle 8.x client.
|
20
|
+
On Oracle 9.0 or upper it is converted in the client side.
|
21
|
+
|
22
|
+
4. An exception is raised if a connection is used in a process which is
|
23
|
+
different with a process to establish the connection.
|
24
|
+
|
25
|
+
If you encounter an exception "The connection cannot be reused in the
|
26
|
+
forked process," see the following link.
|
27
|
+
|
28
|
+
http://groups.google.com/group/phusion-passenger/browse_thread/thread/b00d4770bc1d00b8
|
29
|
+
|
30
|
+
5. fix for 11.1.0.7.0 instant rpm package.
|
31
|
+
(reported by Luis Parravicini.)
|
32
|
+
|
33
|
+
The directory tree is a bit different with that of 11.1.0.6.0
|
34
|
+
or earlier.
|
35
|
+
|
36
|
+
6. suppress compilation warnings.
|
37
|
+
(contributed by Daniel Berger)
|
38
|
+
|
1
39
|
1.0.3:
|
2
40
|
|
3
41
|
1. add workaround code for a losing character problem when reading CLOB.
|
@@ -22,7 +60,7 @@
|
|
22
60
|
OraNumber#to_json is added for Rails.
|
23
61
|
|
24
62
|
4. [dbi] fix a problem when using Oracle 8i and ruby-dbi.
|
25
|
-
(reported by Glauco
|
63
|
+
(reported by Glauco Magnelli.)
|
26
64
|
|
27
65
|
1.0.2:
|
28
66
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.4
|
data/dist-files
CHANGED
@@ -39,7 +39,7 @@ ext/oci8/session.c
|
|
39
39
|
ext/oci8/stmt.c
|
40
40
|
ext/oci8/svcctx.c
|
41
41
|
lib/oci8.rb.in
|
42
|
-
lib/
|
42
|
+
lib/dbd/OCI8.rb
|
43
43
|
support/README
|
44
44
|
support/runit/assert.rb
|
45
45
|
support/runit/cui/testrunner.rb
|
@@ -68,3 +68,4 @@ test/test_oci8.rb
|
|
68
68
|
test/test_oradate.rb
|
69
69
|
test/test_oranumber.rb
|
70
70
|
test/test_metadata.rb
|
71
|
+
test/test_rowid.rb
|
data/ext/oci8/const.c
CHANGED
@@ -45,7 +45,7 @@ static oci8_names_t oci8_typecode[] = {
|
|
45
45
|
static VALUE oci8_make_names(oci8_names_t *names, size_t size)
|
46
46
|
{
|
47
47
|
volatile VALUE ary;
|
48
|
-
int i;
|
48
|
+
unsigned int i;
|
49
49
|
|
50
50
|
ary = rb_ary_new();
|
51
51
|
for (i = 0;i < size;i++)
|
@@ -55,7 +55,7 @@ static VALUE oci8_make_names(oci8_names_t *names, size_t size)
|
|
55
55
|
|
56
56
|
void Init_oci8_const(void)
|
57
57
|
{
|
58
|
-
int i;
|
58
|
+
unsigned int i;
|
59
59
|
|
60
60
|
oci8_id_code = rb_intern("code");
|
61
61
|
oci8_id_define_array = rb_intern("define_array");
|
data/ext/oci8/extconf.rb
CHANGED
data/ext/oci8/handle.c
CHANGED
@@ -10,10 +10,20 @@ See ((<Class Hierarchy>)).
|
|
10
10
|
=end
|
11
11
|
*/
|
12
12
|
#include "oci8.h"
|
13
|
+
#ifdef HAVE_UNISTD_H
|
14
|
+
#include <unistd.h> /* getpid() */
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#ifdef WIN32
|
18
|
+
#ifndef getpid
|
19
|
+
extern rb_pid_t rb_w32_getpid(void);
|
20
|
+
#define getpid() rb_w32_getpid()
|
21
|
+
#endif
|
22
|
+
#endif
|
13
23
|
|
14
24
|
static void oci8_handle_do_free(oci8_handle_t *h)
|
15
25
|
{
|
16
|
-
int i;
|
26
|
+
unsigned int i;
|
17
27
|
if (h->type == 0) {
|
18
28
|
return;
|
19
29
|
}
|
@@ -104,7 +114,7 @@ VALUE oci8_s_new(VALUE self)
|
|
104
114
|
static void oci8_handle_mark(oci8_handle_t *h)
|
105
115
|
{
|
106
116
|
oci8_bind_handle_t *bh;
|
107
|
-
int i;
|
117
|
+
unsigned int i;
|
108
118
|
|
109
119
|
switch (h->type) {
|
110
120
|
case OCI_HTYPE_SVCCTX:
|
@@ -149,6 +159,7 @@ oci8_handle_t *oci8_make_handle(ub4 type, dvoid *hp, OCIError *errhp, oci8_handl
|
|
149
159
|
break;
|
150
160
|
case OCI_HTYPE_SVCCTX:
|
151
161
|
obj = Data_Make_Struct(cOCISvcCtx, oci8_handle_t, oci8_handle_mark, oci8_handle_cleanup, h);
|
162
|
+
h->u.svcctx.pid = getpid();
|
152
163
|
break;
|
153
164
|
case OCI_HTYPE_STMT:
|
154
165
|
obj = Data_Make_Struct(cOCIStmt, oci8_handle_t, oci8_handle_mark, oci8_handle_cleanup, h);
|
@@ -221,8 +232,8 @@ oci8_handle_t *oci8_make_handle(ub4 type, dvoid *hp, OCIError *errhp, oci8_handl
|
|
221
232
|
|
222
233
|
void oci8_link(oci8_handle_t *parent, oci8_handle_t *child)
|
223
234
|
{
|
224
|
-
int i;
|
225
|
-
int new_size;
|
235
|
+
unsigned int i;
|
236
|
+
int new_size, n;
|
226
237
|
|
227
238
|
if (parent == NULL)
|
228
239
|
return;
|
@@ -238,8 +249,8 @@ void oci8_link(oci8_handle_t *parent, oci8_handle_t *child)
|
|
238
249
|
new_size = parent->size + CHILDREN_ARRAY_GROW_SIZE;
|
239
250
|
parent->children = xrealloc(parent->children, sizeof(oci8_handle_t *) * new_size);
|
240
251
|
parent->children[parent->size] = child;
|
241
|
-
for (
|
242
|
-
parent->children[
|
252
|
+
for (n = parent->size + 1;n < new_size;n++) {
|
253
|
+
parent->children[n] = NULL;
|
243
254
|
}
|
244
255
|
parent->size = new_size;
|
245
256
|
return;
|
@@ -248,7 +259,7 @@ void oci8_link(oci8_handle_t *parent, oci8_handle_t *child)
|
|
248
259
|
void oci8_unlink(oci8_handle_t *self)
|
249
260
|
{
|
250
261
|
oci8_handle_t *parent = self->parent;
|
251
|
-
int i;
|
262
|
+
unsigned int i;
|
252
263
|
|
253
264
|
if (self->parent == NULL)
|
254
265
|
return;
|
data/ext/oci8/oci8.c
CHANGED
@@ -77,6 +77,8 @@ VALUE eOCISuccessWithInfo;
|
|
77
77
|
VALUE cOraDate;
|
78
78
|
VALUE cOraNumber;
|
79
79
|
|
80
|
+
static void Init_OCIRowid(void);
|
81
|
+
|
80
82
|
void
|
81
83
|
Init_oci8lib()
|
82
84
|
{
|
@@ -131,7 +133,46 @@ Init_oci8lib()
|
|
131
133
|
Init_ora_date();
|
132
134
|
Init_ora_number();
|
133
135
|
|
136
|
+
Init_OCIRowid();
|
137
|
+
|
134
138
|
#ifdef DEBUG_CORE_FILE
|
135
139
|
signal(SIGSEGV, SIG_DFL);
|
136
140
|
#endif
|
137
141
|
}
|
142
|
+
|
143
|
+
#if defined(WIN32)
|
144
|
+
typedef sword (*OCIRowidToChar_func_t)(OCIRowid *rowidDesc, OraText *outbfp, ub2 *outbflp, OCIError *errhp);
|
145
|
+
static OCIRowidToChar_func_t OCIRowidToChar_func;
|
146
|
+
#define OCIRowidToChar OCIRowidToChar_func
|
147
|
+
#endif
|
148
|
+
|
149
|
+
#if defined(WIN32) || defined(HAVE_OCIROWIDTOCHAR)
|
150
|
+
static VALUE oci8_rowid_to_s(VALUE self)
|
151
|
+
{
|
152
|
+
oci8_handle_t *h;
|
153
|
+
char buf[64];
|
154
|
+
ub2 buflen = sizeof(buf);
|
155
|
+
sword rv;
|
156
|
+
|
157
|
+
Get_Handle(self, h);
|
158
|
+
rv = OCIRowidToChar(h->hp, (text*)buf, &buflen, h->errhp);
|
159
|
+
if (rv != OCI_SUCCESS)
|
160
|
+
oci8_raise(h->errhp, rv, NULL);
|
161
|
+
return rb_str_new(buf, buflen);
|
162
|
+
}
|
163
|
+
#endif
|
164
|
+
|
165
|
+
static void Init_OCIRowid(void)
|
166
|
+
{
|
167
|
+
#if defined(WIN32)
|
168
|
+
HANDLE hModule = GetModuleHandle("OCI.DLL");
|
169
|
+
if (hModule != NULL) {
|
170
|
+
OCIRowidToChar_func = (OCIRowidToChar_func_t)GetProcAddress(hModule, "OCIRowidToChar");
|
171
|
+
}
|
172
|
+
if (OCIRowidToChar_func != NULL) {
|
173
|
+
rb_define_method(cOCIRowid, "to_s", oci8_rowid_to_s, 0);
|
174
|
+
}
|
175
|
+
#elif defined(HAVE_OCIROWIDTOCHAR)
|
176
|
+
rb_define_method(cOCIRowid, "to_s", oci8_rowid_to_s, 0);
|
177
|
+
#endif
|
178
|
+
}
|
data/ext/oci8/oci8.h
CHANGED
@@ -10,6 +10,14 @@
|
|
10
10
|
#include "rubyio.h"
|
11
11
|
#include "intern.h"
|
12
12
|
|
13
|
+
#ifndef rb_pid_t
|
14
|
+
#ifdef WIN32
|
15
|
+
#define rb_pid_t int
|
16
|
+
#else
|
17
|
+
#define rb_pid_t pid_t
|
18
|
+
#endif
|
19
|
+
#endif
|
20
|
+
|
13
21
|
#include <stdio.h>
|
14
22
|
#include <stdlib.h>
|
15
23
|
#ifdef __cplusplus
|
@@ -134,6 +142,9 @@ struct oci8_handle {
|
|
134
142
|
int char_width;
|
135
143
|
} lob_locator;
|
136
144
|
#endif
|
145
|
+
struct {
|
146
|
+
rb_pid_t pid;
|
147
|
+
} svcctx;
|
137
148
|
} u;
|
138
149
|
};
|
139
150
|
typedef struct oci8_handle oci8_handle_t;
|
data/ext/oci8/oraconf.rb
CHANGED
@@ -110,8 +110,23 @@ class MiniSOReader
|
|
110
110
|
when "MZ"
|
111
111
|
# Windows
|
112
112
|
read_pe(f)
|
113
|
+
when "\x02\x10"
|
114
|
+
# HP-UX PA-RISC1.1
|
115
|
+
read_parisc(f)
|
116
|
+
when "\xfe\xed"
|
117
|
+
# Big-endian Mach-O File
|
118
|
+
read_mach_o_be(f)
|
119
|
+
when "\xce\xfa"
|
120
|
+
# 32-bit Little-endian Mach-O File
|
121
|
+
read_mach_o_le(f, 32)
|
122
|
+
when "\xcf\xfa"
|
123
|
+
# 64-bit Little-endian Mach-O File
|
124
|
+
read_mach_o_le(f, 64)
|
125
|
+
when "\xca\xfe"
|
126
|
+
# Universal binary
|
127
|
+
read_mach_o_unversal(f)
|
113
128
|
else
|
114
|
-
#
|
129
|
+
# AIX and Tru64
|
115
130
|
raise format("unknown file header: %02x %02x", file_header[0], file_header[1])
|
116
131
|
end
|
117
132
|
ensure
|
@@ -202,6 +217,79 @@ class MiniSOReader
|
|
202
217
|
raise "Invalid coff machine: #{machine}"
|
203
218
|
end
|
204
219
|
end
|
220
|
+
|
221
|
+
# HP-UX PA-RISC(32 bit)
|
222
|
+
def read_parisc(f)
|
223
|
+
# 0-1 system_id - CPU_PA_RISC1_1
|
224
|
+
@file_format = :pa_risc
|
225
|
+
# 2-3 a_magic - SHL_MAGIC
|
226
|
+
raise 'invalid a_magic' if f.read(2).unpack('n')[0] != 0x10e
|
227
|
+
@bits = 32
|
228
|
+
@endian = :big
|
229
|
+
@cpu = :parisc
|
230
|
+
end
|
231
|
+
|
232
|
+
# Big-endian Mach-O File
|
233
|
+
def read_mach_o_be(f)
|
234
|
+
@file_format = :mach_o
|
235
|
+
@endian = :big
|
236
|
+
case f.read(2)
|
237
|
+
when "\xfa\xce" # feedface
|
238
|
+
@cpu = :ppc
|
239
|
+
@bits = 32
|
240
|
+
when "\xfa\xcf" # feedfacf
|
241
|
+
@cpu = :ppc64
|
242
|
+
@bits = 64
|
243
|
+
else
|
244
|
+
raise "unknown file format"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def read_mach_o_le(f, bits)
|
249
|
+
@file_format = :mach_o
|
250
|
+
@endian = :little
|
251
|
+
raise 'unknown file format' if f.read(2) != "\xed\xfe"
|
252
|
+
case bits
|
253
|
+
when 32
|
254
|
+
@cpu = :i386
|
255
|
+
@bits = 32
|
256
|
+
when 64
|
257
|
+
@cpu = :x86_64
|
258
|
+
@bits = 64
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def read_mach_o_unversal(f)
|
263
|
+
raise 'unknown file format' if f.read(2) != "\xba\xbe" # cafebabe
|
264
|
+
@file_format = :universal
|
265
|
+
nfat_arch = f.read(4).unpack('N')[0]
|
266
|
+
@cpu = []
|
267
|
+
@endian = []
|
268
|
+
@bits = []
|
269
|
+
nfat_arch.times do
|
270
|
+
case cputype = f.read(4).unpack('N')[0]
|
271
|
+
when 7
|
272
|
+
@cpu << :i386
|
273
|
+
@endian << :little
|
274
|
+
@bits << 32
|
275
|
+
when 7 + 0x01000000
|
276
|
+
@cpu << :x86_64
|
277
|
+
@endian << :little
|
278
|
+
@bits << 64
|
279
|
+
when 18
|
280
|
+
@cpu << :ppc
|
281
|
+
@endian << :big
|
282
|
+
@bits << 32
|
283
|
+
when 18 + 0x01000000
|
284
|
+
@cpu << :ppc64
|
285
|
+
@endian << :big
|
286
|
+
@bits << 64
|
287
|
+
else
|
288
|
+
raise "Unknown mach-o cputype: #{cputype}"
|
289
|
+
end
|
290
|
+
f.seek(4 * 4, IO::SEEK_CUR)
|
291
|
+
end
|
292
|
+
end
|
205
293
|
end
|
206
294
|
|
207
295
|
class OraConf
|
@@ -335,6 +423,39 @@ EOS
|
|
335
423
|
when /darwin/
|
336
424
|
@@ld_envs = %w[DYLD_LIBRARY_PATH]
|
337
425
|
so_ext = 'dylib'
|
426
|
+
check_proc = Proc.new do |file|
|
427
|
+
is_32bit = [0].pack('l!').size == 4
|
428
|
+
is_big_endian = "\x01\x02".unpack('s') == 0x0102
|
429
|
+
if is_32bit
|
430
|
+
if is_big_endian
|
431
|
+
this_cpu = :ppc # 32-bit big-endian
|
432
|
+
else
|
433
|
+
this_cpu = :i386 # 32-bit little-endian
|
434
|
+
end
|
435
|
+
else
|
436
|
+
if is_big_endian
|
437
|
+
this_cpu = :ppc64 # 64-bit big-endian
|
438
|
+
else
|
439
|
+
this_cpu = :x86_64 # 64-bit little-endian
|
440
|
+
end
|
441
|
+
end
|
442
|
+
so = MiniSOReader.new(file)
|
443
|
+
if so.file_format == :universal
|
444
|
+
if so.cpu.include? this_cpu
|
445
|
+
true
|
446
|
+
else
|
447
|
+
puts " skip: #{file} is for #{so.cpu} cpu."
|
448
|
+
false
|
449
|
+
end
|
450
|
+
else
|
451
|
+
if so.cpu == this_cpu
|
452
|
+
true
|
453
|
+
else
|
454
|
+
puts " skip: #{file} is for #{so.cpu} cpu."
|
455
|
+
false
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
338
459
|
end
|
339
460
|
|
340
461
|
glob_name = "#{oci_basename}.#{so_ext}#{oci_glob_postfix}"
|
@@ -844,13 +965,21 @@ class OraConfIC < OraConf
|
|
844
965
|
def initialize(ic_dir)
|
845
966
|
init
|
846
967
|
|
847
|
-
if ic_dir =~ /^\/usr\/lib(?:64)?\/oracle\/(\d
|
968
|
+
if ic_dir =~ /^\/usr\/lib(?:64)?\/oracle\/(\d+(?:\.\d+)*)\/client(64)?\/lib(?:64)?/
|
848
969
|
# rpm package
|
849
|
-
#
|
970
|
+
# x86 rpms after 11.1.0.7.0:
|
971
|
+
# library: /usr/lib/oracle/X.X/client/lib/
|
972
|
+
# include: /usr/include/oracle/X.X/client/
|
973
|
+
#
|
974
|
+
# x86_64 rpms after 11.1.0.7.0:
|
975
|
+
# library: /usr/lib/oracle/X.X/client64/lib/
|
976
|
+
# include: /usr/include/oracle/X.X/client64/
|
977
|
+
#
|
978
|
+
# x86 rpms before 11.1.0.6.0:
|
850
979
|
# library: /usr/lib/oracle/X.X.X.X/client/lib/
|
851
980
|
# include: /usr/include/oracle/X.X.X.X/client/
|
852
981
|
#
|
853
|
-
#
|
982
|
+
# x86_64 rpms before 11.1.0.6.0:
|
854
983
|
# library: /usr/lib/oracle/X.X.X.X/client64/lib/
|
855
984
|
# include: /usr/include/oracle/X.X.X.X/client64/
|
856
985
|
#
|
data/ext/oci8/svcctx.c
CHANGED
@@ -180,6 +180,14 @@ static VALUE oci8_close_all_files(VALUE self)
|
|
180
180
|
return self;
|
181
181
|
}
|
182
182
|
|
183
|
+
static VALUE oci8_pid(VALUE self)
|
184
|
+
{
|
185
|
+
oci8_handle_t *h;
|
186
|
+
|
187
|
+
Get_Handle(self, h); /* 0 */
|
188
|
+
return INT2FIX(h->u.svcctx.pid);
|
189
|
+
}
|
190
|
+
|
183
191
|
void Init_oci8_svcctx(void)
|
184
192
|
{
|
185
193
|
rb_define_method(cOCISvcCtx, "logoff", oci8_svcctx_logoff, 0);
|
@@ -196,6 +204,7 @@ void Init_oci8_svcctx(void)
|
|
196
204
|
rb_define_method(cOCISvcCtx, "reset", oci8_reset, 0);
|
197
205
|
#endif
|
198
206
|
rb_define_method(cOCISvcCtx, "close_all_files", oci8_close_all_files, 0);
|
207
|
+
rb_define_method(cOCISvcCtx, "pid", oci8_pid, 0);
|
199
208
|
}
|
200
209
|
|
201
210
|
/*
|
@@ -42,7 +42,32 @@ module DBD # :nodoc:
|
|
42
42
|
module OCI8
|
43
43
|
|
44
44
|
VERSION = "0.1"
|
45
|
-
USED_DBD_VERSION = "0.
|
45
|
+
USED_DBD_VERSION = "0.4"
|
46
|
+
|
47
|
+
def self.driver_name
|
48
|
+
"OCI8"
|
49
|
+
end
|
50
|
+
|
51
|
+
# type converstion handler to bind values. (ruby-dbi 0.4)
|
52
|
+
if DBI.const_defined?(:TypeUtil)
|
53
|
+
DBI::TypeUtil.register_conversion("OCI8") do |obj|
|
54
|
+
case obj
|
55
|
+
when ::TrueClass
|
56
|
+
['1', false]
|
57
|
+
when ::FalseClass
|
58
|
+
['0', false]
|
59
|
+
else
|
60
|
+
[obj, false]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# no type converstion is required for result set. (ruby-dbi 0.4)
|
66
|
+
class NoTypeConversion
|
67
|
+
def self.parse(obj)
|
68
|
+
obj
|
69
|
+
end
|
70
|
+
end
|
46
71
|
|
47
72
|
module Util
|
48
73
|
|
@@ -134,6 +159,7 @@ module Util
|
|
134
159
|
'nullable' => col.nullable?,
|
135
160
|
'precision' => precision,
|
136
161
|
'scale' => scale,
|
162
|
+
'dbi_type' => NoTypeConversion,
|
137
163
|
}
|
138
164
|
end
|
139
165
|
private :column_metadata_to_column_info
|
data/lib/oci8.rb.in
CHANGED
@@ -351,7 +351,7 @@ class OCI8
|
|
351
351
|
def describe_table(table_name)
|
352
352
|
desc = @@env.alloc(OCIDescribe)
|
353
353
|
desc.attrSet(OCI_ATTR_DESC_PUBLIC, -1)
|
354
|
-
desc.describeAny(@svc, table_name.to_s, OCI_PTYPE_UNK)
|
354
|
+
do_ocicall(@ctx) { desc.describeAny(@svc, table_name.to_s, OCI_PTYPE_UNK) }
|
355
355
|
param = desc.attrGet(OCI_ATTR_PARAM)
|
356
356
|
|
357
357
|
case param.attrGet(OCI_ATTR_PTYPE)
|
@@ -679,6 +679,9 @@ class OCI8
|
|
679
679
|
end
|
680
680
|
|
681
681
|
def initialize(env, svc, ctx, stmt = nil)
|
682
|
+
if Process.pid != svc.pid
|
683
|
+
raise "The connection cannot be reused in the forked process."
|
684
|
+
end
|
682
685
|
@env = env
|
683
686
|
@svc = svc
|
684
687
|
@ctx = ctx
|
@@ -811,8 +814,25 @@ class OCI8
|
|
811
814
|
@stmttype = nil
|
812
815
|
end # close
|
813
816
|
|
817
|
+
# Get the rowid of the last inserted/updated/deleted row.
|
814
818
|
def rowid
|
815
|
-
|
819
|
+
# get the binary rowid
|
820
|
+
rid = @stmt.attrGet(OCI_ATTR_ROWID)
|
821
|
+
# convert it to a string rowid.
|
822
|
+
if rid.respond_to? :to_s
|
823
|
+
# (Oracle 9.0 or upper)
|
824
|
+
rid.to_s
|
825
|
+
else
|
826
|
+
# (Oracle 8.1 or lower)
|
827
|
+
stmt = @env.alloc(OCIStmt)
|
828
|
+
stmt.prepare('begin :1 := :2; end;')
|
829
|
+
b = stmt.bindByPos(1, OCI8::SQLT_CHR, 64)
|
830
|
+
stmt.bindByPos(2, OCI8::SQLT_RDD, rid)
|
831
|
+
do_ocicall(@ctx) { stmt.execute(@svc, 1, OCI_DEFAULT) }
|
832
|
+
str_rid = b.get()
|
833
|
+
stmt.free()
|
834
|
+
str_rid
|
835
|
+
end
|
816
836
|
end
|
817
837
|
|
818
838
|
def prefetch_rows=(rows)
|
@@ -899,6 +919,8 @@ class OCI8
|
|
899
919
|
datatype = :nclob if p.attrGet(OCI_ATTR_CHARSET_FORM) == SQLCS_NCHAR
|
900
920
|
when SQLT_BIN
|
901
921
|
datasize *= 2 if OCI8::BindType::Mapping[datatype] == OCI8::BindType::String
|
922
|
+
when SQLT_RDD
|
923
|
+
datasize = 64
|
902
924
|
end
|
903
925
|
|
904
926
|
bind_or_define(:define, i, nil, datatype, datasize, precision, scale, true)
|
@@ -1210,7 +1232,7 @@ class OCI8
|
|
1210
1232
|
# datatype type size prec scale
|
1211
1233
|
# -------------------------------------------------
|
1212
1234
|
# ROWID SQLT_RDD 4 0 0
|
1213
|
-
BindType::Mapping[OCI8::SQLT_RDD] = BindType::
|
1235
|
+
BindType::Mapping[OCI8::SQLT_RDD] = BindType::String
|
1214
1236
|
|
1215
1237
|
# datatype type size prec scale
|
1216
1238
|
# -----------------------------------------------------
|
data/metaconfig
CHANGED
@@ -120,8 +120,8 @@ install_files['oci8lib.so'] = <<-EOS
|
|
120
120
|
install_files['oci8.rb'] = <<-EOS
|
121
121
|
#{get_zcontent('lib/oci8.rb')}EOS
|
122
122
|
|
123
|
-
install_files['
|
124
|
-
#{get_zcontent('lib/
|
123
|
+
install_files['dbd/OCI8.rb'] = <<-EOS
|
124
|
+
#{get_zcontent('lib/dbd/OCI8.rb')}EOS
|
125
125
|
|
126
126
|
begin
|
127
127
|
installer = Installer.new(install_files)
|
data/test/test_all.rb
CHANGED
data/test/test_dbi.rb
CHANGED
@@ -146,17 +146,27 @@ EOS
|
|
146
146
|
end
|
147
147
|
|
148
148
|
def test_bind_dbi_data_type
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
149
|
+
begin
|
150
|
+
if DBI::VERSION >= '0.4.0'
|
151
|
+
# suppress deprecated warnings while running this test.
|
152
|
+
saved_action = Deprecated.action
|
153
|
+
Deprecated.set_action(Proc.new {})
|
154
|
+
end
|
155
|
+
|
156
|
+
inval = DBI::Date.new(2004, 3, 20)
|
157
|
+
sth = @dbh.execute("BEGIN ? := ?; END;", DBI::Date, inval)
|
158
|
+
outval = sth.func(:bind_value, 1)
|
159
|
+
assert_instance_of(DBI::Date, outval)
|
160
|
+
assert_equal(inval.to_time, outval.to_time)
|
154
161
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
162
|
+
inval = DBI::Timestamp.new(2004, 3, 20, 18, 26, 33)
|
163
|
+
sth = @dbh.execute("BEGIN ? := ?; END;", DBI::Timestamp, inval)
|
164
|
+
outval = sth.func(:bind_value, 1)
|
165
|
+
assert_instance_of(DBI::Timestamp, outval)
|
166
|
+
assert_equal(inval.to_time, outval.to_time)
|
167
|
+
ensure
|
168
|
+
Deprecated.set_action(saved_action) if saved_action
|
169
|
+
end
|
160
170
|
end
|
161
171
|
|
162
172
|
def test_column_info
|
data/test/test_dbi_clob.rb
CHANGED
@@ -11,13 +11,14 @@ class TestDbiCLob < RUNIT::TestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_insert
|
14
|
-
|
14
|
+
filename = File.basename($lobfile)
|
15
|
+
@dbh.do("DELETE FROM test_clob WHERE filename = :1", filename)
|
15
16
|
|
16
17
|
# insert an empty clob and get the rowid.
|
17
|
-
rowid = @dbh.execute("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())",
|
18
|
+
rowid = @dbh.execute("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())", filename) do |sth|
|
18
19
|
sth.func(:rowid)
|
19
20
|
end
|
20
|
-
lob = @dbh.select_one("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE",
|
21
|
+
lob = @dbh.select_one("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", filename)[0]
|
21
22
|
begin
|
22
23
|
open($lobfile) do |f|
|
23
24
|
while f.gets()
|
@@ -30,8 +31,9 @@ class TestDbiCLob < RUNIT::TestCase
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def test_read
|
34
|
+
filename = File.basename($lobfile)
|
33
35
|
test_insert() # first insert data.
|
34
|
-
lob = @dbh.select_one("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE",
|
36
|
+
lob = @dbh.select_one("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", filename)[0]
|
35
37
|
begin
|
36
38
|
open($lobfile) do |f|
|
37
39
|
while buf = lob.read($lobreadnum)
|
@@ -52,5 +54,5 @@ class TestDbiCLob < RUNIT::TestCase
|
|
52
54
|
end
|
53
55
|
|
54
56
|
if $0 == __FILE__
|
55
|
-
RUNIT::CUI::TestRunner.run(
|
57
|
+
RUNIT::CUI::TestRunner.run(TestDbiCLob.suite())
|
56
58
|
end
|
data/test/test_rowid.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'oci8'
|
2
|
+
require 'runit/testcase'
|
3
|
+
require 'runit/cui/testrunner'
|
4
|
+
require File.dirname(__FILE__) + '/config'
|
5
|
+
|
6
|
+
class TestRowid < RUNIT::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@conn = get_oci_connection()
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
@conn.logoff
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_rowid
|
17
|
+
drop_table('test_table')
|
18
|
+
sql = <<-EOS
|
19
|
+
CREATE TABLE test_table (N NUMBER(38))
|
20
|
+
EOS
|
21
|
+
@conn.exec(sql)
|
22
|
+
cursor = @conn.parse("INSERT INTO test_table values(1)");
|
23
|
+
cursor.exec
|
24
|
+
rid1 = cursor.rowid
|
25
|
+
assert_instance_of(String, rid1)
|
26
|
+
cursor.close
|
27
|
+
rid2 = nil
|
28
|
+
@conn.exec('select rowid from test_table where rowid = :1', rid1) do |row|
|
29
|
+
rid2 = row[0]
|
30
|
+
end
|
31
|
+
assert_equal(rid2, rid1)
|
32
|
+
drop_table('test_table')
|
33
|
+
end
|
34
|
+
end # TestRowid
|
35
|
+
|
36
|
+
if $0 == __FILE__
|
37
|
+
RUNIT::CUI::TestRunner.run(TestRowid.suite())
|
38
|
+
end
|
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: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- KUBO Takehiro
|
@@ -9,7 +9,7 @@ autorequire: oci8
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-02-08 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -63,7 +63,7 @@ files:
|
|
63
63
|
- ext/oci8/stmt.c
|
64
64
|
- ext/oci8/svcctx.c
|
65
65
|
- lib/oci8.rb.in
|
66
|
-
- lib/
|
66
|
+
- lib/dbd/OCI8.rb
|
67
67
|
- support/README
|
68
68
|
- support/runit/assert.rb
|
69
69
|
- support/runit/cui/testrunner.rb
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- test/test_oradate.rb
|
93
93
|
- test/test_oranumber.rb
|
94
94
|
- test/test_metadata.rb
|
95
|
+
- test/test_rowid.rb
|
95
96
|
has_rdoc: true
|
96
97
|
homepage: http://ruby-oci8.rubyforge.org
|
97
98
|
post_install_message:
|
@@ -117,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
118
|
requirements: []
|
118
119
|
|
119
120
|
rubyforge_project: ruby-oci8
|
120
|
-
rubygems_version: 1.
|
121
|
+
rubygems_version: 1.3.1
|
121
122
|
signing_key:
|
122
123
|
specification_version: 2
|
123
124
|
summary: Ruby interface for Oracle using OCI8 API
|