tiny_tds 1.3.0 → 2.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|