Skip to content

Commit 6f88538

Browse files
authored
Merge pull request #554 from andyundso/adjust-sql-server-support
Drop support for SQL server < 2017
2 parents 8e27be2 + bf00434 commit 6f88538

22 files changed

+591
-1449
lines changed

.circleci/config.yml

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ commands:
5555
jobs:
5656
test_linux:
5757
parameters:
58+
mssql_version:
59+
description: 'Version of MSSQL to be used'
60+
type: string
61+
5862
ruby_version:
5963
description: 'version tag for the cimg/ruby container'
6064
type: string
@@ -74,6 +78,7 @@ jobs:
7478
echo "Waiting for containers to start..."
7579
sleep 10
7680
environment:
81+
MSSQL_VERSION: << parameters.mssql_version >>
7782
RUBY_VERSION: << parameters.ruby_version >>
7883

7984
- run:
@@ -133,6 +138,10 @@ jobs:
133138

134139
test_windows:
135140
parameters:
141+
mssql_version:
142+
description: 'Version of MSSQL to be used'
143+
type: string
144+
136145
ruby_version:
137146
description: 'version tag for rubydev environment'
138147
type: string
@@ -193,18 +202,18 @@ jobs:
193202
194203
- restore_cache:
195204
name: restore mssql installation file
196-
key: downloads-{{ checksum "test/bin/install-mssql.ps1" }}
205+
key: downloads-<< parameters.mssql_version >>-{{ checksum "test/bin/install-mssql.ps1" }}
197206

198207
- run:
199208
name: setup mssql
200209
command: |
201-
.\test\bin\install-mssql.ps1
210+
.\test\bin\install-mssql.ps1 -Version << parameters.mssql_version >>
202211
203212
- save_cache:
204213
name: save downloads cache
205214
paths:
206215
- C:\Downloads
207-
key: downloads-{{ checksum "test/bin/install-mssql.ps1" }}
216+
key: downloads-<< parameters.mssql_version >>-{{ checksum "test/bin/install-mssql.ps1" }}
208217

209218
- run:
210219
name: install toxiproxy-server
@@ -382,16 +391,27 @@ workflows:
382391
- test_windows:
383392
requires:
384393
- cross_compile_gem
385-
matrix: &ruby_versions
394+
matrix:
386395
parameters:
387-
ruby_version:
396+
mssql_version: &mssql_versions
397+
- '2017'
398+
- '2019'
399+
- '2022'
400+
401+
ruby_version: &ruby_versions
388402
- '2.7'
389403
- '3.0'
390404
- '3.1'
391405
- '3.2'
392406
- '3.3'
407+
393408
- test_linux:
394-
matrix: *ruby_versions
409+
matrix:
410+
parameters:
411+
mssql_version: *mssql_versions
412+
ruby_version: *ruby_versions
395413

396414
- install_windows:
397-
matrix: *ruby_versions
415+
matrix:
416+
parameters:
417+
ruby_version: *ruby_versions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
## (unreleased)
22

33
* Drop support for Ruby < 2.7
4+
* Drop support for SQL Server < 2017
5+
* Drop support for FreeTDS < 1.0
46

57
## 2.1.7
68
* Add Ruby 3.3 to the cross compile list

ISSUE_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
* On Windows? If so, do you need devkit for your ruby install?
44
* Using Ubuntu? If so, you may have forgotten to install FreeTDS first.
5-
* Are you using FreeTDS 0.95.80 or later? Check `$ tsql -C` to find out.
5+
* Are you using FreeTDS 1.0.0 or later? Check `$ tsql -C` to find out.
66
* If not, please update then uninstall the TinyTDS gem and re-install it.
77
* Have you made sure to [enable SQL Server authentication](http://bit.ly/1Kw3set)?
88
* Doing work with threads and the raw client? Use the ConnectionPool gem?

README.md

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
## About TinyTDS
88

9-
The TinyTDS gem is meant to serve the extremely common use-case of connecting, querying and iterating over results to Microsoft SQL Server or Sybase databases from Ruby using the FreeTDS's DB-Library API.
9+
The TinyTDS gem is meant to serve the extremely common use-case of connecting, querying and iterating over results to Microsoft SQL Server from Ruby using the FreeTDS's DB-Library API.
1010

11-
TinyTDS offers automatic casting to Ruby primitives along with proper encoding support. It converts all SQL Server datatypes to native Ruby primitives while supporting :utc or :local time zones for time-like types. To date it is the only Ruby client library that allows client encoding options, defaulting to UTF-8, while connecting to SQL Server. It also properly encodes all string and binary data. The motivation for TinyTDS is to become the de-facto low level connection mode for the SQL Server Adapter for ActiveRecord.
11+
TinyTDS offers automatic casting to Ruby primitives along with proper encoding support. It converts all SQL Server datatypes to native Ruby primitives while supporting :utc or :local time zones for time-like types. To date it is the only Ruby client library that allows client encoding options, defaulting to UTF-8, while connecting to SQL Server. It also properly encodes all string and binary data.
1212

1313
The API is simple and consists of these classes:
1414

@@ -19,14 +19,14 @@ The API is simple and consists of these classes:
1919

2020
## Install
2121

22-
Installing with rubygems should just work. TinyTDS is currently tested on Ruby version 2.0.0 and upward.
22+
Installing with rubygems should just work. TinyTDS is currently tested on Ruby version 2.7.0 and upward.
2323

2424
```
2525
$ gem install tiny_tds
2626
```
2727

2828
If you use Windows, we pre-compile TinyTDS with static versions of FreeTDS and supporting libraries.
29-
If you're using RubyInstaller the binary gem will require that devkit is installed and in your path to operate properly.
29+
If you're using RubyInstaller, the binary gem will require that devkit is installed and in your path to operate properly.
3030

3131
On all other platforms, we will find these dependencies. It is recommended that you install the latest FreeTDS via your method of choice. For example, here is how to install FreeTDS on Ubuntu. You might also need the `build-essential` and possibly the `libc6-dev` packages.
3232

@@ -35,10 +35,10 @@ $ apt-get install wget
3535
$ apt-get install build-essential
3636
$ apt-get install libc6-dev
3737

38-
$ wget http://www.freetds.org/files/stable/freetds-1.1.24.tar.gz
39-
$ tar -xzf freetds-1.1.24.tar.gz
40-
$ cd freetds-1.1.24
41-
$ ./configure --prefix=/usr/local --with-tdsver=7.3
38+
$ wget http://www.freetds.org/files/stable/freetds-1.4.10.tar.gz
39+
$ tar -xzf freetds-1.4.10.tar.gz
40+
$ cd freetds-1.4.10
41+
$ ./configure --prefix=/usr/local --with-tdsver=7.4
4242
$ make
4343
$ make install
4444
```
@@ -53,26 +53,22 @@ Please read the MiniPortile and/or Windows sections at the end of this file for
5353

5454
## Getting Started
5555

56-
Optionally, Microsoft has done a great job writing some articles on how to get started with SQL Server and Ruby using TinyTDS. Please checkout one of the following posts that match your platform.
57-
58-
* [SQL Server on a Mac](https://www.microsoft.com/en-us/sql-server/developer-get-started/ruby/mac)
59-
* [SQL Server on RHEL](https://www.microsoft.com/en-us/sql-server/developer-get-started/ruby/rhel)
60-
* [SQL Server on Ubuntu](https://www.microsoft.com/en-us/sql-server/developer-get-started/ruby/ubuntu)
56+
Optionally, Microsoft has done a great job writing [an article](https://learn.microsoft.com/en-us/sql/connect/ruby/ruby-driver-for-sql-server?view=sql-server-ver16) on how to get started with SQL Server and Ruby using TinyTDS, however, the articles are using outdated versions.
6157

6258

6359
## FreeTDS Compatibility & Configuration
6460

65-
TinyTDS is developed against FreeTDS 0.95, 0.99, and 1.0 current. Our default and recommended is 1.0. We also test with SQL Server 2008, 2014, and Azure. However, usage of TinyTDS with SQL Server 2000 or 2005 should be just fine. Below are a few QA style notes about installing FreeTDS.
61+
TinyTDS is developed against FreeTDs 1.1+. We also test with SQL Server 2017, 2019, 2022 and Azure. Older version of SQL Server or FreeTDS could work, but are not supported.
6662

67-
**NOTE:** Windows users of our pre-compiled native gems need not worry about installing FreeTDS and its dependencies.
63+
> [!IMPORTANT]
64+
>
65+
> Windows users of our pre-compiled native gems need not worry about installing FreeTDS and its dependencies.
6866
6967
* **Do I need to install FreeTDS?** Yes! Somehow, someway, you are going to need FreeTDS for TinyTDS to compile against.
7068

7169
* **OK, I am installing FreeTDS, how do I configure it?** Contrary to what most people think, you do not need to specially configure FreeTDS in any way for client libraries like TinyTDS to use it. About the only requirement is that you compile it with libiconv for proper encoding support. FreeTDS must also be compiled with OpenSSL (or the like) to use it with Azure. See the "Using TinyTDS with Azure" section below for more info.
7270

73-
* **Do I need to configure `--with-tdsver` equal to anything?** Most likely! Technically you should not have to. This is only a default for clients/configs that do not specify what TDS version they want to use. We are currently having issues with passing down a TDS version with the login bit. Till we get that fixed, if you are not using a freetds.conf or a TDSVER environment variable, then make sure to use 7.1.
74-
75-
* **But I want to use TDS version 7.2 for SQL Server 2005 and up!** TinyTDS uses TDS version 7.1 (previously named 8.0) and fully supports all the data types supported by FreeTDS, this includes `varchar(max)` and `nvarchar(max)`. Technically compiling and using TDS version 7.2 with FreeTDS is not supported. But this does not mean those data types will not work. I know, it's confusing If you want to learn more, read this thread. http://lists.ibiblio.org/pipermail/freetds/2011q3/027306.html
71+
* **Do I need to configure `--with-tdsver` equal to anything?** Most likely! Technically you should not have to. This is only a default for clients/configs that do not specify what TDS version they want to use. We are currently having issues with passing down a TDS version with the login bit. Till we get that fixed, if you are not using a freetds.conf or a TDSVER environment variable, then make sure to use 7.4.
7672

7773
* **I want to configure FreeTDS using `--enable-msdblib` and/or `--enable-sybase-compat` so it works for my database. Cool?** It's a waste of time and totally moot! Client libraries like TinyTDS define their own C structure names where they diverge from Sybase to SQL Server. Technically we use the MSDBLIB structures which does not mean we only work with that database vs Sybase. These configs are just a low level default for C libraries that do not define what they want. So I repeat, you do not NEED to use any of these, nor will they hurt anything since we control what C structure names we use internally!
7874

@@ -81,7 +77,7 @@ TinyTDS is developed against FreeTDS 0.95, 0.99, and 1.0 current. Our default an
8177

8278
Our goal is to support every SQL Server data type and covert it to a logical Ruby object. When dates or times are returned, they are instantiated to either `:utc` or `:local` time depending on the query options. Only [datetimeoffset] types are excluded. All strings are associated the to the connection's encoding and all binary data types are associated to Ruby's `ASCII-8BIT/BINARY` encoding.
8379

84-
Below is a list of the data types we support when using the 7.3 TDS protocol version. Using a lower protocol version will result in these types being returned as strings.
80+
Below is a list of the data types we support when using the 7.4 TDS protocol version. Using a lower protocol version will result in these types being returned as strings.
8581

8682
* [date]
8783
* [datetime2]
@@ -108,7 +104,7 @@ Creating a new client takes a hash of options. For valid iconv encoding options,
108104
* :appname - Short string seen in SQL Servers process/activity window.
109105
* :tds_version - TDS version. Defaults to "7.3".
110106
* :login_timeout - Seconds to wait for login. Default to 60 seconds.
111-
* :timeout - Seconds to wait for a response to a SQL command. Default 5 seconds. Prior to 1.0rc5, FreeTDS was unable to set the timeout on a per-client basis, permitting only a global timeout value. This means that if you're using an older version, the timeout values for all clients will be overwritten each time you instantiate a new `TinyTds::Client` object. If you are using 1.0rc5 or later, all clients will have an independent timeout setting as you'd expect. Timeouts caused by network failure will raise a timeout error 1 second after the configured timeout limit is hit (see [#481](https://github.com/rails-sqlserver/tiny_tds/pull/481) for details).
107+
* :timeout - Seconds to wait for a response to a SQL command. Default 5 seconds. Timeouts caused by network failure will raise a timeout error 1 second after the configured timeout limit is hit (see [#481](https://github.com/rails-sqlserver/tiny_tds/pull/481) for details).
112108
* :encoding - Any valid iconv value like CP1251 or ISO-8859-1. Default UTF-8.
113109
* :azure - Pass true to signal that you are connecting to azure.
114110
* :contained - Pass true to signal that you are connecting with a contained database user.
@@ -390,15 +386,7 @@ Please read our [thread_test.rb](https://github.com/rails-sqlserver/tiny_tds/blo
390386

391387
## Emoji Support 😍
392388

393-
This is possible using FreeTDS version 0.95 or higher. You must use the `use_utf16` login option or add the following config to your `freetds.conf` in either the global section or a specfic dataserver. If you are on Windows, the default location for your conf file will be in `C:\Sites`.
394-
395-
```ini
396-
[global]
397-
use utf-16 = true
398-
```
399-
400-
The default is true and since FreeTDS v1.0 would do this as well.
401-
389+
This is possible. Since FreeTDS v1.0, utf-16 is enabled by default and supported by tiny_tds. You can toggle it by using `use_utf16` when establishing the connection.
402390

403391
## Compiling Gems for Windows
404392

@@ -427,27 +415,21 @@ After that, the quickest way to get setup for development is to use [Docker](htt
427415
$ docker-compose up -d
428416
```
429417

430-
This will download our SQL Server for Linux Docker image based from [microsoft/mssql-server-linux/](https://hub.docker.com/r/microsoft/mssql-server-linux/). Our image already has the `[tinytdstest]` DB and `tinytds` users created. This will also download a [toxiproxy](https://github.com/shopify/toxiproxy) Docker image which we can use to simulate network failures for tests. Basically, it does the following.
418+
This will download the official SQL Server for Linux Docker image from [Microsoft](https://hub.docker.com/r/microsoft/mssql-server-linux/). This will also download a [toxiproxy](https://github.com/shopify/toxiproxy) Docker image which we can use to simulate network failures for tests. Basically, it does the following:
431419

432420
```shell
433421
$ docker network create main-network
434-
$ docker pull metaskills/mssql-server-linux-tinytds
435-
$ docker run -p 1433:1433 -d --name sqlserver --network main-network metaskills/mssql-server-linux-tinytds
422+
$ docker pull mcr.microsoft.com/mssql/server:2017-latest
423+
$ docker run -p 1433:1433 -d --name sqlserver --network main-network mcr.microsoft.com/mssql/server:2017-latest
436424
$ docker pull shopify/toxiproxy
437425
$ docker run -p 8474:8474 -p 1234:1234 -d --name toxiproxy --network main-network shopify/toxiproxy
438426
```
439427

440-
If you are using your own database. Make sure to run these SQL commands as SA to get the test database and user installed.
428+
Make sure to run these SQL scripts as SA to get the test database and user installed. If needed, install [sqlcmd as described by Microsoft for your platform](https://learn.microsoft.com/en-us/sql/tools/sqlcmd/sqlcmd-utility?view=sql-server-ver16&tabs=go%2Clinux&pivots=cs1-bash).
441429

442-
```sql
443-
CREATE DATABASE [tinytdstest];
444-
```
445-
446-
```sql
447-
CREATE LOGIN [tinytds] WITH PASSWORD = '', CHECK_POLICY = OFF, DEFAULT_DATABASE = [tinytdstest];
448-
USE [tinytdstest];
449-
CREATE USER [tinytds] FOR LOGIN [tinytds];
450-
EXEC sp_addrolemember N'db_owner', N'tinytds';
430+
```shell
431+
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P super01S3cUr3 -i ./test/sql/db-create.sql
432+
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P super01S3cUr3 -i ./test/sql/db-login.sql
451433
```
452434

453435
From here you can build and run tests against an installed version of FreeTDS.
@@ -461,9 +443,8 @@ Examples us using enviornment variables to customize the test task.
461443

462444
```
463445
$ rake TINYTDS_UNIT_DATASERVER=mydbserver
464-
$ rake TINYTDS_UNIT_DATASERVER=mydbserver TINYTDS_SCHEMA=sqlserver_2008
446+
$ rake TINYTDS_UNIT_DATASERVER=mydbserver TINYTDS_SCHEMA=sqlserver_2017
465447
$ rake TINYTDS_UNIT_HOST=mydb.host.net TINYTDS_SCHEMA=sqlserver_azure
466-
$ rake TINYTDS_UNIT_HOST=mydb.host.net TINYTDS_UNIT_PORT=5000 TINYTDS_SCHEMA=sybase_ase
467448
```
468449

469450
## Docker Builds

docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ networks:
55

66
services:
77
mssql:
8-
image: metaskills/mssql-server-linux-tinytds:2017-GA
8+
image: mcr.microsoft.com/mssql/server:${MSSQL_VERSION:-2017}-latest
99
container_name: sqlserver
1010
environment:
1111
ACCEPT_EULA: Y
12-
SA_PASSWORD: super01S3cUr3
12+
MSSQL_SA_PASSWORD: super01S3cUr3
1313
ports:
1414
- "1433:1433"
1515
network_mode: "host"

ext/tiny_tds/client.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -404,17 +404,15 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
404404
#endif
405405
}
406406
}
407-
#ifdef DBSETUTF16
408-
if (use_utf16 == Qtrue) { DBSETLUTF16(cwrap->login, 1); }
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
407+
if (use_utf16 == Qtrue) { DBSETLUTF16(cwrap->login, 1); }
408+
if (use_utf16 == Qfalse) { DBSETLUTF16(cwrap->login, 0); }
415409

416410
cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver));
417411
if (cwrap->client) {
412+
if (dbtds(cwrap->client) < 11) {
413+
rb_raise(cTinyTdsError, "connecting with a TDS version older than 7.3!");
414+
}
415+
418416
VALUE transposed_encoding, timeout_string;
419417

420418
cwrap->closed = 0;
@@ -435,11 +433,7 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
435433
}
436434
transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
437435
cwrap->encoding = rb_enc_find(StringValueCStr(transposed_encoding));
438-
if (dbtds(cwrap->client) <= 7) {
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-
}
436+
cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident";
443437
}
444438
return self;
445439
}

ext/tiny_tds/extconf.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def do_help
8484
end
8585

8686
unless have_dependencies
87-
abort 'Failed! Do you have FreeTDS 0.95.80 or higher installed?'
87+
abort 'Failed! Do you have FreeTDS 1.0.0 or higher installed?'
8888
end
8989

9090
create_makefile('tiny_tds/tiny_tds')

ext/tiny_tds/extconsts.rb

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,5 @@
55
OPENSSL_VERSION = ENV['TINYTDS_OPENSSL_VERSION'] || '1.1.1s'
66
OPENSSL_SOURCE_URI = "https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
77

8-
FREETDS_VERSION = ENV['TINYTDS_FREETDS_VERSION'] || "1.1.24"
9-
FREETDS_VERSION_INFO = Hash.new { |h,k|
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.1.24'
9+
FREETDS_SOURCE_URI = "http://www.freetds.org/files/stable/freetds-#{FREETDS_VERSION}.tar.bz2"

0 commit comments

Comments
 (0)