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

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.
@@ -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