tiny_tds 2.1.0-x64-mingw32 → 2.1.4.pre2-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.
- checksums.yaml +5 -5
- data/.travis.yml +5 -4
- data/CHANGELOG.md +27 -1
- data/ISSUE_TEMPLATE.md +32 -6
- data/README.md +32 -21
- data/VERSION +1 -1
- data/appveyor.yml +26 -7
- data/docker-compose.yml +22 -0
- data/ext/tiny_tds/client.c +95 -50
- data/ext/tiny_tds/client.h +6 -3
- data/ext/tiny_tds/extconf.rb +17 -13
- data/ext/tiny_tds/extconsts.rb +2 -2
- data/ext/tiny_tds/result.c +29 -16
- data/tasks/native_gem.rake +1 -1
- data/tasks/ports.rake +6 -8
- data/tasks/ports/openssl.rb +2 -18
- data/test/bin/setup.sh +1 -1
- data/test/client_test.rb +84 -57
- data/test/gem_test.rb +15 -15
- data/test/result_test.rb +83 -42
- data/test/schema_test.rb +22 -22
- data/test/test_helper.rb +59 -5
- data/test/thread_test.rb +1 -1
- data/tiny_tds.gemspec +3 -2
- metadata +50 -39
- data/BACKERS.md +0 -32
- data/circle.yml +0 -31
data/ext/tiny_tds/client.h
CHANGED
@@ -5,9 +5,9 @@
|
|
5
5
|
void init_tinytds_client();
|
6
6
|
|
7
7
|
#define ERROR_MSG_SIZE 1024
|
8
|
+
#define ERRORS_STACK_INIT_SIZE 2
|
8
9
|
|
9
10
|
typedef struct {
|
10
|
-
short int is_set;
|
11
11
|
int is_message;
|
12
12
|
int cancel;
|
13
13
|
char error[ERROR_MSG_SIZE];
|
@@ -25,7 +25,10 @@ typedef struct {
|
|
25
25
|
RETCODE dbsqlok_retcode;
|
26
26
|
short int dbcancel_sent;
|
27
27
|
short int nonblocking;
|
28
|
-
|
28
|
+
short int nonblocking_errors_length;
|
29
|
+
short int nonblocking_errors_size;
|
30
|
+
tinytds_errordata *nonblocking_errors;
|
31
|
+
VALUE message_handler;
|
29
32
|
} tinytds_client_userdata;
|
30
33
|
|
31
34
|
typedef struct {
|
@@ -39,7 +42,7 @@ typedef struct {
|
|
39
42
|
rb_encoding *encoding;
|
40
43
|
} tinytds_client_wrapper;
|
41
44
|
|
42
|
-
VALUE rb_tinytds_raise_error(DBPROCESS *dbproc,
|
45
|
+
VALUE rb_tinytds_raise_error(DBPROCESS *dbproc, tinytds_errordata error);
|
43
46
|
|
44
47
|
// Lib Macros
|
45
48
|
|
data/ext/tiny_tds/extconf.rb
CHANGED
@@ -22,35 +22,39 @@ do_help if arg_config('--help')
|
|
22
22
|
|
23
23
|
# Make sure to check the ports path for the configured host
|
24
24
|
host = RbConfig::CONFIG['host']
|
25
|
-
project_dir = File.
|
25
|
+
project_dir = File.expand_path("../../..", __FILE__)
|
26
26
|
freetds_ports_dir = File.join(project_dir, 'ports', host, 'freetds', FREETDS_VERSION)
|
27
27
|
freetds_ports_dir = File.expand_path(freetds_ports_dir)
|
28
28
|
|
29
29
|
# Add all the special path searching from the original tiny_tds build
|
30
|
-
# order is important here! First in,
|
30
|
+
# order is important here! First in, first searched.
|
31
31
|
DIRS = %w(
|
32
|
-
/usr/local
|
33
32
|
/opt/local
|
33
|
+
/usr/local
|
34
34
|
)
|
35
35
|
|
36
|
+
# Add the ports directory if it exists for local developer builds
|
37
|
+
DIRS.unshift(freetds_ports_dir) if File.directory?(freetds_ports_dir)
|
38
|
+
|
36
39
|
# Grab freetds environment variable for use by people on services like
|
37
40
|
# Heroku who they can't easily use bundler config to set directories
|
38
|
-
DIRS.
|
39
|
-
|
40
|
-
# Add the ports directory if it exists for local developer builds
|
41
|
-
DIRS.push(freetds_ports_dir) if File.directory?(freetds_ports_dir)
|
41
|
+
DIRS.unshift(ENV['FREETDS_DIR']) if ENV.has_key?('FREETDS_DIR')
|
42
42
|
|
43
43
|
# Add the search paths for freetds configured above
|
44
|
-
DIRS.
|
45
|
-
idir = "#{path}/include"
|
44
|
+
ldirs = DIRS.flat_map do |path|
|
46
45
|
ldir = "#{path}/lib"
|
46
|
+
[ldir, "#{ldir}/freetds"]
|
47
|
+
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
)
|
49
|
+
idirs = DIRS.flat_map do |path|
|
50
|
+
idir = "#{path}/include"
|
51
|
+
[idir, "#{idir}/freetds"]
|
52
52
|
end
|
53
53
|
|
54
|
+
puts "looking for freetds headers in the following directories:\n#{idirs.map{|a| " - #{a}\n"}.join}"
|
55
|
+
puts "looking for freetds library in the following directories:\n#{ldirs.map{|a| " - #{a}\n"}.join}"
|
56
|
+
dir_config('freetds', idirs, ldirs)
|
57
|
+
|
54
58
|
have_dependencies = [
|
55
59
|
find_header('sybfront.h'),
|
56
60
|
find_header('sybdb.h'),
|
data/ext/tiny_tds/extconsts.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
ICONV_VERSION = ENV['TINYTDS_ICONV_VERSION'] || "1.15"
|
3
3
|
ICONV_SOURCE_URI = "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-#{ICONV_VERSION}.tar.gz"
|
4
4
|
|
5
|
-
OPENSSL_VERSION = ENV['TINYTDS_OPENSSL_VERSION'] || '1.1.
|
5
|
+
OPENSSL_VERSION = ENV['TINYTDS_OPENSSL_VERSION'] || '1.1.1d'
|
6
6
|
OPENSSL_SOURCE_URI = "https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
|
7
7
|
|
8
|
-
FREETDS_VERSION = ENV['TINYTDS_FREETDS_VERSION'] || "1.
|
8
|
+
FREETDS_VERSION = ENV['TINYTDS_FREETDS_VERSION'] || "1.1.24"
|
9
9
|
FREETDS_VERSION_INFO = Hash.new { |h,k|
|
10
10
|
h[k] = {files: "http://www.freetds.org/files/stable/freetds-#{k}.tar.bz2"}
|
11
11
|
}
|
data/ext/tiny_tds/result.c
CHANGED
@@ -6,10 +6,10 @@
|
|
6
6
|
|
7
7
|
VALUE cTinyTdsResult;
|
8
8
|
extern VALUE mTinyTds, cTinyTdsClient, cTinyTdsError;
|
9
|
-
VALUE
|
9
|
+
VALUE cKernel, cDate;
|
10
10
|
VALUE opt_decimal_zero, opt_float_zero, opt_one, opt_zero, opt_four, opt_19hdr, opt_onek, opt_tenk, opt_onemil, opt_onebil;
|
11
11
|
static ID intern_new, intern_utc, intern_local, intern_localtime, intern_merge,
|
12
|
-
intern_civil, intern_new_offset, intern_plus, intern_divide;
|
12
|
+
intern_civil, intern_new_offset, intern_plus, intern_divide, intern_bigd;
|
13
13
|
static ID sym_symbolize_keys, sym_as, sym_array, sym_cache_rows, sym_first, sym_timezone, sym_local, sym_utc, sym_empty_sets;
|
14
14
|
|
15
15
|
|
@@ -86,26 +86,38 @@ static void dbcancel_ubf(DBPROCESS *client) {
|
|
86
86
|
static void nogvl_setup(DBPROCESS *client) {
|
87
87
|
GET_CLIENT_USERDATA(client);
|
88
88
|
userdata->nonblocking = 1;
|
89
|
+
userdata->nonblocking_errors_length = 0;
|
90
|
+
userdata->nonblocking_errors = malloc(ERRORS_STACK_INIT_SIZE * sizeof(tinytds_errordata));
|
91
|
+
userdata->nonblocking_errors_size = ERRORS_STACK_INIT_SIZE;
|
89
92
|
}
|
90
93
|
|
91
94
|
static void nogvl_cleanup(DBPROCESS *client) {
|
92
95
|
GET_CLIENT_USERDATA(client);
|
93
96
|
userdata->nonblocking = 0;
|
97
|
+
userdata->timing_out = 0;
|
94
98
|
/*
|
95
99
|
Now that the blocking operation is done, we can finally throw any
|
96
100
|
exceptions based on errors from SQL Server.
|
97
101
|
*/
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
userdata->
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
102
|
+
for (short int i = 0; i < userdata->nonblocking_errors_length; i++) {
|
103
|
+
tinytds_errordata error = userdata->nonblocking_errors[i];
|
104
|
+
|
105
|
+
// lookahead to drain any info messages ahead of raising error
|
106
|
+
if (!error.is_message) {
|
107
|
+
for (short int j = i; j < userdata->nonblocking_errors_length; j++) {
|
108
|
+
tinytds_errordata msg_error = userdata->nonblocking_errors[j];
|
109
|
+
if (msg_error.is_message) {
|
110
|
+
rb_tinytds_raise_error(client, msg_error);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
rb_tinytds_raise_error(client, error);
|
108
116
|
}
|
117
|
+
|
118
|
+
free(userdata->nonblocking_errors);
|
119
|
+
userdata->nonblocking_errors_length = 0;
|
120
|
+
userdata->nonblocking_errors_size = 0;
|
109
121
|
}
|
110
122
|
|
111
123
|
static RETCODE nogvl_dbsqlok(DBPROCESS *client) {
|
@@ -228,7 +240,7 @@ static VALUE rb_tinytds_result_fetch_row(VALUE self, ID timezone, int symbolize_
|
|
228
240
|
int data_slength = (int)data_info->precision + (int)data_info->scale + 1;
|
229
241
|
char converted_decimal[data_slength];
|
230
242
|
dbconvert(rwrap->client, coltype, data, data_len, SYBVARCHAR, (BYTE *)converted_decimal, -1);
|
231
|
-
val = rb_funcall(
|
243
|
+
val = rb_funcall(cKernel, intern_bigd, 1, rb_str_new2((char *)converted_decimal));
|
232
244
|
break;
|
233
245
|
}
|
234
246
|
case SYBFLT8: {
|
@@ -246,7 +258,7 @@ static VALUE rb_tinytds_result_fetch_row(VALUE self, ID timezone, int symbolize_
|
|
246
258
|
char converted_money[25];
|
247
259
|
long long money_value = ((long long)money->mnyhigh << 32) | money->mnylow;
|
248
260
|
sprintf(converted_money, "%" LONG_LONG_FORMAT, money_value);
|
249
|
-
val = rb_funcall(
|
261
|
+
val = rb_funcall(cKernel, intern_bigd, 2, rb_str_new2(converted_money), opt_four);
|
250
262
|
val = rb_funcall(val, intern_divide, 1, opt_tenk);
|
251
263
|
break;
|
252
264
|
}
|
@@ -254,7 +266,7 @@ static VALUE rb_tinytds_result_fetch_row(VALUE self, ID timezone, int symbolize_
|
|
254
266
|
DBMONEY4 *money = (DBMONEY4 *)data;
|
255
267
|
char converted_money[20];
|
256
268
|
sprintf(converted_money, "%f", money->mny4 / 10000.0);
|
257
|
-
val = rb_funcall(
|
269
|
+
val = rb_funcall(cKernel, intern_bigd, 1, rb_str_new2(converted_money));
|
258
270
|
break;
|
259
271
|
}
|
260
272
|
case SYBBINARY:
|
@@ -566,7 +578,7 @@ static VALUE rb_tinytds_result_insert(VALUE self) {
|
|
566
578
|
|
567
579
|
void init_tinytds_result() {
|
568
580
|
/* Data Classes */
|
569
|
-
|
581
|
+
cKernel = rb_const_get(rb_cObject, rb_intern("Kernel"));
|
570
582
|
cDate = rb_const_get(rb_cObject, rb_intern("Date"));
|
571
583
|
/* Define TinyTds::Result */
|
572
584
|
cTinyTdsResult = rb_define_class_under(mTinyTds, "Result", rb_cObject);
|
@@ -588,6 +600,7 @@ void init_tinytds_result() {
|
|
588
600
|
intern_new_offset = rb_intern("new_offset");
|
589
601
|
intern_plus = rb_intern("+");
|
590
602
|
intern_divide = rb_intern("/");
|
603
|
+
intern_bigd = rb_intern("BigDecimal");
|
591
604
|
/* Symbol Helpers */
|
592
605
|
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
593
606
|
sym_as = ID2SYM(rb_intern("as"));
|
data/tasks/native_gem.rake
CHANGED
@@ -8,7 +8,7 @@ task 'gem:windows' => ['ports:cross'] do
|
|
8
8
|
build = ['bundle']
|
9
9
|
|
10
10
|
# and finally build the native gem
|
11
|
-
build << 'rake cross native gem RUBY_CC_VERSION=2.
|
11
|
+
build << 'rake cross native gem RUBY_CC_VERSION=2.7.0:2.6.0:2.5.0:2.4.0 CFLAGS="-Wall" MAKE="make -j`nproc`"'
|
12
12
|
|
13
13
|
RakeCompilerDock.sh build.join(' && ')
|
14
14
|
end
|
data/tasks/ports.rake
CHANGED
@@ -6,14 +6,14 @@ require_relative 'ports/openssl'
|
|
6
6
|
require_relative 'ports/freetds'
|
7
7
|
require_relative '../ext/tiny_tds/extconsts'
|
8
8
|
|
9
|
-
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE if defined? OpenSSL
|
10
|
-
|
11
9
|
namespace :ports do
|
12
10
|
openssl = Ports::Openssl.new(OPENSSL_VERSION)
|
13
11
|
libiconv = Ports::Libiconv.new(ICONV_VERSION)
|
14
12
|
freetds = Ports::Freetds.new(FREETDS_VERSION)
|
15
13
|
|
16
14
|
directory "ports"
|
15
|
+
CLEAN.include "ports/*mingw32*"
|
16
|
+
CLEAN.include "ports/*.installed"
|
17
17
|
|
18
18
|
task :openssl, [:host] do |task, args|
|
19
19
|
args.with_defaults(host: RbConfig::CONFIG['host'])
|
@@ -71,15 +71,13 @@ namespace :ports do
|
|
71
71
|
task 'cross' do
|
72
72
|
require 'rake_compiler_dock'
|
73
73
|
|
74
|
-
# make sure to install our bundle
|
75
|
-
build = ['bundle']
|
76
|
-
|
77
74
|
# build the ports for all our cross compile hosts
|
78
75
|
GEM_PLATFORM_HOSTS.each do |gem_platform, host|
|
79
|
-
|
76
|
+
# make sure to install our bundle
|
77
|
+
build = ['bundle']
|
78
|
+
build << "rake ports:compile[#{host}] MAKE='make -j`nproc`'"
|
79
|
+
RakeCompilerDock.sh build.join(' && '), platform: gem_platform
|
80
80
|
end
|
81
|
-
|
82
|
-
RakeCompilerDock.sh build.join(' && ')
|
83
81
|
end
|
84
82
|
end
|
85
83
|
|
data/tasks/ports/openssl.rb
CHANGED
@@ -27,27 +27,11 @@ module Ports
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def execute(action, command, options={})
|
31
|
-
# OpenSSL Requires Perl >= 5.10, while the Ruby devkit uses MSYS1 with Perl 5.8.8.
|
32
|
-
# To overcome this, prepend Git's usr/bin to the PATH.
|
33
|
-
# It has MSYS2 with a recent version of perl.
|
34
|
-
prev_path = ENV['PATH']
|
35
|
-
if host =~ /mingw/ && IO.popen(["perl", "-e", "print($])"], &:read).to_f < 5.010
|
36
|
-
git_perl = 'C:/Program Files/Git/usr/bin'
|
37
|
-
if File.directory?(git_perl)
|
38
|
-
ENV['PATH'] = "#{git_perl}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
39
|
-
ENV['PERL'] = 'perl'
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
super
|
44
|
-
ENV['PATH'] = prev_path
|
45
|
-
end
|
46
|
-
|
47
30
|
def configure_defaults
|
48
31
|
opts = [
|
49
32
|
'shared',
|
50
|
-
target_arch
|
33
|
+
target_arch,
|
34
|
+
"--openssldir=#{path}",
|
51
35
|
]
|
52
36
|
|
53
37
|
if cross_build?
|
data/test/bin/setup.sh
CHANGED
data/test/client_test.rb
CHANGED
@@ -2,9 +2,7 @@
|
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
4
|
class ClientTest < TinyTds::TestCase
|
5
|
-
|
6
|
-
describe 'With valid credentials' do
|
7
|
-
|
5
|
+
describe 'with valid credentials' do
|
8
6
|
before do
|
9
7
|
@client = new_connection
|
10
8
|
end
|
@@ -67,10 +65,12 @@ class ClientTest < TinyTds::TestCase
|
|
67
65
|
client.close if client
|
68
66
|
end
|
69
67
|
end unless sqlserver_azure?
|
70
|
-
|
71
68
|
end
|
72
69
|
|
73
70
|
describe 'With in-valid options' do
|
71
|
+
before(:all) do
|
72
|
+
init_toxiproxy
|
73
|
+
end
|
74
74
|
|
75
75
|
it 'raises an argument error when no :host given and :dataserver is blank' do
|
76
76
|
assert_raises(ArgumentError) { new_connection :dataserver => nil, :host => nil }
|
@@ -132,30 +132,46 @@ class ClientTest < TinyTds::TestCase
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
it '
|
136
|
-
skip
|
135
|
+
it 'raises TinyTds exception with tcp socket network failure' do
|
136
|
+
skip if ENV['CI'] && ENV['APPVEYOR_BUILD_FOLDER'] # only CI using docker
|
137
137
|
begin
|
138
|
-
client = new_connection :
|
138
|
+
client = new_connection timeout: 2, port: 1234
|
139
139
|
assert_client_works(client)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
140
|
+
action = lambda { client.execute("waitfor delay '00:00:05'").do }
|
141
|
+
|
142
|
+
# Use toxiproxy to close the TCP socket after 1 second.
|
143
|
+
# We want TinyTds to execute the statement, hit the timeout configured above, and then not be able to use the network to cancel
|
144
|
+
# the network connection needs to close after the sql batch is sent and before the timeout above is hit
|
145
|
+
Toxiproxy[:sqlserver_test].toxic(:slow_close, delay: 1000).apply do
|
146
|
+
assert_raise_tinytds_error(action) do |e|
|
147
|
+
assert_equal 20003, e.db_error_number
|
148
|
+
assert_equal 6, e.severity
|
149
|
+
assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
|
150
|
+
end
|
148
151
|
end
|
149
152
|
ensure
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
153
|
+
assert_new_connections_work
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'raises TinyTds exception with dead connection network failure' do
|
158
|
+
skip if ENV['CI'] && ENV['APPVEYOR_BUILD_FOLDER'] # only CI using docker
|
159
|
+
begin
|
160
|
+
client = new_connection timeout: 2, port: 1234
|
161
|
+
assert_client_works(client)
|
162
|
+
action = lambda { client.execute("waitfor delay '00:00:05'").do }
|
163
|
+
|
164
|
+
# Use toxiproxy to close the network connection after 1 second.
|
165
|
+
# We want TinyTds to execute the statement, hit the timeout configured above, and then not be able to use the network to cancel
|
166
|
+
# the network connection needs to close after the sql batch is sent and before the timeout above is hit
|
167
|
+
Toxiproxy[:sqlserver_test].toxic(:timeout, timeout: 1000).apply do
|
168
|
+
assert_raise_tinytds_error(action) do |e|
|
169
|
+
assert_equal 20047, e.db_error_number
|
170
|
+
assert_includes [1,9], e.severity
|
171
|
+
assert_match %r{dead or not enabled}i, e.message, 'ignore if non-english test run'
|
172
|
+
end
|
157
173
|
end
|
158
|
-
|
174
|
+
ensure
|
159
175
|
assert_new_connections_work
|
160
176
|
end
|
161
177
|
end
|
@@ -174,57 +190,68 @@ class ClientTest < TinyTds::TestCase
|
|
174
190
|
|
175
191
|
end
|
176
192
|
|
177
|
-
describe '
|
178
|
-
|
193
|
+
describe '#parse_username' do
|
179
194
|
let(:client) { @client = new_connection }
|
180
195
|
|
181
|
-
it '
|
182
|
-
|
183
|
-
|
196
|
+
it 'returns username if azure is not true' do
|
197
|
+
_(
|
198
|
+
client.send(:parse_username, username: 'user@abc123.database.windows.net')
|
199
|
+
).must_equal 'user@abc123.database.windows.net'
|
184
200
|
end
|
185
201
|
|
186
|
-
it '
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
202
|
+
it 'returns short username if azure is true' do
|
203
|
+
_(
|
204
|
+
client.send(
|
205
|
+
:parse_username,
|
206
|
+
username: 'user@abc123.database.windows.net',
|
207
|
+
host: 'abc123.database.windows.net',
|
208
|
+
azure: true
|
209
|
+
)
|
191
210
|
).must_equal 'user@abc123'
|
192
211
|
end
|
193
212
|
|
194
|
-
it '
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
213
|
+
it 'returns full username if azure is false' do
|
214
|
+
_(
|
215
|
+
client.send(
|
216
|
+
:parse_username,
|
217
|
+
username: 'user@abc123.database.windows.net',
|
218
|
+
host: 'abc123.database.windows.net',
|
219
|
+
azure: false
|
220
|
+
)
|
199
221
|
).must_equal 'user@abc123.database.windows.net'
|
200
222
|
end
|
201
223
|
|
202
|
-
it '
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
224
|
+
it 'returns short username if passed and azure is true' do
|
225
|
+
_(
|
226
|
+
client.send(
|
227
|
+
:parse_username,
|
228
|
+
username: 'user@abc123',
|
229
|
+
host: 'abc123.database.windows.net',
|
230
|
+
azure: true
|
231
|
+
)
|
207
232
|
).must_equal 'user@abc123'
|
208
233
|
end
|
209
234
|
|
210
|
-
it '
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
235
|
+
it 'returns username with servername if passed and azure is true' do
|
236
|
+
_(
|
237
|
+
client.send(
|
238
|
+
:parse_username,
|
239
|
+
username: 'user',
|
240
|
+
host: 'abc123.database.windows.net',
|
241
|
+
azure: true
|
242
|
+
)
|
215
243
|
).must_equal 'user@abc123'
|
216
244
|
end
|
217
245
|
|
218
|
-
it '
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
246
|
+
it 'returns username with servername if passed and azure is false' do
|
247
|
+
_(
|
248
|
+
client.send(
|
249
|
+
:parse_username,
|
250
|
+
username: 'user',
|
251
|
+
host: 'abc123.database.windows.net',
|
252
|
+
azure: false
|
253
|
+
)
|
223
254
|
).must_equal 'user'
|
224
255
|
end
|
225
|
-
|
226
256
|
end
|
227
|
-
|
228
|
-
|
229
257
|
end
|
230
|
-
|