tiny_tds 1.0.4 → 3.2.0
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/.codeclimate.yml +20 -0
- data/.gitattributes +1 -0
- data/.github/workflows/ci.yml +590 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +31 -0
- data/{CHANGELOG → CHANGELOG.md} +133 -26
- data/Gemfile +1 -5
- data/ISSUE_TEMPLATE.md +36 -3
- data/README.md +147 -85
- data/Rakefile +51 -94
- data/VERSION +1 -1
- data/docker-compose.yml +34 -0
- data/ext/tiny_tds/client.c +149 -67
- data/ext/tiny_tds/client.h +11 -5
- data/ext/tiny_tds/extconf.rb +144 -283
- data/ext/tiny_tds/extconsts.rb +4 -11
- data/ext/tiny_tds/result.c +68 -50
- data/ext/tiny_tds/tiny_tds_ext.c +4 -1
- data/lib/tiny_tds/bin.rb +44 -40
- data/lib/tiny_tds/client.rb +63 -55
- data/lib/tiny_tds/error.rb +0 -3
- data/lib/tiny_tds/gem.rb +23 -0
- data/lib/tiny_tds/result.rb +0 -3
- data/lib/tiny_tds.rb +37 -32
- data/{ports/patches/freetds/1.00 → patches/freetds/1.00.27}/0001-mingw_missing_inet_pton.diff +4 -4
- data/patches/freetds/1.00.27/0002-Don-t-use-MSYS2-file-libws2_32.diff +28 -0
- data/patches/libiconv/1.14/1-avoid-gets-error.patch +17 -0
- data/setup_cimgruby_dev.sh +25 -0
- data/start_dev.sh +21 -0
- data/tasks/native_gem.rake +16 -0
- data/tasks/package.rake +6 -0
- data/tasks/ports.rake +24 -0
- data/tasks/test.rake +7 -0
- data/test/bin/install-freetds.sh +18 -0
- data/test/bin/install-mssql.ps1 +42 -0
- data/test/bin/install-mssqltools.sh +9 -0
- data/test/bin/install-openssl.sh +18 -0
- data/test/bin/restore-from-native-gem.ps1 +10 -0
- data/test/bin/setup_tinytds_db.sh +7 -0
- data/test/bin/setup_volume_permissions.sh +10 -0
- data/test/client_test.rb +161 -112
- data/test/gem_test.rb +100 -0
- data/test/result_test.rb +293 -313
- data/test/schema_test.rb +369 -395
- data/test/sql/db-create.sql +18 -0
- data/test/sql/db-login.sql +38 -0
- data/test/test_helper.rb +116 -85
- data/test/thread_test.rb +22 -31
- data/tiny_tds.gemspec +27 -24
- metadata +109 -56
- data/appveyor.yml +0 -51
- data/test/appveyor/dbsetup.ps1 +0 -27
- data/test/appveyor/dbsetup.sql +0 -9
- data/test/benchmark/query.rb +0 -77
- data/test/benchmark/query_odbc.rb +0 -106
- data/test/benchmark/query_tinytds.rb +0 -126
- data/test/schema/sqlserver_2000.sql +0 -140
- data/test/schema/sqlserver_2005.sql +0 -140
- data/test/schema/sqlserver_2014.sql +0 -140
- data/test/schema/sybase_ase.sql +0 -138
- /data/bin/{defncopy → defncopy-ttds} +0 -0
- /data/bin/{tsql → tsql-ttds} +0 -0
- /data/test/schema/{sqlserver_2008.sql → sqlserver_2017.sql} +0 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
From 56e8972f66c3e948e2ad6885595c58fd23dcdb37 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Lars Kanis <kanis@comcard.de>
|
3
|
+
Date: Thu, 6 Jul 2017 17:09:40 +0200
|
4
|
+
Subject: [PATCH] Don't use MSYS2 file libws2_32.a for MINGW build
|
5
|
+
|
6
|
+
This file is intended for MSYS2/cygwin builds and blocks OpenSSL
|
7
|
+
detection of freetds on i686.
|
8
|
+
---
|
9
|
+
configure | 2 --
|
10
|
+
configure.ac | 2 --
|
11
|
+
2 files changed, 4 deletions(-)
|
12
|
+
|
13
|
+
diff --git a/configure b/configure
|
14
|
+
index 9495a49..31eb01d 100644
|
15
|
+
--- a/configure
|
16
|
+
+++ b/configure
|
17
|
+
@@ -15915,8 +15915,6 @@ case $host in
|
18
|
+
tds_mingw=yes
|
19
|
+
if test "$host_cpu" = "x86_64"; then
|
20
|
+
LIBS="-lws2_32"
|
21
|
+
- elif test -r /usr/lib/w32api/libws2_32.a; then
|
22
|
+
- LIBS="-L/usr/lib/w32api -lws2_32"
|
23
|
+
else
|
24
|
+
LIBS="-lws2_32"
|
25
|
+
fi
|
26
|
+
--
|
27
|
+
2.6.2.windows.1
|
28
|
+
|
@@ -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,25 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -x
|
4
|
+
set -e
|
5
|
+
|
6
|
+
# this should mirror the steps outlined in the circleci yml
|
7
|
+
echo "Installing mssql-tools..."
|
8
|
+
sleep 5
|
9
|
+
sudo -E ./test/bin/install-mssqltools.sh
|
10
|
+
|
11
|
+
echo "Configurating tinytds test database..."
|
12
|
+
sleep 5
|
13
|
+
./test/bin/setup_tinytds_db.sh
|
14
|
+
|
15
|
+
echo "Building openssl library..."
|
16
|
+
sleep 5
|
17
|
+
sudo -E ./test/bin/install-openssl.sh
|
18
|
+
|
19
|
+
echo "Building freetds library..."
|
20
|
+
sleep 5
|
21
|
+
sudo -E ./test/bin/install-freetds.sh
|
22
|
+
|
23
|
+
echo "Installing gems..."
|
24
|
+
sleep 5
|
25
|
+
bundle install
|
data/start_dev.sh
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -x
|
4
|
+
set -e
|
5
|
+
|
6
|
+
# set volume read/write permissions to work both outside and inside container
|
7
|
+
sudo ./test/bin/setup_volume_permissions.sh
|
8
|
+
|
9
|
+
docker-compose up -d
|
10
|
+
echo "Waiting for containers to start..."
|
11
|
+
sleep 10
|
12
|
+
|
13
|
+
# setup circleci ruby container for development
|
14
|
+
docker exec cimg_ruby bash -c './setup_cimgruby_dev.sh'
|
15
|
+
|
16
|
+
# enter container
|
17
|
+
set +x
|
18
|
+
echo "cimg/ruby container is ready for tiny_tds development.........."
|
19
|
+
echo "To enter container run: docker exec -it cimg_ruby /bin/bash"
|
20
|
+
echo "To build solution run: docker exec cimg_ruby bash -c 'bundle exec rake build'"
|
21
|
+
echo "To test solution run: docker exec cimg_ruby bash -c 'bundle exec rake test'"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
CrossLibraries.each do |xlib|
|
2
|
+
platform = xlib.platform
|
3
|
+
|
4
|
+
desc "Build fat binary gem for platform #{platform}"
|
5
|
+
task "gem:native:#{platform}" do
|
6
|
+
require "rake_compiler_dock"
|
7
|
+
|
8
|
+
RakeCompilerDock.sh <<-EOT, platform: platform
|
9
|
+
bundle install &&
|
10
|
+
rake native:#{platform} pkg/#{SPEC.full_name}-#{platform}.gem MAKEOPTS=-j`nproc` RUBY_CC_VERSION=#{RakeCompilerDock.set_ruby_cc_version("~> 2.7", "~> 3.0")} MAKEFLAGS="V=1"
|
11
|
+
EOT
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Build the native binary gems"
|
15
|
+
multitask "gem:native" => "gem:native:#{platform}"
|
16
|
+
end
|
data/tasks/package.rake
ADDED
data/tasks/ports.rake
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative "../ext/tiny_tds/extconsts"
|
2
|
+
|
3
|
+
namespace :ports do
|
4
|
+
libraries_to_compile = {
|
5
|
+
openssl: OPENSSL_VERSION,
|
6
|
+
libiconv: ICONV_VERSION,
|
7
|
+
freetds: FREETDS_VERSION
|
8
|
+
}
|
9
|
+
|
10
|
+
desc "Notes the actual versions for the compiled ports into a file"
|
11
|
+
task "version_file", [:gem_platform] do |_task, args|
|
12
|
+
args.with_defaults(gem_platform: RbConfig::CONFIG["arch"])
|
13
|
+
|
14
|
+
ports_version = {}
|
15
|
+
|
16
|
+
libraries_to_compile.each do |library, version|
|
17
|
+
ports_version[library] = version
|
18
|
+
end
|
19
|
+
|
20
|
+
ports_version[:platform] = args.gem_platform
|
21
|
+
|
22
|
+
File.write(".ports_versions", ports_version)
|
23
|
+
end
|
24
|
+
end
|
data/tasks/test.rake
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -x
|
4
|
+
set -e
|
5
|
+
|
6
|
+
if [ -z "$FREETDS_VERSION" ]; then
|
7
|
+
FREETDS_VERSION=$(ruby -r "./ext/tiny_tds/extconsts.rb" -e "puts FREETDS_VERSION")
|
8
|
+
fi
|
9
|
+
|
10
|
+
wget http://www.freetds.org/files/stable/freetds-$FREETDS_VERSION.tar.gz
|
11
|
+
tar -xzf freetds-$FREETDS_VERSION.tar.gz
|
12
|
+
cd freetds-$FREETDS_VERSION
|
13
|
+
./configure
|
14
|
+
make
|
15
|
+
sudo make install
|
16
|
+
cd ..
|
17
|
+
rm -rf freetds-$FREETDS_VERSION
|
18
|
+
rm freetds-$FREETDS_VERSION.tar.gz
|
@@ -0,0 +1,42 @@
|
|
1
|
+
param ([int] $Version)
|
2
|
+
|
3
|
+
$ProgressPreference = 'SilentlyContinue'
|
4
|
+
|
5
|
+
$DownloadLinkTable = @{
|
6
|
+
2017 = "https://go.microsoft.com/fwlink/?linkid=829176";
|
7
|
+
2019 = "https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SQLEXPR_x64_ENU.exe";
|
8
|
+
2022 = "https://download.microsoft.com/download/3/8/d/38de7036-2433-4207-8eae-06e247e17b25/SQLEXPR_x64_ENU.exe";
|
9
|
+
}
|
10
|
+
|
11
|
+
$MajorVersionTable = @{
|
12
|
+
2017 = 14;
|
13
|
+
2019 = 15;
|
14
|
+
2022 = 16;
|
15
|
+
}
|
16
|
+
|
17
|
+
if (-not(Test-path "C:\Downloads")) {
|
18
|
+
mkdir "C:\Downloads"
|
19
|
+
}
|
20
|
+
|
21
|
+
$sqlInstallationFile = "C:\Downloads\sqlexpress.exe"
|
22
|
+
if (-not(Test-path $sqlInstallationFile -PathType leaf)) {
|
23
|
+
Write-Host "Downloading SQL Express ..."
|
24
|
+
Invoke-WebRequest -Uri $DownloadLinkTable[$Version] -OutFile "C:\Downloads\sqlexpress.exe"
|
25
|
+
}
|
26
|
+
|
27
|
+
Write-Host "Installing SQL Express ..."
|
28
|
+
Start-Process -Wait -FilePath "C:\Downloads\sqlexpress.exe" -ArgumentList /qs, /x:"C:\Downloads\setup"
|
29
|
+
C:\Downloads\setup\setup.exe /q /ACTION=Install /INSTANCENAME=SQLEXPRESS /FEATURES=SQLEngine /UPDATEENABLED=0 /SQLSVCACCOUNT='NT AUTHORITY\System' /SQLSYSADMINACCOUNTS='BUILTIN\ADMINISTRATORS' /TCPENABLED=1 /NPENABLED=0 /IACCEPTSQLSERVERLICENSETERMS
|
30
|
+
|
31
|
+
Write-Host "Configuring SQL Express ..."
|
32
|
+
stop-service MSSQL`$SQLEXPRESS
|
33
|
+
set-itemproperty -path "HKLM:\software\microsoft\microsoft sql server\mssql$($MajorVersionTable[$Version]).SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall" -name tcpdynamicports -value ''
|
34
|
+
set-itemproperty -path "HKLM:\software\microsoft\microsoft sql server\mssql$($MajorVersionTable[$Version]).SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall" -name tcpport -value 1433
|
35
|
+
set-itemproperty -path "HKLM:\software\microsoft\microsoft sql server\mssql$($MajorVersionTable[$Version]).SQLEXPRESS\mssqlserver\" -name LoginMode -value 2
|
36
|
+
|
37
|
+
Write-Host "Starting SQL Express ..."
|
38
|
+
start-service MSSQL`$SQLEXPRESS
|
39
|
+
|
40
|
+
Write-Host "Configuring MSSQL for TinyTDS ..."
|
41
|
+
& sqlcmd -i './test/sql/db-create.sql'
|
42
|
+
& sqlcmd -i './test/sql/db-login.sql'
|
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -x
|
4
|
+
set -e
|
5
|
+
|
6
|
+
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
|
7
|
+
curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list | sudo tee /etc/apt/sources.list.d/msprod.list
|
8
|
+
sudo apt-get update
|
9
|
+
sudo ACCEPT_EULA=Y apt-get -y install mssql-tools unixodbc-dev
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -x
|
4
|
+
set -e
|
5
|
+
|
6
|
+
if [ -z "$OPENSSL_VERSION" ]; then
|
7
|
+
OPENSSL_VERSION=$(ruby -r "./ext/tiny_tds/extconsts.rb" -e "puts OPENSSL_VERSION")
|
8
|
+
fi
|
9
|
+
|
10
|
+
wget https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz
|
11
|
+
tar -xzf openssl-$OPENSSL_VERSION.tar.gz
|
12
|
+
cd openssl-$OPENSSL_VERSION
|
13
|
+
./config --prefix=/opt/local --openssldir=/opt/local
|
14
|
+
make
|
15
|
+
make install_sw install_ssldirs
|
16
|
+
cd ..
|
17
|
+
rm -rf openssl-$OPENSSL_VERSION
|
18
|
+
rm openssl-$OPENSSL_VERSION.tar.gz
|
@@ -0,0 +1,10 @@
|
|
1
|
+
$gemVersion = (Get-Content VERSION).Trim()
|
2
|
+
$gemToUnpack = "./tiny_tds-$gemVersion-$env:RUBY_ARCHITECTURE.gem"
|
3
|
+
|
4
|
+
Write-Host "Looking to unpack $gemToUnpack"
|
5
|
+
gem unpack --target ./tmp "$gemToUnpack"
|
6
|
+
|
7
|
+
# Restore precompiled code
|
8
|
+
$source = (Resolve-Path ".\tmp\tiny_tds-$gemVersion-$env:RUBY_ARCHITECTURE\lib\tiny_tds").Path
|
9
|
+
$destination = (Resolve-Path ".\lib\tiny_tds").Path
|
10
|
+
Get-ChildItem $source -Recurse -Exclude "*.rb" | Copy-Item -Destination {Join-Path $destination $_.FullName.Substring($source.length)}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -x
|
4
|
+
|
5
|
+
sudo groupadd -g 3434 circleci_tinytds
|
6
|
+
sudo usermod -a -G circleci_tinytds $USER
|
7
|
+
sudo useradd circleci_tinytds -u 3434 -g 3434
|
8
|
+
sudo usermod -a -G circleci_tinytds circleci_tinytds
|
9
|
+
sudo chgrp -R circleci_tinytds .
|
10
|
+
sudo chmod -R g+rwx .
|
data/test/client_test.rb
CHANGED
@@ -1,113 +1,123 @@
|
|
1
|
-
|
2
|
-
require 'test_helper'
|
1
|
+
require "test_helper"
|
3
2
|
|
4
3
|
class ClientTest < TinyTds::TestCase
|
5
|
-
|
6
|
-
describe 'With valid credentials' do
|
7
|
-
|
4
|
+
describe "with valid credentials" do
|
8
5
|
before do
|
9
6
|
@client = new_connection
|
10
7
|
end
|
11
8
|
|
12
|
-
it
|
9
|
+
it "must not be closed" do
|
13
10
|
assert !@client.closed?
|
14
11
|
assert @client.active?
|
15
12
|
end
|
16
13
|
|
17
|
-
it
|
14
|
+
it "allows client connection to be closed" do
|
18
15
|
assert @client.close
|
19
16
|
assert @client.closed?
|
20
17
|
assert !@client.active?
|
21
|
-
|
18
|
+
assert @client.dead?
|
19
|
+
action = lambda { @client.execute("SELECT 1 as [one]").each }
|
22
20
|
assert_raise_tinytds_error(action) do |e|
|
23
|
-
assert_match %r{closed connection}i, e.message,
|
21
|
+
assert_match %r{closed connection}i, e.message, "ignore if non-english test run"
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
|
-
it
|
28
|
-
if
|
29
|
-
assert_equal 7, @client.tds_version
|
30
|
-
assert_equal 'DBTDS_5_0 - 5.0 SQL Server', @client.tds_version_info
|
31
|
-
elsif @client.tds_73?
|
25
|
+
it "has getters for the tds version information (brittle since conf takes precedence)" do
|
26
|
+
if @client.tds_73?
|
32
27
|
assert_equal 11, @client.tds_version
|
33
|
-
assert_equal
|
28
|
+
assert_equal "DBTDS_7_3 - Microsoft SQL Server 2008", @client.tds_version_info
|
34
29
|
else
|
35
30
|
assert_equal 9, @client.tds_version
|
36
|
-
assert_equal
|
31
|
+
assert_equal "DBTDS_7_1/DBTDS_8_0 - Microsoft SQL Server 2000", @client.tds_version_info
|
37
32
|
end
|
38
33
|
end
|
39
34
|
|
40
|
-
it
|
41
|
-
assert_equal
|
42
|
-
assert_equal Encoding.find(
|
35
|
+
it "uses UTF-8 client charset/encoding by default" do
|
36
|
+
assert_equal "UTF-8", @client.charset
|
37
|
+
assert_equal Encoding.find("UTF-8"), @client.encoding
|
43
38
|
end
|
44
39
|
|
45
|
-
it
|
40
|
+
it "has a #escape method used for quote strings" do
|
46
41
|
assert_equal "''hello''", @client.escape("'hello'")
|
47
42
|
end
|
48
43
|
|
49
|
-
|
50
|
-
|
51
|
-
client = new_connection(:
|
44
|
+
["CP850", "CP1252", "ISO-8859-1"].each do |encoding|
|
45
|
+
it "allows valid iconv character set - #{encoding}" do
|
46
|
+
client = new_connection(encoding: encoding)
|
52
47
|
assert_equal encoding, client.charset
|
53
48
|
assert_equal Encoding.find(encoding), client.encoding
|
54
|
-
|
49
|
+
ensure
|
50
|
+
client&.close
|
55
51
|
end
|
56
52
|
end
|
57
53
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
54
|
+
unless sqlserver_azure?
|
55
|
+
it "must be able to use :host/:port connection" do
|
56
|
+
host = ENV["TINYTDS_UNIT_HOST_TEST"] || ENV["TINYTDS_UNIT_HOST"] || "localhost"
|
57
|
+
port = ENV["TINYTDS_UNIT_PORT_TEST"] || ENV["TINYTDS_UNIT_PORT"] || 1433
|
58
|
+
begin
|
59
|
+
client = new_connection dataserver: nil, host: host, port: port
|
60
|
+
ensure
|
61
|
+
client&.close
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
65
|
end
|
66
66
|
|
67
|
-
describe
|
67
|
+
describe "With in-valid options" do
|
68
|
+
before(:all) do
|
69
|
+
init_toxiproxy
|
70
|
+
end
|
68
71
|
|
69
|
-
it
|
70
|
-
assert_raises(ArgumentError) { new_connection :
|
72
|
+
it "raises an argument error when no :host given and :dataserver is blank" do
|
73
|
+
assert_raises(ArgumentError) { new_connection dataserver: nil, host: nil }
|
71
74
|
end
|
72
75
|
|
73
|
-
it
|
74
|
-
assert_raises(ArgumentError) { TinyTds::Client.new :
|
76
|
+
it "raises an argument error when no :username is supplied" do
|
77
|
+
assert_raises(ArgumentError) { TinyTds::Client.new username: nil }
|
75
78
|
end
|
76
79
|
|
77
|
-
it
|
78
|
-
options = connection_options :
|
80
|
+
it "raises TinyTds exception with undefined :dataserver" do
|
81
|
+
options = connection_options login_timeout: 1, dataserver: "DOESNOTEXIST"
|
79
82
|
action = lambda { new_connection(options) }
|
80
83
|
assert_raise_tinytds_error(action) do |e|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
+
# Not sure why tese are different.
|
85
|
+
if ruby_darwin?
|
86
|
+
assert_equal 20009, e.db_error_number
|
87
|
+
assert_equal 9, e.severity
|
88
|
+
assert_match %r{is unavailable or does not exist}i, e.message, "ignore if non-english test run"
|
89
|
+
else
|
90
|
+
assert_equal 20012, e.db_error_number
|
91
|
+
assert_equal 2, e.severity
|
92
|
+
assert_match %r{server name not found in configuration files}i, e.message, "ignore if non-english test run"
|
93
|
+
end
|
84
94
|
end
|
85
95
|
assert_new_connections_work
|
86
96
|
end
|
87
97
|
|
88
|
-
it
|
89
|
-
client = new_connection :
|
98
|
+
it "raises TinyTds exception with long query past :timeout option" do
|
99
|
+
client = new_connection timeout: 1
|
90
100
|
action = lambda { client.execute("WaitFor Delay '00:00:02'").do }
|
91
101
|
assert_raise_tinytds_error(action) do |e|
|
92
102
|
assert_equal 20003, e.db_error_number
|
93
103
|
assert_equal 6, e.severity
|
94
|
-
assert_match %r{timed out}i, e.message,
|
104
|
+
assert_match %r{timed out}i, e.message, "ignore if non-english test run"
|
95
105
|
end
|
96
106
|
assert_client_works(client)
|
97
107
|
close_client(client)
|
98
108
|
assert_new_connections_work
|
99
109
|
end
|
100
110
|
|
101
|
-
it
|
102
|
-
client = new_connection :
|
111
|
+
it "must not timeout per sql batch when not under transaction" do
|
112
|
+
client = new_connection timeout: 2
|
103
113
|
client.execute("WaitFor Delay '00:00:01'").do
|
104
114
|
client.execute("WaitFor Delay '00:00:01'").do
|
105
115
|
client.execute("WaitFor Delay '00:00:01'").do
|
106
116
|
close_client(client)
|
107
117
|
end
|
108
118
|
|
109
|
-
it
|
110
|
-
client = new_connection :
|
119
|
+
it "must not timeout per sql batch when under transaction" do
|
120
|
+
client = new_connection timeout: 2
|
111
121
|
begin
|
112
122
|
client.execute("BEGIN TRANSACTION").do
|
113
123
|
client.execute("WaitFor Delay '00:00:01'").do
|
@@ -119,99 +129,138 @@ class ClientTest < TinyTds::TestCase
|
|
119
129
|
end
|
120
130
|
end
|
121
131
|
|
122
|
-
it
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
132
|
+
it "raises TinyTds exception with tcp socket network failure" do
|
133
|
+
client = new_connection timeout: 2, port: 1234, host: ENV["TOXIPROXY_HOST"]
|
134
|
+
assert_client_works(client)
|
135
|
+
action = lambda { client.execute("waitfor delay '00:00:05'").do }
|
136
|
+
|
137
|
+
# Use toxiproxy to close the TCP socket after 1 second.
|
138
|
+
# We want TinyTds to execute the statement, hit the timeout configured above, and then not be able to use the network to cancel
|
139
|
+
# the network connection needs to close after the sql batch is sent and before the timeout above is hit
|
140
|
+
Toxiproxy[:sqlserver_test].toxic(:slow_close, delay: 1000).apply do
|
131
141
|
assert_raise_tinytds_error(action) do |e|
|
132
142
|
assert_equal 20003, e.db_error_number
|
133
143
|
assert_equal 6, e.severity
|
134
|
-
assert_match %r{timed out}i, e.message,
|
144
|
+
assert_match %r{timed out}i, e.message, "ignore if non-english test run"
|
135
145
|
end
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
146
|
+
end
|
147
|
+
ensure
|
148
|
+
assert_new_connections_work
|
149
|
+
end
|
150
|
+
|
151
|
+
it "raises TinyTds exception with dead connection network failure" do
|
152
|
+
skip if ruby_windows?
|
153
|
+
|
154
|
+
begin
|
155
|
+
client = new_connection timeout: 2, port: 1234, host: ENV["TOXIPROXY_HOST"]
|
156
|
+
assert_client_works(client)
|
157
|
+
action = lambda { client.execute("waitfor delay '00:00:05'").do }
|
158
|
+
|
159
|
+
# Use toxiproxy to close the network connection after 1 second.
|
160
|
+
# We want TinyTds to execute the statement, hit the timeout configured above, and then not be able to use the network to cancel
|
161
|
+
# the network connection needs to close after the sql batch is sent and before the timeout above is hit
|
162
|
+
Toxiproxy[:sqlserver_test].toxic(:timeout, timeout: 1000).apply do
|
163
|
+
assert_raise_tinytds_error(action) do |e|
|
164
|
+
assert_equal 20047, e.db_error_number
|
165
|
+
assert_includes [1, 9], e.severity
|
166
|
+
assert_match %r{dead or not enabled}i, e.message, "ignore if non-english test run"
|
167
|
+
end
|
144
168
|
end
|
145
|
-
|
169
|
+
ensure
|
146
170
|
assert_new_connections_work
|
147
171
|
end
|
148
172
|
end
|
149
173
|
|
150
|
-
it
|
151
|
-
|
152
|
-
|
174
|
+
it "raises TinyTds exception with login timeout" do
|
175
|
+
action = lambda do
|
176
|
+
Toxiproxy[:sqlserver_test].toxic(:timeout, timeout: 0).apply do
|
177
|
+
new_connection login_timeout: 1, port: 1234, host: ENV["TOXIPROXY_HOST"]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
assert_raise_tinytds_error(action) do |e|
|
181
|
+
assert_equal 20003, e.db_error_number
|
182
|
+
assert_equal 6, e.severity
|
183
|
+
assert_match %r{timed out}i, e.message, "ignore if non-english test run"
|
184
|
+
end
|
185
|
+
ensure
|
186
|
+
assert_new_connections_work
|
187
|
+
end
|
188
|
+
|
189
|
+
it "raises TinyTds exception with wrong :username" do
|
190
|
+
skip if ENV["CI"] && sqlserver_azure? # Some issue with db_error_number.
|
191
|
+
options = connection_options username: "willnotwork"
|
153
192
|
action = lambda { new_connection(options) }
|
154
193
|
assert_raise_tinytds_error(action) do |e|
|
155
|
-
assert_equal
|
194
|
+
assert_equal 18456, e.db_error_number
|
156
195
|
assert_equal 14, e.severity
|
157
|
-
assert_match %r{login failed}i, e.message,
|
196
|
+
assert_match %r{login failed}i, e.message, "ignore if non-english test run"
|
158
197
|
end
|
159
198
|
assert_new_connections_work
|
160
199
|
end
|
161
|
-
|
162
200
|
end
|
163
201
|
|
164
|
-
describe
|
165
|
-
|
202
|
+
describe "#parse_username" do
|
166
203
|
let(:client) { @client = new_connection }
|
167
204
|
|
168
|
-
it
|
169
|
-
|
170
|
-
|
205
|
+
it "returns username if azure is not true" do
|
206
|
+
_(
|
207
|
+
client.send(:parse_username, username: "user@abc123.database.windows.net")
|
208
|
+
).must_equal "user@abc123.database.windows.net"
|
171
209
|
end
|
172
210
|
|
173
|
-
it
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
211
|
+
it "returns short username if azure is true" do
|
212
|
+
_(
|
213
|
+
client.send(
|
214
|
+
:parse_username,
|
215
|
+
username: "user@abc123.database.windows.net",
|
216
|
+
host: "abc123.database.windows.net",
|
217
|
+
azure: true
|
218
|
+
)
|
219
|
+
).must_equal "user@abc123"
|
179
220
|
end
|
180
221
|
|
181
|
-
it
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
222
|
+
it "returns full username if azure is false" do
|
223
|
+
_(
|
224
|
+
client.send(
|
225
|
+
:parse_username,
|
226
|
+
username: "user@abc123.database.windows.net",
|
227
|
+
host: "abc123.database.windows.net",
|
228
|
+
azure: false
|
229
|
+
)
|
230
|
+
).must_equal "user@abc123.database.windows.net"
|
187
231
|
end
|
188
232
|
|
189
|
-
it
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
233
|
+
it "returns short username if passed and azure is true" do
|
234
|
+
_(
|
235
|
+
client.send(
|
236
|
+
:parse_username,
|
237
|
+
username: "user@abc123",
|
238
|
+
host: "abc123.database.windows.net",
|
239
|
+
azure: true
|
240
|
+
)
|
241
|
+
).must_equal "user@abc123"
|
195
242
|
end
|
196
243
|
|
197
|
-
it
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
244
|
+
it "returns username with servername if passed and azure is true" do
|
245
|
+
_(
|
246
|
+
client.send(
|
247
|
+
:parse_username,
|
248
|
+
username: "user",
|
249
|
+
host: "abc123.database.windows.net",
|
250
|
+
azure: true
|
251
|
+
)
|
252
|
+
).must_equal "user@abc123"
|
203
253
|
end
|
204
254
|
|
205
|
-
it
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
255
|
+
it "returns username with servername if passed and azure is false" do
|
256
|
+
_(
|
257
|
+
client.send(
|
258
|
+
:parse_username,
|
259
|
+
username: "user",
|
260
|
+
host: "abc123.database.windows.net",
|
261
|
+
azure: false
|
262
|
+
)
|
263
|
+
).must_equal "user"
|
211
264
|
end
|
212
|
-
|
213
265
|
end
|
214
|
-
|
215
|
-
|
216
266
|
end
|
217
|
-
|