tiny_tds 0.7.0-x86-mingw32 → 0.9.5.beta.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,10 +2,6 @@
2
2
  #ifndef TINYTDS_RESULT_H
3
3
  #define TINYTDS_RESULT_H
4
4
 
5
- #ifndef DBSETLDBNAME
6
- typedef tds_sysdep_int64_type DBBIGINT; /* For FreeTDS 0.82 */
7
- #endif
8
-
9
5
  void init_tinytds_result();
10
6
  VALUE rb_tinytds_new_result_obj(tinytds_client_wrapper *cwrap);
11
7
 
@@ -1,11 +1,13 @@
1
1
  #ifndef TINYTDS_EXT
2
2
  #define TINYTDS_EXT
3
3
 
4
- #undef MSDBLIB
5
- #define SYBDBLIB
4
+ #undef SYBDBLIB
5
+ #define MSDBLIB 1
6
6
 
7
7
  #include <ruby.h>
8
8
  #include <ruby/encoding.h>
9
+ #include <ruby/version.h>
10
+ #include <ruby/thread.h>
9
11
  #include <sybfront.h>
10
12
  #include <sybdb.h>
11
13
 
data/lib/tiny_tds.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  require 'date'
3
3
  require 'bigdecimal'
4
- require 'rational' unless RUBY_VERSION >= '1.9.2'
4
+ require 'rational'
5
5
 
6
6
  require 'tiny_tds/version'
7
7
  require 'tiny_tds/error'
@@ -15,8 +15,7 @@ if RUBY_PLATFORM =~ /mingw|mswin/ && RUBY_VERSION =~ /(\d+.\d+)/
15
15
  old_path = ENV['PATH']
16
16
  begin
17
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')
18
+ ports_dir = RbConfig::CONFIG["host"].gsub('i686-pc-mingw32', 'i686-w64-mingw32')
20
19
  ENV['PATH'] = "#{File.expand_path("../../ports/#{ports_dir}/bin", __FILE__)};#{old_path}"
21
20
  require "tiny_tds/#{ver}/tiny_tds"
22
21
  rescue LoadError
@@ -31,12 +30,7 @@ else
31
30
  ports_libs = File.expand_path("../../ports/#{RbConfig::CONFIG["host"]}/lib/*.so", __FILE__)
32
31
  Dir[ports_libs].each do |lib|
33
32
  require "fiddle"
34
- if Fiddle.respond_to?(:dlopen)
35
- Fiddle.dlopen(lib)
36
- else
37
- # For compat with Ruby < 2.0
38
- DL.dlopen(lib)
39
- end
33
+ Fiddle.dlopen(lib)
40
34
  end
41
35
 
42
36
  require 'tiny_tds/tiny_tds'
@@ -1,39 +1,6 @@
1
1
  module TinyTds
2
2
  class Client
3
3
 
4
- # From sybdb.h comments:
5
- # DBVERSION_xxx are used with dbsetversion()
6
- #
7
- TDS_VERSIONS_SETTERS = {
8
- 'unknown' => 0,
9
- '46' => 1,
10
- '100' => 2,
11
- '42' => 3,
12
- '70' => 4,
13
- '71' => 5,
14
- '80' => 5,
15
- '72' => 6,
16
- '90' => 6
17
- }.freeze
18
-
19
- # From sybdb.h comments:
20
- # DBTDS_xxx are returned by DBTDS()
21
- # The integer values of the constants are poorly chosen.
22
- #
23
- TDS_VERSIONS_GETTERS = {
24
- 0 => {:name => 'DBTDS_UNKNOWN', :description => 'Unknown'},
25
- 1 => {:name => 'DBTDS_2_0', :description => 'Pre 4.0 SQL Server'},
26
- 2 => {:name => 'DBTDS_3_4', :description => 'Microsoft SQL Server (3.0)'},
27
- 3 => {:name => 'DBTDS_4_0', :description => '4.0 SQL Server'},
28
- 4 => {:name => 'DBTDS_4_2', :description => '4.2 SQL Server'},
29
- 5 => {:name => 'DBTDS_4_6', :description => '2.0 OpenServer and 4.6 SQL Server.'},
30
- 6 => {:name => 'DBTDS_4_9_5', :description => '4.9.5 (NCR) SQL Server'},
31
- 7 => {:name => 'DBTDS_5_0', :description => '5.0 SQL Server'},
32
- 8 => {:name => 'DBTDS_7_0', :description => 'Microsoft SQL Server 7.0'},
33
- 9 => {:name => 'DBTDS_7_1/DBTDS_8_0', :description => 'Microsoft SQL Server 2000'},
34
- 10 => {:name => 'DBTDS_7_2/DBTDS_9_0', :description => 'Microsoft SQL Server 2005'}
35
- }.freeze
36
-
37
4
  @@default_query_options = {
38
5
  :as => :hash,
39
6
  :symbolize_keys => false,
@@ -53,6 +20,7 @@ module TinyTds
53
20
  # Most, if not all, iconv encoding names can be found by ruby. Just in case, you can
54
21
  # overide this method to return a string name that Encoding.find would work with. Default
55
22
  # is to return the passed encoding.
23
+ #
56
24
  def transpose_iconv_encoding(encoding)
57
25
  encoding
58
26
  end
@@ -62,10 +30,11 @@ module TinyTds
62
30
 
63
31
  def initialize(opts={})
64
32
  raise ArgumentError, 'missing :host option if no :dataserver given' if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
33
+ opts[:username] = parse_username(opts)
65
34
  @query_options = @@default_query_options.dup
66
35
  opts[:password] = opts[:password].to_s if opts[:password] && opts[:password].to_s.strip != ''
67
36
  opts[:appname] ||= 'TinyTds'
68
- opts[:tds_version] = TDS_VERSIONS_SETTERS[opts[:tds_version].to_s] || TDS_VERSIONS_SETTERS['71']
37
+ opts[:tds_version] = tds_versions_setter(opts)
69
38
  opts[:login_timeout] ||= 60
70
39
  opts[:timeout] ||= 5
71
40
  opts[:encoding] = (opts[:encoding].nil? || opts[:encoding].downcase == 'utf8') ? 'UTF-8' : opts[:encoding].upcase
@@ -74,6 +43,10 @@ module TinyTds
74
43
  connect(opts)
75
44
  end
76
45
 
46
+ def tds_73?
47
+ tds_version >= 11
48
+ end
49
+
77
50
  def tds_version_info
78
51
  info = TDS_VERSIONS_GETTERS[tds_version]
79
52
  "#{info[:name]} - #{info[:description]}" if info
@@ -90,5 +63,59 @@ module TinyTds
90
63
  ::Time.local(2010).utc_offset.to_r / 86400
91
64
  end
92
65
 
66
+ def parse_username(opts)
67
+ username = opts[:username]
68
+ return username if username.nil? || !opts[:azure] || !username.include?("@")
69
+ user, domain = username.split("@")
70
+ "#{user}@#{domain.split('.').first}"
71
+ end
72
+
73
+ def tds_versions_setter(opts={})
74
+ v = opts[:tds_version] || ENV['TDSVER'] || '7.1'
75
+ TDS_VERSIONS_SETTERS[v.to_s]
76
+ end
77
+
78
+ # From sybdb.h comments:
79
+ # DBVERSION_xxx are used with dbsetversion()
80
+ #
81
+ TDS_VERSIONS_SETTERS = {
82
+ 'unknown' => 0,
83
+ '46' => 1,
84
+ '100' => 2,
85
+ '42' => 3,
86
+ '70' => 4,
87
+ '7.0' => 4,
88
+ '71' => 5,
89
+ '7.1' => 5,
90
+ '80' => 5,
91
+ '8.0' => 5,
92
+ '72' => 6,
93
+ '7.2' => 6,
94
+ '90' => 6,
95
+ '9.0' => 6,
96
+ '73' => 7,
97
+ '7.3' => 7
98
+ }.freeze
99
+
100
+ # From sybdb.h comments:
101
+ # DBTDS_xxx are returned by DBTDS()
102
+ # The integer values of the constants are poorly chosen.
103
+ #
104
+ TDS_VERSIONS_GETTERS = {
105
+ 0 => {:name => 'DBTDS_UNKNOWN', :description => 'Unknown'},
106
+ 1 => {:name => 'DBTDS_2_0', :description => 'Pre 4.0 SQL Server'},
107
+ 2 => {:name => 'DBTDS_3_4', :description => 'Microsoft SQL Server (3.0)'},
108
+ 3 => {:name => 'DBTDS_4_0', :description => '4.0 SQL Server'},
109
+ 4 => {:name => 'DBTDS_4_2', :description => '4.2 SQL Server'},
110
+ 5 => {:name => 'DBTDS_4_6', :description => '2.0 OpenServer and 4.6 SQL Server.'},
111
+ 6 => {:name => 'DBTDS_4_9_5', :description => '4.9.5 (NCR) SQL Server'},
112
+ 7 => {:name => 'DBTDS_5_0', :description => '5.0 SQL Server'},
113
+ 8 => {:name => 'DBTDS_7_0', :description => 'Microsoft SQL Server 7.0'},
114
+ 9 => {:name => 'DBTDS_7_1/DBTDS_8_0', :description => 'Microsoft SQL Server 2000'},
115
+ 10 => {:name => 'DBTDS_7_2/DBTDS_9_0', :description => 'Microsoft SQL Server 2005'},
116
+ 11 => {:name => 'DBTDS_7_3', :description => 'Microsoft SQL Server 2008'},
117
+ 12 => {:name => 'DBTDS_7_4', :description => 'Microsoft SQL Server 2012/2014'}
118
+ }.freeze
119
+
93
120
  end
94
121
  end
@@ -1,3 +1,3 @@
1
1
  module TinyTds
2
- VERSION = '0.7.0'
2
+ VERSION = File.read(File.expand_path("../../../VERSION", __FILE__)).chomp
3
3
  end
@@ -0,0 +1,29 @@
1
+ --- a/Makefile.in 2011-08-17 18:57:36.000000000 -0700
2
+ +++ b/Makefile.in 2014-05-02 10:27:01.275813000 -0700
3
+ @@ -772,13 +772,6 @@
4
+
5
+
6
+ install-data-local:
7
+ - $(mkinstalldirs) $(ETC)
8
+ - if test ! -f $(ETC)/freetds.conf; then \
9
+ - $(INSTALL_DATA) $(srcdir)/freetds.conf $(ETC)/freetds.conf; \
10
+ - fi
11
+ - if test ! -f $(ETC)/locales.conf; then \
12
+ - $(INSTALL_DATA) $(srcdir)/locales.conf $(ETC)/locales.conf; \
13
+ - fi
14
+
15
+ clean-local:
16
+ find . \( -name \*.test_output -o -name \*.bb -o -name \*.bbg -o -name \*.da -o -name \*.gc\* \) -exec rm -f {} \;
17
+ --- a/src/pool/Makefile.in 2011-08-17 18:57:36.000000000 -0700
18
+ +++ b/src/pool/Makefile.in 2014-05-02 10:32:39.628347600 -0700
19
+ @@ -574,10 +574,6 @@
20
+
21
+
22
+ install-data-local:
23
+ - $(mkinstalldirs) $(ETC)
24
+ - if test ! -f $(ETC)/pool.conf; then \
25
+ - $(INSTALL_DATA) $(srcdir)/pool.conf $(ETC)/pool.conf; \
26
+ - fi
27
+
28
+ # Tell versions [3.59,3.63) of GNU make to not export all variables.
29
+ # Otherwise a system limit (for SysV at least) may be exceeded.
@@ -0,0 +1,11 @@
1
+ --- a/src/dblib/dblib.c
2
+ +++ b/src/dblib/dblib.c
3
+ @@ -765,7 +765,7 @@ dbsetlname(LOGINREC * login, const char *value, int which)
4
+ return FAIL;
5
+ }
6
+
7
+ - if (TDS_MAX_LOGIN_STR_SZ < strlen(value)) {
8
+ + if (login->tds_login->tds_version < 0x700 && TDS_MAX_LOGIN_STR_SZ < strlen(value)) {
9
+ dbperror(NULL, SYBENTLL, 0);
10
+ return FAIL;
11
+ }
@@ -0,0 +1,34 @@
1
+ diff --git a/src/tds/tls.c b/src/tds/tls.c
2
+ index 0d11a33..b8ab2ba 100644
3
+ --- a/src/tds/tls.c
4
+ +++ b/src/tds/tls.c
5
+ @@ -72,6 +72,29 @@
6
+ #define SSL_PTR bio->ptr
7
+ #endif
8
+
9
+ +/*
10
+ + * Add a workaround for older Mingw versions without inet_pton().
11
+ + * This means RubyInstallers DevKit-4.7.2 in particular.
12
+ + */
13
+ +#if defined(__MINGW64_VERSION_MAJOR) && !defined(InetPtonA)
14
+ + #include <windows.h>
15
+ +
16
+ + static HMODULE ws2_32 = NULL;
17
+ + typedef INT (WINAPI * __inet_pton)(INT Family, LPCWSTR pStringBuf, PVOID pAddr);
18
+ + static __inet_pton _inet_pton = NULL;
19
+ +
20
+ + INT WINAPI inet_pton(INT Family, LPCWSTR pStringBuf, PVOID pAddr)
21
+ + {
22
+ + if (_inet_pton == NULL) {
23
+ + ws2_32 = LoadLibraryEx("Ws2_32.dll", NULL, 0);
24
+ +
25
+ + _inet_pton = (__inet_pton)GetProcAddress(ws2_32, "inet_pton");
26
+ + }
27
+ +
28
+ + return (_inet_pton)(Family, pStringBuf, pAddr);
29
+ + }
30
+ +#endif
31
+ +
32
+ static SSL_RET
33
+ tds_pull_func_login(SSL_PULL_ARGS)
34
+ {
data/test/client_test.rb CHANGED
@@ -28,6 +28,9 @@ class ClientTest < TinyTds::TestCase
28
28
  if sybase_ase?
29
29
  assert_equal 7, @client.tds_version
30
30
  assert_equal 'DBTDS_5_0 - 5.0 SQL Server', @client.tds_version_info
31
+ elsif @client.tds_73?
32
+ assert_equal 11, @client.tds_version
33
+ assert_equal 'DBTDS_7_3 - Microsoft SQL Server 2008', @client.tds_version_info
31
34
  else
32
35
  assert_equal 9, @client.tds_version
33
36
  assert_equal 'DBTDS_7_1/DBTDS_8_0 - Microsoft SQL Server 2000', @client.tds_version_info
@@ -48,6 +51,7 @@ class ClientTest < TinyTds::TestCase
48
51
  client = new_connection(:encoding => encoding)
49
52
  assert_equal encoding, client.charset
50
53
  assert_equal Encoding.find(encoding), client.encoding
54
+ client.close
51
55
  end
52
56
  end
53
57
 
@@ -55,6 +59,7 @@ class ClientTest < TinyTds::TestCase
55
59
  host = ENV['TINYTDS_UNIT_HOST_TEST'] || ENV['TINYTDS_UNIT_HOST']
56
60
  port = ENV['TINYTDS_UNIT_PORT_TEST'] || ENV['TINYTDS_UNIT_PORT'] || 1433
57
61
  client = new_connection dataserver: nil, host: host, port: port
62
+ client.close
58
63
  end unless sqlserver_azure?
59
64
 
60
65
  end
@@ -89,6 +94,7 @@ class ClientTest < TinyTds::TestCase
89
94
  assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
90
95
  end
91
96
  assert_client_works(client)
97
+ close_client(client)
92
98
  assert_new_connections_work
93
99
  end
94
100
 
@@ -97,6 +103,7 @@ class ClientTest < TinyTds::TestCase
97
103
  client.execute("WaitFor Delay '00:00:01'").do
98
104
  client.execute("WaitFor Delay '00:00:01'").do
99
105
  client.execute("WaitFor Delay '00:00:01'").do
106
+ close_client(client)
100
107
  end
101
108
 
102
109
  it 'must not timeout per sql batch when under transaction' do
@@ -108,6 +115,7 @@ class ClientTest < TinyTds::TestCase
108
115
  client.execute("WaitFor Delay '00:00:01'").do
109
116
  ensure
110
117
  client.execute("COMMIT TRANSACTION").do
118
+ close_client(client)
111
119
  end
112
120
  end
113
121
 
@@ -134,6 +142,7 @@ class ClientTest < TinyTds::TestCase
134
142
  assert_equal 1, e.severity
135
143
  assert_match %r{dead or not enabled}i, e.message, 'ignore if non-english test run'
136
144
  end
145
+ close_client(client)
137
146
  assert_new_connections_work
138
147
  end
139
148
  end
@@ -143,7 +152,9 @@ class ClientTest < TinyTds::TestCase
143
152
  action = lambda { new_connection(options) }
144
153
  assert_raise_tinytds_error(action) do |e|
145
154
  if sqlserver_azure?
146
- assert_match %r{server name cannot be determined}i, e.message, 'ignore if non-english test run'
155
+ assert_equal 40532, e.db_error_number
156
+ assert_equal 20, e.severity
157
+ assert_match %r{login failed}i, e.message, 'ignore if non-english test run'
147
158
  else
148
159
  assert_equal sybase_ase? ? 4002 : 18456, e.db_error_number
149
160
  assert_equal 14, e.severity
@@ -153,19 +164,28 @@ class ClientTest < TinyTds::TestCase
153
164
  assert_new_connections_work
154
165
  end
155
166
 
156
- it 'fails miserably with unknown encoding option' do
157
- options = connection_options :encoding => 'ISO-WTF'
158
- action = lambda { new_connection(options) }
159
- assert_raise_tinytds_error(action) do |e|
160
- assert_equal 20002, e.db_error_number
161
- assert_equal 9, e.severity
162
- assert_match %r{connection failed}i, e.message, 'ignore if non-english test run'
163
- end
164
- assert_new_connections_work
165
- end unless sybase_ase?
166
-
167
167
  end
168
168
 
169
+ describe 'Private methods' do
170
+
171
+ let(:client) { @client = new_connection }
172
+
173
+ it '#parse_username returns username if azure is not true' do
174
+ username = 'user@long.domain.name.com'
175
+ client.send(:parse_username, username: username).must_equal username
176
+ end
177
+
178
+ it '#parse_username returns short username if azure is true' do
179
+ username = 'user@long.domain.name.com'
180
+ client.send(:parse_username, username: username, azure: true).must_equal 'user@long'
181
+ end
182
+
183
+ it '#parse_username returns short username if passed and azure is true' do
184
+ username = 'user@short'
185
+ client.send(:parse_username, username: username, azure: true).must_equal 'user@short'
186
+ end
187
+
188
+ end
169
189
 
170
190
 
171
191
  end
data/test/result_test.rb CHANGED
@@ -397,6 +397,7 @@ class ResultTest < TinyTds::TestCase
397
397
  describe 'using :empty_sets TRUE' do
398
398
 
399
399
  before do
400
+ close_client
400
401
  @old_query_option_value = TinyTds::Client.default_query_options[:empty_sets]
401
402
  TinyTds::Client.default_query_options[:empty_sets] = true
402
403
  @client = new_connection
@@ -477,6 +478,7 @@ class ResultTest < TinyTds::TestCase
477
478
  describe 'using :empty_sets FALSE' do
478
479
 
479
480
  before do
481
+ close_client
480
482
  @old_query_option_value = TinyTds::Client.default_query_options[:empty_sets]
481
483
  TinyTds::Client.default_query_options[:empty_sets] = false
482
484
  @client = new_connection
@@ -668,12 +670,14 @@ class ResultTest < TinyTds::TestCase
668
670
  end
669
671
 
670
672
  it 'must not error at all from reading non-convertable charcters and just use ? marks' do
673
+ close_client
671
674
  @client = new_connection :encoding => 'ASCII'
672
675
  @client.charset.must_equal 'ASCII'
673
676
  find_value(202, :nvarchar_50).must_equal 'test nvarchar_50 ??'
674
677
  end
675
678
 
676
679
  it 'must error gracefully from writing non-convertable characters' do
680
+ close_client
677
681
  @client = new_connection :encoding => 'ASCII'
678
682
  @client.charset.must_equal 'ASCII'
679
683
  rollback_transaction(@client) do
@@ -681,26 +685,22 @@ class ResultTest < TinyTds::TestCase
681
685
  @client.execute("DELETE FROM [datatypes] WHERE [nvarchar_50] IS NOT NULL").do
682
686
  action = lambda { @client.execute("INSERT INTO [datatypes] ([nvarchar_50]) VALUES ('#{text}')").do }
683
687
  assert_raise_tinytds_error(action) do |e|
684
- e.message.must_match %r{Error converting characters into server's character set}i
685
- e.severity.must_equal 4
686
- e.db_error_number.must_equal 2402
688
+ e.message.must_match %r{Unclosed quotation mark}i
689
+ e.severity.must_equal 15
690
+ e.db_error_number.must_equal 105
687
691
  end
688
692
  assert_followup_query
689
693
  end
690
694
  end
691
695
 
692
696
  it 'errors gracefully with incorrect syntax in sp_executesql' do
693
- if @client.freetds_091_or_higer?
694
- action = lambda { @client.execute("EXEC sp_executesql N'this will not work'").each }
695
- assert_raise_tinytds_error(action) do |e|
696
- assert_match %r|incorrect syntax|i, e.message
697
- assert_equal 15, e.severity
698
- assert_equal 156, e.db_error_number
699
- end
700
- assert_followup_query
701
- else
702
- skip 'FreeTDS 0.91 and higher can only pass this test.'
697
+ action = lambda { @client.execute("EXEC sp_executesql N'this will not work'").each }
698
+ assert_raise_tinytds_error(action) do |e|
699
+ assert_match %r|incorrect syntax|i, e.message
700
+ assert_equal 15, e.severity
701
+ assert_equal 156, e.db_error_number
703
702
  end
703
+ assert_followup_query
704
704
  end unless sybase_ase?
705
705
 
706
706
  end