tiny_tds 1.3.0 → 2.0.0.pre1
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 +4 -4
- data/.travis.yml +2 -5
- data/BACKERS.md +32 -0
- data/Gemfile +4 -1
- data/README.md +23 -32
- data/Rakefile +26 -83
- data/VERSION +1 -1
- data/appveyor.yml +7 -4
- data/circle.yml +2 -4
- data/ext/tiny_tds/extconf.rb +33 -336
- data/lib/tiny_tds/bin.rb +38 -19
- data/lib/tiny_tds/gem.rb +32 -0
- data/lib/tiny_tds.rb +9 -4
- data/{ports/patches → patches}/freetds/1.00.27/0001-mingw_missing_inet_pton.diff +0 -0
- data/patches/libiconv/1.14/1-avoid-gets-error.patch +17 -0
- data/tasks/native_gem.rake +14 -0
- data/tasks/package.rake +8 -0
- data/tasks/ports/freetds.rb +37 -0
- data/tasks/ports/libiconv.rb +43 -0
- data/tasks/ports/openssl.rb +75 -0
- data/tasks/ports/recipe.rb +52 -0
- data/tasks/ports.rake +84 -0
- data/tasks/test.rake +9 -0
- data/test/bin/install-openssl.sh +2 -2
- data/test/bin/setup.sh +1 -1
- data/test/gem_test.rb +179 -0
- data/test/result_test.rb +2 -2
- metadata +19 -5
data/ext/tiny_tds/extconf.rb
CHANGED
@@ -3,366 +3,63 @@ ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
|
|
3
3
|
# :stopdoc:
|
4
4
|
|
5
5
|
require 'mkmf'
|
6
|
-
require '
|
7
|
-
|
8
|
-
# The gem version constraint in the gemspec is not respected at install time.
|
9
|
-
# Keep this version in sync with the one in the gemspec !
|
10
|
-
gem 'mini_portile2', '~> 2.0'
|
11
|
-
require 'mini_portile2'
|
6
|
+
require 'rbconfig'
|
12
7
|
require_relative './extconsts'
|
13
8
|
|
14
|
-
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
15
|
-
|
16
9
|
# Shamelessly copied from nokogiri
|
17
10
|
#
|
18
11
|
|
19
12
|
def do_help
|
20
13
|
print <<HELP
|
21
14
|
usage: ruby #{$0} [options]
|
22
|
-
|
23
|
-
--enable-system-freetds / --disable-system-freetds
|
24
|
-
--enable-system-iconv / --disable-system-iconv
|
25
|
-
--enable-system-openssl / --disable-system-openssl
|
26
|
-
Force use of system or builtin freetds/iconv/openssl library.
|
27
|
-
Default is to prefer system libraries and fallback to builtin.
|
28
|
-
|
29
15
|
--with-freetds-dir=DIR
|
30
16
|
Use the freetds library placed under DIR.
|
31
|
-
|
32
|
-
--enable-lookup
|
33
|
-
Search for freetds through all paths in the PATH environment variable.
|
34
|
-
|
35
|
-
--disable-openssl
|
36
|
-
Disable OpenSSL for freetds build. No effect on system-freetds.
|
37
|
-
|
38
|
-
--enable-gnutls
|
39
|
-
Use GnuTLS instead of OpenSSL for freetds build.
|
40
|
-
|
41
|
-
--enable-cross-build
|
42
|
-
Do cross-build.
|
43
17
|
HELP
|
44
18
|
exit! 0
|
45
19
|
end
|
46
20
|
|
47
21
|
do_help if arg_config('--help')
|
48
22
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
23
|
+
# Make sure to check the ports path for the configured host
|
24
|
+
host = RbConfig::CONFIG['host']
|
25
|
+
project_dir = File.join(['..']*4)
|
26
|
+
freetds_dir = File.join(project_dir, 'ports', host, 'freetds', FREETDS_VERSION)
|
27
|
+
freetds_dir = File.expand_path(freetds_dir)
|
28
|
+
|
29
|
+
# Add all the special path searching from the original tiny_tds build
|
30
|
+
# order is important here! First in, last searched.
|
31
|
+
%w(
|
32
|
+
/usr/local
|
33
|
+
/opt/local
|
34
|
+
).each do |path|
|
35
|
+
idir = "#{path}/include"
|
36
|
+
ldir = "#{path}/lib"
|
37
|
+
|
38
|
+
dir_config('freetds',
|
39
|
+
[idir, "#{idir}/freetds"],
|
40
|
+
[ldir, "#{ldir}/freetds"]
|
41
|
+
)
|
58
42
|
end
|
59
43
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
SEARCHABLE_PATHS = begin
|
65
|
-
eop_regexp = /#{File::SEPARATOR}bin$/
|
66
|
-
paths = ENV['PATH']
|
67
|
-
paths = paths.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
|
68
|
-
paths = paths.split(File::PATH_SEPARATOR)
|
69
|
-
bin_paths = paths.select{ |p| p =~ eop_regexp }
|
70
|
-
bin_paths.map{ |p| p.sub(eop_regexp,'') }.compact.reject{ |p| p.empty? }.uniq
|
44
|
+
# Add the ports directory if it exists for local developer builds
|
45
|
+
if File.directory?(freetds_dir)
|
46
|
+
puts "Using freetds port path #{freetds_dir}"
|
47
|
+
dir_config('freetds', "#{freetds_dir}/include", "#{freetds_dir}/lib")
|
71
48
|
end
|
72
49
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
50
|
+
have_dependencies = [
|
51
|
+
find_header('sybfront.h'),
|
52
|
+
find_header('sybdb.h'),
|
53
|
+
find_library('sybdb', 'tdsdbopen'),
|
54
|
+
find_library('sybdb', 'dbanydatecrack')
|
55
|
+
].inject(true) do |memo, current|
|
56
|
+
memo && current
|
80
57
|
end
|
81
58
|
|
82
|
-
|
83
|
-
|
84
|
-
super(name, version)
|
85
|
-
self.files = files
|
86
|
-
self.target = File.expand_path('../../../ports', __FILE__)
|
87
|
-
self.host = consolidated_host(RbConfig::CONFIG["host"])
|
88
|
-
self.patch_files = Dir[File.join(self.target, "patches", self.name, self.version, "*.diff")].sort
|
89
|
-
end
|
90
|
-
|
91
|
-
def consolidated_host(name)
|
92
|
-
# Host name and prefix of build tools are different on Windows 32 bit.
|
93
|
-
name.gsub('i686-pc-mingw32', 'i686-w64-mingw32')
|
94
|
-
end
|
95
|
-
|
96
|
-
def configure_defaults
|
97
|
-
[
|
98
|
-
"--host=#{host}", # build for specific target (host)
|
99
|
-
"--disable-static",
|
100
|
-
"--enable-shared",
|
101
|
-
]
|
102
|
-
end
|
103
|
-
|
104
|
-
# Use the same path for all recipes, so that only one include/lib path is required.
|
105
|
-
def port_path
|
106
|
-
"#{target}/#{host}"
|
107
|
-
end
|
108
|
-
|
109
|
-
# We use the same port_path for all recipes. That breaks the standard installed? method.
|
110
|
-
def installed?
|
111
|
-
false
|
112
|
-
end
|
113
|
-
|
114
|
-
# When using rake-compiler-dock on Windows, the underlying Virtualbox shared
|
115
|
-
# folders don't support symlinks, but libiconv expects it for a build on
|
116
|
-
# Linux. We work around this limitation by using the temp dir for cooking.
|
117
|
-
def chdir_for_build
|
118
|
-
build_dir = ENV['RCD_HOST_RUBY_PLATFORM'].to_s =~ /mingw|mswin|cygwin/ ? '/tmp' : '.'
|
119
|
-
Dir.chdir(build_dir) do
|
120
|
-
yield
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def cook_and_activate
|
125
|
-
checkpoint = File.join(self.target, "#{self.name}-#{self.version}-#{self.host}.installed")
|
126
|
-
unless File.exist?(checkpoint)
|
127
|
-
chdir_for_build do
|
128
|
-
self.cook
|
129
|
-
end
|
130
|
-
FileUtils.touch checkpoint
|
131
|
-
end
|
132
|
-
self.activate
|
133
|
-
self
|
134
|
-
end
|
59
|
+
unless have_dependencies
|
60
|
+
abort 'Failed! Do you have FreeTDS 0.95.80 or higher installed?'
|
135
61
|
end
|
136
62
|
|
137
|
-
def define_libssl_recipe(host)
|
138
|
-
BuildRecipe.new("openssl", OPENSSL_VERSION, [OPENSSL_SOURCE_URI]).tap do |recipe|
|
139
|
-
class << recipe
|
140
|
-
def extract_file(file, target)
|
141
|
-
filename = File.basename(file)
|
142
|
-
FileUtils.mkdir_p target
|
143
|
-
|
144
|
-
message "Extracting #{filename} into #{target}... "
|
145
|
-
result = `#{tar_exe} #{tar_compression_switch(filename)}xf "#{file}" -C "#{target}" 2>&1`
|
146
|
-
if $?.success?
|
147
|
-
output "OK"
|
148
|
-
else
|
149
|
-
# tar on windows returns error exit code, because it can not extract symlinks
|
150
|
-
output "ERROR (ignored)"
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def execute(action, command, options={})
|
155
|
-
prev_path = ENV['PATH']
|
156
|
-
if host=~/mingw/
|
157
|
-
git_perl = 'C:/Program Files/Git/usr/bin'
|
158
|
-
if File.directory?(git_perl)
|
159
|
-
ENV['PATH'] = git_perl + ';' + ENV['PATH']
|
160
|
-
ENV['PERL'] = 'perl'
|
161
|
-
end
|
162
|
-
end
|
163
|
-
super
|
164
|
-
ENV['PATH'] = prev_path
|
165
|
-
end
|
166
|
-
|
167
|
-
def configure
|
168
|
-
config = if host=~/mingw/
|
169
|
-
host=~/x86_64/ ? 'mingw64' : 'mingw'
|
170
|
-
end
|
171
|
-
args = [ "CFLAGS=-DDSO_WIN32",
|
172
|
-
"./Configure",
|
173
|
-
"no-shared",
|
174
|
-
configure_prefix,
|
175
|
-
config,
|
176
|
-
]
|
177
|
-
args.unshift("CROSS_COMPILE=#{host}-") if enable_config("cross-build")
|
178
|
-
|
179
|
-
execute "configure", "sh -c \"#{args.join(" ")}\""
|
180
|
-
end
|
181
|
-
|
182
|
-
def dllwrap(dllname, outputlib, deffile, linkto)
|
183
|
-
gcc = consolidated_host(RbConfig::CONFIG["CC"])
|
184
|
-
|
185
|
-
#RbConfig does not provide dlltool, but it should exist where dllwrap lives
|
186
|
-
dlltool = consolidated_host(RbConfig::CONFIG["DLLWRAP"]).sub('dllwrap','dlltool')
|
187
|
-
|
188
|
-
execute "gcc-#{dllname}-compile", "#{gcc} -Wl,--base-file,#{dllname}.base -mdll -o #{dllname}.dll --leading-underscore #{linkto}"
|
189
|
-
execute "dlltool-#{dllname}-exp", "#{dlltool} --base-file #{dllname}.base --output-exp #{dllname}.exp --dllname #{dllname}.dll --def #{deffile}"
|
190
|
-
execute "gcc-#{dllname}-dll", "#{gcc} -Wl,--base-file,#{dllname}.base #{dllname}.exp -mdll -o #{dllname}.dll --leading-underscore #{linkto}"
|
191
|
-
execute "dlltool-#{dllname}-outputlib", "#{dlltool} --base-file #{dllname}.base --output-exp #{dllname}.exp --dllname #{dllname}.dll --def #{deffile} --output-lib #{outputlib}"
|
192
|
-
execute "gcc-#{dllname}-link", "#{gcc} #{dllname}.exp -mdll -o #{dllname}.dll --leading-underscore #{linkto}"
|
193
|
-
end
|
194
|
-
|
195
|
-
def compile
|
196
|
-
super
|
197
|
-
# OpenSSL DLLs are called "libcrypto32.dll" and "libssl32.dll" per default,
|
198
|
-
# regardless to the version. This is best suited to meet the Windows DLL hell.
|
199
|
-
# To avoid any conflicts we do a static build and build DLLs afterwards,
|
200
|
-
# with our own naming scheme.
|
201
|
-
execute "mkdef-crypto32", "(perl util/mkdef.pl crypto 32 >libcrypto32.def)"
|
202
|
-
execute "mkdef-ssl32", "(perl util/mkdef.pl ssl 32 >libssl32.def)"
|
203
|
-
dllwrap("libcrypto32-#{version}-#{host}", "libcrypto.dll.a", "libcrypto32.def", "libcrypto.a -lws2_32 -lgdi32 -lcrypt32")
|
204
|
-
dllwrap("libssl32-#{version}-#{host}", "libssl.dll.a", "libssl32.def", "libssl.a libcrypto.dll.a")
|
205
|
-
end
|
206
|
-
|
207
|
-
def install
|
208
|
-
unless installed?
|
209
|
-
execute('install', %Q(#{make_cmd} install_sw install_ssldirs))
|
210
|
-
end
|
211
|
-
FileUtils.cp "#{work_path}/libcrypto32-#{version}-#{host}.dll", "#{path}/bin/"
|
212
|
-
FileUtils.cp "#{work_path}/libssl32-#{version}-#{host}.dll", "#{path}/bin/"
|
213
|
-
FileUtils.cp "#{work_path}/libcrypto.dll.a", "#{path}/lib/"
|
214
|
-
FileUtils.cp "#{work_path}/libssl.dll.a", "#{path}/lib/"
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def define_libiconv_recipe(host)
|
221
|
-
BuildRecipe.new("libiconv", ICONV_VERSION, [ICONV_SOURCE_URI]).tap do |recipe|
|
222
|
-
# always produce position independent code
|
223
|
-
# and set an explicit optimization to avoid inline functions being optimized
|
224
|
-
# out of libiconv
|
225
|
-
recipe.configure_options << "CFLAGS=-fPIC -O2"
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def define_freetds_recipe(host, libiconv, libssl, gnutls)
|
230
|
-
BuildRecipe.new("freetds", FREETDS_VERSION, [FREETDS_SOURCE_URI]).tap do |recipe|
|
231
|
-
with_tdsver = FREETDS_VERSION =~ /0\.91/ ? "--with-tdsver=7.1" : "--with-tdsver=7.3"
|
232
|
-
for_windows = recipe.host =~ /mswin|mingw/i
|
233
|
-
recipe.configure_options << '--with-pic'
|
234
|
-
recipe.configure_options << "--with-libiconv-prefix=#{libiconv.path}" if libiconv
|
235
|
-
if true == libssl
|
236
|
-
recipe.configure_options << "--with-openssl"
|
237
|
-
elsif libssl
|
238
|
-
recipe.configure_options << "--with-openssl=#{libssl.path}"
|
239
|
-
end
|
240
|
-
recipe.configure_options << "--with-gnutls" if gnutls
|
241
|
-
recipe.configure_options << '--sysconfdir=C:\Sites' if for_windows
|
242
|
-
recipe.configure_options << '--enable-sspi' if for_windows
|
243
|
-
recipe.configure_options << "--disable-odbc"
|
244
|
-
recipe.configure_options << with_tdsver
|
245
|
-
if libiconv
|
246
|
-
# For some reason freetds doesn't honor --with-libiconv-prefix
|
247
|
-
# so we have do add it by hand:
|
248
|
-
recipe.configure_options << "CFLAGS=-I#{libiconv.path}/include"
|
249
|
-
recipe.configure_options << "LDFLAGS=-L#{libiconv.path}/lib -liconv"
|
250
|
-
end
|
251
|
-
|
252
|
-
class << recipe
|
253
|
-
|
254
|
-
def configure
|
255
|
-
cross = enable_config("cross-build")
|
256
|
-
if cross
|
257
|
-
prev_cc = ENV['CC']
|
258
|
-
ENV['CC'] = consolidated_host(gcc_cmd) + ' -static-libgcc'
|
259
|
-
end
|
260
|
-
super
|
261
|
-
ENV['CC'] = prev_cc if cross
|
262
|
-
end
|
263
|
-
|
264
|
-
def install
|
265
|
-
super_value = super
|
266
|
-
# Install binstub target binaries.
|
267
|
-
if super_value
|
268
|
-
bin_path = File.expand_path File.join(path, 'bin')
|
269
|
-
exe_path = File.expand_path File.join(target, '..', 'exe')
|
270
|
-
return unless File.directory?(bin_path)
|
271
|
-
['tsql', 'defncopy'].each do |bin|
|
272
|
-
['.exe', ''].each do |ext|
|
273
|
-
exe = File.join bin_path, "#{bin}#{ext}"
|
274
|
-
next unless File.exists?(exe)
|
275
|
-
next unless File.executable?(exe)
|
276
|
-
FileUtils.cp exe, exe_path
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|
280
|
-
super_value
|
281
|
-
end
|
282
|
-
|
283
|
-
end
|
284
|
-
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
if RbConfig::CONFIG['target_os'] =~ /mswin32|mingw32/
|
289
|
-
lib_prefix = 'lib' unless RbConfig::CONFIG['target_os'] =~ /mingw32/
|
290
|
-
# There's no default include/lib dir on Windows. Let's just add the Ruby ones
|
291
|
-
# and resort on the search path specified by INCLUDE and LIB environment
|
292
|
-
# variables
|
293
|
-
HEADER_DIRS = [INCLUDEDIR]
|
294
|
-
LIB_DIRS = [LIBDIR]
|
295
|
-
else
|
296
|
-
lib_prefix = ''
|
297
|
-
HEADER_DIRS = [
|
298
|
-
# First search /opt/local for macports
|
299
|
-
'/opt/local/include',
|
300
|
-
# Then search /usr/local for people that installed from source
|
301
|
-
'/usr/local/include',
|
302
|
-
# Check the ruby install locations
|
303
|
-
INCLUDEDIR,
|
304
|
-
# Finally fall back to /usr
|
305
|
-
'/usr/include'
|
306
|
-
].reject{ |dir| !File.directory?(dir) }
|
307
|
-
LIB_DIRS = [
|
308
|
-
# First search /opt/local for macports
|
309
|
-
'/opt/local/lib',
|
310
|
-
# Then search /usr/local for people that installed from source
|
311
|
-
'/usr/local/lib',
|
312
|
-
# Check the ruby install locations
|
313
|
-
LIBDIR,
|
314
|
-
# Finally fall back to /usr
|
315
|
-
'/usr/lib',
|
316
|
-
].reject{ |dir| !File.directory?(dir) }
|
317
|
-
end
|
318
|
-
|
319
|
-
FREETDS_HEADER_DIRS = (searchable_paths_with_directories(['include'],['include','freetds']) + HEADER_DIRS).uniq
|
320
|
-
FREETDS_LIB_DIRS = (searchable_paths_with_directories(['lib'],['lib','freetds']) + LIB_DIRS).uniq
|
321
|
-
|
322
|
-
# lookup over searchable paths is great for native compilation, however, when
|
323
|
-
# cross compiling we need to specify our own paths.
|
324
|
-
if enable_config("lookup", true)
|
325
|
-
dir_config('freetds', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS)
|
326
|
-
else
|
327
|
-
dir_config('freetds')
|
328
|
-
|
329
|
-
# remove LDFLAGS
|
330
|
-
$LDFLAGS = ENV.fetch("LDFLAGS", "")
|
331
|
-
end
|
332
|
-
|
333
|
-
def asplode(lib)
|
334
|
-
msg = "-----\n"
|
335
|
-
msg << "#{lib} is missing.\n"
|
336
|
-
msg << "Do you have FreeTDS 0.95.80 or higher installed?\n" if lib == 'freetds'
|
337
|
-
msg << "-----"
|
338
|
-
abort(msg)
|
339
|
-
end
|
340
|
-
|
341
|
-
def freetds_usable?(lib_prefix)
|
342
|
-
have_header('sybfront.h') && have_header('sybdb.h') &&
|
343
|
-
find_library("#{lib_prefix}sybdb", 'tdsdbopen') &&
|
344
|
-
find_library("#{lib_prefix}sybdb", 'dbanydatecrack')
|
345
|
-
end
|
346
|
-
|
347
|
-
# We use freetds, when available already, and fallback to compilation of ports
|
348
|
-
system_freetds = enable_config('system-freetds', ENV['TINYTDS_SKIP_PORTS'] || freetds_usable?(lib_prefix))
|
349
|
-
|
350
|
-
# We expect to have iconv and OpenSSL available on non-Windows systems
|
351
|
-
host = RbConfig::CONFIG["host"]
|
352
|
-
system_iconv = enable_config('system-iconv', host =~ /mingw|mswin/ ? false : true)
|
353
|
-
system_openssl = enable_config('system-openssl', host =~ /mingw|mswin/ ? false : true )
|
354
|
-
enable_gnutls = enable_config('gnutls', false )
|
355
|
-
enable_openssl = enable_config('openssl', !enable_gnutls )
|
356
|
-
|
357
|
-
unless system_freetds
|
358
|
-
libssl = define_libssl_recipe(host).cook_and_activate unless system_openssl
|
359
|
-
libiconv = define_libiconv_recipe(host).cook_and_activate unless system_iconv
|
360
|
-
freetds = define_freetds_recipe(host, libiconv, libssl || enable_openssl, enable_gnutls).cook_and_activate
|
361
|
-
dir_config('freetds', freetds.path + "/include", freetds.path + "/lib")
|
362
|
-
end
|
363
|
-
|
364
|
-
asplode 'freetds' unless freetds_usable?(lib_prefix)
|
365
|
-
|
366
63
|
create_makefile('tiny_tds/tiny_tds')
|
367
64
|
|
368
65
|
# :startdoc:
|
data/lib/tiny_tds/bin.rb
CHANGED
@@ -1,40 +1,39 @@
|
|
1
1
|
require_relative './version'
|
2
|
+
require_relative './gem'
|
2
3
|
require 'shellwords'
|
3
4
|
|
4
5
|
module TinyTds
|
5
6
|
class Bin
|
6
7
|
|
7
|
-
ROOT = File.expand_path '../../..', __FILE__
|
8
|
-
PATHS = ENV['PATH'].split File::PATH_SEPARATOR
|
9
|
-
EXTS = (ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']) | ['.exe']
|
10
|
-
|
11
8
|
attr_reader :name
|
12
9
|
|
13
10
|
class << self
|
14
|
-
|
15
11
|
def exe(name, *args)
|
16
12
|
bin = new(name)
|
17
13
|
puts bin.info unless args.any? { |x| x == '-q' }
|
18
14
|
bin.run(*args)
|
19
15
|
end
|
20
|
-
|
21
16
|
end
|
22
17
|
|
23
18
|
def initialize(name)
|
19
|
+
@root = Gem.root_path
|
20
|
+
@exts = (ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']) | ['.exe']
|
21
|
+
|
24
22
|
@name = name
|
25
23
|
@binstub = find_bin
|
26
24
|
@exefile = find_exe
|
27
25
|
end
|
28
26
|
|
29
27
|
def run(*args)
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
with_ports_paths do
|
29
|
+
return nil unless path
|
30
|
+
Kernel.system Shellwords.join(args.unshift(path))
|
31
|
+
$CHILD_STATUS.to_i
|
32
|
+
end
|
33
33
|
end
|
34
34
|
|
35
35
|
def path
|
36
|
-
|
37
|
-
@path = @exefile && File.exist?(@exefile) ? @exefile : which
|
36
|
+
@path ||= @exefile && File.exist?(@exefile) ? @exefile : which
|
38
37
|
end
|
39
38
|
|
40
39
|
def info
|
@@ -43,22 +42,43 @@ module TinyTds
|
|
43
42
|
|
44
43
|
private
|
45
44
|
|
45
|
+
def search_paths
|
46
|
+
ENV['PATH'].split File::PATH_SEPARATOR
|
47
|
+
end
|
48
|
+
|
49
|
+
def with_ports_paths
|
50
|
+
old_path = ENV['PATH']
|
51
|
+
|
52
|
+
begin
|
53
|
+
ENV['PATH'] = [
|
54
|
+
Gem.ports_bin_paths,
|
55
|
+
old_path
|
56
|
+
].flatten.join File::PATH_SEPARATOR
|
57
|
+
|
58
|
+
yield if block_given?
|
59
|
+
ensure
|
60
|
+
ENV['PATH'] = old_path
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
46
64
|
def find_bin
|
47
|
-
File.join
|
65
|
+
File.join @root, 'bin', name
|
48
66
|
end
|
49
67
|
|
50
68
|
def find_exe
|
51
|
-
|
52
|
-
|
53
|
-
|
69
|
+
Gem.ports_bin_paths.each do |bin|
|
70
|
+
@exts.each do |ext|
|
71
|
+
f = File.join bin, "#{name}#{ext}"
|
72
|
+
return f if File.exist?(f)
|
73
|
+
end
|
54
74
|
end
|
55
75
|
nil
|
56
76
|
end
|
57
77
|
|
58
78
|
def which
|
59
|
-
|
60
|
-
|
61
|
-
exe = File.expand_path File.join(path, "#{name}#{ext}"),
|
79
|
+
search_paths.each do |path|
|
80
|
+
@exts.each do |ext|
|
81
|
+
exe = File.expand_path File.join(path, "#{name}#{ext}"), @root
|
62
82
|
next if exe == @binstub
|
63
83
|
next unless File.executable?(exe)
|
64
84
|
next unless binary?(exe)
|
@@ -80,6 +100,5 @@ module TinyTds
|
|
80
100
|
s = s.encode('US-ASCII', undef: :replace).split(//)
|
81
101
|
((s.size - s.grep(' '..'~').size) / s.size.to_f) > 0.30
|
82
102
|
end
|
83
|
-
|
84
103
|
end
|
85
104
|
end
|
data/lib/tiny_tds/gem.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module TinyTds
|
4
|
+
module Gem
|
5
|
+
class << self
|
6
|
+
def root_path
|
7
|
+
File.expand_path '../../..', __FILE__
|
8
|
+
end
|
9
|
+
|
10
|
+
def ports_root_path
|
11
|
+
File.join(root_path,'ports')
|
12
|
+
end
|
13
|
+
|
14
|
+
def ports_bin_paths
|
15
|
+
Dir.glob(File.join(ports_root_path,ports_host,'**','bin'))
|
16
|
+
end
|
17
|
+
|
18
|
+
def ports_lib_paths
|
19
|
+
Dir.glob(File.join(ports_root_path,ports_host,'**','lib'))
|
20
|
+
end
|
21
|
+
|
22
|
+
def ports_host
|
23
|
+
h = RbConfig::CONFIG['host']
|
24
|
+
|
25
|
+
# Our fat binary builds with a i686-w64-mingw32 toolchain
|
26
|
+
# but ruby for windows x32-mingw32 reports i686-pc-mingw32
|
27
|
+
# so correct the host here
|
28
|
+
h.gsub('i686-pc-mingw32', 'i686-w64-mingw32')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/tiny_tds.rb
CHANGED
@@ -7,6 +7,7 @@ require 'tiny_tds/version'
|
|
7
7
|
require 'tiny_tds/error'
|
8
8
|
require 'tiny_tds/client'
|
9
9
|
require 'tiny_tds/result'
|
10
|
+
require 'tiny_tds/gem'
|
10
11
|
|
11
12
|
# Support multiple ruby versions, fat binaries under Windows.
|
12
13
|
if RUBY_PLATFORM =~ /mingw|mswin/ && RUBY_VERSION =~ /(\d+.\d+)/
|
@@ -14,9 +15,12 @@ if RUBY_PLATFORM =~ /mingw|mswin/ && RUBY_VERSION =~ /(\d+.\d+)/
|
|
14
15
|
# Set the PATH environment variable, so that the DLLs can be found.
|
15
16
|
old_path = ENV['PATH']
|
16
17
|
begin
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
ENV['PATH'] = [
|
19
|
+
TinyTds::Gem.ports_bin_paths,
|
20
|
+
TinyTds::Gem.ports_lib_paths,
|
21
|
+
old_path
|
22
|
+
].flatten.join File::PATH_SEPARATOR
|
23
|
+
|
20
24
|
require "tiny_tds/#{ver}/tiny_tds"
|
21
25
|
rescue LoadError
|
22
26
|
require 'tiny_tds/tiny_tds'
|
@@ -27,7 +31,8 @@ else
|
|
27
31
|
# Load dependent shared libraries into the process, so that they are already present,
|
28
32
|
# when tiny_tds.so is loaded. This ensures, that shared libraries are loaded even when
|
29
33
|
# the path is different between build and run time (e.g. Heroku).
|
30
|
-
ports_libs = File.
|
34
|
+
ports_libs = File.join(TinyTds::Gem.ports_root_path,
|
35
|
+
"#{RbConfig::CONFIG['host']}/lib/*.so")
|
31
36
|
Dir[ports_libs].each do |lib|
|
32
37
|
require 'fiddle'
|
33
38
|
Fiddle.dlopen(lib)
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
--- a/srclib/stdio.in.h 2017-01-22 01:23:00.000000000 -0400
|
2
|
+
+++ b/srclib/stdio.in.h 2017-01-22 01:24:00.000000000 -0400
|
3
|
+
@@ -695,8 +695,14 @@
|
4
|
+
/* It is very rare that the developer ever has full control of stdin,
|
5
|
+
so any use of gets warrants an unconditional warning. Assume it is
|
6
|
+
always declared, since it is required by C89. */
|
7
|
+
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
|
8
|
+
+# ifdef __GLIBC_PREREQ
|
9
|
+
+# if !__GLIBC_PREREQ(2, 16)
|
10
|
+
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
|
11
|
+
+# endif
|
12
|
+
+# endif
|
13
|
+
+#endif
|
14
|
+
#endif
|
15
|
+
|
16
|
+
|
17
|
+
#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
desc 'Build the windows binary gems per rake-compiler-dock'
|
4
|
+
task 'gem:windows' => ['ports:cross'] do
|
5
|
+
require 'rake_compiler_dock'
|
6
|
+
|
7
|
+
# make sure to install our bundle
|
8
|
+
build = ['bundle']
|
9
|
+
|
10
|
+
# and finally build the native gem
|
11
|
+
build << 'rake cross native gem RUBY_CC_VERSION=2.4.0:2.3.0:2.2.2:2.1.6:2.0.0 CFLAGS="-Wall"'
|
12
|
+
|
13
|
+
RakeCompilerDock.sh build.join(' && ')
|
14
|
+
end
|
data/tasks/package.rake
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative './recipe'
|
2
|
+
|
3
|
+
module Ports
|
4
|
+
class Freetds < Recipe
|
5
|
+
def initialize(version)
|
6
|
+
super('freetds', version)
|
7
|
+
|
8
|
+
set_patches
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def configure_defaults
|
14
|
+
opts = super
|
15
|
+
|
16
|
+
opts << '--with-pic'
|
17
|
+
opts << '--disable-odbc'
|
18
|
+
|
19
|
+
if version =~ /0\.91/
|
20
|
+
opts << '--with-tdsver=7.1'
|
21
|
+
else
|
22
|
+
opts << '--with-tdsver=7.3'
|
23
|
+
end
|
24
|
+
|
25
|
+
if windows?
|
26
|
+
opts << '--sysconfdir=C:\Sites'
|
27
|
+
opts << '--enable-sspi'
|
28
|
+
end
|
29
|
+
|
30
|
+
opts
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_patches
|
34
|
+
self.patch_files.concat get_patches(name, version)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|