Skip to content

Merge ODBC restoration from 5.1 to 5.2 #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: 5-2-stable-with-odbc
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ Gemfile.lock
test/profile/output/*
.rvmrc
.rbenv-version
.tool-versions
.idea
coverage/*
.flooignore
.floo
.byebug_history
.floo
35 changes: 19 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ services:
- docker
env:
global:
- COMPOSE_FILE: docker-compose.ci.yml
- TINYTDS_VERSION=2.1.0
- ACTIVERECORD_UNITTEST_HOST=localhost
- ACTIVERECORD_UNITTEST_DATASERVER=localhost
rvm:
- 2.2.5
- 2.3.1
- 2.4.0
before_install:
- sudo rm /usr/local/bin/docker-compose
- sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- sudo chmod +x /usr/local/bin/docker-compose
- export PATH=/opt/local/bin:$PATH
- docker info
- sudo ./test/bin/setup.sh
- sudo ./test/bin/install-openssl.sh
- openssl version
- sudo ./test/bin/install-freetds.sh
- tsql -C
install:
- docker-compose build --build-arg TARGET_VERSION=$TARGET_VERSION
- export PATH=/opt/local/bin:$PATH
- gem install bundler
- bundle --version
- bundle install
script:
- docker-compose run ci
matrix:
include:
- name: 2.3.8
env: TARGET_VERSION=2.3.8
- name: 2.4.6
env: TARGET_VERSION=2.4.6
- name: 2.5.5
env: TARGET_VERSION=2.5.5
- name: 2.6.3
env: TARGET_VERSION=2.6.3
- bundle exec rake
32 changes: 32 additions & 0 deletions BACKERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Backers

You can join in supporting TinyTDS and the Rails SQL Server Adapter development by [pledging on Patreon](https://www.patreon.com/metaskills)! Backers in the same pledge level appear in the order of pledge date.

### $2000

[It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611218)


### $500

[It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611209)


### $250

[It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611199)


### $100

[It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611196)


### $50+

[It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611186)


### $10+

[It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611149)
58 changes: 47 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,61 @@
## v5.2.0
## v5.1.6.odbc

- #686 sql_for_insert set table name in case when pk is not nil
#### Added

## v5.2.0.rc2
* ODBC restoration.


## v5.1.6

#### Added

* Use lock hint when joining table in query.


## v5.1.5

#### Fixed

- #681 change_column_null should not clear other column attributes. Fixes #582.
- #684 Fix explain with array conditions. Fixes #673.
* Memoize `@@version` queries. Fixes #632


## v5.2.0.rc1
## v5.1.4

#### Fixed

- #638 Don't disable referential integrity for the same table twice.
- #646 Make String equality check work for Type::Data values. Fixes #645.
- #671 Fix tinyint columns schema migration. Fixes #670.
* Add case insensitive comparison for better performance with CI collations. Fixes #624


## v5.1.3

#### Fixed

* Use bigint type in sqlserver_type when needed. Fixes #616


## v5.1.2

#### Fixed

* The `fast_string_to_time` method when zone local. Fixes #609 #614 #620
* Patched `Relation#build_count_subquery`. Fixes #613.
* Inserts to tables with triggers using default `OUTPUT INSERTED` style. Fixes #595.


## v5.1.1

#### Fixed

* Use `ActiveSupport.on_load` to hook into ActiveRecord Fixes #588 #598


## v5.1.0

#### Changed

- #642 Added with (nolock) hint to information_schema.views.
* The `drop_table` with force cascade option now mimics in via pure SQL for us.

#### Added

* Support MismatchedForeignKey exception.

Please check [5-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/5-1-stable/CHANGELOG.md) for previous changes.
14 changes: 0 additions & 14 deletions Dockerfile

This file was deleted.

7 changes: 6 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ require 'openssl'
source 'https://rubygems.org'
gemspec

gem 'sqlite3', '~> 1.3.6'
gem 'sqlite3', '< 1.4'
gem 'minitest', '< 5.3.4'
gem 'bcrypt'
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Expand Down Expand Up @@ -50,6 +51,10 @@ group :tinytds do
end
end

group :odbc do
gem 'ruby-odbc', :git => 'https://github.com/cloudvolumes/ruby-odbc.git', :tag => '0.101.cv'
end

group :development do
gem 'byebug'
gem 'mocha'
Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@
* [![Dependency Status](https://dependencyci.com/github/rails-sqlserver/activerecord-sqlserver-adapter/badge)](https://dependencyci.com/github/rails-sqlserver/activerecord-sqlserver-adapter) - Dependency Status
* [![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

## Supporting TinyTDS/Adapter

Both TinyTDS and the Rails SQL Server Adapter are MIT-licensed open source projects. Its ongoing development is made possible thanks to the support by these awesome [backers](https://github.com/rails-sqlserver/tiny_tds/blob/master/BACKERS.md). If you'd like to join them, check out our [Patreon Campaign](https://www.patreon.com/metaskills).


## About The Adapter

The SQL Server adapter for ActiveRecord v5.2 using SQL Server 2012 or higher.
The SQL Server adapter for ActiveRecord v5.1 using SQL Server 2012 or higher.

Interested in older versions? We follow a rational versioning policy that tracks Rails. That means that our 5.1.x version of the adapter is only for the latest 5.1 version of Rails. If you need the adapter for SQL Server 2008 or 2005, you are still in the right spot. Just install the latest 3.2.x to 4.1.x version of the adapter that matches your Rails version. We also have stable branches for each major/minor release of ActiveRecord.
Interested in older versions? We follow a rational versioning policy that tracks Rails. That means that our 5.0.x version of the adapter is only for the latest 5.0 version of Rails. If you need the adapter for SQL Server 2008 or 2005, you are still in the right spot. Just install the latest 3.2.x to 4.1.x version of the adapter that matches your Rails version. We also have stable branches for each major/minor release of ActiveRecord.

#### Native Data Type Support

We support every data type supported by FreeTDS. All simplified Rails types in migrations will coorespond to a matching SQL Server national (unicode) data type. Always check the `initialize_native_database_types` [(here)](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/master/lib/active_record/connection_adapters/sqlserver/schema_statements.rb) for an updated list.
We support every data type supported by FreeTDS. All simplified Rails types in migrations will coorespond to a matching SQL Server national (unicode) data type. Always check the `initialize_native_database_types` [(here)](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/master/lib/active_record/connection_adapters/sqlserver/schema_statements.rb#L243) for an updated list.

The following types (date, datetime2, datetimeoffset, time) all require TDS version 7.3 with TinyTDS. We recommend using FreeTDS 1.0 or higher which default to using `TDSVER` to "7.3". The adapter also sets TinyTDS's `tds_version` to this as well if non is specified.

Expand Down Expand Up @@ -131,7 +136,7 @@ gem 'activerecord-sqlserver-adapter'

## Contributing

If you would like to contribute a feature or bugfix, thanks! To make sure your fix/feature has a high chance of being added, please read the following guidelines. First, ask on the Gitter, or post a ticket on github issues. Second, make sure there are tests! We will not accept any patch that is not tested. Please read the [`RUNNING_UNIT_TESTS`](RUNNING_UNIT_TESTS.md) file for the details of how to run the unit tests.
If you would like to contribute a feature or bugfix, thanks! To make sure your fix/feature has a high chance of being added, please read the following guidelines. First, ask on the Gitter, or post a ticket on github issues. Second, make sure there are tests! We will not accept any patch that is not tested. Please read the `RUNNING_UNIT_TESTS` file for the details of how to run the unit tests.

* Github: http://github.com/rails-sqlserver/activerecord-sqlserver-adapter
* Gitter: https://gitter.im/rails-sqlserver/activerecord-sqlserver-adapter
Expand Down
9 changes: 7 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ task default: [:test]

namespace :test do

%w(dblib).each do |mode|
%w(dblib odbc).each do |mode|

Rake::TestTask.new(mode) do |t|
t.libs = ARTest::SQLServer.test_load_paths
Expand All @@ -23,12 +23,17 @@ namespace :test do
ENV['ARCONN'] = 'dblib'
end

task 'odbc:env' do
ENV['ARCONN'] = 'odbc'
end

end

task 'test:dblib' => 'test:dblib:env'
task 'test:odbc' => 'test:odbc:env'

namespace :profile do
['dblib'].each do |mode|
['dblib', 'odbc'].each do |mode|
namespace mode.to_sym do
Dir.glob('test/profile/*_profile_case.rb').sort.each do |test_file|
profile_case = File.basename(test_file).sub('_profile_case.rb', '')
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.2.0
5.1.6.odbc
4 changes: 2 additions & 2 deletions activerecord-sqlserver-adapter.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']
spec.add_dependency 'activerecord', '~> 5.2.0'
spec.add_dependency 'tiny_tds'
spec.add_dependency 'activerecord', '~> 5.1.0'
spec.add_dependency 'ruby-odbc'
end
14 changes: 6 additions & 8 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ dependencies:
- openssl version
- sudo ./test/bin/install-freetds.sh
- tsql -C
- rvm-exec 2.3.8 bundle install
- rvm-exec 2.4.5 bundle install
- rvm-exec 2.5.3 bundle install
- rvm-exec 2.6.0 bundle install
- rvm-exec 2.2.5 bundle install
- rvm-exec 2.3.1 bundle install
- rvm-exec 2.4.0 bundle install

database:
override:
Expand All @@ -32,7 +31,6 @@ database:

test:
override:
- rvm-exec 2.3.8 bundle exec rake test
- rvm-exec 2.4.5 bundle exec rake test
- rvm-exec 2.5.3 bundle exec rake test
- rvm-exec 2.6.0 bundle exec rake test
- rvm-exec 2.2.5 bundle exec rake test
- rvm-exec 2.3.1 bundle exec rake test
- rvm-exec 2.4.0 bundle exec rake test
11 changes: 0 additions & 11 deletions docker-compose.ci.yml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ module Calculations
private

def build_count_subquery(relation, column_name, distinct)
super(relation.unscope(:order), column_name, distinct)
end
relation.select_values = [
if column_name == :all
distinct ? table[Arel.star] : Arel.sql(FinderMethods::ONE_AS_ONE)
else
column_alias = Arel.sql("count_column")
aggregate_column(column_name).as(column_alias)
end
]

subquery = relation.arel.as(Arel.sql("subquery_for_count"))
select_value = operation_over_aggregate_column(column_alias || Arel.star, "count", false)

def type_cast_calculated_value(value, type, operation = nil)
case operation
when "count" then value.to_i
when "sum" then type.deserialize(value || 0)
when "average" then value&.respond_to?(:to_d) ? value.to_d : value
else type.deserialize(value)
end
Arel::SelectManager.new(subquery).project(select_value)
end
end
end
Expand All @@ -27,6 +30,10 @@ def type_cast_calculated_value(value, type, operation = nil)
end

ActiveSupport.on_load(:active_record) do
mod = ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::Calculations
ActiveRecord::Relation.prepend(mod)
if ActiveRecord::VERSION::MAJOR == 5 &&
ActiveRecord::VERSION::MINOR == 1 &&
ActiveRecord::VERSION::TINY >= 4
mod = ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::Calculations
ActiveRecord::Relation.prepend(mod)
end
end
32 changes: 18 additions & 14 deletions lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ module CoreExt
module Explain

SQLSERVER_STATEMENT_PREFIX = 'EXEC sp_executesql '.freeze
SQLSERVER_STATEMENT_REGEXP = /N'(.+)', N'(.+)', (.+)/
SQLSERVER_PARAM_MATCHER = /@\d+ = (.*)/
SQLSERVER_NATIONAL_STRING_MATCHER = /N'(.*)'/m

def exec_explain(queries)
unprepared_queries = queries.map do |(sql, binds)|
[unprepare_sqlserver_statement(sql, binds), binds]
[unprepare_sqlserver_statement(sql), binds]
end
super(unprepared_queries)
end
Expand All @@ -18,19 +19,22 @@ def exec_explain(queries)

# This is somewhat hacky, but it should reliably reformat our prepared sql statment
# which uses sp_executesql to just the first argument, then unquote it. Likewise our
# `sp_executesql` method should substitude the @n args with the quoted values.
def unprepare_sqlserver_statement(sql, binds)
return sql unless sql.starts_with?(SQLSERVER_STATEMENT_PREFIX)

executesql = sql.from(SQLSERVER_STATEMENT_PREFIX.length)
executesql = executesql.match(SQLSERVER_STATEMENT_REGEXP).to_a[1]

binds.each_with_index do |bind, index|
value = connection.quote(bind)
executesql = executesql.sub("@#{index}", value)
# `sp_executesql` method should substitude the @n args withe the quoted values.
def unprepare_sqlserver_statement(sql)
if sql.starts_with?(SQLSERVER_STATEMENT_PREFIX)
executesql = sql.from(SQLSERVER_STATEMENT_PREFIX.length)
args = executesql.split(', ')
unprepared_sql = args.shift.strip.match(SQLSERVER_NATIONAL_STRING_MATCHER)[1]
unprepared_sql = Utils.unquote_string(unprepared_sql)
args = args.from(args.length / 2)
args.each_with_index do |arg, index|
value = arg.match(SQLSERVER_PARAM_MATCHER)[1]
unprepared_sql.sub! "@#{index}", value
end
unprepared_sql
else
sql
end

executesql
end

end
Expand Down
Loading