tiny_tds 1.0.4 → 2.1.5

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.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +20 -0
  3. data/.gitattributes +1 -0
  4. data/.rubocop.yml +31 -0
  5. data/.travis.yml +25 -0
  6. data/{CHANGELOG → CHANGELOG.md} +102 -26
  7. data/Gemfile +4 -1
  8. data/ISSUE_TEMPLATE.md +35 -2
  9. data/README.md +131 -56
  10. data/Rakefile +31 -88
  11. data/VERSION +1 -1
  12. data/appveyor.yml +38 -17
  13. data/docker-compose.yml +22 -0
  14. data/ext/tiny_tds/client.c +147 -60
  15. data/ext/tiny_tds/client.h +11 -5
  16. data/ext/tiny_tds/extconf.rb +41 -297
  17. data/ext/tiny_tds/extconsts.rb +7 -7
  18. data/ext/tiny_tds/result.c +40 -15
  19. data/lib/tiny_tds/bin.rb +45 -27
  20. data/lib/tiny_tds/client.rb +46 -34
  21. data/lib/tiny_tds/error.rb +0 -1
  22. data/lib/tiny_tds/gem.rb +32 -0
  23. data/lib/tiny_tds/result.rb +2 -3
  24. data/lib/tiny_tds/version.rb +1 -1
  25. data/lib/tiny_tds.rb +38 -14
  26. data/{ports/patches/freetds/1.00 → patches/freetds/1.00.27}/0001-mingw_missing_inet_pton.diff +4 -4
  27. data/patches/freetds/1.00.27/0002-Don-t-use-MSYS2-file-libws2_32.diff +28 -0
  28. data/patches/libiconv/1.14/1-avoid-gets-error.patch +17 -0
  29. data/tasks/native_gem.rake +14 -0
  30. data/tasks/package.rake +8 -0
  31. data/tasks/ports/freetds.rb +37 -0
  32. data/tasks/ports/libiconv.rb +43 -0
  33. data/tasks/ports/openssl.rb +62 -0
  34. data/tasks/ports/recipe.rb +52 -0
  35. data/tasks/ports.rake +85 -0
  36. data/tasks/test.rake +9 -0
  37. data/test/appveyor/dbsetup.ps1 +1 -1
  38. data/test/bin/install-freetds.sh +20 -0
  39. data/test/bin/install-openssl.sh +18 -0
  40. data/test/bin/setup.sh +19 -0
  41. data/test/client_test.rb +124 -66
  42. data/test/gem_test.rb +179 -0
  43. data/test/result_test.rb +128 -42
  44. data/test/schema/sqlserver_2016.sql +140 -0
  45. data/test/schema_test.rb +23 -23
  46. data/test/test_helper.rb +65 -7
  47. data/test/thread_test.rb +1 -1
  48. data/tiny_tds.gemspec +9 -7
  49. metadata +60 -20
  50. /data/bin/{defncopy → defncopy-ttds} +0 -0
  51. /data/bin/{tsql → tsql-ttds} +0 -0
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # TinyTDS - Simple and fast FreeTDS bindings for Ruby using DB-Library.
2
2
 
3
- [![Build Status](https://ci.appveyor.com/api/projects/status/g2bhhbsdkx0mal55/branch/master?svg=true)](https://ci.appveyor.com/project/rails-sqlserver/tiny-tds/branch/master) [![Gem Version](https://img.shields.io/gem/v/tiny_tds.svg)](https://rubygems.org/gems/tiny_tds) [![Gitter chat](https://img.shields.io/badge/%E2%8A%AA%20GITTER%20-JOIN%20CHAT%20%E2%86%92-brightgreen.svg?style=flat)](https://gitter.im/rails-sqlserver/activerecord-sqlserver-adapter)
3
+ * [![TravisCI](https://travis-ci.org/rails-sqlserver/tiny_tds.svg?branch=master)](https://travis-ci.org/rails-sqlserver/tiny_tds) - TravisCI
4
+ * [![Build Status](https://ci.appveyor.com/api/projects/status/g2bhhbsdkx0mal55/branch/master?svg=true)](https://ci.appveyor.com/project/rails-sqlserver/tiny-tds/branch/master) - Appveyor
5
+ * [![Gem Version](https://img.shields.io/gem/v/tiny_tds.svg)](https://rubygems.org/gems/tiny_tds) - Gem Version
6
+ * [![Gitter chat](https://img.shields.io/badge/%E2%8A%AA%20GITTER%20-JOIN%20CHAT%20%E2%86%92-brightgreen.svg?style=flat)](https://gitter.im/rails-sqlserver/activerecord-sqlserver-adapter) - Community
7
+
8
+
9
+ ## About TinyTDS
4
10
 
5
11
  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.
6
12
 
@@ -21,24 +27,39 @@ Installing with rubygems should just work. TinyTDS is currently tested on Ruby v
21
27
  $ gem install tiny_tds
22
28
  ```
23
29
 
24
- If you use Windows, we pre-compile TinyTDS with static versions of FreeTDS, libiconv, and OpenSSL. On all other platforms, we will find these dependencies. If none exist, our native extension will use MiniPortile to install any missing dependencies listed above for your specific platform. These dependencies will be built and linked within the installed TinyTDS gem. Please read the MiniPortile and/or Windows sections at the end of this file for advanced configuration options past the following:
30
+ If you use Windows, we pre-compile TinyTDS with static versions of FreeTDS and supporting libraries.
31
+ If you're using RubyInstaller the binary gem will require that devkit is installed and in your path to operate properly.
32
+
33
+ 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.
25
34
 
35
+ ```shell
36
+ $ apt-get install wget
37
+ $ apt-get install build-essential
38
+ $ apt-get install libc6-dev
39
+
40
+ $ wget http://www.freetds.org/files/stable/freetds-1.1.24.tar.gz
41
+ $ tar -xzf freetds-1.1.24.tar.gz
42
+ $ cd freetds-1.1.24
43
+ $ ./configure --prefix=/usr/local --with-tdsver=7.3
44
+ $ make
45
+ $ make install
26
46
  ```
27
- --enable-system-freetds / --disable-system-freetds
28
- --enable-system-iconv / --disable-system-iconv
29
- --enable-system-openssl / --disable-system-openssl
30
- Force use of system or builtin freetds/iconv/openssl library.
31
- Default is to prefer system libraries and fallback to builtin.
32
47
 
48
+ Please read the MiniPortile and/or Windows sections at the end of this file for advanced configuration options past the following:
49
+
50
+ ```
33
51
  --with-freetds-dir=DIR
34
52
  Use the freetds library placed under DIR.
53
+ ```
35
54
 
36
- --enable-lookup
37
- Search for freetds through all paths in the PATH environment variable.
38
55
 
39
- --enable-cross-build
40
- Do cross-build.
41
- ```
56
+ ## Getting Started
57
+
58
+ 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.
59
+
60
+ * [SQL Server on a Mac](https://www.microsoft.com/en-us/sql-server/developer-get-started/ruby/mac)
61
+ * [SQL Server on RHEL](https://www.microsoft.com/en-us/sql-server/developer-get-started/ruby/rhel)
62
+ * [SQL Server on Ubuntu](https://www.microsoft.com/en-us/sql-server/developer-get-started/ruby/ubuntu)
42
63
 
43
64
 
44
65
  ## FreeTDS Compatibility & Configuration
@@ -47,11 +68,11 @@ TinyTDS is developed against FreeTDS 0.95, 0.99, and 1.0 current. Our default an
47
68
 
48
69
  **NOTE:** Windows users of our pre-compiled native gems need not worry about installing FreeTDS and its dependencies.
49
70
 
50
- * **Do I need to install FreeTDS?** Yes! Somehow, someway, you are going to need FreeTDS for TinyTDS to compile against. You can avoid installing FreeTDS on your system by using our projects usage of rake-compiler and mini_portile to compile and package a native gem just for you. See the "Using MiniPortile" section below.
71
+ * **Do I need to install FreeTDS?** Yes! Somehow, someway, you are going to need FreeTDS for TinyTDS to compile against.
51
72
 
52
73
  * **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.
53
74
 
54
- * **Do I need to configure `--with-tdsver` equal to anything?** Most likely! Technically you should not have too. 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.
75
+ * **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.
55
76
 
56
77
  * **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
57
78
 
@@ -89,9 +110,22 @@ Creating a new client takes a hash of options. For valid iconv encoding options,
89
110
  * :appname - Short string seen in SQL Servers process/activity window.
90
111
  * :tds_version - TDS version. Defaults to "7.3".
91
112
  * :login_timeout - Seconds to wait for login. Default to 60 seconds.
92
- * :timeout - Seconds to wait for a response to a SQL command. Default 5 seconds.
113
+ * :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).
93
114
  * :encoding - Any valid iconv value like CP1251 or ISO-8859-1. Default UTF-8.
94
115
  * :azure - Pass true to signal that you are connecting to azure.
116
+ * :contained - Pass true to signal that you are connecting with a contained database user.
117
+ * :use_utf16 - Instead of using UCS-2 for database wide character encoding use UTF-16. Newer Windows versions use this encoding instead of UCS-2. Default true.
118
+ * :message_handler - Pass in a `call`-able object such as a `Proc` or a method to receive info messages from the database. It should have a single parameter, which will be a `TinyTds::Error` object representing the message. For example:
119
+
120
+ ```ruby
121
+ opts = ... # host, username, password, etc
122
+ opts[:message_handler] = Proc.new { |m| puts m.message }
123
+ client = TinyTds::Client.new opts
124
+ # => Changed database context to 'master'.
125
+ # => Changed language setting to us_english.
126
+ client.execute("print 'hello world!'").do
127
+ # => hello world!
128
+ ```
95
129
 
96
130
  Use the `#active?` method to determine if a connection is good. The implementation of this method may change but it should always guarantee that a connection is good. Current it checks for either a closed or dead connection.
97
131
 
@@ -288,9 +322,13 @@ By default row caching is turned on because the SQL Server adapter for ActiveRec
288
322
  TinyTDS takes an opinionated stance on how we handle encoding errors. First, we treat errors differently on reads vs. writes. Our opinion is that if you are reading bad data due to your client's encoding option, you would rather just find `?` marks in your strings vs being blocked with exceptions. This is how things wold work via ODBC or SMS. On the other hand, writes will raise an exception. In this case we raise the SYBEICONVO/2402 error message which has a description of `Error converting characters into server's character set. Some character(s) could not be converted.`. Even though the severity of this message is only a `4` and TinyTDS will automatically strip/ignore unknown characters, we feel you should know that you are inserting bad encodings. In this way, a transaction can be rolled back, etc. Remember, any database write that has bad characters due to the client encoding will still be written to the database, but it is up to you rollback said write if needed. Most ORMs like ActiveRecord handle this scenario just fine.
289
323
 
290
324
 
325
+ ## Timeout Error Handling
326
+
327
+ TinyTDS will raise a `TinyTDS::Error` when a timeout is reached based on the options supplied to the client. Depending on the reason for the timeout, the connection could be dead or alive. When db processing is the cause for the timeout, the connection should still be usable after the error is raised. When network failure is the cause of the timeout, the connection will be dead. If you attempt to execute another command batch on a dead connection you will see a `DBPROCESS is dead or not enabled` error. Therefore, it is recommended to check for a `dead?` connection before trying to execute another command batch.
328
+
291
329
  ## Binstubs
292
330
 
293
- The TinyTDS gem uses binstub wrappers which mirror compiled [FreeTDS Utilities](http://www.freetds.org/userguide/usefreetds.htm) binaries. These native executables are usually installed at the system level when installing FreeTDS. However, when using MiniPortile to install TinyTDS as we do with Windows binaries, these binstubs will find and prefer local gem `exe` directory executables. These are the following binstubs we wrap.
331
+ The TinyTDS gem uses binstub wrappers which mirror compiled [FreeTDS Utilities](https://www.freetds.org/userguide/usefreetds.html) binaries. These native executables are usually installed at the system level when installing FreeTDS. However, when using MiniPortile to install TinyTDS as we do with Windows binaries, these binstubs will find and prefer local gem `exe` directory executables. These are the following binstubs we wrap.
294
332
 
295
333
  * tsql - Used to test connections and debug compile time settings.
296
334
  * defncopy - Used to dump schema structures.
@@ -309,49 +347,64 @@ TinyTDS is fully tested with the Azure platform. You must set the `azure: true`
309
347
 
310
348
  **IMPORTANT**: Do not use `username@server.database.windows.net` for the username connection option! You must use the shorter `username@server` instead!
311
349
 
312
- We recommend the following settings when using TinyTDS with Azure. These are the same settings used in the ActiveRecord SQL Server adapter.
350
+ Also, please read the [Azure SQL Database General Guidelines and Limitations](https://msdn.microsoft.com/en-us/library/ee336245.aspx) MSDN article to understand the differences. Specifically, the connection constraints section!
351
+
352
+ ## Connection Settings
353
+
354
+ A DBLIB connection does not have the same default SET options for a standard SMS SQL Server connection. Hence, we recommend the following options post establishing your connection.
355
+
356
+ #### SQL Server
313
357
 
314
358
  ```sql
315
- SET ANSI_NULLS ON
359
+ SET ANSI_DEFAULTS ON
360
+
361
+ SET QUOTED_IDENTIFIER ON
316
362
  SET CURSOR_CLOSE_ON_COMMIT OFF
317
- SET ANSI_NULL_DFLT_ON ON
318
363
  SET IMPLICIT_TRANSACTIONS OFF
319
- SET ANSI_PADDING ON
320
- SET QUOTED_IDENTIFIER ON
321
- SET ANSI_WARNINGS ON
364
+ SET TEXTSIZE 2147483647
365
+ SET CONCAT_NULL_YIELDS_NULL ON
322
366
  ```
323
367
 
324
- Also, please read the [Azure SQL Database General Guidelines and Limitations](https://msdn.microsoft.com/en-us/library/ee336245.aspx) MSDN article to understand the differences. Specifically, the connection constraints section!
368
+ #### Azure
325
369
 
370
+ ```sql
371
+ SET ANSI_NULLS ON
372
+ SET ANSI_NULL_DFLT_ON ON
373
+ SET ANSI_PADDING ON
374
+ SET ANSI_WARNINGS ON
326
375
 
327
- ## Emoji Support 😍
376
+ SET QUOTED_IDENTIFIER ON
377
+ SET CURSOR_CLOSE_ON_COMMIT OFF
378
+ SET IMPLICIT_TRANSACTIONS OFF
379
+ SET TEXTSIZE 2147483647
380
+ SET CONCAT_NULL_YIELDS_NULL ON
381
+ ```
328
382
 
329
- This is possible using FreeTDS version 0.95 or higher. You must 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`.
330
383
 
331
- ```ini
332
- [global]
333
- use utf-16 = true
334
- ```
384
+ ## Thread Safety
335
385
 
336
- Good news! If you are using FreeTDS v1.0 or later, then `use utf-16` is set true by default!
386
+ TinyTDS must be used with a connection pool for thread safety. If you use ActiveRecord or the [Sequel](https://github.com/jeremyevans/sequel) gem this is done for you. However, if you are using TinyTDS on your own, we recommend using the ConnectionPool gem when using threads:
337
387
 
388
+ * ConnectionPool Gem - https://github.com/mperham/connection_pool
338
389
 
339
- ## Using MiniPortile
390
+ Please read our [thread_test.rb](https://github.com/rails-sqlserver/tiny_tds/blob/master/test/thread_test.rb) file for details on how we test its usage.
340
391
 
341
- MiniPortile is a minimalistic implementation of a port/recipe system. <https://github.com/luislavena/mini_portile>
342
392
 
343
- The TinyTDS project uses MiniPortile so that we can easily install a local version of FreeTDS and supporting libraries to link against when building a test version of TinyTDS. This same system is also used when installing TinyTDS with Rubygems and building native extensions. It is possible to build TinyTDS with a specific version of FreeTDS using the `TINYTDS_FREETDS_VERSION` environment variable. Here are some exampbles of possible values.
393
+ ## Emoji Support 😍
344
394
 
345
- ```
346
- $ rake TDSVER='7.1' TINYTDS_FREETDS_VERSION='0.95' -- --disable-system-freetds --disable-system-iconv
395
+ 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`.
396
+
397
+ ```ini
398
+ [global]
399
+ use utf-16 = true
347
400
  ```
348
401
 
349
- To find out more about the FreeTDS release system [visit this thread](http://lists.ibiblio.org/pipermail/freetds/2012q1/027756.html) on their mailing list. You can also browse thier FTP server [ftp://ftp.astron.com/pub/freetds/](ftp://ftp.astron.com/pub/freetds/) for version number strings.
402
+ The default is true and since FreeTDS v1.0 would do this as well.
350
403
 
351
404
 
352
405
  ## Compiling Gems for Windows
353
406
 
354
- For the convenience of Windows users, TinyTDS ships pre-compiled gems for Ruby 2.0, 2.1 and 2.2 on Windows. In order to generate these gems, [rake-compiler-dock](https://github.com/rake-compiler/rake-compiler-dock) is used. This project provides a [Docker image](https://registry.hub.docker.com/u/larskanis/rake-compiler-dock/) with rvm, cross-compilers and a number of different target versions of Ruby.
407
+ For the convenience of Windows users, TinyTDS ships pre-compiled gems for supported versions of Ruby on Windows. In order to generate these gems, [rake-compiler-dock](https://github.com/rake-compiler/rake-compiler-dock) is used. This project provides several [Docker images](https://registry.hub.docker.com/u/larskanis/) with rvm, cross-compilers and a number of different target versions of Ruby.
355
408
 
356
409
  Run the following rake task to compile the gems for Windows. This will check the availability of [Docker](https://www.docker.com/) (and boot2docker on Windows or OS-X) and will give some advice for download and installation. When docker is running, it will download the docker image (once-only) and start the build:
357
410
 
@@ -364,49 +417,73 @@ The compiled gems will exist in `./pkg` directory.
364
417
 
365
418
  ## Development & Testing
366
419
 
367
- First make sure your local database has a `[tinytdstest]` database with a owner login named `[tinytds]` having no password. The following SQL run via the `sa` account should set that up for you.
420
+ First, clone the repo using the command line or your Git GUI of choice.
421
+
422
+ ```shell
423
+ $ git clone git@github.com:rails-sqlserver/tiny_tds.git
424
+ ```
425
+
426
+ After that, the quickest way to get setup for development is to use [Docker](https://www.docker.com/). Assuming you have [downloaded docker](https://www.docker.com/products/docker) for your platform, you can use [docker-compose](https://docs.docker.com/compose/install/) to run the necessary containers for testing.
427
+
428
+ ```shell
429
+ $ docker-compose up -d
430
+ ```
431
+
432
+ 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.
368
433
 
369
- ```bash
370
- $ tsql -H <host> -p 1433 -U sa -P <pass>
371
- $ sqsh -H <host> -p 1433 -U sa -P <pass>
434
+ ```shell
435
+ $ docker network create main-network
436
+ $ docker pull metaskills/mssql-server-linux-tinytds
437
+ $ docker run -p 1433:1433 -d --name sqlserver --network main-network metaskills/mssql-server-linux-tinytds
438
+ $ docker pull shopify/toxiproxy
439
+ $ docker run -p 8474:8474 -p 1234:1234 -d --name toxiproxy --network main-network shopify/toxiproxy
372
440
  ```
373
441
 
442
+ If you are using your own database. Make sure to run these SQL commands as SA to get the test database and user installed.
443
+
374
444
  ```sql
375
445
  CREATE DATABASE [tinytdstest];
376
- GO
446
+ ```
447
+
448
+ ```sql
377
449
  CREATE LOGIN [tinytds] WITH PASSWORD = '', CHECK_POLICY = OFF, DEFAULT_DATABASE = [tinytdstest];
378
- GO
379
450
  USE [tinytdstest];
380
451
  CREATE USER [tinytds] FOR LOGIN [tinytds];
381
- GO
382
452
  EXEC sp_addrolemember N'db_owner', N'tinytds';
383
- GO
384
453
  ```
385
454
 
386
- We use bundler for development. Simply run `bundle install` then `rake` to build the gem and run the unit tests. Before running the test rake task, you may need to define a pair of environment variables that help the client connect to your specific FreeTDS database server name and which schema (2000, 2005, 2008, 2014, Azure or Sybase ASE) to use. For example:
455
+ From here you can build and run tests against an installed version of FreeTDS.
456
+
457
+ ```shell
458
+ $ bundle install
459
+ $ bundle exec rake
460
+ ```
461
+
462
+ Examples us using enviornment variables to customize the test task.
387
463
 
388
464
  ```
389
465
  $ rake TINYTDS_UNIT_DATASERVER=mydbserver
390
- or
391
466
  $ rake TINYTDS_UNIT_DATASERVER=mydbserver TINYTDS_SCHEMA=sqlserver_2008
392
- or
393
467
  $ rake TINYTDS_UNIT_HOST=mydb.host.net TINYTDS_SCHEMA=sqlserver_azure
394
- or
395
468
  $ rake TINYTDS_UNIT_HOST=mydb.host.net TINYTDS_UNIT_PORT=5000 TINYTDS_SCHEMA=sybase_ase
396
469
  ```
397
470
 
398
- If you do not want to use MiniPortile to compile a local project version of FreeTDS and instead use your local system version, use the `TINYTDS_SKIP_PORTS` environment variable. This will ignore any port tasks and will instead build and link to your system's FreeTDS installation as a normal gem install would.
471
+ ## Docker Builds
399
472
 
400
- ```
401
- $ rake TINYTDS_SKIP_PORTS=1
402
- ```
473
+ If you use a [multi stage](https://docs.docker.com/develop/develop-images/multistage-build/) Docker build to assemble your gems in one phase and then copy your app and gems
474
+ into another, lighter, container without build tools you will need to make sure you tell the OS how to find dependencies for TinyTDS.
475
+
476
+ After you have built and installed FreeTDS it will normally place library files in `/usr/local/lib`. When TinyTDS builds native extensions,
477
+ it [already knows to look here](https://github.com/rails-sqlserver/tiny_tds/blob/master/ext/tiny_tds/extconf.rb#L31) but if you copy your app to a new container that link will be broken.
403
478
 
479
+ Set the LD_LIBRARY_PATH environment variable `export LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH}` and run `ldconfig`. If you run `ldd tiny_tds.so` you should not see any broken links. Make
480
+ sure you also copied in the library dependencies from your build container with a command like `COPY --from=builder /usr/local/lib /usr/local/lib`.
404
481
 
405
482
  ## Help & Support
406
483
 
407
484
  * Github Source: http://github.com/rails-sqlserver/tiny_tds
408
485
  * Github Issues: http://github.com/rails-sqlserver/tiny_tds/issues
409
- * Google Group: http://groups.google.com/group/rails-sqlserver-adapter
486
+ * Gitter Chat: https://gitter.im/rails-sqlserver/activerecord-sqlserver-adapter
410
487
  * IRC Room: #rails-sqlserver on irc.freenode.net
411
488
 
412
489
 
@@ -427,5 +504,3 @@ My name is Ken Collins and I currently maintain the SQL Server adapter for Activ
427
504
  ## License
428
505
 
429
506
  TinyTDS is Copyright (c) 2010-2015 Ken Collins, <ken@metaskills.net> and Will Bond (Veracross LLC) <wbond@breuer.com>. It is distributed under the MIT license. Windows binaries contain pre-compiled versions of FreeTDS <http://www.freetds.org/> which is licensed under the GNU LGPL license at <http://www.gnu.org/licenses/lgpl-2.0.html>
430
-
431
-
data/Rakefile CHANGED
@@ -1,110 +1,53 @@
1
1
  # encoding: UTF-8
2
+ require 'rbconfig'
2
3
  require 'rake'
3
4
  require 'rake/clean'
4
- require 'rbconfig'
5
- require 'rake/testtask'
6
5
  require 'rake/extensiontask'
7
- require 'rubygems/package_task'
8
6
  require_relative './ext/tiny_tds/extconsts'
9
7
 
10
- def test_libs
11
- ['lib','test']
12
- end
13
-
14
- def test_files
15
- if ENV['TEST_FILES']
16
- ENV['TEST_FILES'].split(',').map{ |f| f.strip }.sort
17
- else
18
- Dir.glob("test/**/*_test.rb").sort
19
- end
20
- end
21
-
22
- def add_file_to_gem(spec, relative_path)
23
- target_path = File.join gem_build_path(spec), relative_path
24
- target_dir = File.dirname(target_path)
25
- mkdir_p target_dir
26
- rm_f target_path
27
- safe_ln relative_path, target_path
28
- spec.files += [relative_path]
29
- end
30
-
31
- def gem_build_path(spec)
32
- File.join 'pkg', spec.full_name
33
- end
34
-
35
- gemspec = Gem::Specification::load(File.expand_path('../tiny_tds.gemspec', __FILE__))
8
+ SPEC = Gem::Specification.load(File.expand_path('../tiny_tds.gemspec', __FILE__))
9
+ GEM_PLATFORM_HOSTS = {
10
+ 'x86-mingw32' => 'i686-w64-mingw32',
11
+ 'x64-mingw32' => 'x86_64-w64-mingw32'
12
+ }
36
13
 
37
- Rake::TestTask.new do |t|
38
- t.libs = test_libs
39
- t.test_files = test_files
40
- t.verbose = true
41
- end
42
-
43
- Gem::PackageTask.new(gemspec) do |pkg|
44
- pkg.need_tar = false
45
- pkg.need_zip = false
46
- end
14
+ # Add our project specific files to clean for a rebuild
15
+ CLEAN.include FileList["{ext,lib}/**/*.{so,#{RbConfig::CONFIG['DLEXT']},o}"],
16
+ FileList["exe/*"]
47
17
 
48
- task :compile
18
+ # Clobber all our temp files and ports files including .install files
19
+ # and archives
20
+ CLOBBER.include FileList["tmp/**/*"],
21
+ FileList["ports/**/*"].exclude(%r{^ports/archives})
49
22
 
50
- task :build => [:clean, :compile]
51
- task(:build_quietly) { capture_stds { Rake::Task[:build].invoke } }
23
+ Dir['tasks/*.rake'].sort.each { |f| load f }
52
24
 
53
- task :default => [:build, :test]
54
-
55
- Dir["tasks/*.rake"].sort.each { |f| load f }
56
-
57
- Rake::ExtensionTask.new('tiny_tds', gemspec) do |ext|
25
+ Rake::ExtensionTask.new('tiny_tds', SPEC) do |ext|
58
26
  ext.lib_dir = 'lib/tiny_tds'
59
27
  ext.cross_compile = true
60
- ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
61
- ext.cross_config_options += %w[ --disable-lookup --enable-cross-build ]
28
+ ext.cross_platform = GEM_PLATFORM_HOSTS.keys
29
+
62
30
  # Add dependent DLLs to the cross gems
63
31
  ext.cross_compiling do |spec|
64
- platform_host_map = {
65
- 'x86-mingw32' => 'i686-w64-mingw32',
66
- 'x64-mingw32' => 'x86_64-w64-mingw32'
67
- }
32
+ # The fat binary gem doesn't depend on the freetds package, since it bundles the library.
33
+ spec.metadata.delete('msys2_mingw_dependencies')
34
+
35
+ platform_host_map = GEM_PLATFORM_HOSTS
68
36
  gemplat = spec.platform.to_s
69
37
  host = platform_host_map[gemplat]
70
- dlls = [
71
- "libeay32-1.0.2g-#{host}.dll",
72
- "ssleay32-1.0.2g-#{host}.dll",
73
- "libiconv-2.dll",
74
- "libsybdb-5.dll",
75
- ]
38
+
76
39
  # We don't need the sources in a fat binary gem
77
- spec.files = spec.files.reject { |f| f=~/^ports\/archives/ }
78
- spec.files += dlls.map { |dll| "ports/#{host}/bin/#{File.basename(dll)}" }
79
- spec.files += Dir.glob('exe/*')
80
- dlls.each do |dll|
81
- file "ports/#{host}/bin/#{dll}" do |t|
82
- sh "x86_64-w64-mingw32-strip", t.name
83
- end
40
+ spec.files = spec.files.reject { |f| f =~ %r{^ports\/archives/} }
41
+
42
+ # Make sure to include the ports binaries and libraries
43
+ spec.files += FileList["ports/#{host}/**/**/{bin,lib}/*"].exclude do |f|
44
+ File.directory? f
84
45
  end
85
- end
86
- end
87
46
 
88
- # Bundle the freetds sources to avoid download while gem install.
89
- task gem_build_path(gemspec) do
90
- add_file_to_gem gemspec, "ports/archives/freetds-#{FREETDS_VERSION}.tar.bz2"
47
+ spec.files += Dir.glob('exe/*')
48
+ end
91
49
  end
92
50
 
93
- desc "Build the windows binary gems per rake-compiler-dock"
94
- task 'gem:windows' do
95
- require 'rake_compiler_dock'
96
- RakeCompilerDock.sh <<-EOT
97
- bundle && rake cross native gem RUBY_CC_VERSION=2.0.0:2.1.6:2.2.2:2.3.0 CFLAGS="-Wall"
98
- EOT
99
- end
51
+ task build: [:clean, :compile]
52
+ task default: [:build, :test]
100
53
 
101
- def capture_stds
102
- pstdout, $stdout = $stdout, StringIO.new
103
- pstderr, $stderr = $stderr, StringIO.new
104
- yield
105
- $stdout.string
106
- $stderr.string
107
- ensure
108
- $stdout = pstdout
109
- $stderr = pstderr
110
- end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.4
1
+ 2.1.5
data/appveyor.yml CHANGED
@@ -1,17 +1,44 @@
1
1
  init:
2
2
  - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
3
- - SET PATH=C:\MinGW\msys\1.0\bin;%PATH%
4
3
  - SET RAKEOPT=-rdevkit
4
+ - SET TESTOPTS='-v'
5
+ - SET MAKE=make V=1 -j2
5
6
  clone_depth: 5
6
7
  skip_tags: true
8
+ skip_branch_with_pr: true
7
9
  matrix:
8
- fast_finish: true
10
+ fast_finish: false
9
11
  install:
12
+ # Output debugging info
10
13
  - ps: Update-AppveyorBuild -Version "$(Get-Content $env:appveyor_build_folder\VERSION).$env:appveyor_build_number"
14
+ - ps: |
15
+ if ($env:ruby_version -like "*head*") {
16
+ $(new-object net.webclient).DownloadFile("https://github.com/oneclick/rubyinstaller2/releases/download/rubyinstaller-head/rubyinstaller-$env:ruby_version.exe", "$pwd/ruby-setup.exe")
17
+ cmd /c ruby-setup.exe /verysilent /dir=C:/Ruby$env:ruby_version
18
+ }
19
+ - perl --version
11
20
  - ruby --version
12
21
  - gem --version
22
+ # Update keyring according to https://www.msys2.org/news/#2020-06-29-new-packagers
23
+ - C:\msys64\usr\bin\curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz
24
+ - C:\msys64\usr\bin\curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig
25
+ - ridk exec bash -c "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
26
+ - ridk exec bash -c "pacman -U --noconfirm --config <(echo) msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
27
+ # Update zstd and pacman first https://github.com/msys2/MSYS2-packages/issues/2300
28
+ - C:\msys64\usr\bin\pacman --noconfirm --upgrade https://repo.msys2.org/msys/x86_64/zstd-1.4.7-1-x86_64.pkg.tar.xz # Must come First, or else pacman will install 1.4.8
29
+ - C:\msys64\usr\bin\pacman --noconfirm --upgrade https://repo.msys2.org/msys/x86_64/pacman-5.2.2-5-x86_64.pkg.tar.xz
30
+ # update packages
31
+ - C:\msys64\usr\bin\pacman --noconfirm --ask 20 --sync --refresh --refresh --sysupgrade --sysupgrade
32
+ # Kill all running msys2 binaries to avoid error "size of shared memory region changed".
33
+ # See https://github.com/msys2/MSYS2-packages/issues/258
34
+ - powershell -Command "Get-Process | Where-Object {$_.path -like 'C:\msys64*'} | Stop-Process"
35
+ # refresh the package list to avoid "error: failed to prepare transaction (could not find database)"
36
+ - ridk exec bash -c "pacman --noconfirm -Sy"
37
+ # prevent freetds to link to wrong ws2_32 lib on i686-w64-mingw32
38
+ - c:/msys64/usr/bin/rm /usr/lib/w32api/libws2_32.a
39
+ # Set up project prerequisits
13
40
  - bundle install
14
- - bundle exec rake build
41
+ - bundle exec rake ports
15
42
  build: off
16
43
  branches:
17
44
  except:
@@ -23,29 +50,23 @@ test_script:
23
50
  - ps: Start-Service 'MSSQL$SQL2014'
24
51
  - timeout /t 4 /nobreak > NUL
25
52
  - sqlcmd -S ".\SQL2014" -U sa -P Password12! -i %APPVEYOR_BUILD_FOLDER%\test\appveyor\dbsetup.sql
26
- - bundle exec rake TINYTDS_UNIT_HOST_TEST=localhost TINYTDS_UNIT_DATASERVER="localhost\SQL2014" TINYTDS_SCHEMA=sqlserver_2014 TDSVER=7.1
27
- - bundle exec rake TINYTDS_UNIT_HOST_TEST=localhost TINYTDS_UNIT_DATASERVER="localhost\SQL2014" TINYTDS_SCHEMA=sqlserver_2014
53
+ - bundle exec rake ports build test TINYTDS_UNIT_HOST_TEST=localhost TINYTDS_UNIT_DATASERVER="localhost\SQL2014" TINYTDS_SCHEMA=sqlserver_2014 TDSVER=7.1
54
+ - bundle exec rake ports build test TINYTDS_UNIT_HOST_TEST=localhost TINYTDS_UNIT_DATASERVER="localhost\SQL2014" TINYTDS_SCHEMA=sqlserver_2014
28
55
  - ps: Stop-Service 'MSSQL$SQL2014'
29
56
  - ps: Start-Service 'MSSQL$SQL2012SP1'
30
57
  - timeout /t 4 /nobreak > NUL
31
58
  - sqlcmd -S ".\SQL2012SP1" -U sa -P Password12! -i %APPVEYOR_BUILD_FOLDER%\test\appveyor\dbsetup.sql
32
- - bundle exec rake TINYTDS_UNIT_HOST_TEST=localhost TINYTDS_UNIT_DATASERVER="localhost\SQL2012SP1" TINYTDS_SCHEMA=sqlserver_2014
33
- - ps: Stop-Service 'MSSQL$SQL2012SP1'
34
- - ps: Start-Service 'MSSQL$SQL2008R2SP2'
35
- - timeout /t 4 /nobreak > NUL
36
- - sqlcmd -S ".\SQL2008R2SP2" -U sa -P Password12! -i %APPVEYOR_BUILD_FOLDER%\test\appveyor\dbsetup.sql
37
- - bundle exec rake TINYTDS_UNIT_HOST_TEST=localhost TINYTDS_UNIT_DATASERVER="localhost\SQL2008R2SP2" TINYTDS_SCHEMA=sqlserver_2008
38
- - timeout /t 4 /nobreak > NUL
39
- - bundle exec rake TINYTDS_UNIT_HOST_TEST=%CI_AZURE_HOST% TINYTDS_UNIT_HOST=%CI_AZURE_HOST% TINYTDS_SCHEMA=sqlserver_azure
59
+ - bundle exec rake ports build test TINYTDS_UNIT_HOST_TEST=localhost TINYTDS_UNIT_DATASERVER="localhost\SQL2012SP1" TINYTDS_SCHEMA=sqlserver_2014
40
60
  environment:
41
61
  CI_AZURE_HOST:
42
62
  secure: 8ydpYysZYKEBKvp6plKlYfepH98/zAuT27FFCaJ9Sss=
43
63
  TINYTDS_UNIT_AZURE_PASS:
44
64
  secure: fYKSKV4v+36OFQp2nZdX4DfUpgmy5cm0wuR73cgdmEk=
45
65
  matrix:
46
- - ruby_version: "200"
47
- - ruby_version: "23"
48
- - ruby_version: "23-x64"
66
+ - ruby_version: "24"
67
+ - ruby_version: "25-x64"
68
+ - ruby_version: "26"
69
+ - ruby_version: "head-x64"
49
70
  on_failure:
71
+ - find -name config.log | xargs cat
50
72
  - find -name compile.log | xargs cat
51
-
@@ -0,0 +1,22 @@
1
+ version: '3'
2
+
3
+ networks:
4
+ main-network:
5
+
6
+ services:
7
+ mssql:
8
+ image: metaskills/mssql-server-linux-tinytds:2017-GA
9
+ container_name: sqlserver
10
+ ports:
11
+ - "1433:1433"
12
+ networks:
13
+ - main-network
14
+
15
+ toxiproxy:
16
+ image: shopify/toxiproxy
17
+ container_name: toxiproxy
18
+ ports:
19
+ - "8474:8474"
20
+ - "1234:1234"
21
+ networks:
22
+ - main-network