ruby-staci 2.2.9
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 +14 -0
- data/COPYING +30 -0
- data/COPYING_old +64 -0
- data/ChangeLog +3826 -0
- data/Makefile +92 -0
- data/NEWS +1194 -0
- data/README.md +66 -0
- data/dist-files +113 -0
- 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 +44 -0
- data/docs/install-full-client.md +111 -0
- data/docs/install-instant-client.md +194 -0
- data/docs/install-on-osx.md +133 -0
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/docs/osx-install-dev-tools.png +0 -0
- data/docs/platform-specific-issues.md +164 -0
- data/docs/report-installation-issue.md +50 -0
- data/docs/timeout-parameters.md +94 -0
- data/ext/oci8/.document +18 -0
- data/ext/oci8/MANIFEST +18 -0
- data/ext/oci8/apiwrap.c.tmpl +178 -0
- data/ext/oci8/apiwrap.h.tmpl +61 -0
- data/ext/oci8/apiwrap.rb +96 -0
- data/ext/oci8/apiwrap.yml +1322 -0
- data/ext/oci8/attr.c +57 -0
- data/ext/oci8/bind.c +838 -0
- data/ext/oci8/connection_pool.c +216 -0
- data/ext/oci8/encoding.c +196 -0
- data/ext/oci8/env.c +139 -0
- data/ext/oci8/error.c +385 -0
- data/ext/oci8/extconf.rb +219 -0
- data/ext/oci8/hook_funcs.c +407 -0
- data/ext/oci8/lob.c +1278 -0
- data/ext/oci8/metadata.c +279 -0
- data/ext/oci8/object.c +919 -0
- data/ext/oci8/oci8.c +1058 -0
- data/ext/oci8/oci8.h +556 -0
- data/ext/oci8/oci8lib.c +704 -0
- data/ext/oci8/ocidatetime.c +506 -0
- data/ext/oci8/ocihandle.c +852 -0
- data/ext/oci8/ocinumber.c +1922 -0
- data/ext/oci8/oraconf.rb +1145 -0
- data/ext/oci8/oradate.c +670 -0
- data/ext/oci8/oranumber_util.c +352 -0
- data/ext/oci8/oranumber_util.h +24 -0
- data/ext/oci8/plthook.h +66 -0
- data/ext/oci8/plthook_elf.c +702 -0
- data/ext/oci8/plthook_osx.c +505 -0
- data/ext/oci8/plthook_win32.c +391 -0
- data/ext/oci8/post-config.rb +5 -0
- data/ext/oci8/stmt.c +448 -0
- data/ext/oci8/thread_util.c +81 -0
- data/ext/oci8/thread_util.h +18 -0
- data/ext/oci8/util.c +71 -0
- data/ext/oci8/win32.c +117 -0
- data/lib/.document +1 -0
- data/lib/dbd/STACI.rb +591 -0
- data/lib/oci8/.document +8 -0
- data/lib/oci8/bindtype.rb +333 -0
- data/lib/oci8/check_load_error.rb +146 -0
- data/lib/oci8/compat.rb +117 -0
- data/lib/oci8/connection_pool.rb +179 -0
- data/lib/oci8/cursor.rb +605 -0
- data/lib/oci8/datetime.rb +605 -0
- data/lib/oci8/encoding-init.rb +45 -0
- data/lib/oci8/encoding.yml +537 -0
- data/lib/oci8/metadata.rb +2148 -0
- data/lib/oci8/object.rb +641 -0
- data/lib/oci8/oci8.rb +756 -0
- data/lib/oci8/ocihandle.rb +591 -0
- data/lib/oci8/oracle_version.rb +153 -0
- data/lib/oci8/properties.rb +196 -0
- data/lib/oci8/version.rb +3 -0
- data/lib/ruby-staci.rb +1 -0
- data/lib/staci.rb +190 -0
- data/metaconfig +142 -0
- data/pre-distclean.rb +7 -0
- data/ruby-aci.gemspec +83 -0
- data/setup.rb +1342 -0
- data/test/README.md +37 -0
- data/test/config.rb +201 -0
- data/test/setup_test_object.sql +199 -0
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +56 -0
- data/test/test_appinfo.rb +62 -0
- data/test/test_array_dml.rb +333 -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_bind_raw.rb +45 -0
- data/test/test_bind_string.rb +105 -0
- data/test/test_bind_time.rb +177 -0
- data/test/test_break.rb +124 -0
- data/test/test_clob.rb +86 -0
- data/test/test_connection_pool.rb +124 -0
- data/test/test_connstr.rb +220 -0
- data/test/test_datetime.rb +585 -0
- data/test/test_dbi.rb +365 -0
- data/test/test_dbi_clob.rb +53 -0
- data/test/test_encoding.rb +103 -0
- data/test/test_error.rb +87 -0
- data/test/test_metadata.rb +2674 -0
- data/test/test_object.rb +546 -0
- data/test/test_oci8.rb +624 -0
- data/test/test_oracle_version.rb +68 -0
- data/test/test_oradate.rb +255 -0
- data/test/test_oranumber.rb +786 -0
- data/test/test_package_type.rb +981 -0
- data/test/test_properties.rb +17 -0
- data/test/test_rowid.rb +32 -0
- metadata +158 -0
data/ext/oci8/oraconf.rb
ADDED
@@ -0,0 +1,1145 @@
|
|
1
|
+
# coding: ascii
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
# compatibility for ruby-1.9
|
5
|
+
RbConfig = Config unless defined? RbConfig
|
6
|
+
|
7
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw32|bccwin32/
|
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\ShenTong') do |key|
|
24
|
+
key.each_key do |subkey_name|
|
25
|
+
subkey = key.open(subkey_name)
|
26
|
+
begin
|
27
|
+
homes << OracleHome.new(subkey['SZ_OSCAR_HOME'], subkey['SZ_OSCAR_HOME'].chomp('\\'))
|
28
|
+
rescue Win32::Registry::Error
|
29
|
+
# ignore errors
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
homes
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# minimal implementation to read information of a shared object.
|
40
|
+
class MiniSOReader
|
41
|
+
attr_reader :file_format
|
42
|
+
attr_reader :cpu
|
43
|
+
attr_reader :endian
|
44
|
+
attr_reader :bits
|
45
|
+
|
46
|
+
def initialize(filename)
|
47
|
+
f = open(filename, 'rb')
|
48
|
+
begin
|
49
|
+
case file_header = f.read(2)
|
50
|
+
when "\177E"
|
51
|
+
# Linux, Solaris and HP-UX(64-bit)
|
52
|
+
read_elf(f) if f.read(2) == 'LF'
|
53
|
+
when "MZ"
|
54
|
+
# Windows
|
55
|
+
read_pe(f)
|
56
|
+
when "\x02\x10"
|
57
|
+
# HP-UX PA-RISC1.1
|
58
|
+
read_parisc(f)
|
59
|
+
when "\xfe\xed"
|
60
|
+
# Big-endian Mach-O File
|
61
|
+
read_mach_o_be(f)
|
62
|
+
when "\xce\xfa"
|
63
|
+
# 32-bit Little-endian Mach-O File
|
64
|
+
read_mach_o_le(f, 32)
|
65
|
+
when "\xcf\xfa"
|
66
|
+
# 64-bit Little-endian Mach-O File
|
67
|
+
read_mach_o_le(f, 64)
|
68
|
+
when "\xca\xfe"
|
69
|
+
# Universal binary
|
70
|
+
read_mach_o_unversal(f)
|
71
|
+
else
|
72
|
+
# AIX and Tru64
|
73
|
+
raise format("unknown file header: %02x %02x", file_header[0].to_i, file_header[1].to_i)
|
74
|
+
end
|
75
|
+
ensure
|
76
|
+
f.close
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
# ELF format
|
82
|
+
def read_elf(f)
|
83
|
+
# 0-3 "\177ELF"
|
84
|
+
@file_format = :elf
|
85
|
+
# 4
|
86
|
+
case f.read(1).unpack('C')[0]
|
87
|
+
when 1
|
88
|
+
@bits = 32
|
89
|
+
when 2
|
90
|
+
@bits = 64
|
91
|
+
else
|
92
|
+
raise 'Invalid ELF class'
|
93
|
+
end
|
94
|
+
# 5
|
95
|
+
case f.read(1).unpack('C')[0]
|
96
|
+
when 1
|
97
|
+
@endian = :little
|
98
|
+
pack_type_short = 'v'
|
99
|
+
when 2
|
100
|
+
@endian = :big
|
101
|
+
pack_type_short = 'n'
|
102
|
+
else
|
103
|
+
raise 'Invalid ELF byte order'
|
104
|
+
end
|
105
|
+
# 6
|
106
|
+
raise 'Invalid ELF header version' if f.read(1) != "\x01"
|
107
|
+
# 16-17
|
108
|
+
f.seek(16, IO::SEEK_SET)
|
109
|
+
raise 'Invalid ELF filetype' if f.read(2).unpack(pack_type_short)[0] != 3
|
110
|
+
# 18-19
|
111
|
+
case archtype = f.read(2).unpack(pack_type_short)[0]
|
112
|
+
when 2
|
113
|
+
@cpu = :sparc
|
114
|
+
when 3
|
115
|
+
@cpu = :i386
|
116
|
+
when 15
|
117
|
+
@cpu = :parisc
|
118
|
+
when 18
|
119
|
+
@cpu = :sparc32plus
|
120
|
+
when 20
|
121
|
+
@cpu = :ppc
|
122
|
+
when 21
|
123
|
+
@cpu = :ppc64
|
124
|
+
when 22
|
125
|
+
@cpu = :s390
|
126
|
+
when 43
|
127
|
+
@cpu = :sparcv9
|
128
|
+
when 50
|
129
|
+
@cpu = :ia64
|
130
|
+
when 62
|
131
|
+
@cpu = :x86_64
|
132
|
+
else
|
133
|
+
raise "Invalid ELF archtype: #{archtype}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# PE/COFF format
|
138
|
+
def read_pe(f)
|
139
|
+
# 0-1 "MZ"
|
140
|
+
@file_format = :pe
|
141
|
+
# 60-63
|
142
|
+
f.seek(60, IO::SEEK_SET)
|
143
|
+
pe_offset = f.read(4).unpack('V')[0]
|
144
|
+
# read PE signature
|
145
|
+
f.seek(pe_offset)
|
146
|
+
raise 'invalid pe format' if f.read(4) != "PE\000\000"
|
147
|
+
# read COFF header
|
148
|
+
case machine = f.read(2).unpack('v')[0]
|
149
|
+
when 0x014c
|
150
|
+
@cpu = :i386
|
151
|
+
@endian = :little
|
152
|
+
@bits = 32
|
153
|
+
when 0x0200
|
154
|
+
@cpu = :ia64
|
155
|
+
@endian = :little
|
156
|
+
@bits = 64
|
157
|
+
when 0x8664
|
158
|
+
@cpu = :x86_64
|
159
|
+
@endian = :little
|
160
|
+
@bits = 64
|
161
|
+
else
|
162
|
+
raise "Invalid coff machine: #{machine}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# HP-UX PA-RISC(32 bit)
|
167
|
+
def read_parisc(f)
|
168
|
+
# 0-1 system_id - CPU_PA_RISC1_1
|
169
|
+
@file_format = :pa_risc
|
170
|
+
# 2-3 a_magic - SHL_MAGIC
|
171
|
+
raise 'invalid a_magic' if f.read(2).unpack('n')[0] != 0x10e
|
172
|
+
@bits = 32
|
173
|
+
@endian = :big
|
174
|
+
@cpu = :parisc
|
175
|
+
end
|
176
|
+
|
177
|
+
# Big-endian Mach-O File
|
178
|
+
def read_mach_o_be(f)
|
179
|
+
@file_format = :mach_o
|
180
|
+
@endian = :big
|
181
|
+
case f.read(2)
|
182
|
+
when "\xfa\xce" # feedface
|
183
|
+
@cpu = :ppc
|
184
|
+
@bits = 32
|
185
|
+
when "\xfa\xcf" # feedfacf
|
186
|
+
@cpu = :ppc64
|
187
|
+
@bits = 64
|
188
|
+
else
|
189
|
+
raise "unknown file format"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def read_mach_o_le(f, bits)
|
194
|
+
@file_format = :mach_o
|
195
|
+
@endian = :little
|
196
|
+
raise 'unknown file format' if f.read(2) != "\xed\xfe"
|
197
|
+
case bits
|
198
|
+
when 32
|
199
|
+
@cpu = :i386
|
200
|
+
@bits = 32
|
201
|
+
when 64
|
202
|
+
@cpu = :x86_64
|
203
|
+
@bits = 64
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def read_mach_o_unversal(f)
|
208
|
+
raise 'unknown file format' if f.read(2) != "\xba\xbe" # cafebabe
|
209
|
+
@file_format = :universal
|
210
|
+
nfat_arch = f.read(4).unpack('N')[0]
|
211
|
+
@cpu = []
|
212
|
+
@endian = []
|
213
|
+
@bits = []
|
214
|
+
nfat_arch.times do
|
215
|
+
case cputype = f.read(4).unpack('N')[0]
|
216
|
+
when 7
|
217
|
+
@cpu << :i386
|
218
|
+
@endian << :little
|
219
|
+
@bits << 32
|
220
|
+
when 7 + 0x01000000
|
221
|
+
@cpu << :x86_64
|
222
|
+
@endian << :little
|
223
|
+
@bits << 64
|
224
|
+
when 18
|
225
|
+
@cpu << :ppc
|
226
|
+
@endian << :big
|
227
|
+
@bits << 32
|
228
|
+
when 18 + 0x01000000
|
229
|
+
@cpu << :ppc64
|
230
|
+
@endian << :big
|
231
|
+
@bits << 64
|
232
|
+
else
|
233
|
+
raise "Unknown mach-o cputype: #{cputype}"
|
234
|
+
end
|
235
|
+
f.seek(4 * 4, IO::SEEK_CUR)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
class OraConf
|
241
|
+
attr_reader :cc_is_gcc
|
242
|
+
attr_reader :version
|
243
|
+
attr_reader :cflags
|
244
|
+
attr_reader :libs
|
245
|
+
|
246
|
+
def initialize
|
247
|
+
raise 'use OraConf.get instead'
|
248
|
+
end
|
249
|
+
|
250
|
+
def self.get
|
251
|
+
original_CFLAGS = $CFLAGS
|
252
|
+
original_defs = $defs
|
253
|
+
begin
|
254
|
+
# check Oracle instant client
|
255
|
+
if with_config('instant-client')
|
256
|
+
puts <<EOS
|
257
|
+
=======================================================
|
258
|
+
|
259
|
+
'--with-instant-client' is an obsolete option. ignore it.
|
260
|
+
|
261
|
+
=======================================================
|
262
|
+
EOS
|
263
|
+
end
|
264
|
+
inc, lib = dir_config('instant-client')
|
265
|
+
if inc && lib
|
266
|
+
OraConfIC.new(inc, lib)
|
267
|
+
else
|
268
|
+
base = guess_ic_dir
|
269
|
+
if base
|
270
|
+
inc, lib = guess_dirs_from_ic_base(base)
|
271
|
+
OraConfIC.new(inc, lib)
|
272
|
+
else
|
273
|
+
OraConfFC.new
|
274
|
+
end
|
275
|
+
end
|
276
|
+
rescue
|
277
|
+
case ENV['LANG']
|
278
|
+
when /^ja/
|
279
|
+
lang = 'ja'
|
280
|
+
else
|
281
|
+
lang = 'en'
|
282
|
+
end
|
283
|
+
print <<EOS
|
284
|
+
---------------------------------------------------
|
285
|
+
Error Message:
|
286
|
+
#{$!.to_s.gsub(/\n/, "\n ")}
|
287
|
+
Backtrace:
|
288
|
+
#{$!.backtrace.join("\n ")}
|
289
|
+
---------------------------------------------------
|
290
|
+
See:
|
291
|
+
* http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-full-client.md for Oracle full client
|
292
|
+
* http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-instant-client.md for Oracle instant client
|
293
|
+
* http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-on-osx.md for OS X
|
294
|
+
* http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/report-installation-issue.md to report an issue.
|
295
|
+
|
296
|
+
EOS
|
297
|
+
exc = RuntimeError.new
|
298
|
+
exc.set_backtrace($!.backtrace)
|
299
|
+
raise exc
|
300
|
+
ensure
|
301
|
+
$CFLAGS = original_CFLAGS
|
302
|
+
$defs = original_defs
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
# Guess the include and directory paths from
|
307
|
+
def self.guess_dirs_from_ic_base(ic_dir)
|
308
|
+
if ic_dir =~ /^\/usr\/lib(?:64)?\/oracle\/(\d+(?:\.\d+)*)\/client(64)?\/lib(?:64)?/
|
309
|
+
# rpm package
|
310
|
+
# x86 rpms after 11.1.0.7.0:
|
311
|
+
# library: /usr/lib/oracle/X.X/client/lib/
|
312
|
+
# include: /usr/include/oracle/X.X/client/
|
313
|
+
#
|
314
|
+
# x86_64 rpms after 11.1.0.7.0:
|
315
|
+
# library: /usr/lib/oracle/X.X/client64/lib/
|
316
|
+
# include: /usr/include/oracle/X.X/client64/
|
317
|
+
#
|
318
|
+
# x86 rpms before 11.1.0.6.0:
|
319
|
+
# library: /usr/lib/oracle/X.X.X.X/client/lib/
|
320
|
+
# include: /usr/include/oracle/X.X.X.X/client/
|
321
|
+
#
|
322
|
+
# x86_64 rpms before 11.1.0.6.0:
|
323
|
+
# library: /usr/lib/oracle/X.X.X.X/client64/lib/
|
324
|
+
# include: /usr/include/oracle/X.X.X.X/client64/
|
325
|
+
#
|
326
|
+
# third-party x86_64 rpms(*1):
|
327
|
+
# library: /usr/lib64/oracle/X.X.X.X/client/lib/
|
328
|
+
# or /usr/lib64/oracle/X.X.X.X/client/lib64/
|
329
|
+
# include: /usr/include/oracle/X.X.X.X/client/
|
330
|
+
#
|
331
|
+
# *1 These had been used before Oracle released official x86_64 rpms.
|
332
|
+
#
|
333
|
+
lib_dir = ic_dir
|
334
|
+
inc_dir = "/usr/include/oracle/#{$1}/client#{$2}"
|
335
|
+
else
|
336
|
+
# zip package
|
337
|
+
lib_dir = ic_dir
|
338
|
+
inc_dir = "#{ic_dir}/sdk/include"
|
339
|
+
end
|
340
|
+
|
341
|
+
[inc_dir, lib_dir]
|
342
|
+
end
|
343
|
+
|
344
|
+
def self.ld_envs
|
345
|
+
@@ld_envs
|
346
|
+
end
|
347
|
+
|
348
|
+
private
|
349
|
+
|
350
|
+
def self.make_proc_to_check_cpu(*expect)
|
351
|
+
Proc.new do |file|
|
352
|
+
so = MiniSOReader.new(file)
|
353
|
+
if expect.include? so.cpu
|
354
|
+
true
|
355
|
+
else
|
356
|
+
puts " skip: #{file} is for #{so.cpu} cpu."
|
357
|
+
false
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
def self.guess_ic_dir
|
363
|
+
puts "attempting to locate oracle-instantclient..."
|
364
|
+
puts "checking load library path... "
|
365
|
+
STDOUT.flush
|
366
|
+
|
367
|
+
# get library load path names
|
368
|
+
oci_basename = 'libaci'
|
369
|
+
oci_glob_postfix = '.[0-9]*'
|
370
|
+
nls_data_basename = ['libociei', 'libociicus']
|
371
|
+
@@ld_envs = %w[LD_LIBRARY_PATH]
|
372
|
+
so_ext = 'so'
|
373
|
+
nls_data_ext = nil
|
374
|
+
check_proc = nil
|
375
|
+
size_of_pointer = begin
|
376
|
+
# the size of a pointer.
|
377
|
+
[nil].pack('P').size
|
378
|
+
rescue ArgumentError
|
379
|
+
# Rubinius 1.2.3 doesn't support Array#pack('P').
|
380
|
+
# Use Integer#size, which returns the size of long.
|
381
|
+
1.size
|
382
|
+
end
|
383
|
+
is_32bit = size_of_pointer == 4
|
384
|
+
is_big_endian = "\x01\x02".unpack('s')[0] == 0x0102
|
385
|
+
case RUBY_PLATFORM
|
386
|
+
when /mswin32|mswin64|cygwin|mingw32|bccwin32/
|
387
|
+
oci_basename = 'aci'
|
388
|
+
oci_glob_postfix = ''
|
389
|
+
nls_data_basename = ['oraociei*', 'oraociicus*']
|
390
|
+
@@ld_envs = %w[PATH]
|
391
|
+
so_ext = 'dll'
|
392
|
+
check_proc = make_proc_to_check_cpu(is_32bit ? :i386 : :x86_64)
|
393
|
+
when /i.86-linux/
|
394
|
+
check_proc = make_proc_to_check_cpu(:i386)
|
395
|
+
when /ia64-linux/
|
396
|
+
check_proc = make_proc_to_check_cpu(:ia64)
|
397
|
+
when /x86_64-linux/
|
398
|
+
# RUBY_PLATFORM depends on the compilation environment.
|
399
|
+
# Even though it is x86_64-linux, the compiled ruby may
|
400
|
+
# be a 32-bit executable.
|
401
|
+
check_proc = make_proc_to_check_cpu(is_32bit ? :i386 : :x86_64)
|
402
|
+
when /solaris/
|
403
|
+
if is_32bit
|
404
|
+
@@ld_envs = %w[LD_LIBRARY_PATH_32 LD_LIBRARY_PATH]
|
405
|
+
if is_big_endian
|
406
|
+
check_proc = make_proc_to_check_cpu(:sparc, :sparc32plus)
|
407
|
+
else
|
408
|
+
check_proc = make_proc_to_check_cpu(:i386)
|
409
|
+
end
|
410
|
+
else
|
411
|
+
@@ld_envs = %w[LD_LIBRARY_PATH_64 LD_LIBRARY_PATH]
|
412
|
+
if is_big_endian
|
413
|
+
check_proc = make_proc_to_check_cpu(:sparcv9)
|
414
|
+
else
|
415
|
+
check_proc = make_proc_to_check_cpu(:x86_64)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
when /aix/
|
419
|
+
oci_glob_postfix = ''
|
420
|
+
@@ld_envs = %w[LIBPATH]
|
421
|
+
so_ext = 'a'
|
422
|
+
nls_data_ext = 'so'
|
423
|
+
when /hppa.*-hpux/
|
424
|
+
if is_32bit
|
425
|
+
@@ld_envs = %w[SHLIB_PATH]
|
426
|
+
end
|
427
|
+
so_ext = 'sl'
|
428
|
+
when /darwin/
|
429
|
+
@@ld_envs = %w[DYLD_LIBRARY_PATH]
|
430
|
+
so_ext = 'dylib'
|
431
|
+
if is_32bit
|
432
|
+
if is_big_endian
|
433
|
+
this_cpu = :ppc # 32-bit big-endian
|
434
|
+
else
|
435
|
+
this_cpu = :i386 # 32-bit little-endian
|
436
|
+
end
|
437
|
+
else
|
438
|
+
if is_big_endian
|
439
|
+
this_cpu = :ppc64 # 64-bit big-endian
|
440
|
+
else
|
441
|
+
this_cpu = :x86_64 # 64-bit little-endian
|
442
|
+
end
|
443
|
+
end
|
444
|
+
check_proc = Proc.new do |file|
|
445
|
+
so = MiniSOReader.new(file)
|
446
|
+
if so.file_format == :universal
|
447
|
+
if so.cpu.include? this_cpu
|
448
|
+
true
|
449
|
+
else
|
450
|
+
if so.cpu.size > 1
|
451
|
+
arch_types = so.cpu[0..-2].join(', ') + ' and ' + so.cpu[-1].to_s
|
452
|
+
else
|
453
|
+
arch_types = so.cpu[0]
|
454
|
+
end
|
455
|
+
puts " skip: #{file} is for #{arch_types} cpu."
|
456
|
+
false
|
457
|
+
end
|
458
|
+
else
|
459
|
+
if so.cpu == this_cpu
|
460
|
+
true
|
461
|
+
else
|
462
|
+
puts " skip: #{file} is for #{so.cpu} cpu."
|
463
|
+
false
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
glob_name = "#{oci_basename}.#{so_ext}#{oci_glob_postfix}"
|
470
|
+
ld_path = nil
|
471
|
+
file = nil
|
472
|
+
@@ld_envs.each do |env|
|
473
|
+
if ENV[env].nil?
|
474
|
+
puts " #{env} is not set."
|
475
|
+
next
|
476
|
+
end
|
477
|
+
puts " #{env}... "
|
478
|
+
ld_path, file = check_lib_in_path(ENV[env], glob_name, check_proc)
|
479
|
+
break if ld_path
|
480
|
+
end
|
481
|
+
|
482
|
+
if ld_path.nil?
|
483
|
+
case RUBY_PLATFORM
|
484
|
+
when /linux/
|
485
|
+
open("|/sbin/ldconfig -p") do |f|
|
486
|
+
print " checking ld.so.conf... "
|
487
|
+
STDOUT.flush
|
488
|
+
while line = f.gets
|
489
|
+
if line =~ /libaci\.so\..* => (\/.*)\/libaci\.so\.(.*)/
|
490
|
+
file = "#$1/libaci.so.#$2"
|
491
|
+
path = $1
|
492
|
+
next if (check_proc && !check_proc.call(file))
|
493
|
+
ld_path = path
|
494
|
+
puts "yes"
|
495
|
+
break
|
496
|
+
end
|
497
|
+
end
|
498
|
+
puts "no"
|
499
|
+
end
|
500
|
+
when /solaris/
|
501
|
+
if is_32bit
|
502
|
+
crle_cmd = 'crle'
|
503
|
+
else
|
504
|
+
crle_cmd = 'crle -64'
|
505
|
+
end
|
506
|
+
open('|env LANG=C /usr/bin/' + crle_cmd) do |f|
|
507
|
+
while line = f.gets
|
508
|
+
if line =~ /Default Library Path[^:]*:\s*(\S*)/
|
509
|
+
puts " checking output of `#{crle_cmd}'... "
|
510
|
+
ld_path, file = check_lib_in_path($1, glob_name, check_proc)
|
511
|
+
break
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
when /darwin/
|
516
|
+
fallback_path = ENV['DYLD_FALLBACK_LIBRARY_PATH']
|
517
|
+
if fallback_path.nil?
|
518
|
+
puts " DYLD_FALLBACK_LIBRARY_PATH is not set."
|
519
|
+
else
|
520
|
+
puts " checking DYLD_FALLBACK_LIBRARY_PATH..."
|
521
|
+
ld_path, file = check_lib_in_path(fallback_path, glob_name, check_proc)
|
522
|
+
end
|
523
|
+
if ld_path.nil?
|
524
|
+
puts " checking OCI_DIR..."
|
525
|
+
ld_path, file = check_lib_in_path(ENV['OCI_DIR'], glob_name, check_proc)
|
526
|
+
if ld_path
|
527
|
+
puts " checking dependent shared libraries in #{file}..."
|
528
|
+
open("|otool -L #{file}") do |f|
|
529
|
+
f.gets # discard the first line
|
530
|
+
while line = f.gets
|
531
|
+
line =~ /^\s+(\S+)/
|
532
|
+
libname = $1
|
533
|
+
case libname
|
534
|
+
when /^@rpath\/libaci\.dylib/, /^@rpath\/libnnz\d\d\.dylib/, /^@loader_path\/libnnz\d\d\.dylib/
|
535
|
+
# No need to check the real path.
|
536
|
+
# The current instant client doesn't use @rpath or @loader_path.
|
537
|
+
when /\/libaci\.dylib/, /\/libnnz\d\d.dylib/
|
538
|
+
raise <<EOS unless File.exists?(libname)
|
539
|
+
The output of "otool -L #{file}" is:
|
540
|
+
| #{IO.readlines("|otool -L #{file}").join(' | ')}
|
541
|
+
Ruby-oci8 doesn't work without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH
|
542
|
+
because the dependent file "#{libname}" doesn't exist.
|
543
|
+
|
544
|
+
If you need to use ruby-oci8 without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH,
|
545
|
+
download "fix_oralib.rb" in https://github.com/kubo/fix_oralib_osx
|
546
|
+
and execute it in the directory "#{File.dirname(file)}" as follows to fix the path.
|
547
|
+
|
548
|
+
cd #{File.dirname(file)}
|
549
|
+
curl -O https://raw.githubusercontent.com/kubo/fix_oralib_osx/master/fix_oralib.rb
|
550
|
+
ruby fix_oralib.rb
|
551
|
+
|
552
|
+
Note: DYLD_* environment variables are unavailable for security reasons on OS X 10.11 El Capitan.
|
553
|
+
EOS
|
554
|
+
end
|
555
|
+
end
|
556
|
+
end
|
557
|
+
end
|
558
|
+
end
|
559
|
+
if ld_path.nil?
|
560
|
+
fallback_path = ENV['DYLD_FALLBACK_LIBRARY_PATH']
|
561
|
+
if fallback_path.nil?
|
562
|
+
fallback_path = "#{ENV['HOME']}/lib:/usr/local/lib:/lib:/usr/lib"
|
563
|
+
puts " checking the default value of DYLD_FALLBACK_LIBRARY_PATH..."
|
564
|
+
ld_path, file = check_lib_in_path(fallback_path, glob_name, check_proc)
|
565
|
+
end
|
566
|
+
end
|
567
|
+
if ld_path.nil?
|
568
|
+
raise <<EOS
|
569
|
+
Set the environment variable DYLD_LIBRARY_PATH, DYLD_FALLBACK_LIBRARY_PATH or
|
570
|
+
OCI_DIR to point to the Instant client directory.
|
571
|
+
|
572
|
+
If DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH is set, the environment
|
573
|
+
variable must be set at runtime also.
|
574
|
+
|
575
|
+
If OCI_DIR is set, dependent shared library paths are checked. If the checking
|
576
|
+
is passed, ruby-oci8 works without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH.
|
577
|
+
|
578
|
+
Note: OCI_DIR should be absolute path.
|
579
|
+
Note: DYLD_* environment variables are unavailable for security reasons on OS X 10.11 El Capitan.
|
580
|
+
EOS
|
581
|
+
end
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
if ld_path
|
586
|
+
nls_data_ext ||= so_ext # nls_data_ext is same with so_ext by default.
|
587
|
+
nls_data_basename.each do |basename|
|
588
|
+
if Dir.glob(File.join(ld_path, "#{basename}.#{nls_data_ext}")).size > 0
|
589
|
+
puts " #{file} looks like an instant client."
|
590
|
+
return ld_path
|
591
|
+
end
|
592
|
+
end
|
593
|
+
puts " #{file} looks like a full client."
|
594
|
+
end
|
595
|
+
nil
|
596
|
+
end
|
597
|
+
|
598
|
+
def self.check_lib_in_path(paths, glob_name, check_proc)
|
599
|
+
return nil if paths.nil?
|
600
|
+
paths.split(File::PATH_SEPARATOR).each do |path|
|
601
|
+
next if path.nil? or path == ''
|
602
|
+
print " checking #{path}... "
|
603
|
+
path.gsub!(/\\/, '/') if /mswin32|mswin64|cygwin|mingw32|bccwin32/ =~ RUBY_PLATFORM
|
604
|
+
files = Dir.glob(File.join(path, glob_name))
|
605
|
+
if files.empty?
|
606
|
+
puts "no"
|
607
|
+
next
|
608
|
+
end
|
609
|
+
STDOUT.flush
|
610
|
+
next if (check_proc && !check_proc.call(files[0]))
|
611
|
+
puts "yes"
|
612
|
+
return path, files[0]
|
613
|
+
end
|
614
|
+
nil
|
615
|
+
end
|
616
|
+
|
617
|
+
def init
|
618
|
+
check_cc()
|
619
|
+
@cc_is_gcc = check_cc_is_gcc()
|
620
|
+
@lp64 = check_lp64()
|
621
|
+
check_system_header()
|
622
|
+
check_ruby_header()
|
623
|
+
end
|
624
|
+
|
625
|
+
def check_cc
|
626
|
+
print "checking for cc... "
|
627
|
+
STDOUT.flush
|
628
|
+
if try_run("int main() { return 0; }")
|
629
|
+
puts "ok"
|
630
|
+
else
|
631
|
+
puts "failed"
|
632
|
+
raise "C compiler doesn't work correctly."
|
633
|
+
end
|
634
|
+
end # check_cc
|
635
|
+
|
636
|
+
def check_cc_is_gcc
|
637
|
+
# bcc defines __GNUC__. why??
|
638
|
+
return false if RUBY_PLATFORM =~ /bccwin32/
|
639
|
+
|
640
|
+
print "checking for gcc... "
|
641
|
+
STDOUT.flush
|
642
|
+
if macro_defined?("__GNUC__", "")
|
643
|
+
print "yes\n"
|
644
|
+
return true
|
645
|
+
else
|
646
|
+
print "no\n"
|
647
|
+
return false
|
648
|
+
end
|
649
|
+
end # check_cc_is_gcc
|
650
|
+
|
651
|
+
def check_lp64
|
652
|
+
print "checking for LP64... "
|
653
|
+
STDOUT.flush
|
654
|
+
if try_run("int main() { return sizeof(long) == 8 ? 0 : 1; }")
|
655
|
+
puts "yes"
|
656
|
+
true
|
657
|
+
else
|
658
|
+
puts "no"
|
659
|
+
false
|
660
|
+
end
|
661
|
+
end # check_lp64
|
662
|
+
|
663
|
+
def check_system_header
|
664
|
+
if not have_header('sys/types.h')
|
665
|
+
raise <<EOS
|
666
|
+
A standard C header file 'sys/types.h' doesn't exist.
|
667
|
+
Did you install glibc-devel(redhat) or libc6-dev(debian/ubuntu)?
|
668
|
+
EOS
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
def check_ruby_header
|
673
|
+
print "checking for ruby header... "
|
674
|
+
STDOUT.flush
|
675
|
+
rubyhdrdir = RbConfig::CONFIG["rubyhdrdir"] || RbConfig::CONFIG['archdir']
|
676
|
+
unless File.exist?(rubyhdrdir + '/ruby.h')
|
677
|
+
puts "failed"
|
678
|
+
if RUBY_PLATFORM =~ /darwin/ and File.exist?("#{RbConfig::CONFIG['archdir']}/../universal-darwin8.0/ruby.h")
|
679
|
+
raise <<EOS
|
680
|
+
#{RbConfig::CONFIG['archdir']}/ruby.h doesn't exist.
|
681
|
+
Run the following commands to fix the problem.
|
682
|
+
|
683
|
+
cd #{RbConfig::CONFIG['archdir']}
|
684
|
+
sudo ln -s ../universal-darwin8.0/* ./
|
685
|
+
EOS
|
686
|
+
else
|
687
|
+
raise <<EOS
|
688
|
+
#{RbConfig::CONFIG['archdir']}/ruby.h doesn't exist.
|
689
|
+
Install the ruby development library.
|
690
|
+
EOS
|
691
|
+
end
|
692
|
+
end
|
693
|
+
puts "ok"
|
694
|
+
$stdout.flush
|
695
|
+
end # check_ruby_header
|
696
|
+
|
697
|
+
def try_link_oci
|
698
|
+
original_libs = $libs
|
699
|
+
begin
|
700
|
+
$libs += " -L#{CONFIG['libdir']} " + @libs
|
701
|
+
#have_func("OCIEnvCreate", "aci.h")
|
702
|
+
ensure
|
703
|
+
$libs = original_libs
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
707
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw32|bccwin32/ # when Windows
|
708
|
+
|
709
|
+
def get_libs(lib_dir)
|
710
|
+
case RUBY_PLATFORM
|
711
|
+
when /cygwin/
|
712
|
+
regex = ([nil].pack('P').size == 8) ? / T (OCI\w+)/ : / T _(OCI\w+)/
|
713
|
+
oci_funcs = YAML.load(open(File.dirname(__FILE__) + '/apiwrap.yml')).keys.collect do |func|
|
714
|
+
func =~ /_nb$/ ? $` : func
|
715
|
+
end
|
716
|
+
open("ACI.def", "w") do |f|
|
717
|
+
f.puts("EXPORTS")
|
718
|
+
open("|nm #{lib_dir}/MSVC/ACI.LIB") do |r|
|
719
|
+
while line = r.gets
|
720
|
+
f.puts($1) if regex =~ line and oci_funcs.include?($1)
|
721
|
+
end
|
722
|
+
end
|
723
|
+
end
|
724
|
+
command = "dlltool -d ACI.def -D ACI.DLL -l libACI.a"
|
725
|
+
print("Running: '#{command}' ...")
|
726
|
+
STDOUT.flush
|
727
|
+
system(command)
|
728
|
+
puts("done")
|
729
|
+
"-L. -lACI"
|
730
|
+
when /bccwin32/
|
731
|
+
# replace '/' to '\\' because bcc linker misunderstands
|
732
|
+
# 'C:/foo/bar/OCI.LIB' as unknown option.
|
733
|
+
lib = "#{lib_dir}/BORLAND/ACI.LIB"
|
734
|
+
return lib.tr('/', '\\') if File.exist?(lib)
|
735
|
+
raise <<EOS
|
736
|
+
#{lib} does not exist.
|
737
|
+
|
738
|
+
Your Oracle may not support Borland C++.
|
739
|
+
If you want to run this module, run the following command at your own risk.
|
740
|
+
cd #{lib_dir.tr('/', '\\')}
|
741
|
+
mkdir Borland
|
742
|
+
cd Borland
|
743
|
+
coff2omf ..\\MSVC\\OCI.LIB OCI.LIB
|
744
|
+
EOS
|
745
|
+
exit 1
|
746
|
+
else
|
747
|
+
"\"#{lib_dir}/MSVC/ACI.LIB\""
|
748
|
+
end
|
749
|
+
end
|
750
|
+
|
751
|
+
else
|
752
|
+
# Unix
|
753
|
+
def get_libs(lib_dir)
|
754
|
+
case RUBY_PLATFORM
|
755
|
+
when /solaris/
|
756
|
+
" -L#{lib_dir} -R#{lib_dir} -laci"
|
757
|
+
when /linux/,/darwin/
|
758
|
+
" -L#{lib_dir} -Wl,-rpath,#{lib_dir} -laci"
|
759
|
+
else
|
760
|
+
" -L#{lib_dir} -laci"
|
761
|
+
end
|
762
|
+
end
|
763
|
+
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
# OraConf for Full Client
|
768
|
+
class OraConfFC < OraConf
|
769
|
+
def initialize
|
770
|
+
init
|
771
|
+
|
772
|
+
@oracle_home = get_home()
|
773
|
+
if RUBY_PLATFORM =~ /freebsd/ && @oracle_home == '/opt/ShenTong'
|
774
|
+
raise "Oralce 8i is not supported."
|
775
|
+
else
|
776
|
+
@version = get_version()
|
777
|
+
end
|
778
|
+
@cflags = get_cflags()
|
779
|
+
$CFLAGS += @cflags
|
780
|
+
|
781
|
+
if !@lp64 && File.exist?("#{@oracle_home}/lib32")
|
782
|
+
# ruby - 32bit
|
783
|
+
# oracle - 64bit
|
784
|
+
use_lib32 = true
|
785
|
+
else
|
786
|
+
use_lib32 = false
|
787
|
+
end
|
788
|
+
|
789
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw32|bccwin32/
|
790
|
+
lib_dir = "#{@oracle_home}/bin"
|
791
|
+
elsif use_lib32
|
792
|
+
lib_dir = "#{@oracle_home}/bin"
|
793
|
+
else
|
794
|
+
lib_dir = "#{@oracle_home}/bin"
|
795
|
+
end
|
796
|
+
@libs = get_libs(lib_dir)
|
797
|
+
return if try_link_oci()
|
798
|
+
|
799
|
+
raise 'cannot compile ACI'
|
800
|
+
end
|
801
|
+
|
802
|
+
private
|
803
|
+
|
804
|
+
def get_version
|
805
|
+
print("Get the version of ShenTong")
|
806
|
+
STDOUT.flush
|
807
|
+
version = nil
|
808
|
+
|
809
|
+
version = '11.2.1'
|
810
|
+
puts version
|
811
|
+
version
|
812
|
+
end # get_version
|
813
|
+
|
814
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw32|bccwin32/ # when Windows
|
815
|
+
|
816
|
+
def is_valid_home?(oracle_home)
|
817
|
+
return false if oracle_home.nil?
|
818
|
+
sqlplus = "#{oracle_home}/bin/sqlplus.exe"
|
819
|
+
print("checking for ORACLE_HOME(#{oracle_home})... ")
|
820
|
+
STDOUT.flush
|
821
|
+
if File.exist?(sqlplus)
|
822
|
+
puts("yes")
|
823
|
+
true
|
824
|
+
else
|
825
|
+
puts("no")
|
826
|
+
false
|
827
|
+
end
|
828
|
+
end
|
829
|
+
|
830
|
+
def get_home()
|
831
|
+
oracle_home = ENV['SZ_OSCAR_HOME']
|
832
|
+
if oracle_home.nil?
|
833
|
+
oracle_homes = Registry::oracle_homes.select do |home|
|
834
|
+
is_valid_home?(home.path)
|
835
|
+
end
|
836
|
+
if oracle_homes.empty?
|
837
|
+
raise <<EOS
|
838
|
+
Set the environment variable SZ_OSCAR_HOME if ShenTong Full Client.
|
839
|
+
Append the path of ShenTong client libraries to #{OraConf.ld_envs[0]} if ShenTong Instant Client.
|
840
|
+
EOS
|
841
|
+
end
|
842
|
+
if oracle_homes.length == 1
|
843
|
+
oracle_home = oracle_homes[0].path
|
844
|
+
else
|
845
|
+
default_path = ''
|
846
|
+
if RUBY_PLATFORM =~ /cygwin/
|
847
|
+
path_sep = ':'
|
848
|
+
dir_sep = '/'
|
849
|
+
else
|
850
|
+
path_sep = ';'
|
851
|
+
dir_sep = '\\'
|
852
|
+
end
|
853
|
+
ENV['PATH'].split(path_sep).each do |path|
|
854
|
+
path.chomp!(dir_sep)
|
855
|
+
if File.exist?("#{path}/aci.dll")
|
856
|
+
default_path = path
|
857
|
+
break
|
858
|
+
end
|
859
|
+
end
|
860
|
+
puts "---------------------------------------------------"
|
861
|
+
puts "Multiple Oracle Homes are found."
|
862
|
+
printf " %-15s : %s\n", "[NAME]", "[PATH]"
|
863
|
+
oracle_homes.each do |home|
|
864
|
+
if RUBY_PLATFORM =~ /cygwin/
|
865
|
+
path = `cygpath -u '#{home.path}'`.chomp!
|
866
|
+
else
|
867
|
+
path = home.path
|
868
|
+
end
|
869
|
+
if default_path.downcase == "#{path.downcase}#{dir_sep}bin"
|
870
|
+
oracle_home = home
|
871
|
+
end
|
872
|
+
printf " %-15s : %s\n", home.name, home.path
|
873
|
+
end
|
874
|
+
if oracle_home.nil?
|
875
|
+
puts "default oracle home is not found."
|
876
|
+
puts "---------------------------------------------------"
|
877
|
+
raise 'Cannot get SZ_OSCAR_HOME. Please set the environment valiable SZ_OSCAR_HOME.'
|
878
|
+
else
|
879
|
+
printf "use %s\n", oracle_home.name
|
880
|
+
puts "run ohsel.exe to use another oracle home."
|
881
|
+
puts "---------------------------------------------------"
|
882
|
+
oracle_home = oracle_home.path
|
883
|
+
end
|
884
|
+
end
|
885
|
+
end
|
886
|
+
if RUBY_PLATFORM =~ /cygwin/
|
887
|
+
oracle_home = oracle_home.sub(/^([a-zA-Z]):/, "/cygdrive/\\1")
|
888
|
+
end
|
889
|
+
oracle_home.gsub(/\\/, '/')
|
890
|
+
end
|
891
|
+
|
892
|
+
def get_cflags
|
893
|
+
unless File.exist?("#{@oracle_home}/aci/include/aci.h")
|
894
|
+
raise "'#{@oracle_home}/aci/include/aci.h' does not exists. Please install 'ShenTong Call Interface'."
|
895
|
+
end
|
896
|
+
if RUBY_PLATFORM =~ /cygwin|mingw32/
|
897
|
+
" \"-I#{@oracle_home}/aci/include\" -D_int64=\"long long\""
|
898
|
+
else
|
899
|
+
" \"-I#{@oracle_home}/aci/include\""
|
900
|
+
end
|
901
|
+
end
|
902
|
+
|
903
|
+
else # when UNIX
|
904
|
+
|
905
|
+
def get_home
|
906
|
+
oracle_home = ENV['SZ_OSCAR_HOME']
|
907
|
+
if oracle_home.nil?
|
908
|
+
msg = <<EOS
|
909
|
+
Set the environment variable SZ_OSCAR_HOME if ShenTong Full Client.
|
910
|
+
Append the path of ShenTong client libraries to #{OraConf.ld_envs[0]} if ShenTong Instant Client.
|
911
|
+
EOS
|
912
|
+
|
913
|
+
# check sudo environment
|
914
|
+
sudo_command = ENV['SUDO_COMMAND']
|
915
|
+
if /\w*make\b/ =~ sudo_command
|
916
|
+
msg += <<EOS
|
917
|
+
|
918
|
+
The 'sudo' command unset some environment variables for security reasons.
|
919
|
+
Use it only when running 'make install' as follows
|
920
|
+
make
|
921
|
+
sudo make install
|
922
|
+
EOS
|
923
|
+
end
|
924
|
+
if /\w+\/gem\b/ =~ sudo_command
|
925
|
+
msg += <<EOS
|
926
|
+
|
927
|
+
The 'sudo' command unset some environment variables for security reasons.
|
928
|
+
Pass required varialbes as follows
|
929
|
+
sudo env #{OraConf.ld_envs[0]}=$#{OraConf.ld_envs[0]} #{sudo_command}
|
930
|
+
or
|
931
|
+
sudo env ORACLE_HOME=$ORACLE_HOME #{sudo_command}
|
932
|
+
EOS
|
933
|
+
end
|
934
|
+
raise msg
|
935
|
+
end
|
936
|
+
oracle_home
|
937
|
+
end
|
938
|
+
|
939
|
+
def get_cflags
|
940
|
+
cflags = ''
|
941
|
+
ok = false
|
942
|
+
original_CFLAGS = $CFLAGS
|
943
|
+
begin
|
944
|
+
for i in ["aci/include"]
|
945
|
+
cflags += " -I#{@oracle_home}/#{i}"
|
946
|
+
$CFLAGS += " -I#{@oracle_home}/#{i}"
|
947
|
+
print("try #{cflags}\n");
|
948
|
+
ok = true
|
949
|
+
|
950
|
+
end
|
951
|
+
unless ok
|
952
|
+
if @version.to_i >= 1000
|
953
|
+
oci_h = "#{@oracle_home}/aci/include/aci.h"
|
954
|
+
else
|
955
|
+
oci_h = "#{@oracle_home}/aci/include/aci.h"
|
956
|
+
end
|
957
|
+
unless File.exist?(oci_h)
|
958
|
+
raise "'#{oci_h}' does not exists. Install 'ShenTong Call Interface' component."
|
959
|
+
end
|
960
|
+
raise 'Cannot get proper cflags.'
|
961
|
+
end
|
962
|
+
cflags
|
963
|
+
ensure
|
964
|
+
$CFLAGS = original_CFLAGS
|
965
|
+
end
|
966
|
+
end # get_cflags
|
967
|
+
|
968
|
+
end
|
969
|
+
end
|
970
|
+
|
971
|
+
# OraConf for Instant Client
|
972
|
+
class OraConfIC < OraConf
|
973
|
+
def initialize(inc_dir, lib_dir)
|
974
|
+
init
|
975
|
+
|
976
|
+
# check lib_dir
|
977
|
+
lib_dirs = lib_dir.split(File::PATH_SEPARATOR)
|
978
|
+
if RUBY_PLATFORM =~ /mswin32|mswin64|cygwin|mingw32|bccwin32/ # when Windows
|
979
|
+
ocilib = lib_dirs.find do |dir|
|
980
|
+
File.exist?("#{dir}/sdk/lib/msvc/oci.lib")
|
981
|
+
end
|
982
|
+
unless ocilib
|
983
|
+
raise <<EOS
|
984
|
+
Could not compile with Oracle instant client.
|
985
|
+
"sdk/lib/msvc/oci.lib" could not be found in: #{lib_dirs.join(' ')}
|
986
|
+
Did you install instantclient-basic?
|
987
|
+
EOS
|
988
|
+
end
|
989
|
+
@libs = get_libs("#{ocilib}/sdk/lib")
|
990
|
+
ld_path = nil
|
991
|
+
else
|
992
|
+
# set ld_path and so_ext
|
993
|
+
case RUBY_PLATFORM
|
994
|
+
when /aix/
|
995
|
+
ld_path = 'LIBPATH'
|
996
|
+
so_ext = 'a'
|
997
|
+
when /hppa.*-hpux/
|
998
|
+
if @lp64
|
999
|
+
ld_path = 'LD_LIBRARY_PATH'
|
1000
|
+
else
|
1001
|
+
ld_path = 'SHLIB_PATH'
|
1002
|
+
end
|
1003
|
+
so_ext = 'sl'
|
1004
|
+
when /darwin/
|
1005
|
+
ld_path = 'DYLD_LIBRARY_PATH'
|
1006
|
+
so_ext = 'dylib'
|
1007
|
+
else
|
1008
|
+
ld_path = 'LD_LIBRARY_PATH'
|
1009
|
+
so_ext = 'so'
|
1010
|
+
end
|
1011
|
+
# check Oracle client library.
|
1012
|
+
ocilib = lib_dirs.find do |dir|
|
1013
|
+
File.exist?("#{dir}/libaci.#{so_ext}")
|
1014
|
+
end
|
1015
|
+
unless ocilib
|
1016
|
+
files = lib_dirs.map do |dir|
|
1017
|
+
Dir.glob("#{dir}/libaci.#{so_ext}.*")
|
1018
|
+
end.flatten
|
1019
|
+
if files.empty?
|
1020
|
+
raise <<EOS
|
1021
|
+
Could not compile with Oracle instant client.
|
1022
|
+
"libaci.#{so_ext}" could not be found in: #{lib_dirs.join(' ')}
|
1023
|
+
Did you install instantclient-basic?
|
1024
|
+
EOS
|
1025
|
+
else
|
1026
|
+
file = files.sort[-1]
|
1027
|
+
raise <<EOS
|
1028
|
+
Could not compile with Oracle instant client.
|
1029
|
+
"libaci.#{so_ext}" could not be found in: #{lib_dirs.join(' ')}
|
1030
|
+
You may need to make a symbolic link.
|
1031
|
+
cd #{File.dirname(file)}
|
1032
|
+
ln -s #{File.basename(file)} libaci.#{so_ext}
|
1033
|
+
EOS
|
1034
|
+
end
|
1035
|
+
raise 'failed'
|
1036
|
+
end
|
1037
|
+
@libs = get_libs(lib_dir)
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
# check inc_dir
|
1041
|
+
inc_dirs = inc_dir.split(File::PATH_SEPARATOR)
|
1042
|
+
ociinc = inc_dirs.find do |dir|
|
1043
|
+
File.exists?("#{dir}/aci.h")
|
1044
|
+
end
|
1045
|
+
unless ociinc
|
1046
|
+
raise <<EOS
|
1047
|
+
"aci.h" could not be found in: #{inc_dirs.join(' ')}
|
1048
|
+
Install 'Instant Client SDK'.
|
1049
|
+
EOS
|
1050
|
+
end
|
1051
|
+
if ociinc.include?(' ')
|
1052
|
+
@cflags = " \"-I#{ociinc}\""
|
1053
|
+
else
|
1054
|
+
@cflags = " -I#{ociinc}"
|
1055
|
+
end
|
1056
|
+
@cflags += " -D_int64=\"long long\"" if RUBY_PLATFORM =~ /cygwin|mingw32/
|
1057
|
+
|
1058
|
+
# check link
|
1059
|
+
$CFLAGS += @cflags
|
1060
|
+
if try_link_oci()
|
1061
|
+
major = try_constant("ACI_MAJOR_VERSION", "aci.h")
|
1062
|
+
minor = try_constant("ACI_MINOR_VERSION", "aci.h")
|
1063
|
+
if major and minor
|
1064
|
+
@version = format('%d%d0', major, minor)
|
1065
|
+
else
|
1066
|
+
# 10.1.0 doesn't have ACI_MAJOR_VERSION and ACI_MINOR_VERSION in aci.h.
|
1067
|
+
@version = "1010"
|
1068
|
+
if RUBY_PLATFORM =~ /darwin/ and 1.size == 8 and `sw_vers -productVersion`.chomp == "10.7"
|
1069
|
+
$stderr.print <<EOS
|
1070
|
+
WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN!
|
1071
|
+
|
1072
|
+
64-bit Oracle instant client doesn't work on OS X Lion.
|
1073
|
+
See: https://forums.oracle.com/forums/thread.jspa?threadID=2187558
|
1074
|
+
|
1075
|
+
The compilation is continued because the issue may be fixed in future.
|
1076
|
+
|
1077
|
+
WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN! WARN!
|
1078
|
+
EOS
|
1079
|
+
end
|
1080
|
+
end
|
1081
|
+
return
|
1082
|
+
end
|
1083
|
+
|
1084
|
+
if RUBY_PLATFORM =~ /darwin/
|
1085
|
+
open('mkmf.log', 'r') do |f|
|
1086
|
+
while line = f.gets
|
1087
|
+
if line.include? '/libaci.dylib load command 8 unknown cmd field'
|
1088
|
+
raise <<EOS
|
1089
|
+
Intel mac instant client is for Mac OS X 10.5.
|
1090
|
+
It doesn't work on Mac OS X 10.4 or before.
|
1091
|
+
|
1092
|
+
You have three workarounds.
|
1093
|
+
1. Compile ruby as ppc binary and use it with ppc instant client.
|
1094
|
+
2. Use JRuby and JDBC
|
1095
|
+
3. Use a third-party ODBC driver and ruby-odbc.
|
1096
|
+
EOS
|
1097
|
+
# '
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
case line
|
1101
|
+
when /cputype \(\d+, architecture \w+\) does not match cputype \(\d+\) for specified -arch flag: (\w+)/
|
1102
|
+
missing_arch = $1
|
1103
|
+
when /Undefined symbols for architecture (\w+)/
|
1104
|
+
missing_arch = $1
|
1105
|
+
when /missing required architecture (\w+) in file/
|
1106
|
+
missing_arch = $1
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
if missing_arch
|
1110
|
+
if [nil].pack('p').size == 8
|
1111
|
+
my_arch = 'x86_64'
|
1112
|
+
elsif "\x01\x02".unpack('s')[0] == 0x0201
|
1113
|
+
my_arch = 'i386'
|
1114
|
+
else
|
1115
|
+
my_arch = 'ppc'
|
1116
|
+
end
|
1117
|
+
raise <<EOS
|
1118
|
+
Could not compile with Oracle instant client.
|
1119
|
+
You may need to set the environment variable RC_ARCHS or ARCHFLAGS as follows:
|
1120
|
+
|
1121
|
+
RC_ARCHS=#{my_arch}
|
1122
|
+
export RC_ARCHS
|
1123
|
+
or
|
1124
|
+
ARCHFLAGS='-arch #{my_arch}'
|
1125
|
+
export RC_ARCHS
|
1126
|
+
|
1127
|
+
If it does not fix the problem, delete all '-arch #{missing_arch}'
|
1128
|
+
in '#{RbConfig::CONFIG['archdir']}/rbconfig.rb'.
|
1129
|
+
EOS
|
1130
|
+
end
|
1131
|
+
end
|
1132
|
+
end
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
unless ld_path.nil?
|
1136
|
+
raise <<EOS
|
1137
|
+
Could not compile with Oracle instant client.
|
1138
|
+
You may need to set a environment variable:
|
1139
|
+
#{ld_path}=#{lib_dir}
|
1140
|
+
export #{ld_path}
|
1141
|
+
EOS
|
1142
|
+
end
|
1143
|
+
raise 'failed'
|
1144
|
+
end
|
1145
|
+
end
|