ruby-oci8 1.0.3 → 1.0.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 +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
|