ruby-oci8 2.2.0.2 → 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/.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.
|