ruby-oci8 2.2.0.2 → 2.2.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +1 -6
- data/ChangeLog +600 -0
- data/NEWS +426 -35
- data/README.md +27 -9
- data/dist-files +13 -2
- data/docs/bind-array-to-in_cond.md +38 -0
- data/docs/conflicts-local-connections-and-processes.md +98 -0
- 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 -117
- 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 +11 -8
- data/docs/timeout-parameters.md +94 -0
- data/ext/oci8/apiwrap.c.tmpl +2 -5
- data/ext/oci8/apiwrap.rb +6 -1
- data/ext/oci8/apiwrap.yml +39 -143
- data/ext/oci8/attr.c +4 -2
- data/ext/oci8/bind.c +421 -9
- 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 +35 -63
- data/ext/oci8/hook_funcs.c +274 -61
- data/ext/oci8/lob.c +31 -75
- data/ext/oci8/metadata.c +8 -6
- data/ext/oci8/object.c +119 -29
- data/ext/oci8/oci8.c +46 -133
- data/ext/oci8/oci8.h +40 -123
- data/ext/oci8/oci8lib.c +178 -46
- data/ext/oci8/ocihandle.c +37 -37
- data/ext/oci8/ocinumber.c +24 -35
- data/ext/oci8/oraconf.rb +168 -337
- 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 +16 -1
- data/ext/oci8/stmt.c +52 -17
- data/ext/oci8/win32.c +4 -22
- data/lib/oci8/bindtype.rb +10 -17
- data/lib/oci8/check_load_error.rb +57 -10
- data/lib/oci8/compat.rb +5 -1
- data/lib/oci8/connection_pool.rb +74 -3
- data/lib/oci8/cursor.rb +70 -31
- data/lib/oci8/metadata.rb +9 -1
- data/lib/oci8/object.rb +14 -1
- data/lib/oci8/oci8.rb +184 -58
- data/lib/oci8/ocihandle.rb +0 -16
- data/lib/oci8/oracle_version.rb +11 -1
- data/lib/oci8/properties.rb +55 -0
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8.rb +48 -4
- data/lib/ruby-oci8.rb +1 -0
- data/pre-distclean.rb +1 -3
- data/ruby-oci8.gemspec +4 -9
- data/setup.rb +11 -2
- data/test/README.md +37 -0
- data/test/config.rb +8 -1
- data/test/setup_test_object.sql +42 -14
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +4 -0
- data/test/test_bind_array.rb +70 -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 +5 -17
- data/test/test_connstr.rb +142 -0
- data/test/test_datetime.rb +8 -3
- data/test/test_metadata.rb +2 -1
- data/test/test_object.rb +99 -18
- data/test/test_oci8.rb +170 -46
- data/test/test_oranumber.rb +12 -6
- data/test/test_package_type.rb +17 -3
- data/test/test_properties.rb +17 -0
- metadata +45 -55
- 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|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,61 +495,18 @@ 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
|
-
fallback_path = "#{ENV['HOME']}/lib:/usr/local/lib:/lib:/usr/lib"
|
526
|
-
end
|
527
|
-
puts " checking DYLD_FALLBACK_LIBRARY_PATH..."
|
528
|
-
ld_path, file = check_lib_in_path(fallback_path, glob_name, check_proc)
|
529
498
|
if ld_path.nil?
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
puts " checking
|
534
|
-
|
535
|
-
f.gets # discard the first line
|
536
|
-
while line = f.gets
|
537
|
-
line =~ /^\s+(\S+)/
|
538
|
-
libname = $1
|
539
|
-
case libname
|
540
|
-
when /^@rpath\/libclntsh\.dylib/, /^@rpath\/libnnz\d\d\.dylib/, /^@loader_path\/libnnz\d\d\.dylib/
|
541
|
-
# No need to check the real path.
|
542
|
-
# The current instant client doesn't use @rpath or @loader_path.
|
543
|
-
when /\/libclntsh\.dylib/, /\/libnnz\d\d.dylib/
|
544
|
-
raise <<EOS unless File.exists?(libname)
|
545
|
-
The output of "otool -L #{file}" is:
|
546
|
-
| #{IO.readlines("|otool -L #{file}").join(' | ')}
|
547
|
-
Ruby-oci8 doesn't work without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH
|
548
|
-
because the dependent file "#{libname}" doesn't exist.
|
549
|
-
|
550
|
-
If you need to use ruby-oci8 without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH,
|
551
|
-
download "fix_oralib.rb" in https://github.com/kubo/fix_oralib_osx
|
552
|
-
and execute it in the directory "#{File.dirname(file)}" as follows to fix the path.
|
553
|
-
|
554
|
-
cd #{File.dirname(file)}
|
555
|
-
curl -O https://raw.githubusercontent.com/kubo/fix_oralib_osx/master/fix_oralib.rb
|
556
|
-
ruby fix_oralib.rb
|
557
|
-
|
558
|
-
Note: DYLD_* environment variables are unavailable for security reasons on OS X 10.11 El Capitan.
|
559
|
-
EOS
|
560
|
-
end
|
561
|
-
end
|
562
|
-
end
|
499
|
+
fallback_path = ENV['DYLD_FALLBACK_LIBRARY_PATH']
|
500
|
+
if fallback_path.nil?
|
501
|
+
fallback_path = "#{ENV['HOME']}/lib:/usr/local/lib:/lib:/usr/lib"
|
502
|
+
puts " checking the default value of DYLD_FALLBACK_LIBRARY_PATH..."
|
503
|
+
ld_path, file = check_lib_in_path(fallback_path, glob_name, check_proc)
|
563
504
|
end
|
564
505
|
end
|
565
506
|
if ld_path.nil?
|
566
507
|
raise <<EOS
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
If DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH is set, the environment
|
571
|
-
variable must be set at runtime also.
|
572
|
-
|
573
|
-
If OCI_DIR is set, dependent shared library paths are checked. If the checking
|
574
|
-
is passed, ruby-oci8 works without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH.
|
575
|
-
|
576
|
-
Note: OCI_DIR should be absolute path.
|
577
|
-
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.
|
578
510
|
EOS
|
579
511
|
end
|
580
512
|
end
|
@@ -598,8 +530,8 @@ EOS
|
|
598
530
|
paths.split(File::PATH_SEPARATOR).each do |path|
|
599
531
|
next if path.nil? or path == ''
|
600
532
|
print " checking #{path}... "
|
601
|
-
path.gsub!(/\\/, '/') if /mswin32|cygwin|
|
602
|
-
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
|
603
535
|
if files.empty?
|
604
536
|
puts "no"
|
605
537
|
next
|
@@ -626,7 +558,7 @@ EOS
|
|
626
558
|
if try_run("int main() { return 0; }")
|
627
559
|
puts "ok"
|
628
560
|
else
|
629
|
-
puts "
|
561
|
+
puts "failed"
|
630
562
|
raise "C compiler doesn't work correctly."
|
631
563
|
end
|
632
564
|
end # check_cc
|
@@ -672,21 +604,11 @@ EOS
|
|
672
604
|
STDOUT.flush
|
673
605
|
rubyhdrdir = RbConfig::CONFIG["rubyhdrdir"] || RbConfig::CONFIG['archdir']
|
674
606
|
unless File.exist?(rubyhdrdir + '/ruby.h')
|
675
|
-
puts "
|
676
|
-
|
677
|
-
raise <<EOS
|
678
|
-
#{RbConfig::CONFIG['archdir']}/ruby.h doesn't exist.
|
679
|
-
Run the following commands to fix the problem.
|
680
|
-
|
681
|
-
cd #{RbConfig::CONFIG['archdir']}
|
682
|
-
sudo ln -s ../universal-darwin8.0/* ./
|
683
|
-
EOS
|
684
|
-
else
|
685
|
-
raise <<EOS
|
607
|
+
puts "failed"
|
608
|
+
raise <<EOS
|
686
609
|
#{RbConfig::CONFIG['archdir']}/ruby.h doesn't exist.
|
687
610
|
Install the ruby development library.
|
688
611
|
EOS
|
689
|
-
end
|
690
612
|
end
|
691
613
|
puts "ok"
|
692
614
|
$stdout.flush
|
@@ -696,23 +618,26 @@ EOS
|
|
696
618
|
original_libs = $libs
|
697
619
|
begin
|
698
620
|
$libs += " -L#{CONFIG['libdir']} " + @libs
|
699
|
-
have_func("
|
621
|
+
have_func("OCIEnvCreate", "oci.h")
|
700
622
|
ensure
|
701
623
|
$libs = original_libs
|
702
624
|
end
|
703
625
|
end
|
704
626
|
|
705
|
-
if RUBY_PLATFORM =~ /mswin32|cygwin|
|
627
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw/ # when Windows
|
706
628
|
|
707
629
|
def get_libs(lib_dir)
|
708
630
|
case RUBY_PLATFORM
|
709
|
-
when /cygwin
|
631
|
+
when /cygwin/
|
710
632
|
regex = ([nil].pack('P').size == 8) ? / T (OCI\w+)/ : / T _(OCI\w+)/
|
633
|
+
oci_funcs = YAML.load(open(File.dirname(__FILE__) + '/apiwrap.yml')).keys.collect do |func|
|
634
|
+
func =~ /_nb$/ ? $` : func
|
635
|
+
end
|
711
636
|
open("OCI.def", "w") do |f|
|
712
637
|
f.puts("EXPORTS")
|
713
638
|
open("|nm #{lib_dir}/MSVC/OCI.LIB") do |r|
|
714
639
|
while line = r.gets
|
715
|
-
f.puts($1) if regex =~ line
|
640
|
+
f.puts($1) if regex =~ line and oci_funcs.include?($1)
|
716
641
|
end
|
717
642
|
end
|
718
643
|
end
|
@@ -722,22 +647,6 @@ EOS
|
|
722
647
|
system(command)
|
723
648
|
puts("done")
|
724
649
|
"-L. -lOCI"
|
725
|
-
when /bccwin32/
|
726
|
-
# replace '/' to '\\' because bcc linker misunderstands
|
727
|
-
# 'C:/foo/bar/OCI.LIB' as unknown option.
|
728
|
-
lib = "#{lib_dir}/BORLAND/OCI.LIB"
|
729
|
-
return lib.tr('/', '\\') if File.exist?(lib)
|
730
|
-
raise <<EOS
|
731
|
-
#{lib} does not exist.
|
732
|
-
|
733
|
-
Your Oracle may not support Borland C++.
|
734
|
-
If you want to run this module, run the following command at your own risk.
|
735
|
-
cd #{lib_dir.tr('/', '\\')}
|
736
|
-
mkdir Borland
|
737
|
-
cd Borland
|
738
|
-
coff2omf ..\\MSVC\\OCI.LIB OCI.LIB
|
739
|
-
EOS
|
740
|
-
exit 1
|
741
650
|
else
|
742
651
|
"\"#{lib_dir}/MSVC/OCI.LIB\""
|
743
652
|
end
|
@@ -781,7 +690,7 @@ class OraConfFC < OraConf
|
|
781
690
|
use_lib32 = false
|
782
691
|
end
|
783
692
|
|
784
|
-
if RUBY_PLATFORM =~ /mswin32|cygwin|
|
693
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw/
|
785
694
|
lib_dir = "#{@oracle_home}/oci/lib"
|
786
695
|
elsif use_lib32
|
787
696
|
lib_dir = "#{@oracle_home}/lib32"
|
@@ -800,7 +709,7 @@ class OraConfFC < OraConf
|
|
800
709
|
print("Get the version of Oracle from SQL*Plus... ")
|
801
710
|
STDOUT.flush
|
802
711
|
version = nil
|
803
|
-
dev_null = RUBY_PLATFORM =~ /mswin32|
|
712
|
+
dev_null = RUBY_PLATFORM =~ /mswin32|mswin64|mingw/ ? "nul" : "/dev/null"
|
804
713
|
if File.exist?("#{@oracle_home}/bin/plus80.exe")
|
805
714
|
sqlplus = "plus80.exe"
|
806
715
|
else
|
@@ -825,7 +734,7 @@ class OraConfFC < OraConf
|
|
825
734
|
version
|
826
735
|
end # get_version
|
827
736
|
|
828
|
-
if RUBY_PLATFORM =~ /mswin32|cygwin|
|
737
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw/ # when Windows
|
829
738
|
|
830
739
|
def is_valid_home?(oracle_home)
|
831
740
|
return false if oracle_home.nil?
|
@@ -844,11 +753,8 @@ class OraConfFC < OraConf
|
|
844
753
|
def get_home()
|
845
754
|
oracle_home = ENV['ORACLE_HOME']
|
846
755
|
if oracle_home.nil?
|
847
|
-
|
848
|
-
|
849
|
-
MiniRegistry.enum_homes do |name, path|
|
850
|
-
path.chomp!("\\") if path
|
851
|
-
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)
|
852
758
|
end
|
853
759
|
if oracle_homes.empty?
|
854
760
|
raise <<EOS
|
@@ -910,7 +816,7 @@ EOS
|
|
910
816
|
unless File.exist?("#{@oracle_home}/OCI/INCLUDE/OCI.H")
|
911
817
|
raise "'#{@oracle_home}/OCI/INCLUDE/OCI.H' does not exists. Please install 'Oracle Call Interface'."
|
912
818
|
end
|
913
|
-
if RUBY_PLATFORM =~ /cygwin|
|
819
|
+
if RUBY_PLATFORM =~ /cygwin|mingw/
|
914
820
|
" \"-I#{@oracle_home}/OCI/INCLUDE\" -D_int64=\"long long\""
|
915
821
|
else
|
916
822
|
" \"-I#{@oracle_home}/OCI/INCLUDE\""
|
@@ -989,56 +895,25 @@ end
|
|
989
895
|
|
990
896
|
# OraConf for Instant Client
|
991
897
|
class OraConfIC < OraConf
|
992
|
-
def initialize(
|
898
|
+
def initialize(inc_dir, lib_dir)
|
993
899
|
init
|
994
900
|
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
# library: /usr/lib/oracle/X.X/client64/lib/
|
1003
|
-
# include: /usr/include/oracle/X.X/client64/
|
1004
|
-
#
|
1005
|
-
# x86 rpms before 11.1.0.6.0:
|
1006
|
-
# library: /usr/lib/oracle/X.X.X.X/client/lib/
|
1007
|
-
# include: /usr/include/oracle/X.X.X.X/client/
|
1008
|
-
#
|
1009
|
-
# x86_64 rpms before 11.1.0.6.0:
|
1010
|
-
# library: /usr/lib/oracle/X.X.X.X/client64/lib/
|
1011
|
-
# include: /usr/include/oracle/X.X.X.X/client64/
|
1012
|
-
#
|
1013
|
-
# third-party x86_64 rpms(*1):
|
1014
|
-
# library: /usr/lib64/oracle/X.X.X.X/client/lib/
|
1015
|
-
# or /usr/lib64/oracle/X.X.X.X/client/lib64/
|
1016
|
-
# include: /usr/include/oracle/X.X.X.X/client/
|
1017
|
-
#
|
1018
|
-
# *1 These had been used before Oracle released official x86_64 rpms.
|
1019
|
-
#
|
1020
|
-
lib_dir = ic_dir
|
1021
|
-
inc_dir = "/usr/include/oracle/#{$1}/client#{$2}"
|
1022
|
-
else
|
1023
|
-
# zip package
|
1024
|
-
lib_dir = ic_dir
|
1025
|
-
inc_dir = "#{ic_dir}/sdk/include"
|
1026
|
-
end
|
1027
|
-
|
1028
|
-
if RUBY_PLATFORM =~ /mswin32|cygwin|mingw32|bccwin32/ # when Windows
|
1029
|
-
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
|
1030
908
|
raise <<EOS
|
1031
909
|
Could not compile with Oracle instant client.
|
1032
|
-
|
910
|
+
"sdk/lib/msvc/oci.lib" could not be found in: #{lib_dirs.join(' ')}
|
911
|
+
Did you install instantclient-basic?
|
1033
912
|
EOS
|
1034
|
-
raise 'failed'
|
1035
913
|
end
|
1036
|
-
@
|
1037
|
-
@cflags += " -D_int64=\"long long\"" if RUBY_PLATFORM =~ /cygwin|mingw32/
|
1038
|
-
@libs = get_libs("#{ic_dir}/sdk/lib")
|
914
|
+
@libs = get_libs("#{ocilib}/sdk/lib")
|
1039
915
|
ld_path = nil
|
1040
916
|
else
|
1041
|
-
@cflags = " -I#{inc_dir}"
|
1042
917
|
# set ld_path and so_ext
|
1043
918
|
case RUBY_PLATFORM
|
1044
919
|
when /aix/
|
@@ -1059,34 +934,53 @@ EOS
|
|
1059
934
|
so_ext = 'so'
|
1060
935
|
end
|
1061
936
|
# check Oracle client library.
|
1062
|
-
|
1063
|
-
|
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
|
1064
944
|
if files.empty?
|
1065
945
|
raise <<EOS
|
1066
946
|
Could not compile with Oracle instant client.
|
1067
|
-
|
947
|
+
"libclntsh.#{so_ext}" could not be found in: #{lib_dirs.join(' ')}
|
1068
948
|
Did you install instantclient-basic?
|
1069
949
|
EOS
|
1070
950
|
else
|
1071
|
-
file =
|
951
|
+
file = files.sort[-1]
|
1072
952
|
raise <<EOS
|
1073
953
|
Could not compile with Oracle instant client.
|
1074
|
-
|
954
|
+
"libclntsh.#{so_ext}" could not be found in: #{lib_dirs.join(' ')}
|
1075
955
|
You may need to make a symbolic link.
|
1076
|
-
cd #{
|
1077
|
-
ln -s #{file} libclntsh.#{so_ext}
|
956
|
+
cd #{File.dirname(file)}
|
957
|
+
ln -s #{File.basename(file)} libclntsh.#{so_ext}
|
1078
958
|
EOS
|
1079
959
|
end
|
1080
960
|
raise 'failed'
|
1081
961
|
end
|
1082
962
|
@libs = get_libs(lib_dir)
|
1083
963
|
end
|
1084
|
-
|
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
|
1085
971
|
raise <<EOS
|
1086
|
-
|
972
|
+
"oci.h" could not be found in: #{inc_dirs.join(' ')}
|
1087
973
|
Install 'Instant Client SDK'.
|
1088
974
|
EOS
|
1089
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
|
1090
984
|
$CFLAGS += @cflags
|
1091
985
|
if try_link_oci()
|
1092
986
|
major = try_constant("OCI_MAJOR_VERSION", "oci.h")
|
@@ -1096,73 +990,10 @@ EOS
|
|
1096
990
|
else
|
1097
991
|
# 10.1.0 doesn't have OCI_MAJOR_VERSION and OCI_MINOR_VERSION in oci.h.
|
1098
992
|
@version = "1010"
|
1099
|
-
if RUBY_PLATFORM =~ /darwin/ and 1.size == 8 and `sw_vers -productVersion`.chomp == "10.7"
|
1100
|
-
$stderr.print <<EOS
|
1101
|
-
WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN!
|
1102
|
-
|
1103
|
-
64-bit Oracle instant client doesn't work on OS X Lion.
|
1104
|
-
See: https://forums.oracle.com/forums/thread.jspa?threadID=2187558
|
1105
|
-
|
1106
|
-
The compilation is continued because the issue may be fixed in future.
|
1107
|
-
|
1108
|
-
WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN!
|
1109
|
-
EOS
|
1110
|
-
end
|
1111
993
|
end
|
1112
994
|
return
|
1113
995
|
end
|
1114
996
|
|
1115
|
-
if RUBY_PLATFORM =~ /darwin/
|
1116
|
-
open('mkmf.log', 'r') do |f|
|
1117
|
-
while line = f.gets
|
1118
|
-
if line.include? '/libclntsh.dylib load command 8 unknown cmd field'
|
1119
|
-
raise <<EOS
|
1120
|
-
Intel mac instant client is for Mac OS X 10.5.
|
1121
|
-
It doesn't work on Mac OS X 10.4 or before.
|
1122
|
-
|
1123
|
-
You have three workarounds.
|
1124
|
-
1. Compile ruby as ppc binary and use it with ppc instant client.
|
1125
|
-
2. Use JRuby and JDBC
|
1126
|
-
3. Use a third-party ODBC driver and ruby-odbc.
|
1127
|
-
EOS
|
1128
|
-
# '
|
1129
|
-
end
|
1130
|
-
|
1131
|
-
case line
|
1132
|
-
when /cputype \(\d+, architecture \w+\) does not match cputype \(\d+\) for specified -arch flag: (\w+)/
|
1133
|
-
missing_arch = $1
|
1134
|
-
when /Undefined symbols for architecture (\w+)/
|
1135
|
-
missing_arch = $1
|
1136
|
-
when /missing required architecture (\w+) in file/
|
1137
|
-
missing_arch = $1
|
1138
|
-
end
|
1139
|
-
|
1140
|
-
if missing_arch
|
1141
|
-
if [nil].pack('p').size == 8
|
1142
|
-
my_arch = 'x86_64'
|
1143
|
-
elsif "\x01\x02".unpack('s')[0] == 0x0201
|
1144
|
-
my_arch = 'i386'
|
1145
|
-
else
|
1146
|
-
my_arch = 'ppc'
|
1147
|
-
end
|
1148
|
-
raise <<EOS
|
1149
|
-
Could not compile with Oracle instant client.
|
1150
|
-
You may need to set the environment variable RC_ARCHS or ARCHFLAGS as follows:
|
1151
|
-
|
1152
|
-
RC_ARCHS=#{my_arch}
|
1153
|
-
export RC_ARCHS
|
1154
|
-
or
|
1155
|
-
ARCHFLAGS='-arch #{my_arch}'
|
1156
|
-
export RC_ARCHS
|
1157
|
-
|
1158
|
-
If it does not fix the problem, delete all '-arch #{missing_arch}'
|
1159
|
-
in '#{RbConfig::CONFIG['archdir']}/rbconfig.rb'.
|
1160
|
-
EOS
|
1161
|
-
end
|
1162
|
-
end
|
1163
|
-
end
|
1164
|
-
end
|
1165
|
-
|
1166
997
|
unless ld_path.nil?
|
1167
998
|
raise <<EOS
|
1168
999
|
Could not compile with Oracle instant client.
|