tiny_tds 0.6.2-x64-mingw32 → 0.6.3.rc2-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -73,9 +73,9 @@ int tinytds_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, c
73
73
  /*
74
74
  SYBETIME is the only error that can send INT_TIMEOUT or INT_CONTINUE,
75
75
  but we don't ever want to automatically retry. Instead have the app
76
- decide what to do. We would use INT_TIMEOUT, however it seems tdserror()
77
- in tds/util.c converts INT_TIMEOUT to INT_CONTINUE.
76
+ decide what to do.
78
77
  */
78
+ return_value = INT_TIMEOUT;
79
79
  cancel = 1;
80
80
  break;
81
81
 
@@ -233,7 +233,7 @@ static VALUE rb_tinytds_execute(VALUE self, VALUE sql) {
233
233
  GET_CLIENT_WRAPPER(self);
234
234
  rb_tinytds_client_reset_userdata(cwrap->userdata);
235
235
  REQUIRE_OPEN_CLIENT(cwrap);
236
- dbcmd(cwrap->client, StringValuePtr(sql));
236
+ dbcmd(cwrap->client, StringValueCStr(sql));
237
237
  if (dbsqlsend(cwrap->client) == FAIL) {
238
238
  rb_warn("TinyTds: dbsqlsend() returned FAIL.\n");
239
239
  return Qfalse;
@@ -316,25 +316,25 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
316
316
  if (!NIL_P(version))
317
317
  dbsetlversion(cwrap->login, NUM2INT(version));
318
318
  if (!NIL_P(user))
319
- dbsetluser(cwrap->login, StringValuePtr(user));
319
+ dbsetluser(cwrap->login, StringValueCStr(user));
320
320
  if (!NIL_P(pass))
321
- dbsetlpwd(cwrap->login, StringValuePtr(pass));
321
+ dbsetlpwd(cwrap->login, StringValueCStr(pass));
322
322
  if (!NIL_P(app))
323
- dbsetlapp(cwrap->login, StringValuePtr(app));
323
+ dbsetlapp(cwrap->login, StringValueCStr(app));
324
324
  if (!NIL_P(ltimeout))
325
325
  dbsetlogintime(NUM2INT(ltimeout));
326
326
  if (!NIL_P(timeout))
327
327
  dbsettime(NUM2INT(timeout));
328
328
  if (!NIL_P(charset))
329
- DBSETLCHARSET(cwrap->login, StringValuePtr(charset));
329
+ DBSETLCHARSET(cwrap->login, StringValueCStr(charset));
330
330
  if (!NIL_P(database) && (azure == Qtrue)) {
331
331
  #ifdef DBSETLDBNAME
332
- DBSETLDBNAME(cwrap->login, StringValuePtr(database));
332
+ DBSETLDBNAME(cwrap->login, StringValueCStr(database));
333
333
  #else
334
334
  rb_warn("TinyTds: Azure connections not supported in this version of FreeTDS.\n");
335
335
  #endif
336
336
  }
337
- cwrap->client = dbopen(cwrap->login, StringValuePtr(dataserver));
337
+ cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver));
338
338
  if (cwrap->client) {
339
339
  cwrap->closed = 0;
340
340
  cwrap->charset = charset;
@@ -343,10 +343,10 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
343
343
  dbsetuserdata(cwrap->client, (BYTE*)cwrap->userdata);
344
344
  cwrap->userdata->closed = 0;
345
345
  if (!NIL_P(database) && (azure != Qtrue)) {
346
- dbuse(cwrap->client, StringValuePtr(database));
346
+ dbuse(cwrap->client, StringValueCStr(database));
347
347
  }
348
348
  VALUE transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
349
- cwrap->encoding = rb_enc_find(StringValuePtr(transposed_encoding));
349
+ cwrap->encoding = rb_enc_find(StringValueCStr(transposed_encoding));
350
350
  if (dbtds(cwrap->client) <= 7) {
351
351
  cwrap->identity_insert_sql = "SELECT CAST(@@IDENTITY AS bigint) AS Ident";
352
352
  } else {
@@ -3,10 +3,54 @@ ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
3
3
  # :stopdoc:
4
4
 
5
5
  require 'mkmf'
6
+ require 'mini_portile'
7
+ require 'fileutils'
8
+
9
+ # If your using 0.82, you may have to make a conf file to get it to work. For example:
10
+ # $ export FREETDSCONF='/opt/local/etc/freetds/freetds.conf'
11
+ ICONV_VERSION = ENV['TINYTDS_ICONV_VERSION'] || "1.14"
12
+ ICONV_SOURCE_URI = "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-#{ICONV_VERSION}.tar.gz"
13
+
14
+ OPENSSL_VERSION = ENV['TINYTDS_OPENSSL_VERSION'] || '1.0.2d'
15
+ OPENSSL_SOURCE_URI = "http://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
16
+
17
+ FREETDS_VERSION = ENV['TINYTDS_FREETDS_VERSION'] || "0.91"
18
+ FREETDS_VERSION_INFO = Hash.new { |h,k|
19
+ h[k] = {:files => "ftp://ftp.freetds.org/pub/freetds/stable/freetds-#{k}.tar.gz"}
20
+ }.merge({
21
+ "0.82" => {:files => "ftp://ftp.freetds.org/pub/freetds/old/0.82/freetds-0.82.tar.gz"},
22
+ "0.91" => {:files => "ftp://ftp.freetds.org/pub/freetds/stable/freetds-0.91.112.tar.gz"},
23
+ "current" => {:files => "ftp://ftp.freetds.org/pub/freetds/current/freetds-current.tar.gz"}
24
+ })
25
+ FREETDS_SOURCE_URI = FREETDS_VERSION_INFO[FREETDS_VERSION][:files]
6
26
 
7
27
  # Shamelessly copied from nokogiri
8
28
  #
9
29
 
30
+ def do_help
31
+ print <<HELP
32
+ usage: ruby #{$0} [options]
33
+
34
+ --enable-system-freetds / --disable-system-freetds
35
+ --enable-system-iconv / --disable-system-iconv
36
+ --enable-system-openssl / --disable-system-openssl
37
+ Force use of system or builtin freetds/iconv/openssl library.
38
+ Default is to prefer system libraries and fallback to builtin.
39
+
40
+ --with-freetds-dir=DIR
41
+ Use the freetds library placed under DIR.
42
+
43
+ --enable-lookup
44
+ Search for freetds through all paths in the PATH environment variable.
45
+
46
+ --enable-cross-build
47
+ Do cross-build.
48
+ HELP
49
+ exit! 0
50
+ end
51
+
52
+ do_help if arg_config('--help')
53
+
10
54
  FREETDSDIR = ENV['FREETDS_DIR']
11
55
 
12
56
  if FREETDSDIR.nil? || FREETDSDIR.empty?
@@ -40,6 +84,144 @@ def searchable_paths_with_directories(*directories)
40
84
  end.flatten.compact
41
85
  end
42
86
 
87
+ class BuildRecipe < MiniPortile
88
+ def initialize(name, version, files)
89
+ super(name, version)
90
+ self.files = files
91
+ self.target = File.expand_path('../../../ports', __FILE__)
92
+ # Prefer host_alias over host in order to use i586-mingw32msvc as
93
+ # correct compiler prefix for cross build, but use host if not set.
94
+ self.host = consolidated_host(RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"])
95
+ self.patch_files = Dir[File.join(self.target, "patches", self.name, self.version, "*.diff")].sort
96
+ end
97
+
98
+ def consolidated_host(name)
99
+ # For ruby-1.9.3 we use newer mingw-w64 (i686-w64-mingw32) to build the shared libraries
100
+ # and mingw32 (i586-mingw32msvc) to build the extension.
101
+ name.gsub('i586-mingw32msvc', 'i686-w64-mingw32').
102
+ gsub('i686-pc-mingw32', 'i686-w64-mingw32')
103
+ end
104
+
105
+ def configure_defaults
106
+ [
107
+ "--host=#{host}", # build for specific target (host)
108
+ "--disable-static",
109
+ "--enable-shared",
110
+ ]
111
+ end
112
+
113
+ def port_path
114
+ "#{target}/#{host}"
115
+ end
116
+
117
+ # When using rake-compiler-dock on Windows, the underlying Virtualbox shared
118
+ # folders don't support symlinks, but libiconv expects it for a build on
119
+ # Linux. We work around this limitation by using the temp dir for cooking.
120
+ def chdir_for_build
121
+ build_dir = ENV['RCD_HOST_RUBY_PLATFORM'].to_s =~ /mingw|mswin|cygwin/ ? '/tmp' : '.'
122
+ Dir.chdir(build_dir) do
123
+ yield
124
+ end
125
+ end
126
+
127
+ def cook_and_activate
128
+ checkpoint = File.join(self.target, "#{self.name}-#{self.version}-#{self.host}.installed")
129
+ unless File.exist?(checkpoint)
130
+ chdir_for_build do
131
+ self.cook
132
+ end
133
+ FileUtils.touch checkpoint
134
+ end
135
+ self.activate
136
+ self
137
+ end
138
+ end
139
+
140
+ def define_libssl_recipe(host)
141
+ BuildRecipe.new("openssl", OPENSSL_VERSION, [OPENSSL_SOURCE_URI]).tap do |recipe|
142
+ class << recipe
143
+ def extract_file(file, target)
144
+ filename = File.basename(file)
145
+ FileUtils.mkdir_p target
146
+
147
+ message "Extracting #{filename} into #{target}... "
148
+ result = `#{tar_exe} #{tar_compression_switch(filename)}xf "#{file}" -C "#{target}" 2>&1`
149
+ if $?.success?
150
+ output "OK"
151
+ else
152
+ # tar on windows returns error exit code, because it can not extract symlinks
153
+ output "ERROR (ignored)"
154
+ end
155
+ end
156
+
157
+ def configure
158
+ config = if host=~/mingw/
159
+ host=~/x86_64/ ? 'mingw64' : 'mingw'
160
+ end
161
+ args = [ "CFLAGS=-DDSO_WIN32",
162
+ "./Configure",
163
+ "no-shared",
164
+ configure_prefix,
165
+ config,
166
+ ]
167
+ args.unshift("CROSS_COMPILE=#{host}-") if enable_config("cross-build")
168
+
169
+ execute "configure", "sh -c \"#{args.join(" ")}\""
170
+ end
171
+
172
+ def compile
173
+ super
174
+ # OpenSSL DLLs are called "libeay32.dll" and "ssleay32.dll" per default,
175
+ # regardless to the version. This is best suited to meet the Windows DLL hell.
176
+ # To avoid any conflicts we do a static build and build DLLs afterwards,
177
+ # with our own naming scheme.
178
+ execute "mkdef-libeay32", "(perl util/mkdef.pl 32 libeay >libeay32.def)"
179
+ execute "mkdef-ssleay32", "(perl util/mkdef.pl 32 ssleay >ssleay32.def)"
180
+ dllwrap = consolidated_host(RbConfig::CONFIG["DLLWRAP"])
181
+ execute "dllwrap-libeay32", "#{dllwrap} --dllname libeay32-#{version}-#{host}.dll --output-lib libcrypto.dll.a --def libeay32.def libcrypto.a -lwsock32 -lgdi32 -lcrypt32"
182
+ execute "dllwrap-ssleay32", "#{dllwrap} --dllname ssleay32-#{version}-#{host}.dll --output-lib libssl.dll.a --def ssleay32.def libssl.a libcrypto.dll.a"
183
+ end
184
+
185
+ def install
186
+ super
187
+ FileUtils.cp "#{work_path}/libeay32-#{version}-#{host}.dll", "#{path}/bin/"
188
+ FileUtils.cp "#{work_path}/ssleay32-#{version}-#{host}.dll", "#{path}/bin/"
189
+ FileUtils.cp "#{work_path}/libcrypto.dll.a", "#{path}/lib/"
190
+ FileUtils.cp "#{work_path}/libssl.dll.a", "#{path}/lib/"
191
+ end
192
+ end
193
+ end
194
+ end
195
+
196
+ def define_libiconv_recipe(host)
197
+ BuildRecipe.new("libiconv", ICONV_VERSION, [ICONV_SOURCE_URI])
198
+ .tap do |recipe|
199
+ # always produce position independent code
200
+ recipe.configure_options << "CFLAGS=-fPIC"
201
+ end
202
+ end
203
+
204
+ def define_freetds_recipe(host, libiconv, libssl)
205
+ BuildRecipe.new("freetds", FREETDS_VERSION, [FREETDS_SOURCE_URI])
206
+ .tap do |recipe|
207
+ with_tdsver = FREETDS_VERSION =~ /0\.8/ ? "--with-tdsver=8.0" : "--with-tdsver=7.1"
208
+ for_windows = recipe.host =~ /mswin|mingw/i
209
+ recipe.configure_options << '--with-pic'
210
+ recipe.configure_options << "--with-libiconv-prefix=#{libiconv.path}" if libiconv
211
+ recipe.configure_options << "--with-openssl=#{libssl.path}" if libssl
212
+ recipe.configure_options << '--sysconfdir=C:/Sites' if for_windows
213
+ recipe.configure_options << '--enable-sspi' if for_windows
214
+ recipe.configure_options << "--disable-odbc"
215
+ recipe.configure_options << with_tdsver
216
+ if libiconv
217
+ # For some reason freetds doesn't honor --with-libiconv-prefix
218
+ # so we have do add it by hand:
219
+ recipe.configure_options << "\"CFLAGS=-I#{libiconv.path}/include\""
220
+ recipe.configure_options << "\"LDFLAGS=-L#{libiconv.path}/lib -liconv\""
221
+ end
222
+ end
223
+ end
224
+
43
225
  if RbConfig::CONFIG['target_os'] =~ /mswin32|mingw32/
44
226
  lib_prefix = 'lib' unless RbConfig::CONFIG['target_os'] =~ /mingw32/
45
227
  # There's no default include/lib dir on Windows. Let's just add the Ruby ones
@@ -77,10 +259,8 @@ FREETDS_LIB_DIRS = (searchable_paths_with_directories(['lib'],['lib','freetds'])
77
259
  # lookup over searchable paths is great for native compilation, however, when
78
260
  # cross compiling we need to specify our own paths.
79
261
  if enable_config("lookup", true)
80
- dir_config('iconv', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS)
81
262
  dir_config('freetds', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS)
82
263
  else
83
- dir_config('iconv')
84
264
  dir_config('freetds')
85
265
 
86
266
  # remove LDFLAGS
@@ -91,11 +271,28 @@ def asplode(lib)
91
271
  abort "-----\n#{lib} is missing.\n-----"
92
272
  end
93
273
 
94
- asplode 'libiconv' unless have_func('iconv_open', 'iconv.h') || have_library('iconv', 'iconv_open', 'iconv.h')
95
- asplode 'freetds' unless have_header('sybfront.h') && have_header('sybdb.h')
274
+ def freetds_usable?(lib_prefix)
275
+ have_header('sybfront.h') && have_header('sybdb.h') &&
276
+ find_library("#{lib_prefix}sybdb", 'tdsdbopen') &&
277
+ find_library("#{lib_prefix}ct", 'ct_bind')
278
+ end
279
+
280
+ # We use freetds, when available already, and fallback to compilation of ports
281
+ system_freetds = enable_config('system-freetds', ENV['TINYTDS_SKIP_PORTS'] || freetds_usable?(lib_prefix))
282
+
283
+ # We expect to have iconv and OpenSSL available on non-Windows systems
284
+ host = RbConfig::CONFIG["host"]
285
+ system_iconv = enable_config('system-iconv', host =~ /mingw|mswin/ ? false : true)
286
+ system_openssl = enable_config('system-openssl', host =~ /mingw|mswin/ ? false : true )
287
+
288
+ unless system_freetds
289
+ libssl = define_libssl_recipe(host).cook_and_activate unless system_openssl
290
+ libiconv = define_libiconv_recipe(host).cook_and_activate unless system_iconv
291
+ freetds = define_freetds_recipe(host, libiconv, libssl).cook_and_activate
292
+ dir_config('freetds', freetds.path + "/include", freetds.path + "/lib")
293
+ end
96
294
 
97
- asplode 'freetds' unless find_library("#{lib_prefix}sybdb", 'tdsdbopen')
98
- asplode 'freetds' unless find_library("#{lib_prefix}ct", 'ct_bind')
295
+ asplode 'freetds' unless freetds_usable?(lib_prefix)
99
296
 
100
297
  create_makefile('tiny_tds/tiny_tds')
101
298
 
@@ -2,23 +2,12 @@
2
2
  #include <tiny_tds_ext.h>
3
3
  #include <stdint.h>
4
4
 
5
- // TINY_TDS_MAX_TIME
6
-
7
- #define TINY_TDS_MAX_TIME 315607276799ULL
8
-
9
-
10
- // TINY_TDS_MIN_TIME
11
-
12
- #define TINY_TDS_MIN_TIME 2678400ULL
13
-
14
-
15
5
  // File Types/Vars
16
6
 
17
7
  VALUE cTinyTdsResult;
18
8
  extern VALUE mTinyTds, cTinyTdsClient, cTinyTdsError;
19
- VALUE cBigDecimal, cDate, cDateTime;
9
+ VALUE cBigDecimal, cDate;
20
10
  VALUE opt_decimal_zero, opt_float_zero, opt_one, opt_zero, opt_four, opt_19hdr, opt_tenk, opt_onemil;
21
- int opt_ruby_186;
22
11
  static ID intern_new, intern_utc, intern_local, intern_localtime, intern_merge,
23
12
  intern_civil, intern_new_offset, intern_plus, intern_divide, intern_Rational;
24
13
  static ID sym_symbolize_keys, sym_as, sym_array, sym_cache_rows, sym_first, sym_timezone, sym_local, sym_utc, sym_empty_sets;
@@ -78,7 +67,7 @@ VALUE rb_tinytds_new_result_obj(tinytds_client_wrapper *cwrap) {
78
67
  // No GVL Helpers
79
68
 
80
69
  #define NOGVL_DBCALL(_dbfunction, _client) ( \
81
- (RETCODE)rb_thread_blocking_region( \
70
+ (RETCODE)rb_thread_call_without_gvl( \
82
71
  (rb_blocking_function_t*)_dbfunction, _client, \
83
72
  (rb_unblock_function_t*)dbcancel_ubf, _client ) \
84
73
  )
@@ -293,25 +282,7 @@ static VALUE rb_tinytds_result_fetch_row(VALUE self, ID timezone, int symbolize_
293
282
  if (year+month+day+hour+min+sec+msec != 0) {
294
283
  VALUE offset = (timezone == intern_local) ? rwrap->local_offset : opt_zero;
295
284
  uint64_t seconds = (year*31557600ULL) + (month*2592000ULL) + (day*86400ULL) + (hour*3600ULL) + (min*60ULL) + sec;
296
- /* Use DateTime */
297
- if (seconds < TINY_TDS_MIN_TIME || seconds > TINY_TDS_MAX_TIME) {
298
- VALUE datetime_sec = INT2NUM(sec);
299
- if (msec != 0) {
300
- if ((opt_ruby_186 == 1 && sec < 59) || (opt_ruby_186 != 1)) {
301
- #ifdef HAVE_RUBY_ENCODING_H
302
- VALUE rational_msec = rb_Rational2(INT2NUM(msec*1000), opt_onemil);
303
- #else
304
- VALUE rational_msec = rb_funcall(rb_cObject, intern_Rational, 2, INT2NUM(msec*1000), opt_onemil);
305
- #endif
306
- datetime_sec = rb_funcall(datetime_sec, intern_plus, 1, rational_msec);
307
- }
308
- }
309
- val = rb_funcall(cDateTime, intern_civil, 7, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), datetime_sec, offset);
310
- val = rb_funcall(val, intern_new_offset, 1, offset);
311
- /* Use Time */
312
- } else {
313
- val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec), INT2NUM(msec*1000));
314
- }
285
+ val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec), INT2NUM(msec*1000));
315
286
  }
316
287
  break;
317
288
  }
@@ -547,7 +518,6 @@ void init_tinytds_result() {
547
518
  /* Data Classes */
548
519
  cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
549
520
  cDate = rb_const_get(rb_cObject, rb_intern("Date"));
550
- cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
551
521
  /* Define TinyTds::Result */
552
522
  cTinyTdsResult = rb_define_class_under(mTinyTds, "Result", rb_cObject);
553
523
  /* Define TinyTds::Result Public Methods */
@@ -590,8 +560,6 @@ void init_tinytds_result() {
590
560
  opt_19hdr = INT2NUM(1900);
591
561
  opt_tenk = INT2NUM(10000);
592
562
  opt_onemil = INT2NUM(1000000);
593
- /* Ruby version flags */
594
- opt_ruby_186 = (rb_eval_string("RUBY_VERSION == '1.8.6'") == Qtrue) ? 1 : 0;
595
563
  /* Encoding */
596
564
  #ifdef HAVE_RUBY_ENCODING_H
597
565
  binaryEncoding = rb_enc_find("binary");
data/lib/tiny_tds.rb CHANGED
@@ -9,11 +9,30 @@ require 'tiny_tds/client'
9
9
  require 'tiny_tds/result'
10
10
 
11
11
  # Support multiple ruby versions, fat binaries under Windows.
12
- begin
13
- RUBY_VERSION =~ /(\d+.\d+)/
14
- require "tiny_tds/#{$1}/tiny_tds"
15
- rescue LoadError
12
+ if RUBY_PLATFORM =~ /mingw|mswin/ && RUBY_VERSION =~ /(\d+.\d+)/
13
+ ver = $1
14
+ # Set the PATH environment variable, so that the DLLs can be found.
15
+ old_path = ENV['PATH']
16
+ begin
17
+ # Do the same host consolidation as in extconf.rb
18
+ ports_dir = RbConfig::CONFIG["host"].gsub('i586-mingw32msvc', 'i686-w64-mingw32').
19
+ gsub('i686-pc-mingw32', 'i686-w64-mingw32')
20
+ ENV['PATH'] = "#{File.expand_path("../../ports/#{ports_dir}/bin", __FILE__)};#{old_path}"
21
+ require "tiny_tds/#{ver}/tiny_tds"
22
+ rescue LoadError
23
+ require 'tiny_tds/tiny_tds'
24
+ ensure
25
+ ENV['PATH'] = old_path
26
+ end
27
+ else
28
+ # Load dependent shared libraries into the process, so that they are already present,
29
+ # when tiny_tds.so is loaded. This ensures, that shared libraries are loaded even when
30
+ # the path is different between build and run time (e.g. Heroku).
31
+ ports_libs = File.expand_path("../../ports/#{RbConfig::CONFIG["host"]}/lib/*.so", __FILE__)
32
+ Dir[ports_libs].each do |lib|
33
+ require "fiddle"
34
+ Fiddle.dlopen(lib)
35
+ end
36
+
16
37
  require 'tiny_tds/tiny_tds'
17
38
  end
18
-
19
-
@@ -1,9 +1,9 @@
1
1
  module TinyTds
2
2
  class Client
3
-
3
+
4
4
  # From sybdb.h comments:
5
5
  # DBVERSION_xxx are used with dbsetversion()
6
- #
6
+ #
7
7
  TDS_VERSIONS_SETTERS = {
8
8
  'unknown' => 0,
9
9
  '46' => 1,
@@ -19,7 +19,7 @@ module TinyTds
19
19
  # From sybdb.h comments:
20
20
  # DBTDS_xxx are returned by DBTDS()
21
21
  # The integer values of the constants are poorly chosen.
22
- #
22
+ #
23
23
  TDS_VERSIONS_GETTERS = {
24
24
  0 => {:name => 'DBTDS_UNKNOWN', :description => 'Unknown'},
25
25
  1 => {:name => 'DBTDS_2_0', :description => 'Pre 4.0 SQL Server'},
@@ -33,7 +33,7 @@ module TinyTds
33
33
  9 => {:name => 'DBTDS_7_1/DBTDS_8_0', :description => 'Microsoft SQL Server 2000'},
34
34
  10 => {:name => 'DBTDS_7_2/DBTDS_9_0', :description => 'Microsoft SQL Server 2005'}
35
35
  }.freeze
36
-
36
+
37
37
  @@default_query_options = {
38
38
  :as => :hash,
39
39
  :symbolize_keys => false,
@@ -41,32 +41,29 @@ module TinyTds
41
41
  :timezone => :local,
42
42
  :empty_sets => true
43
43
  }
44
-
44
+
45
45
  attr_reader :query_options
46
-
46
+
47
47
  class << self
48
-
48
+
49
49
  def default_query_options
50
50
  @@default_query_options
51
51
  end
52
52
 
53
- # Most, if not all, iconv encoding names can be found by ruby. Just in case, you can
54
- # overide this method to return a string name that Encoding.find would work with. Default
53
+ # Most, if not all, iconv encoding names can be found by ruby. Just in case, you can
54
+ # overide this method to return a string name that Encoding.find would work with. Default
55
55
  # is to return the passed encoding.
56
56
  def transpose_iconv_encoding(encoding)
57
57
  encoding
58
58
  end
59
-
59
+
60
60
  end
61
61
 
62
62
 
63
63
  def initialize(opts={})
64
- if opts[:password] && opts[:password].to_s.strip != ''
65
- opts[:password] = opts[:password].to_s
66
- warn 'FreeTDS may have issues with passwords longer than 30 characters!' if opts[:password].length > 30
67
- end
68
64
  raise ArgumentError, 'missing :host option if no :dataserver given' if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
69
65
  @query_options = @@default_query_options.dup
66
+ opts[:password] = opts[:password].to_s if opts[:password] && opts[:password].to_s.strip != ''
70
67
  opts[:appname] ||= 'TinyTds'
71
68
  opts[:tds_version] = TDS_VERSIONS_SETTERS[opts[:tds_version].to_s] || TDS_VERSIONS_SETTERS['71']
72
69
  opts[:login_timeout] ||= 60
@@ -76,7 +73,7 @@ module TinyTds
76
73
  opts[:dataserver] = "#{opts[:host]}:#{opts[:port]}" if opts[:dataserver].to_s.empty?
77
74
  connect(opts)
78
75
  end
79
-
76
+
80
77
  def tds_version_info
81
78
  info = TDS_VERSIONS_GETTERS[tds_version]
82
79
  "#{info[:name]} - #{info[:description]}" if info
@@ -86,11 +83,12 @@ module TinyTds
86
83
  !closed? && !dead?
87
84
  end
88
85
 
86
+
89
87
  private
90
-
88
+
91
89
  def self.local_offset
92
90
  ::Time.local(2010).utc_offset.to_r / 86400
93
91
  end
94
-
92
+
95
93
  end
96
94
  end