ruby-oci8 2.2.3 → 2.2.12
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.
- checksums.yaml +7 -0
- data/ChangeLog +427 -0
- data/NEWS +335 -42
- data/README.md +20 -9
- data/dist-files +9 -3
- data/docs/bind-array-to-in_cond.md +2 -2
- data/docs/conflicts-local-connections-and-processes.md +7 -4
- data/docs/hanging-after-inactivity.md +63 -0
- data/docs/install-binary-package.md +15 -11
- data/docs/install-full-client.md +18 -21
- data/docs/install-instant-client.md +45 -27
- data/docs/install-on-osx.md +31 -120
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/docs/platform-specific-issues.md +17 -50
- data/docs/report-installation-issue.md +3 -0
- data/docs/timeout-parameters.md +3 -0
- data/ext/oci8/apiwrap.c.tmpl +2 -5
- data/ext/oci8/apiwrap.rb +6 -1
- data/ext/oci8/apiwrap.yml +34 -22
- data/ext/oci8/attr.c +4 -2
- data/ext/oci8/bind.c +366 -6
- data/ext/oci8/connection_pool.c +3 -3
- data/ext/oci8/encoding.c +5 -5
- data/ext/oci8/env.c +8 -2
- data/ext/oci8/error.c +24 -16
- data/ext/oci8/extconf.rb +8 -4
- data/ext/oci8/hook_funcs.c +274 -61
- data/ext/oci8/lob.c +31 -75
- data/ext/oci8/metadata.c +2 -2
- data/ext/oci8/object.c +72 -27
- data/ext/oci8/oci8.c +45 -132
- data/ext/oci8/oci8.h +32 -88
- data/ext/oci8/oci8lib.c +178 -38
- data/ext/oci8/ocihandle.c +37 -37
- data/ext/oci8/ocinumber.c +23 -18
- data/ext/oci8/oraconf.rb +158 -339
- data/ext/oci8/oradate.c +19 -19
- data/ext/oci8/plthook.h +10 -0
- data/ext/oci8/plthook_elf.c +433 -268
- data/ext/oci8/plthook_osx.c +40 -9
- data/ext/oci8/plthook_win32.c +9 -0
- data/ext/oci8/stmt.c +52 -17
- data/ext/oci8/win32.c +4 -22
- data/lib/oci8/bindtype.rb +1 -15
- data/lib/oci8/check_load_error.rb +57 -10
- data/lib/oci8/cursor.rb +57 -25
- data/lib/oci8/metadata.rb +9 -1
- data/lib/oci8/object.rb +10 -0
- data/lib/oci8/oci8.rb +33 -28
- data/lib/oci8/oracle_version.rb +11 -1
- data/lib/oci8/properties.rb +22 -0
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8.rb +48 -4
- data/lib/ruby-oci8.rb +0 -3
- data/pre-distclean.rb +1 -3
- data/ruby-oci8.gemspec +3 -8
- data/setup.rb +11 -2
- data/test/README.md +37 -0
- data/test/config.rb +1 -1
- data/test/setup_test_object.sql +21 -13
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +2 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_bind_integer.rb +47 -0
- data/test/test_break.rb +11 -9
- data/test/test_clob.rb +4 -16
- data/test/test_connstr.rb +29 -13
- data/test/test_datetime.rb +8 -3
- data/test/test_object.rb +27 -9
- data/test/test_oci8.rb +170 -46
- data/test/test_oranumber.rb +12 -6
- data/test/test_package_type.rb +15 -3
- data/test/test_properties.rb +17 -0
- metadata +40 -54
- data/docs/osx-install-dev-tools.png +0 -0
- data/test/README +0 -42
data/ext/oci8/oraconf.rb
CHANGED
@@ -4,88 +4,37 @@ require 'mkmf'
|
|
4
4
|
# compatibility for ruby-1.9
|
5
5
|
RbConfig = Config unless defined? RbConfig
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
RegQueryValueExA = Win32API.new('advapi32','RegQueryValueExA','LPPPPP','L')
|
32
|
-
RegCloseKey = Win32API.new('advapi32', 'RegCloseKey', 'L', 'L')
|
33
|
-
|
34
|
-
def self.get_str_value(hKey, name)
|
35
|
-
lpcbData = [0].pack('L')
|
36
|
-
code = RegQueryValueExA.call(hKey, name, nil, nil, nil, lpcbData)
|
37
|
-
if code == ERROR_FILE_NOT_FOUND
|
38
|
-
return nil
|
39
|
-
elsif code != ERROR_SUCCESS
|
40
|
-
raise MiniRegistryError.new("Win32::RegQueryValueExA",code)
|
41
|
-
end
|
42
|
-
len = lpcbData.unpack('L')[0]
|
43
|
-
lpType = [0].pack('L')
|
44
|
-
lpData = "\0"*len
|
45
|
-
lpcbData = [len].pack('L')
|
46
|
-
code = RegQueryValueExA.call(hKey, name, nil, lpType, lpData, lpcbData)
|
47
|
-
if code != ERROR_SUCCESS
|
48
|
-
raise MiniRegistryError.new("Win32::RegQueryValueExA",code)
|
49
|
-
end
|
50
|
-
lpData.unpack('Z*')[0]
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.enum_homes
|
54
|
-
phkResult = [0].pack('L')
|
55
|
-
code = RegOpenKeyExA.call(HKEY_LOCAL_MACHINE, 'SOFTWARE\ORACLE', 0, 0x20019, phkResult)
|
56
|
-
if code != ERROR_SUCCESS
|
57
|
-
raise MiniRegistryError.new("Win32::RegOpenKeyExA", code)
|
58
|
-
end
|
59
|
-
hKey = phkResult.unpack('L')[0]
|
60
|
-
idx = 0
|
61
|
-
maxkeylen = 256
|
62
|
-
loop do
|
63
|
-
lpName = "\0" * maxkeylen
|
64
|
-
lpcName = [maxkeylen].pack('L')
|
65
|
-
code = RegEnumKeyExA.call(hKey, idx, lpName, lpcName, nil, nil, nil, nil);
|
66
|
-
break if code == ERROR_NO_MORE_ITEMS
|
67
|
-
if code != ERROR_SUCCESS
|
68
|
-
RegCloseKey.call(hKey)
|
69
|
-
raise MiniRegistryError.new("Win32::RegEnumKeyEx", code)
|
70
|
-
end
|
71
|
-
code = RegOpenKeyExA.call(hKey, lpName, 0, KEY_QUERY_VALUE, phkResult)
|
72
|
-
if code != ERROR_SUCCESS
|
73
|
-
RegCloseKey.call(hKey)
|
74
|
-
raise MiniRegistryError.new("Win32::RegEnumKeyEx", code)
|
7
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw/
|
8
|
+
# Windows
|
9
|
+
require 'win32/registry'
|
10
|
+
module Registry
|
11
|
+
|
12
|
+
class OracleHome
|
13
|
+
attr_reader :name
|
14
|
+
attr_reader :path
|
15
|
+
def initialize(name, path)
|
16
|
+
@name = name
|
17
|
+
@path = path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.oracle_homes
|
22
|
+
homes = []
|
23
|
+
Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Oracle') do |key|
|
24
|
+
key.each_key do |subkey_name|
|
25
|
+
subkey = key.open(subkey_name)
|
26
|
+
begin
|
27
|
+
homes << OracleHome.new(subkey['ORACLE_HOME_NAME'], subkey['ORACLE_HOME'].chomp('\\'))
|
28
|
+
rescue Win32::Registry::Error
|
29
|
+
# ignore errors
|
30
|
+
end
|
75
31
|
end
|
76
|
-
hSubkey = phkResult.unpack('L')[0]
|
77
|
-
|
78
|
-
name = get_str_value(hSubkey, 'ORACLE_HOME_NAME')
|
79
|
-
path = get_str_value(hSubkey, 'ORACLE_HOME')
|
80
|
-
yield name, path
|
81
|
-
RegCloseKey.call(hSubkey)
|
82
|
-
idx += 1
|
83
32
|
end
|
84
|
-
|
33
|
+
homes
|
85
34
|
end
|
86
35
|
|
87
36
|
end
|
88
|
-
end
|
37
|
+
end
|
89
38
|
|
90
39
|
# minimal implementation to read information of a shared object.
|
91
40
|
class MiniSOReader
|
@@ -94,6 +43,10 @@ class MiniSOReader
|
|
94
43
|
attr_reader :endian
|
95
44
|
attr_reader :bits
|
96
45
|
|
46
|
+
MACH_O_CPU_TYPE_I386 = 7
|
47
|
+
MACH_O_CPU_TYPE_X86_64 = 7 + 0x01000000
|
48
|
+
MACH_O_CPU_TYPE_ARM64 = 12 + 0x01000000
|
49
|
+
|
97
50
|
def initialize(filename)
|
98
51
|
f = open(filename, 'rb')
|
99
52
|
begin
|
@@ -107,9 +60,6 @@ class MiniSOReader
|
|
107
60
|
when "\x02\x10"
|
108
61
|
# HP-UX PA-RISC1.1
|
109
62
|
read_parisc(f)
|
110
|
-
when "\xfe\xed"
|
111
|
-
# Big-endian Mach-O File
|
112
|
-
read_mach_o_be(f)
|
113
63
|
when "\xce\xfa"
|
114
64
|
# 32-bit Little-endian Mach-O File
|
115
65
|
read_mach_o_le(f, 32)
|
@@ -118,10 +68,10 @@ class MiniSOReader
|
|
118
68
|
read_mach_o_le(f, 64)
|
119
69
|
when "\xca\xfe"
|
120
70
|
# Universal binary
|
121
|
-
|
71
|
+
read_mach_o_universal(f)
|
122
72
|
else
|
123
73
|
# AIX and Tru64
|
124
|
-
raise format("unknown file header: %02x %02x", file_header[0].
|
74
|
+
raise format("unknown file header: %02x %02x (%s)", file_header[0].ord, file_header[1].ord, filename)
|
125
75
|
end
|
126
76
|
ensure
|
127
77
|
f.close
|
@@ -225,22 +175,6 @@ class MiniSOReader
|
|
225
175
|
@cpu = :parisc
|
226
176
|
end
|
227
177
|
|
228
|
-
# Big-endian Mach-O File
|
229
|
-
def read_mach_o_be(f)
|
230
|
-
@file_format = :mach_o
|
231
|
-
@endian = :big
|
232
|
-
case f.read(2)
|
233
|
-
when "\xfa\xce" # feedface
|
234
|
-
@cpu = :ppc
|
235
|
-
@bits = 32
|
236
|
-
when "\xfa\xcf" # feedfacf
|
237
|
-
@cpu = :ppc64
|
238
|
-
@bits = 64
|
239
|
-
else
|
240
|
-
raise "unknown file format"
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
178
|
def read_mach_o_le(f, bits)
|
245
179
|
@file_format = :mach_o
|
246
180
|
@endian = :little
|
@@ -250,12 +184,20 @@ class MiniSOReader
|
|
250
184
|
@cpu = :i386
|
251
185
|
@bits = 32
|
252
186
|
when 64
|
253
|
-
|
187
|
+
cputype = f.read(4).unpack('V')[0]
|
188
|
+
case cputype
|
189
|
+
when MACH_O_CPU_TYPE_X86_64
|
190
|
+
@cpu = :x86_64
|
191
|
+
when MACH_O_CPU_TYPE_ARM64
|
192
|
+
@cpu = :arm64
|
193
|
+
else
|
194
|
+
raise "unknown mach-o cpu type: #{cputype}"
|
195
|
+
end
|
254
196
|
@bits = 64
|
255
197
|
end
|
256
198
|
end
|
257
199
|
|
258
|
-
def
|
200
|
+
def read_mach_o_universal(f)
|
259
201
|
raise 'unknown file format' if f.read(2) != "\xba\xbe" # cafebabe
|
260
202
|
@file_format = :universal
|
261
203
|
nfat_arch = f.read(4).unpack('N')[0]
|
@@ -264,21 +206,17 @@ class MiniSOReader
|
|
264
206
|
@bits = []
|
265
207
|
nfat_arch.times do
|
266
208
|
case cputype = f.read(4).unpack('N')[0]
|
267
|
-
when
|
209
|
+
when MACH_O_CPU_TYPE_I386
|
268
210
|
@cpu << :i386
|
269
211
|
@endian << :little
|
270
212
|
@bits << 32
|
271
|
-
when
|
213
|
+
when MACH_O_CPU_TYPE_X86_64
|
272
214
|
@cpu << :x86_64
|
273
215
|
@endian << :little
|
274
216
|
@bits << 64
|
275
|
-
when
|
276
|
-
@cpu << :
|
277
|
-
@endian << :
|
278
|
-
@bits << 32
|
279
|
-
when 18 + 0x01000000
|
280
|
-
@cpu << :ppc64
|
281
|
-
@endian << :big
|
217
|
+
when MACH_O_CPU_TYPE_ARM64
|
218
|
+
@cpu << :arm64
|
219
|
+
@endian << :little
|
282
220
|
@bits << 64
|
283
221
|
else
|
284
222
|
raise "Unknown mach-o cputype: #{cputype}"
|
@@ -301,7 +239,6 @@ class OraConf
|
|
301
239
|
def self.get
|
302
240
|
original_CFLAGS = $CFLAGS
|
303
241
|
original_defs = $defs
|
304
|
-
ic_dir = nil
|
305
242
|
begin
|
306
243
|
# check Oracle instant client
|
307
244
|
if with_config('instant-client')
|
@@ -313,11 +250,17 @@ class OraConf
|
|
313
250
|
=======================================================
|
314
251
|
EOS
|
315
252
|
end
|
316
|
-
|
317
|
-
if
|
318
|
-
OraConfIC.new(
|
253
|
+
inc, lib = dir_config('instant-client')
|
254
|
+
if inc && lib
|
255
|
+
OraConfIC.new(inc, lib)
|
319
256
|
else
|
320
|
-
|
257
|
+
base = guess_ic_dir
|
258
|
+
if base
|
259
|
+
inc, lib = guess_dirs_from_ic_base(base)
|
260
|
+
OraConfIC.new(inc, lib)
|
261
|
+
else
|
262
|
+
OraConfFC.new
|
263
|
+
end
|
321
264
|
end
|
322
265
|
rescue
|
323
266
|
case ENV['LANG']
|
@@ -349,6 +292,44 @@ EOS
|
|
349
292
|
end
|
350
293
|
end
|
351
294
|
|
295
|
+
# Guess the include and directory paths from
|
296
|
+
def self.guess_dirs_from_ic_base(ic_dir)
|
297
|
+
if ic_dir =~ /^\/usr\/lib(?:64)?\/oracle\/(\d+(?:\.\d+)*)\/client(64)?\/lib(?:64)?/
|
298
|
+
# rpm package
|
299
|
+
# x86 rpms after 11.1.0.7.0:
|
300
|
+
# library: /usr/lib/oracle/X.X/client/lib/
|
301
|
+
# include: /usr/include/oracle/X.X/client/
|
302
|
+
#
|
303
|
+
# x86_64 rpms after 11.1.0.7.0:
|
304
|
+
# library: /usr/lib/oracle/X.X/client64/lib/
|
305
|
+
# include: /usr/include/oracle/X.X/client64/
|
306
|
+
#
|
307
|
+
# x86 rpms before 11.1.0.6.0:
|
308
|
+
# library: /usr/lib/oracle/X.X.X.X/client/lib/
|
309
|
+
# include: /usr/include/oracle/X.X.X.X/client/
|
310
|
+
#
|
311
|
+
# x86_64 rpms before 11.1.0.6.0:
|
312
|
+
# library: /usr/lib/oracle/X.X.X.X/client64/lib/
|
313
|
+
# include: /usr/include/oracle/X.X.X.X/client64/
|
314
|
+
#
|
315
|
+
# third-party x86_64 rpms(*1):
|
316
|
+
# library: /usr/lib64/oracle/X.X.X.X/client/lib/
|
317
|
+
# or /usr/lib64/oracle/X.X.X.X/client/lib64/
|
318
|
+
# include: /usr/include/oracle/X.X.X.X/client/
|
319
|
+
#
|
320
|
+
# *1 These had been used before Oracle released official x86_64 rpms.
|
321
|
+
#
|
322
|
+
lib_dir = ic_dir
|
323
|
+
inc_dir = "/usr/include/oracle/#{$1}/client#{$2}"
|
324
|
+
else
|
325
|
+
# zip package
|
326
|
+
lib_dir = ic_dir
|
327
|
+
inc_dir = "#{ic_dir}/sdk/include"
|
328
|
+
end
|
329
|
+
|
330
|
+
[inc_dir, lib_dir]
|
331
|
+
end
|
332
|
+
|
352
333
|
def self.ld_envs
|
353
334
|
@@ld_envs
|
354
335
|
end
|
@@ -367,8 +348,9 @@ EOS
|
|
367
348
|
end
|
368
349
|
end
|
369
350
|
|
370
|
-
def self.
|
371
|
-
puts "
|
351
|
+
def self.guess_ic_dir
|
352
|
+
puts "attempting to locate oracle-instantclient..."
|
353
|
+
puts "checking load library path... "
|
372
354
|
STDOUT.flush
|
373
355
|
|
374
356
|
# get library load path names
|
@@ -384,13 +366,13 @@ EOS
|
|
384
366
|
[nil].pack('P').size
|
385
367
|
rescue ArgumentError
|
386
368
|
# Rubinius 1.2.3 doesn't support Array#pack('P').
|
387
|
-
# Use
|
369
|
+
# Use Integer#size, which returns the size of long.
|
388
370
|
1.size
|
389
371
|
end
|
390
372
|
is_32bit = size_of_pointer == 4
|
391
373
|
is_big_endian = "\x01\x02".unpack('s')[0] == 0x0102
|
392
374
|
case RUBY_PLATFORM
|
393
|
-
when /mswin32|mswin64|cygwin|
|
375
|
+
when /mswin32|mswin64|cygwin|mingw/
|
394
376
|
oci_basename = 'oci'
|
395
377
|
oci_glob_postfix = ''
|
396
378
|
nls_data_basename = ['oraociei*', 'oraociicus*']
|
@@ -433,20 +415,13 @@ EOS
|
|
433
415
|
end
|
434
416
|
so_ext = 'sl'
|
435
417
|
when /darwin/
|
436
|
-
@@ld_envs = %w[
|
418
|
+
@@ld_envs = %w[OCI_DIR]
|
437
419
|
so_ext = 'dylib'
|
438
420
|
if is_32bit
|
439
|
-
|
440
|
-
this_cpu = :ppc # 32-bit big-endian
|
441
|
-
else
|
442
|
-
this_cpu = :i386 # 32-bit little-endian
|
443
|
-
end
|
421
|
+
this_cpu = :i386 # 32-bit little-endian
|
444
422
|
else
|
445
|
-
|
446
|
-
|
447
|
-
else
|
448
|
-
this_cpu = :x86_64 # 64-bit little-endian
|
449
|
-
end
|
423
|
+
require 'etc'
|
424
|
+
this_cpu = Etc.uname[:machine].to_sym
|
450
425
|
end
|
451
426
|
check_proc = Proc.new do |file|
|
452
427
|
so = MiniSOReader.new(file)
|
@@ -520,49 +495,6 @@ EOS
|
|
520
495
|
end
|
521
496
|
end
|
522
497
|
when /darwin/
|
523
|
-
fallback_path = ENV['DYLD_FALLBACK_LIBRARY_PATH']
|
524
|
-
if fallback_path.nil?
|
525
|
-
puts " DYLD_FALLBACK_LIBRARY_PATH is not set."
|
526
|
-
else
|
527
|
-
puts " checking DYLD_FALLBACK_LIBRARY_PATH..."
|
528
|
-
ld_path, file = check_lib_in_path(fallback_path, glob_name, check_proc)
|
529
|
-
end
|
530
|
-
if ld_path.nil?
|
531
|
-
puts " checking OCI_DIR..."
|
532
|
-
ld_path, file = check_lib_in_path(ENV['OCI_DIR'], glob_name, check_proc)
|
533
|
-
if ld_path
|
534
|
-
puts " checking dependent shared libraries in #{file}..."
|
535
|
-
open("|otool -L #{file}") do |f|
|
536
|
-
f.gets # discard the first line
|
537
|
-
while line = f.gets
|
538
|
-
line =~ /^\s+(\S+)/
|
539
|
-
libname = $1
|
540
|
-
case libname
|
541
|
-
when /^@rpath\/libclntsh\.dylib/, /^@rpath\/libnnz\d\d\.dylib/, /^@loader_path\/libnnz\d\d\.dylib/
|
542
|
-
# No need to check the real path.
|
543
|
-
# The current instant client doesn't use @rpath or @loader_path.
|
544
|
-
when /\/libclntsh\.dylib/, /\/libnnz\d\d.dylib/
|
545
|
-
raise <<EOS unless File.exists?(libname)
|
546
|
-
The output of "otool -L #{file}" is:
|
547
|
-
| #{IO.readlines("|otool -L #{file}").join(' | ')}
|
548
|
-
Ruby-oci8 doesn't work without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH
|
549
|
-
because the dependent file "#{libname}" doesn't exist.
|
550
|
-
|
551
|
-
If you need to use ruby-oci8 without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH,
|
552
|
-
download "fix_oralib.rb" in https://github.com/kubo/fix_oralib_osx
|
553
|
-
and execute it in the directory "#{File.dirname(file)}" as follows to fix the path.
|
554
|
-
|
555
|
-
cd #{File.dirname(file)}
|
556
|
-
curl -O https://raw.githubusercontent.com/kubo/fix_oralib_osx/master/fix_oralib.rb
|
557
|
-
ruby fix_oralib.rb
|
558
|
-
|
559
|
-
Note: DYLD_* environment variables are unavailable for security reasons on OS X 10.11 El Capitan.
|
560
|
-
EOS
|
561
|
-
end
|
562
|
-
end
|
563
|
-
end
|
564
|
-
end
|
565
|
-
end
|
566
498
|
if ld_path.nil?
|
567
499
|
fallback_path = ENV['DYLD_FALLBACK_LIBRARY_PATH']
|
568
500
|
if fallback_path.nil?
|
@@ -573,17 +505,8 @@ EOS
|
|
573
505
|
end
|
574
506
|
if ld_path.nil?
|
575
507
|
raise <<EOS
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
If DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH is set, the environment
|
580
|
-
variable must be set at runtime also.
|
581
|
-
|
582
|
-
If OCI_DIR is set, dependent shared library paths are checked. If the checking
|
583
|
-
is passed, ruby-oci8 works without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH.
|
584
|
-
|
585
|
-
Note: OCI_DIR should be absolute path.
|
586
|
-
Note: DYLD_* environment variables are unavailable for security reasons on OS X 10.11 El Capitan.
|
508
|
+
Oracle instant client is not found.
|
509
|
+
You need to install Oracle instant client.
|
587
510
|
EOS
|
588
511
|
end
|
589
512
|
end
|
@@ -607,8 +530,8 @@ EOS
|
|
607
530
|
paths.split(File::PATH_SEPARATOR).each do |path|
|
608
531
|
next if path.nil? or path == ''
|
609
532
|
print " checking #{path}... "
|
610
|
-
path.gsub!(/\\/, '/') if /mswin32|mswin64|cygwin|
|
611
|
-
files = Dir.glob(File.join(path, glob_name))
|
533
|
+
path.gsub!(/\\/, '/') if /mswin32|mswin64|cygwin|mingw/ =~ RUBY_PLATFORM
|
534
|
+
files = Dir.glob(File.join(path, glob_name)).sort.reverse
|
612
535
|
if files.empty?
|
613
536
|
puts "no"
|
614
537
|
next
|
@@ -635,7 +558,7 @@ EOS
|
|
635
558
|
if try_run("int main() { return 0; }")
|
636
559
|
puts "ok"
|
637
560
|
else
|
638
|
-
puts "
|
561
|
+
puts "failed"
|
639
562
|
raise "C compiler doesn't work correctly."
|
640
563
|
end
|
641
564
|
end # check_cc
|
@@ -681,21 +604,11 @@ EOS
|
|
681
604
|
STDOUT.flush
|
682
605
|
rubyhdrdir = RbConfig::CONFIG["rubyhdrdir"] || RbConfig::CONFIG['archdir']
|
683
606
|
unless File.exist?(rubyhdrdir + '/ruby.h')
|
684
|
-
puts "
|
685
|
-
|
686
|
-
raise <<EOS
|
687
|
-
#{RbConfig::CONFIG['archdir']}/ruby.h doesn't exist.
|
688
|
-
Run the following commands to fix the problem.
|
689
|
-
|
690
|
-
cd #{RbConfig::CONFIG['archdir']}
|
691
|
-
sudo ln -s ../universal-darwin8.0/* ./
|
692
|
-
EOS
|
693
|
-
else
|
694
|
-
raise <<EOS
|
607
|
+
puts "failed"
|
608
|
+
raise <<EOS
|
695
609
|
#{RbConfig::CONFIG['archdir']}/ruby.h doesn't exist.
|
696
610
|
Install the ruby development library.
|
697
611
|
EOS
|
698
|
-
end
|
699
612
|
end
|
700
613
|
puts "ok"
|
701
614
|
$stdout.flush
|
@@ -711,11 +624,11 @@ EOS
|
|
711
624
|
end
|
712
625
|
end
|
713
626
|
|
714
|
-
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|
|
627
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw/ # when Windows
|
715
628
|
|
716
629
|
def get_libs(lib_dir)
|
717
630
|
case RUBY_PLATFORM
|
718
|
-
when /cygwin
|
631
|
+
when /cygwin/
|
719
632
|
regex = ([nil].pack('P').size == 8) ? / T (OCI\w+)/ : / T _(OCI\w+)/
|
720
633
|
oci_funcs = YAML.load(open(File.dirname(__FILE__) + '/apiwrap.yml')).keys.collect do |func|
|
721
634
|
func =~ /_nb$/ ? $` : func
|
@@ -734,22 +647,6 @@ EOS
|
|
734
647
|
system(command)
|
735
648
|
puts("done")
|
736
649
|
"-L. -lOCI"
|
737
|
-
when /bccwin32/
|
738
|
-
# replace '/' to '\\' because bcc linker misunderstands
|
739
|
-
# 'C:/foo/bar/OCI.LIB' as unknown option.
|
740
|
-
lib = "#{lib_dir}/BORLAND/OCI.LIB"
|
741
|
-
return lib.tr('/', '\\') if File.exist?(lib)
|
742
|
-
raise <<EOS
|
743
|
-
#{lib} does not exist.
|
744
|
-
|
745
|
-
Your Oracle may not support Borland C++.
|
746
|
-
If you want to run this module, run the following command at your own risk.
|
747
|
-
cd #{lib_dir.tr('/', '\\')}
|
748
|
-
mkdir Borland
|
749
|
-
cd Borland
|
750
|
-
coff2omf ..\\MSVC\\OCI.LIB OCI.LIB
|
751
|
-
EOS
|
752
|
-
exit 1
|
753
650
|
else
|
754
651
|
"\"#{lib_dir}/MSVC/OCI.LIB\""
|
755
652
|
end
|
@@ -793,7 +690,7 @@ class OraConfFC < OraConf
|
|
793
690
|
use_lib32 = false
|
794
691
|
end
|
795
692
|
|
796
|
-
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|
|
693
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw/
|
797
694
|
lib_dir = "#{@oracle_home}/oci/lib"
|
798
695
|
elsif use_lib32
|
799
696
|
lib_dir = "#{@oracle_home}/lib32"
|
@@ -812,7 +709,7 @@ class OraConfFC < OraConf
|
|
812
709
|
print("Get the version of Oracle from SQL*Plus... ")
|
813
710
|
STDOUT.flush
|
814
711
|
version = nil
|
815
|
-
dev_null = RUBY_PLATFORM =~ /mswin32|mswin64|
|
712
|
+
dev_null = RUBY_PLATFORM =~ /mswin32|mswin64|mingw/ ? "nul" : "/dev/null"
|
816
713
|
if File.exist?("#{@oracle_home}/bin/plus80.exe")
|
817
714
|
sqlplus = "plus80.exe"
|
818
715
|
else
|
@@ -837,7 +734,7 @@ class OraConfFC < OraConf
|
|
837
734
|
version
|
838
735
|
end # get_version
|
839
736
|
|
840
|
-
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|
|
737
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw/ # when Windows
|
841
738
|
|
842
739
|
def is_valid_home?(oracle_home)
|
843
740
|
return false if oracle_home.nil?
|
@@ -856,11 +753,8 @@ class OraConfFC < OraConf
|
|
856
753
|
def get_home()
|
857
754
|
oracle_home = ENV['ORACLE_HOME']
|
858
755
|
if oracle_home.nil?
|
859
|
-
|
860
|
-
|
861
|
-
MiniRegistry.enum_homes do |name, path|
|
862
|
-
path.chomp!("\\") if path
|
863
|
-
oracle_homes << struct.new(name, path) if is_valid_home?(path)
|
756
|
+
oracle_homes = Registry::oracle_homes.select do |home|
|
757
|
+
is_valid_home?(home.path)
|
864
758
|
end
|
865
759
|
if oracle_homes.empty?
|
866
760
|
raise <<EOS
|
@@ -922,7 +816,7 @@ EOS
|
|
922
816
|
unless File.exist?("#{@oracle_home}/OCI/INCLUDE/OCI.H")
|
923
817
|
raise "'#{@oracle_home}/OCI/INCLUDE/OCI.H' does not exists. Please install 'Oracle Call Interface'."
|
924
818
|
end
|
925
|
-
if RUBY_PLATFORM =~ /cygwin|
|
819
|
+
if RUBY_PLATFORM =~ /cygwin|mingw/
|
926
820
|
" \"-I#{@oracle_home}/OCI/INCLUDE\" -D_int64=\"long long\""
|
927
821
|
else
|
928
822
|
" \"-I#{@oracle_home}/OCI/INCLUDE\""
|
@@ -1001,56 +895,25 @@ end
|
|
1001
895
|
|
1002
896
|
# OraConf for Instant Client
|
1003
897
|
class OraConfIC < OraConf
|
1004
|
-
def initialize(
|
898
|
+
def initialize(inc_dir, lib_dir)
|
1005
899
|
init
|
1006
900
|
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
# library: /usr/lib/oracle/X.X/client64/lib/
|
1015
|
-
# include: /usr/include/oracle/X.X/client64/
|
1016
|
-
#
|
1017
|
-
# x86 rpms before 11.1.0.6.0:
|
1018
|
-
# library: /usr/lib/oracle/X.X.X.X/client/lib/
|
1019
|
-
# include: /usr/include/oracle/X.X.X.X/client/
|
1020
|
-
#
|
1021
|
-
# x86_64 rpms before 11.1.0.6.0:
|
1022
|
-
# library: /usr/lib/oracle/X.X.X.X/client64/lib/
|
1023
|
-
# include: /usr/include/oracle/X.X.X.X/client64/
|
1024
|
-
#
|
1025
|
-
# third-party x86_64 rpms(*1):
|
1026
|
-
# library: /usr/lib64/oracle/X.X.X.X/client/lib/
|
1027
|
-
# or /usr/lib64/oracle/X.X.X.X/client/lib64/
|
1028
|
-
# include: /usr/include/oracle/X.X.X.X/client/
|
1029
|
-
#
|
1030
|
-
# *1 These had been used before Oracle released official x86_64 rpms.
|
1031
|
-
#
|
1032
|
-
lib_dir = ic_dir
|
1033
|
-
inc_dir = "/usr/include/oracle/#{$1}/client#{$2}"
|
1034
|
-
else
|
1035
|
-
# zip package
|
1036
|
-
lib_dir = ic_dir
|
1037
|
-
inc_dir = "#{ic_dir}/sdk/include"
|
1038
|
-
end
|
1039
|
-
|
1040
|
-
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw32|bccwin32/ # when Windows
|
1041
|
-
unless File.exist?("#{ic_dir}/sdk/lib/msvc/oci.lib")
|
901
|
+
# check lib_dir
|
902
|
+
lib_dirs = lib_dir.split(File::PATH_SEPARATOR)
|
903
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw/ # when Windows
|
904
|
+
ocilib = lib_dirs.find do |dir|
|
905
|
+
File.exist?("#{dir}/sdk/lib/msvc/oci.lib")
|
906
|
+
end
|
907
|
+
unless ocilib
|
1042
908
|
raise <<EOS
|
1043
909
|
Could not compile with Oracle instant client.
|
1044
|
-
|
910
|
+
"sdk/lib/msvc/oci.lib" could not be found in: #{lib_dirs.join(' ')}
|
911
|
+
Did you install instantclient-basic?
|
1045
912
|
EOS
|
1046
|
-
raise 'failed'
|
1047
913
|
end
|
1048
|
-
@
|
1049
|
-
@cflags += " -D_int64=\"long long\"" if RUBY_PLATFORM =~ /cygwin|mingw32/
|
1050
|
-
@libs = get_libs("#{ic_dir}/sdk/lib")
|
914
|
+
@libs = get_libs("#{ocilib}/sdk/lib")
|
1051
915
|
ld_path = nil
|
1052
916
|
else
|
1053
|
-
@cflags = " -I#{inc_dir}"
|
1054
917
|
# set ld_path and so_ext
|
1055
918
|
case RUBY_PLATFORM
|
1056
919
|
when /aix/
|
@@ -1071,34 +934,53 @@ EOS
|
|
1071
934
|
so_ext = 'so'
|
1072
935
|
end
|
1073
936
|
# check Oracle client library.
|
1074
|
-
|
1075
|
-
|
937
|
+
ocilib = lib_dirs.find do |dir|
|
938
|
+
File.exist?("#{dir}/libclntsh.#{so_ext}")
|
939
|
+
end
|
940
|
+
unless ocilib
|
941
|
+
files = lib_dirs.map do |dir|
|
942
|
+
Dir.glob("#{dir}/libclntsh.#{so_ext}.*")
|
943
|
+
end.flatten
|
1076
944
|
if files.empty?
|
1077
945
|
raise <<EOS
|
1078
946
|
Could not compile with Oracle instant client.
|
1079
|
-
|
947
|
+
"libclntsh.#{so_ext}" could not be found in: #{lib_dirs.join(' ')}
|
1080
948
|
Did you install instantclient-basic?
|
1081
949
|
EOS
|
1082
950
|
else
|
1083
|
-
file =
|
951
|
+
file = files.sort[-1]
|
1084
952
|
raise <<EOS
|
1085
953
|
Could not compile with Oracle instant client.
|
1086
|
-
|
954
|
+
"libclntsh.#{so_ext}" could not be found in: #{lib_dirs.join(' ')}
|
1087
955
|
You may need to make a symbolic link.
|
1088
|
-
cd #{
|
1089
|
-
ln -s #{file} libclntsh.#{so_ext}
|
956
|
+
cd #{File.dirname(file)}
|
957
|
+
ln -s #{File.basename(file)} libclntsh.#{so_ext}
|
1090
958
|
EOS
|
1091
959
|
end
|
1092
960
|
raise 'failed'
|
1093
961
|
end
|
1094
962
|
@libs = get_libs(lib_dir)
|
1095
963
|
end
|
1096
|
-
|
964
|
+
|
965
|
+
# check inc_dir
|
966
|
+
inc_dirs = inc_dir.split(File::PATH_SEPARATOR)
|
967
|
+
ociinc = inc_dirs.find do |dir|
|
968
|
+
File.exist?("#{dir}/oci.h")
|
969
|
+
end
|
970
|
+
unless ociinc
|
1097
971
|
raise <<EOS
|
1098
|
-
|
972
|
+
"oci.h" could not be found in: #{inc_dirs.join(' ')}
|
1099
973
|
Install 'Instant Client SDK'.
|
1100
974
|
EOS
|
1101
975
|
end
|
976
|
+
if ociinc.include?(' ')
|
977
|
+
@cflags = " \"-I#{ociinc}\""
|
978
|
+
else
|
979
|
+
@cflags = " -I#{ociinc}"
|
980
|
+
end
|
981
|
+
@cflags += " -D_int64=\"long long\"" if RUBY_PLATFORM =~ /cygwin|mingw/
|
982
|
+
|
983
|
+
# check link
|
1102
984
|
$CFLAGS += @cflags
|
1103
985
|
if try_link_oci()
|
1104
986
|
major = try_constant("OCI_MAJOR_VERSION", "oci.h")
|
@@ -1108,73 +990,10 @@ EOS
|
|
1108
990
|
else
|
1109
991
|
# 10.1.0 doesn't have OCI_MAJOR_VERSION and OCI_MINOR_VERSION in oci.h.
|
1110
992
|
@version = "1010"
|
1111
|
-
if RUBY_PLATFORM =~ /darwin/ and 1.size == 8 and `sw_vers -productVersion`.chomp == "10.7"
|
1112
|
-
$stderr.print <<EOS
|
1113
|
-
WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN!
|
1114
|
-
|
1115
|
-
64-bit Oracle instant client doesn't work on OS X Lion.
|
1116
|
-
See: https://forums.oracle.com/forums/thread.jspa?threadID=2187558
|
1117
|
-
|
1118
|
-
The compilation is continued because the issue may be fixed in future.
|
1119
|
-
|
1120
|
-
WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN!
|
1121
|
-
EOS
|
1122
|
-
end
|
1123
993
|
end
|
1124
994
|
return
|
1125
995
|
end
|
1126
996
|
|
1127
|
-
if RUBY_PLATFORM =~ /darwin/
|
1128
|
-
open('mkmf.log', 'r') do |f|
|
1129
|
-
while line = f.gets
|
1130
|
-
if line.include? '/libclntsh.dylib load command 8 unknown cmd field'
|
1131
|
-
raise <<EOS
|
1132
|
-
Intel mac instant client is for Mac OS X 10.5.
|
1133
|
-
It doesn't work on Mac OS X 10.4 or before.
|
1134
|
-
|
1135
|
-
You have three workarounds.
|
1136
|
-
1. Compile ruby as ppc binary and use it with ppc instant client.
|
1137
|
-
2. Use JRuby and JDBC
|
1138
|
-
3. Use a third-party ODBC driver and ruby-odbc.
|
1139
|
-
EOS
|
1140
|
-
# '
|
1141
|
-
end
|
1142
|
-
|
1143
|
-
case line
|
1144
|
-
when /cputype \(\d+, architecture \w+\) does not match cputype \(\d+\) for specified -arch flag: (\w+)/
|
1145
|
-
missing_arch = $1
|
1146
|
-
when /Undefined symbols for architecture (\w+)/
|
1147
|
-
missing_arch = $1
|
1148
|
-
when /missing required architecture (\w+) in file/
|
1149
|
-
missing_arch = $1
|
1150
|
-
end
|
1151
|
-
|
1152
|
-
if missing_arch
|
1153
|
-
if [nil].pack('p').size == 8
|
1154
|
-
my_arch = 'x86_64'
|
1155
|
-
elsif "\x01\x02".unpack('s')[0] == 0x0201
|
1156
|
-
my_arch = 'i386'
|
1157
|
-
else
|
1158
|
-
my_arch = 'ppc'
|
1159
|
-
end
|
1160
|
-
raise <<EOS
|
1161
|
-
Could not compile with Oracle instant client.
|
1162
|
-
You may need to set the environment variable RC_ARCHS or ARCHFLAGS as follows:
|
1163
|
-
|
1164
|
-
RC_ARCHS=#{my_arch}
|
1165
|
-
export RC_ARCHS
|
1166
|
-
or
|
1167
|
-
ARCHFLAGS='-arch #{my_arch}'
|
1168
|
-
export RC_ARCHS
|
1169
|
-
|
1170
|
-
If it does not fix the problem, delete all '-arch #{missing_arch}'
|
1171
|
-
in '#{RbConfig::CONFIG['archdir']}/rbconfig.rb'.
|
1172
|
-
EOS
|
1173
|
-
end
|
1174
|
-
end
|
1175
|
-
end
|
1176
|
-
end
|
1177
|
-
|
1178
997
|
unless ld_path.nil?
|
1179
998
|
raise <<EOS
|
1180
999
|
Could not compile with Oracle instant client.
|