tiny_tds 2.1.7 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +470 -0
- data/CHANGELOG.md +10 -0
- data/ISSUE_TEMPLATE.md +1 -1
- data/README.md +25 -45
- data/Rakefile +1 -5
- data/VERSION +1 -1
- data/docker-compose.yml +2 -2
- data/ext/tiny_tds/client.c +8 -15
- data/ext/tiny_tds/extconf.rb +1 -2
- data/ext/tiny_tds/extconsts.rb +4 -10
- data/ext/tiny_tds/result.c +27 -35
- data/ext/tiny_tds/tiny_tds_ext.c +4 -1
- data/tasks/ports/freetds.rb +1 -6
- data/tasks/ports.rake +2 -2
- data/test/bin/install-mssql.ps1 +22 -11
- data/test/client_test.rb +2 -5
- data/test/gem_test.rb +0 -1
- data/test/result_test.rb +99 -192
- data/test/schema_test.rb +366 -388
- data/test/test_helper.rb +6 -37
- data/tiny_tds.gemspec +3 -2
- metadata +23 -14
- data/.circleci/config.yml +0 -409
- 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/sqlserver_2016.sql +0 -140
- data/test/schema/sybase_ase.sql +0 -138
- /data/test/schema/{sqlserver_2008.sql → sqlserver_2017.sql} +0 -0
data/Rakefile
CHANGED
@@ -8,13 +8,9 @@ require_relative './ext/tiny_tds/extconsts'
|
|
8
8
|
SPEC = Gem::Specification.load(File.expand_path('../tiny_tds.gemspec', __FILE__))
|
9
9
|
|
10
10
|
ruby_cc_ucrt_versions = "3.3.0:3.2.0:3.1.0".freeze
|
11
|
-
ruby_cc_mingw32_versions = "3.0.0:2.7.0
|
11
|
+
ruby_cc_mingw32_versions = "3.0.0:2.7.0".freeze
|
12
12
|
|
13
13
|
GEM_PLATFORM_HOSTS = {
|
14
|
-
'x86-mingw32' => {
|
15
|
-
host: 'i686-w64-mingw32',
|
16
|
-
ruby_versions: ruby_cc_mingw32_versions
|
17
|
-
},
|
18
14
|
'x64-mingw32' => {
|
19
15
|
host: 'x86_64-w64-mingw32',
|
20
16
|
ruby_versions: ruby_cc_mingw32_versions
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.0
|
data/docker-compose.yml
CHANGED
@@ -5,11 +5,11 @@ networks:
|
|
5
5
|
|
6
6
|
services:
|
7
7
|
mssql:
|
8
|
-
image:
|
8
|
+
image: mcr.microsoft.com/mssql/server:${MSSQL_VERSION:-2017}-latest
|
9
9
|
container_name: sqlserver
|
10
10
|
environment:
|
11
11
|
ACCEPT_EULA: Y
|
12
|
-
|
12
|
+
MSSQL_SA_PASSWORD: super01S3cUr3
|
13
13
|
ports:
|
14
14
|
- "1433:1433"
|
15
15
|
network_mode: "host"
|
data/ext/tiny_tds/client.c
CHANGED
@@ -299,8 +299,7 @@ static VALUE rb_tinytds_execute(VALUE self, VALUE sql) {
|
|
299
299
|
REQUIRE_OPEN_CLIENT(cwrap);
|
300
300
|
dbcmd(cwrap->client, StringValueCStr(sql));
|
301
301
|
if (dbsqlsend(cwrap->client) == FAIL) {
|
302
|
-
|
303
|
-
return Qfalse;
|
302
|
+
rb_raise(cTinyTdsError, "failed dbsqlsend() function");
|
304
303
|
}
|
305
304
|
cwrap->userdata->dbsql_sent = 1;
|
306
305
|
result = rb_tinytds_new_result_obj(cwrap);
|
@@ -404,17 +403,15 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
|
|
404
403
|
#endif
|
405
404
|
}
|
406
405
|
}
|
407
|
-
|
408
|
-
|
409
|
-
if (use_utf16 == Qfalse) { DBSETLUTF16(cwrap->login, 0); }
|
410
|
-
#else
|
411
|
-
if (use_utf16 == Qtrue || use_utf16 == Qfalse) {
|
412
|
-
rb_warning("TinyTds: Please consider upgrading to FreeTDS 0.99 or higher for better unicode support.\n");
|
413
|
-
}
|
414
|
-
#endif
|
406
|
+
if (use_utf16 == Qtrue) { DBSETLUTF16(cwrap->login, 1); }
|
407
|
+
if (use_utf16 == Qfalse) { DBSETLUTF16(cwrap->login, 0); }
|
415
408
|
|
416
409
|
cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver));
|
417
410
|
if (cwrap->client) {
|
411
|
+
if (dbtds(cwrap->client) < 11) {
|
412
|
+
rb_raise(cTinyTdsError, "connecting with a TDS version older than 7.3!");
|
413
|
+
}
|
414
|
+
|
418
415
|
VALUE transposed_encoding, timeout_string;
|
419
416
|
|
420
417
|
cwrap->closed = 0;
|
@@ -435,11 +432,7 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
|
|
435
432
|
}
|
436
433
|
transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
|
437
434
|
cwrap->encoding = rb_enc_find(StringValueCStr(transposed_encoding));
|
438
|
-
|
439
|
-
cwrap->identity_insert_sql = "SELECT CAST(@@IDENTITY AS bigint) AS Ident";
|
440
|
-
} else {
|
441
|
-
cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident";
|
442
|
-
}
|
435
|
+
cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident";
|
443
436
|
}
|
444
437
|
return self;
|
445
438
|
}
|
data/ext/tiny_tds/extconf.rb
CHANGED
@@ -22,7 +22,6 @@ do_help if arg_config('--help')
|
|
22
22
|
|
23
23
|
# Make sure to check the ports path for the configured host
|
24
24
|
architecture = RbConfig::CONFIG['arch']
|
25
|
-
architecture = "x86-mingw32" if architecture == "i386-mingw32"
|
26
25
|
|
27
26
|
project_dir = File.expand_path("../../..", __FILE__)
|
28
27
|
freetds_ports_dir = File.join(project_dir, 'ports', architecture, 'freetds', FREETDS_VERSION)
|
@@ -84,7 +83,7 @@ have_dependencies = [
|
|
84
83
|
end
|
85
84
|
|
86
85
|
unless have_dependencies
|
87
|
-
abort 'Failed! Do you have FreeTDS 0.
|
86
|
+
abort 'Failed! Do you have FreeTDS 1.0.0 or higher installed?'
|
88
87
|
end
|
89
88
|
|
90
89
|
create_makefile('tiny_tds/tiny_tds')
|
data/ext/tiny_tds/extconsts.rb
CHANGED
@@ -1,15 +1,9 @@
|
|
1
1
|
|
2
|
-
ICONV_VERSION = ENV['TINYTDS_ICONV_VERSION'] || "1.
|
2
|
+
ICONV_VERSION = ENV['TINYTDS_ICONV_VERSION'] || "1.17"
|
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'] || '
|
5
|
+
OPENSSL_VERSION = ENV['TINYTDS_OPENSSL_VERSION'] || '3.4.0'
|
6
6
|
OPENSSL_SOURCE_URI = "https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
|
7
7
|
|
8
|
-
FREETDS_VERSION = ENV['TINYTDS_FREETDS_VERSION'] ||
|
9
|
-
|
10
|
-
h[k] = {files: "http://www.freetds.org/files/stable/freetds-#{k}.tar.bz2"}
|
11
|
-
}
|
12
|
-
FREETDS_VERSION_INFO['1.00'] = {files: 'http://www.freetds.org/files/stable/freetds-1.00.tar.bz2'}
|
13
|
-
FREETDS_VERSION_INFO['0.99'] = {files: 'http://www.freetds.org/files/current/freetds-dev.0.99.678.tar.gz'}
|
14
|
-
FREETDS_VERSION_INFO['0.95'] = {files: 'http://www.freetds.org/files/stable/freetds-0.95.92.tar.gz'}
|
15
|
-
FREETDS_SOURCE_URI = FREETDS_VERSION_INFO[FREETDS_VERSION][:files]
|
8
|
+
FREETDS_VERSION = ENV['TINYTDS_FREETDS_VERSION'] || '1.4.23'
|
9
|
+
FREETDS_SOURCE_URI = "http://www.freetds.org/files/stable/freetds-#{FREETDS_VERSION}.tar.bz2"
|
data/ext/tiny_tds/result.c
CHANGED
@@ -298,42 +298,34 @@ static VALUE rb_tinytds_result_fetch_row(VALUE self, ID timezone, int symbolize_
|
|
298
298
|
}
|
299
299
|
break;
|
300
300
|
}
|
301
|
-
case
|
302
|
-
case
|
303
|
-
case
|
304
|
-
case
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
val = rb_funcall(cDate, intern_new, 3, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day));
|
312
|
-
break;
|
313
|
-
}
|
314
|
-
case 41: { // SYBMSTIME
|
315
|
-
VALUE rational_nsec = rb_Rational(INT2NUM(dr2.nanosecond), opt_onek);
|
316
|
-
val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(1900), INT2NUM(1), INT2NUM(1), INT2NUM(dr2.hour), INT2NUM(dr2.minute), INT2NUM(dr2.second), rational_nsec);
|
317
|
-
break;
|
318
|
-
}
|
319
|
-
case 42: { // SYBMSDATETIME2
|
320
|
-
VALUE rational_nsec = rb_Rational(INT2NUM(dr2.nanosecond), opt_onek);
|
321
|
-
val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day), INT2NUM(dr2.hour), INT2NUM(dr2.minute), INT2NUM(dr2.second), rational_nsec);
|
322
|
-
break;
|
323
|
-
}
|
324
|
-
case 43: { // SYBMSDATETIMEOFFSET
|
325
|
-
long long numerator = ((long)dr2.second * (long long)1000000000) + (long long)dr2.nanosecond;
|
326
|
-
VALUE rational_sec = rb_Rational(LL2NUM(numerator), opt_onebil);
|
327
|
-
val = rb_funcall(rb_cTime, intern_new, 7, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day), INT2NUM(dr2.hour), INT2NUM(dr2.minute), rational_sec, INT2NUM(dr2.tzone*60));
|
328
|
-
break;
|
329
|
-
}
|
330
|
-
}
|
331
|
-
} else {
|
332
|
-
val = ENCODED_STR_NEW(data, data_len);
|
301
|
+
case SYBMSDATE:
|
302
|
+
case SYBMSTIME:
|
303
|
+
case SYBMSDATETIME2:
|
304
|
+
case SYBMSDATETIMEOFFSET: {
|
305
|
+
DBDATEREC2 dr2;
|
306
|
+
dbanydatecrack(rwrap->client, &dr2, coltype, data);
|
307
|
+
switch(coltype) {
|
308
|
+
case SYBMSDATE: {
|
309
|
+
val = rb_funcall(cDate, intern_new, 3, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day));
|
310
|
+
break;
|
333
311
|
}
|
334
|
-
|
335
|
-
|
336
|
-
|
312
|
+
case SYBMSTIME: {
|
313
|
+
VALUE rational_nsec = rb_Rational(INT2NUM(dr2.nanosecond), opt_onek);
|
314
|
+
val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(1900), INT2NUM(1), INT2NUM(1), INT2NUM(dr2.hour), INT2NUM(dr2.minute), INT2NUM(dr2.second), rational_nsec);
|
315
|
+
break;
|
316
|
+
}
|
317
|
+
case SYBMSDATETIME2: {
|
318
|
+
VALUE rational_nsec = rb_Rational(INT2NUM(dr2.nanosecond), opt_onek);
|
319
|
+
val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day), INT2NUM(dr2.hour), INT2NUM(dr2.minute), INT2NUM(dr2.second), rational_nsec);
|
320
|
+
break;
|
321
|
+
}
|
322
|
+
case SYBMSDATETIMEOFFSET: {
|
323
|
+
long long numerator = ((long)dr2.second * (long long)1000000000) + (long long)dr2.nanosecond;
|
324
|
+
VALUE rational_sec = rb_Rational(LL2NUM(numerator), opt_onebil);
|
325
|
+
val = rb_funcall(rb_cTime, intern_new, 7, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day), INT2NUM(dr2.hour), INT2NUM(dr2.minute), rational_sec, INT2NUM(dr2.tzone*60));
|
326
|
+
break;
|
327
|
+
}
|
328
|
+
}
|
337
329
|
break;
|
338
330
|
}
|
339
331
|
case SYBCHAR:
|
data/ext/tiny_tds/tiny_tds_ext.c
CHANGED
data/tasks/ports/freetds.rb
CHANGED
@@ -15,12 +15,7 @@ module Ports
|
|
15
15
|
|
16
16
|
opts << '--with-pic'
|
17
17
|
opts << '--disable-odbc'
|
18
|
-
|
19
|
-
if version =~ /0\.91/
|
20
|
-
opts << '--with-tdsver=7.1'
|
21
|
-
else
|
22
|
-
opts << '--with-tdsver=7.3'
|
23
|
-
end
|
18
|
+
opts << '--with-tdsver=7.3'
|
24
19
|
|
25
20
|
if windows?
|
26
21
|
opts << '--sysconfdir=C:/Sites'
|
data/tasks/ports.rake
CHANGED
@@ -48,10 +48,10 @@ namespace :ports do
|
|
48
48
|
if libraries_to_compile[:openssl]
|
49
49
|
# freetds doesn't have an option that will provide an rpath
|
50
50
|
# so we do it manually
|
51
|
-
ENV['OPENSSL_CFLAGS'] = "-Wl,-rpath -Wl,#{libraries_to_compile[:openssl].path}/
|
51
|
+
ENV['OPENSSL_CFLAGS'] = "-Wl,-rpath -Wl,#{libraries_to_compile[:openssl].path}/lib64"
|
52
52
|
# Add the pkgconfig file with MSYS2'ish path, to prefer our ports build
|
53
53
|
# over MSYS2 system OpenSSL.
|
54
|
-
ENV['PKG_CONFIG_PATH'] = "#{libraries_to_compile[:openssl].path.gsub(/^(\w):/i) { "/" + $1.downcase }}/
|
54
|
+
ENV['PKG_CONFIG_PATH'] = "#{libraries_to_compile[:openssl].path.gsub(/^(\w):/i) { "/" + $1.downcase }}/lib64/pkgconfig:#{ENV['PKG_CONFIG_PATH']}"
|
55
55
|
libraries_to_compile[:freetds].configure_options << "--with-openssl=#{libraries_to_compile[:openssl].path}"
|
56
56
|
end
|
57
57
|
|
data/test/bin/install-mssql.ps1
CHANGED
@@ -1,15 +1,27 @@
|
|
1
|
+
param ([int] $Version)
|
2
|
+
|
1
3
|
$ProgressPreference = 'SilentlyContinue'
|
2
4
|
|
3
|
-
|
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")) {
|
5
18
|
mkdir "C:\Downloads"
|
6
19
|
}
|
7
20
|
|
8
21
|
$sqlInstallationFile = "C:\Downloads\sqlexpress.exe"
|
9
|
-
if (-not(Test-path $sqlInstallationFile -PathType leaf))
|
10
|
-
{
|
22
|
+
if (-not(Test-path $sqlInstallationFile -PathType leaf)) {
|
11
23
|
Write-Host "Downloading SQL Express ..."
|
12
|
-
Invoke-WebRequest -Uri
|
24
|
+
Invoke-WebRequest -Uri $DownloadLinkTable[$Version] -OutFile "C:\Downloads\sqlexpress.exe"
|
13
25
|
}
|
14
26
|
|
15
27
|
Write-Host "Installing SQL Express ..."
|
@@ -18,14 +30,13 @@ C:\Downloads\setup\setup.exe /q /ACTION=Install /INSTANCENAME=SQLEXPRESS /FEATUR
|
|
18
30
|
|
19
31
|
Write-Host "Configuring SQL Express ..."
|
20
32
|
stop-service MSSQL`$SQLEXPRESS
|
21
|
-
set-itemproperty -path
|
22
|
-
set-itemproperty -path
|
23
|
-
set-itemproperty -path
|
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
|
24
36
|
|
25
37
|
Write-Host "Starting SQL Express ..."
|
26
38
|
start-service MSSQL`$SQLEXPRESS
|
27
39
|
|
28
40
|
Write-Host "Configuring MSSQL for TinyTDS ..."
|
29
|
-
& sqlcmd -
|
30
|
-
& sqlcmd -
|
31
|
-
& sqlcmd -Q "USE [tinytdstest]; CREATE USER [tinytds] FOR LOGIN [tinytds]; EXEC sp_addrolemember N'db_owner', N'tinytds';"
|
41
|
+
& sqlcmd -i './test/sql/db-create.sql'
|
42
|
+
& sqlcmd -i './test/sql/db-login.sql'
|
data/test/client_test.rb
CHANGED
@@ -24,10 +24,7 @@ class ClientTest < TinyTds::TestCase
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'has getters for the tds version information (brittle since conf takes precedence)' do
|
27
|
-
if
|
28
|
-
assert_equal 7, @client.tds_version
|
29
|
-
assert_equal 'DBTDS_5_0 - 5.0 SQL Server', @client.tds_version_info
|
30
|
-
elsif @client.tds_73?
|
27
|
+
if @client.tds_73?
|
31
28
|
assert_equal 11, @client.tds_version
|
32
29
|
assert_equal 'DBTDS_7_3 - Microsoft SQL Server 2008', @client.tds_version_info
|
33
30
|
else
|
@@ -199,7 +196,7 @@ class ClientTest < TinyTds::TestCase
|
|
199
196
|
options = connection_options :username => 'willnotwork'
|
200
197
|
action = lambda { new_connection(options) }
|
201
198
|
assert_raise_tinytds_error(action) do |e|
|
202
|
-
assert_equal
|
199
|
+
assert_equal 18456, e.db_error_number
|
203
200
|
assert_equal 14, e.severity
|
204
201
|
assert_match %r{login failed}i, e.message, 'ignore if non-english test run'
|
205
202
|
end
|
data/test/gem_test.rb
CHANGED
@@ -158,7 +158,6 @@ class GemTest < MiniTest::Spec
|
|
158
158
|
{
|
159
159
|
'x64-mingw-ucrt' => 'x64-mingw-ucrt',
|
160
160
|
'x64-mingw32' => 'x64-mingw32',
|
161
|
-
'x86-mingw32' => 'x86-mingw32',
|
162
161
|
'x86_64-linux' => 'x86_64-linux',
|
163
162
|
}.each do |host,expected|
|
164
163
|
describe "on a #{host} architecture" do
|