activerecord-jdbcsqlserver-adapter 51.1.0 → 52.0.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +22 -39
  4. data/{Dockerfile → Dockerfile.ci} +0 -0
  5. data/Gemfile +1 -3
  6. data/README.md +5 -8
  7. data/VERSION +1 -1
  8. data/activerecord-jdbcsqlserver-adapter.gemspec +2 -3
  9. data/docker-compose.ci.yml +7 -5
  10. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +25 -29
  11. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +14 -18
  12. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +43 -0
  13. data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +26 -0
  14. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +13 -2
  15. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +53 -10
  16. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +1 -0
  17. data/lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb +5 -13
  18. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +2 -1
  19. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +2 -2
  20. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +43 -27
  21. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +3 -4
  22. data/lib/active_record/connection_adapters/sqlserver/type/json.rb +1 -1
  23. data/lib/active_record/connection_adapters/sqlserver/type/string.rb +7 -0
  24. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +1 -0
  25. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +20 -14
  26. data/lib/active_record/tasks/sqlserver_database_tasks.rb +3 -1
  27. data/lib/activerecord-jdbcsqlserver-adapter.rb +3 -0
  28. data/lib/arel/visitors/sqlserver.rb +1 -1
  29. data/lib/arel_sqlserver.rb +0 -1
  30. data/test/bin/install-freetds.sh +18 -0
  31. data/test/cases/adapter_test_sqlserver.rb +29 -21
  32. data/test/cases/change_column_null_test_sqlserver.rb +42 -0
  33. data/test/cases/coerced_tests.rb +304 -30
  34. data/test/cases/column_test_sqlserver.rb +496 -462
  35. data/test/cases/connection_test_sqlserver.rb +2 -2
  36. data/test/cases/fetch_test_sqlserver.rb +5 -5
  37. data/test/cases/helper_sqlserver.rb +6 -0
  38. data/test/cases/json_test_sqlserver.rb +6 -6
  39. data/test/cases/migration_test_sqlserver.rb +13 -3
  40. data/test/cases/order_test_sqlserver.rb +19 -19
  41. data/test/cases/pessimistic_locking_test_sqlserver.rb +9 -9
  42. data/test/cases/rake_test_sqlserver.rb +20 -20
  43. data/test/cases/schema_dumper_test_sqlserver.rb +34 -33
  44. data/test/cases/schema_test_sqlserver.rb +2 -2
  45. data/test/cases/showplan_test_sqlserver.rb +25 -10
  46. data/test/cases/specific_schema_test_sqlserver.rb +11 -11
  47. data/test/cases/transaction_test_sqlserver.rb +9 -9
  48. data/test/cases/trigger_test_sqlserver.rb +8 -8
  49. data/test/cases/utils_test_sqlserver.rb +36 -36
  50. data/test/cases/uuid_test_sqlserver.rb +8 -8
  51. data/test/migrations/create_clients_and_change_column_null.rb +23 -0
  52. data/test/schema/datatypes/2012.sql +1 -0
  53. data/test/schema/sqlserver_specific_schema.rb +9 -1
  54. data/test/support/core_ext/query_cache.rb +29 -0
  55. metadata +19 -10
  56. data/BACKERS.md +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0fc70db649cdce388b0aa9682a6c67c425953238feed9db877e597edea9a887
4
- data.tar.gz: ae1c960295840fecfb6a6134d012e557f2ac61c2da7f1651cd10e9ceb2f23025
3
+ metadata.gz: c764412410f757d3f4ee0312e3950ba5eb3cd1b3f7e21645e2d081ce4974f7b2
4
+ data.tar.gz: 463f9a3245a8d95ff78d76fd2284a8cacbc64b8510bfb95915d55c2e2b50021f
5
5
  SHA512:
6
- metadata.gz: 4d17bb43ed779b8dbb7b27c12d64e00666368dd1aa7eec19a1b2ef19db4c7202dd2f4a81058ade3dcc4c4977630a4109e952f43cec683f728fcc05cc3939055c
7
- data.tar.gz: bd361d607277b673f3e2f83428024730c9aa86a08b38cf5e01677dbd2b0ba7e817338c58efff22bf33ca9a915f0ae8030624f5d93bfb84a3053d04a81e05c7f1
6
+ metadata.gz: 703e10527b9d65e5e237dde6b5cdc381cb2f398f8fcd3cad780f64567694c193e9922ac58f5b4e591611157cb480ed405c75093d314e535c00210ad2ccbaeb99
7
+ data.tar.gz: f229972c054e17396b5aa1f6f554ae0a661a4e8d69ca9cb8e9ed52e4c7c3afef0f2d0eeb3e217f3e8b9c0323140329c16aa1e0986e2bc2b57da7817524a0232e
@@ -5,7 +5,7 @@ services:
5
5
  env:
6
6
  global:
7
7
  - COMPOSE_FILE: docker-compose.ci.yml
8
- - ARJDBC_BRANCH=51-stable
8
+ - ARJDBC_BRANCH: 52-stable
9
9
  matrix:
10
10
  - TARGET_VERSION=9.1
11
11
  - TARGET_VERSION=9.2
@@ -1,62 +1,45 @@
1
- ## v51.1.0
2
1
 
3
- * Updated activerecord-jdbc-adapter dependecy to fix an issue with inserts on tables with composite primary keys
4
- * Changed how the jdbc driver is loaded so that other drivers can be used if needed
2
+ ## v52.0.0
5
3
 
6
- ## v51.0.0
4
+ - Forked to support JRuby
7
5
 
8
- * Forked original gem to provide JRuby support
9
-
10
- ## v5.1.6
11
-
12
- #### Added
13
-
14
- * Use lock hint when joining table in query.
15
-
16
-
17
- ## v5.1.5
6
+ ## v5.2.1
18
7
 
19
8
  #### Fixed
20
9
 
21
- * Memoize `@@version` queries. Fixes #632
22
-
10
+ - [#691](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/691) Fix constraints bug
11
+ - [#700](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/700) SET SINGLE_USER before dropping the database
12
+ - [#733](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/733) Calculate should not remove ordering for MSSQL
13
+ - [#735](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/735) Order by selected items when using distinct exists
14
+ - [#737](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/737) Use default precision for 'time' column type
15
+ - [#744](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/744) Adapter does not use prepared statement cache
16
+ - [#743](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/743) Set default time precision when registering time type
17
+ - [#745](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/745) Quoted table names containing square brackets need to be regex escaped
23
18
 
24
- ## v5.1.4
19
+ ## v5.2.0
25
20
 
26
21
  #### Fixed
27
22
 
28
- * Add case insensitive comparison for better performance with CI collations. Fixes #624
23
+ - [#686](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/686) sql_for_insert set table name in case when pk is not nil
29
24
 
30
-
31
- ## v5.1.3
25
+ ## v5.2.0.rc2
32
26
 
33
27
  #### Fixed
34
28
 
35
- * Use bigint type in sqlserver_type when needed. Fixes #616
36
-
29
+ - [#681](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/681) change_column_null should not clear other column attributes. Fixes #582.
30
+ - [#684](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/684) Fix explain with array conditions. Fixes #673.
37
31
 
38
- ## v5.1.2
32
+ ## v5.2.0.rc1
39
33
 
40
34
  #### Fixed
41
35
 
42
- * The `fast_string_to_time` method when zone local. Fixes #609 #614 #620
43
- * Patched `Relation#build_count_subquery`. Fixes #613.
44
- * Inserts to tables with triggers using default `OUTPUT INSERTED` style. Fixes #595.
45
-
46
-
47
- ## v5.1.1
48
-
49
- #### Fixed
50
-
51
- * Use `ActiveSupport.on_load` to hook into ActiveRecord Fixes #588 #598
52
-
53
-
54
- ## v5.1.0
36
+ - [#638](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/638) Don't disable referential integrity for the same table twice.
37
+ - [#646](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/646) Make String equality check work for Type::Data values. Fixes #645.
38
+ - [#671](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/671) Fix tinyint columns schema migration. Fixes #670.
55
39
 
56
40
  #### Changed
57
41
 
58
- * The `drop_table` with force cascade option now mimics in via pure SQL for us.
42
+ - [#642](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/642) Added with (nolock) hint to information_schema.views.
59
43
 
60
- #### Added
61
44
 
62
- * Support MismatchedForeignKey exception.
45
+ Please check [5-1-stable-jdbc](https://github.com/jruby/activerecord-jdbcsqlserver-adapter/blob/5-1-stable-jdbc/CHANGELOG.md) for previous changes.
File without changes
data/Gemfile CHANGED
@@ -2,9 +2,7 @@ require 'openssl'
2
2
  source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
- gem 'rb-readline', platform: :mri
6
- gem 'sqlite3', platform: :mri
7
- gem 'minitest', '< 5.3.4'
5
+ gem 'sqlite3', '~> 1.3.6', platform: :mri
8
6
  gem 'bcrypt'
9
7
  gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
10
8
 
data/README.md CHANGED
@@ -1,18 +1,16 @@
1
- # ActiveRecord SQL Server Adapter. For SQL Server 2012 And Higher.
1
+ # ActiveRecord JDBC SQL Server Adapter. For SQL Server 2012 And Higher.
2
2
 
3
3
  [![Gem Version](http://img.shields.io/gem/v/activerecord-jdbcsqlserver-adapter.svg)](https://rubygems.org/gems/activerecord-jdbcsqlserver-adapter) - Gem Version
4
4
 
5
- The JDBC SQL Server adapter for ActiveRecord v5.1 using SQL Server 2012 or higher.
5
+ ## About The Adapter
6
+
7
+ The JDBC SQL Server adapter for ActiveRecord v5.2 using SQL Server 2012 or higher.
6
8
 
7
9
  We currently support JRuby 9.2+. Older versions may work but they are not tested and there is a known date issue with JRuby 9.1.
8
10
 
9
11
  For older versions see [activerecord-jdbcmssql-adapter](https://rubygems.org/gems/activerecord-jdbcmssql-adapter)
10
12
 
11
13
 
12
- #### Native Data Type Support
13
-
14
- The Rails v5 adapter supports ActiveRecord's `datetime_with_precision` setting. This means that passing `:precision` to a datetime column is supported. Using a pecision with the `:datetime` type will signal the adapter to use the `datetime2` type under the hood.
15
-
16
14
  #### Schemas & Users
17
15
 
18
16
  Depending on your user and schema setup, it may be needed to use a table name prefix of `dbo.`. So something like this in your initializer file for ActiveRecord or the adapter.
@@ -48,7 +46,7 @@ gem 'activerecord-jdbcsqlserver-adapter'
48
46
 
49
47
  ## Contributing
50
48
 
51
- 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.
49
+ 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.
52
50
 
53
51
  This is a fork of the activerecord-sqlserver-adapter. If you find a bug in the base code, please submit patches to: http://github.com/rails-sqlserver/activerecord-sqlserver-adapter
54
52
 
@@ -89,4 +87,3 @@ JDBC version of the gem:
89
87
  ## License
90
88
 
91
89
  Copyright © 2008-2019. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
92
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 51.1.0
1
+ 52.0.0
@@ -15,8 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
16
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
17
  spec.require_paths = ['lib']
18
-
19
- spec.add_dependency 'activerecord', '~> 5.1.0', '>= 5.1.7'
20
- spec.add_dependency 'activerecord-jdbc-adapter' , '~> 51.8'
18
+ spec.add_dependency 'activerecord', '~> 5.2.0', '>= 5.2.3'
19
+ spec.add_dependency 'activerecord-jdbc-adapter' , '~> 52.7'
21
20
  spec.add_dependency 'jdbc-mssql', '>= 0.6.0'
22
21
  end
@@ -1,11 +1,13 @@
1
1
  version: "2.2"
2
2
  services:
3
- database:
3
+ sqlserver:
4
4
  image: metaskills/mssql-server-linux-rails
5
5
  ci:
6
6
  environment:
7
- - ACTIVERECORD_UNITTEST_HOST=database
8
- build: .
9
- command: test/bin/wait-for.sh database:1433 -- bundle exec rake test
7
+ - ACTIVERECORD_UNITTEST_HOST=sqlserver
8
+ build:
9
+ context: .
10
+ dockerfile: Dockerfile.ci
11
+ command: test/bin/wait-for.sh sqlserver:1433 -- bundle exec rake test
10
12
  depends_on:
11
- - "database"
13
+ - "sqlserver"
@@ -7,37 +7,37 @@ module ActiveRecord
7
7
  module CoreExt
8
8
  module Calculations
9
9
 
10
- # @Override
11
- # If we are ordering a subquery for a count, we have to artificially add the offset bind parameter
12
- def bound_attributes
13
- attrs = super
14
- if @_setting_offset_for_count
15
- @_setting_offset_for_count = false
16
- attrs << Attribute.with_cast_value('OFFSET'.freeze, 0, ::ActiveRecord::Type.default_value)
10
+ # Same as original except we don't perform PostgreSQL hack that removes ordering.
11
+ def calculate(operation, column_name)
12
+ if has_include?(column_name)
13
+ relation = apply_join_dependency
14
+
15
+ if operation.to_s.downcase == "count"
16
+ unless distinct_value || distinct_select?(column_name || select_for_count)
17
+ relation.distinct!
18
+ relation.select_values = [ klass.primary_key || table[Arel.star] ]
19
+ end
20
+ end
21
+
22
+ relation.calculate(operation, column_name)
23
+ else
24
+ perform_calculation(operation, column_name)
17
25
  end
18
- attrs
19
26
  end
20
27
 
21
28
  private
22
29
 
23
- # @Override
24
30
  def build_count_subquery(relation, column_name, distinct)
31
+ super(relation.unscope(:order), column_name, distinct)
32
+ end
25
33
 
26
- # For whatever reason, mssql requires an offset if an ORDER BY is included in a subquery
27
- if distinct && !has_limit_or_offset? && !relation.orders.empty?
28
- relation = relation.offset(0)
29
-
30
- # This is purely to appease activerecord/test/cases/calculations_test.rb @ line 258 CalculationsTest#test_distinct_count_all_with_custom_select_and_order
31
- # hopefully nobody tries to do anything too crazy in a literal...
32
- if relation.projections.length == 1 && relation.projections.first.is_a?(::Arel::Nodes::SqlLiteral)
33
- relation.projections[0] = ::Arel::Nodes::SqlLiteral.new(relation.projections.first + ' as some_name_that_hopefully_never_exists123')
34
- end
35
-
36
- @_setting_offset_for_count = true
34
+ def type_cast_calculated_value(value, type, operation = nil)
35
+ case operation
36
+ when "count" then value.to_i
37
+ when "sum" then type.deserialize(value || 0)
38
+ when "average" then value&.respond_to?(:to_d) ? value.to_d : value
39
+ else type.deserialize(value)
37
40
  end
38
-
39
- super
40
-
41
41
  end
42
42
  end
43
43
  end
@@ -46,10 +46,6 @@ module ActiveRecord
46
46
  end
47
47
 
48
48
  ActiveSupport.on_load(:active_record) do
49
- if ActiveRecord::VERSION::MAJOR == 5 &&
50
- ActiveRecord::VERSION::MINOR == 1 &&
51
- ActiveRecord::VERSION::TINY >= 4
52
- mod = ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::Calculations
53
- ActiveRecord::Relation.prepend(mod)
54
- end
49
+ mod = ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::Calculations
50
+ ActiveRecord::Relation.prepend(mod)
55
51
  end
@@ -5,12 +5,11 @@ module ActiveRecord
5
5
  module Explain
6
6
 
7
7
  SQLSERVER_STATEMENT_PREFIX = 'EXEC sp_executesql '.freeze
8
- SQLSERVER_PARAM_MATCHER = /@\d+ = (.*)/
9
- SQLSERVER_NATIONAL_STRING_MATCHER = /N'(.*)'/m
8
+ SQLSERVER_STATEMENT_REGEXP = /N'(.+)', N'(.+)', (.+)/
10
9
 
11
10
  def exec_explain(queries)
12
11
  unprepared_queries = queries.map do |(sql, binds)|
13
- [unprepare_sqlserver_statement(sql), binds]
12
+ [unprepare_sqlserver_statement(sql, binds), binds]
14
13
  end
15
14
  super(unprepared_queries)
16
15
  end
@@ -19,22 +18,19 @@ module ActiveRecord
19
18
 
20
19
  # This is somewhat hacky, but it should reliably reformat our prepared sql statment
21
20
  # which uses sp_executesql to just the first argument, then unquote it. Likewise our
22
- # `sp_executesql` method should substitude the @n args withe the quoted values.
23
- def unprepare_sqlserver_statement(sql)
24
- if sql.starts_with?(SQLSERVER_STATEMENT_PREFIX)
25
- executesql = sql.from(SQLSERVER_STATEMENT_PREFIX.length)
26
- args = executesql.split(', ')
27
- unprepared_sql = args.shift.strip.match(SQLSERVER_NATIONAL_STRING_MATCHER)[1]
28
- unprepared_sql = Utils.unquote_string(unprepared_sql)
29
- args = args.from(args.length / 2)
30
- args.each_with_index do |arg, index|
31
- value = arg.match(SQLSERVER_PARAM_MATCHER)[1]
32
- unprepared_sql.sub! "@#{index}", value
33
- end
34
- unprepared_sql
35
- else
36
- sql
21
+ # `sp_executesql` method should substitude the @n args with the quoted values.
22
+ def unprepare_sqlserver_statement(sql, binds)
23
+ return sql unless sql.starts_with?(SQLSERVER_STATEMENT_PREFIX)
24
+
25
+ executesql = sql.from(SQLSERVER_STATEMENT_PREFIX.length)
26
+ executesql = executesql.match(SQLSERVER_STATEMENT_REGEXP).to_a[1]
27
+
28
+ binds.each_with_index do |bind, index|
29
+ value = connection.quote(bind)
30
+ executesql = executesql.sub("@#{index}", value)
37
31
  end
32
+
33
+ executesql
38
34
  end
39
35
 
40
36
  end
@@ -0,0 +1,43 @@
1
+ require 'active_record/relation'
2
+ require 'active_record/version'
3
+
4
+ module ActiveRecord
5
+ module ConnectionAdapters
6
+ module SQLServer
7
+ module CoreExt
8
+ module FinderMethods
9
+
10
+ private
11
+
12
+ # Same as original except we order by values in distinct select if present.
13
+ def construct_relation_for_exists(conditions)
14
+ if distinct_value && offset_value
15
+ relation = limit!(1)
16
+
17
+ if select_values.present?
18
+ relation = relation.order(*select_values)
19
+ else
20
+ relation = relation.except(:order)
21
+ end
22
+ else
23
+ relation = except(:select, :distinct, :order)._select!(::ActiveRecord::FinderMethods::ONE_AS_ONE).limit!(1)
24
+ end
25
+
26
+ case conditions
27
+ when Array, Hash
28
+ relation.where!(conditions) unless conditions.empty?
29
+ else
30
+ relation.where!(primary_key => conditions) unless conditions == :none
31
+ end
32
+
33
+ relation
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ ActiveSupport.on_load(:active_record) do
42
+ ActiveRecord::Relation.include(ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::FinderMethods)
43
+ end
@@ -0,0 +1,26 @@
1
+ require 'active_record/relation'
2
+ require 'active_record/version'
3
+
4
+ module ActiveRecord
5
+ module ConnectionAdapters
6
+ module SQLServer
7
+ module CoreExt
8
+ module QueryMethods
9
+
10
+ private
11
+
12
+ # Copy of original from Rails master. This patch can be removed when adapter supports Rails 6.
13
+ def table_name_matches?(from)
14
+ table_name = Regexp.escape(table.name)
15
+ quoted_table_name = Regexp.escape(connection.quote_table_name(table.name))
16
+ /(?:\A|(?<!FROM)\s)(?:\b#{table_name}\b|#{quoted_table_name})(?!\.)/i.match?(from.to_s)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ ActiveSupport.on_load(:active_record) do
25
+ ActiveRecord::Relation.include(ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::QueryMethods)
26
+ end
@@ -2,7 +2,6 @@ module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module SQLServer
4
4
  module DatabaseLimits
5
-
6
5
  def table_alias_length
7
6
  128
8
7
  end
@@ -32,7 +31,7 @@ module ActiveRecord
32
31
  end
33
32
 
34
33
  def in_clause_length
35
- 65_536
34
+ 10_000
36
35
  end
37
36
 
38
37
  def sql_query_length
@@ -43,6 +42,18 @@ module ActiveRecord
43
42
  256
44
43
  end
45
44
 
45
+ private
46
+
47
+ # The max number of binds is 2100, but because sp_executesql takes
48
+ # the first 2 params as the query string and the list of types,
49
+ # we have only 2098 spaces left
50
+ def bind_params_length
51
+ 2_098
52
+ end
53
+
54
+ def insert_rows_length
55
+ 1_000
56
+ end
46
57
  end
47
58
  end
48
59
  end
@@ -33,10 +33,6 @@ module ActiveRecord
33
33
  super(sql, name, binds).rows.first.first
34
34
  end
35
35
 
36
- def supports_statement_cache?
37
- true
38
- end
39
-
40
36
  def begin_db_transaction
41
37
  do_execute 'BEGIN TRANSACTION'
42
38
  end
@@ -77,17 +73,55 @@ module ActiveRecord
77
73
 
78
74
  def case_sensitive_comparison(table, attribute, column, value)
79
75
  if column.collation && !column.case_sensitive?
80
- table[attribute].eq(Arel::Nodes::Bin.new(Arel::Nodes::BindParam.new))
76
+ table[attribute].eq(Arel::Nodes::Bin.new(value))
81
77
  else
82
78
  super
83
79
  end
84
80
  end
85
81
 
82
+ # We should propose this change to Rails team
83
+ def insert_fixtures_set(fixture_set, tables_to_delete = [])
84
+ fixture_inserts = []
85
+
86
+ fixture_set.each do |table_name, fixtures|
87
+ fixtures.each_slice(insert_rows_length) do |batch|
88
+ fixture_inserts << build_fixture_sql(batch, table_name)
89
+ end
90
+ end
91
+
92
+ table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name table}".dup }
93
+ total_sql = Array.wrap(combine_multi_statements(table_deletes + fixture_inserts))
94
+
95
+ disable_referential_integrity do
96
+ transaction(requires_new: true) do
97
+ total_sql.each do |sql|
98
+ execute sql, "Fixtures Load"
99
+ yield if block_given?
100
+ end
101
+ end
102
+ end
103
+ end
104
+
86
105
  def can_perform_case_insensitive_comparison_for?(column)
87
106
  column.type == :string && (!column.collation || column.case_sensitive?)
88
107
  end
89
108
  private :can_perform_case_insensitive_comparison_for?
90
109
 
110
+ def combine_multi_statements(total_sql)
111
+ total_sql
112
+ end
113
+ private :combine_multi_statements
114
+
115
+ def default_insert_value(column)
116
+ if column.is_identity?
117
+ table_name = quote(quote_table_name(column.table_name))
118
+ Arel.sql("IDENT_CURRENT(#{table_name}) + IDENT_INCR(#{table_name})")
119
+ else
120
+ super
121
+ end
122
+ end
123
+ private :default_insert_value
124
+
91
125
  # === SQLServer Specific ======================================== #
92
126
 
93
127
  def execute_procedure(proc_name, *variables)
@@ -238,6 +272,8 @@ module ActiveRecord
238
272
  def sp_executesql_types_and_parameters(binds)
239
273
  types, params = [], []
240
274
  binds.each_with_index do |attr, index|
275
+ attr = attr.value if attr.is_a?(Arel::Nodes::BindParam)
276
+
241
277
  types << "@#{index} #{sp_executesql_sql_type(attr)}"
242
278
  params << sp_executesql_sql_param(attr)
243
279
  end
@@ -255,12 +291,12 @@ module ActiveRecord
255
291
  end
256
292
 
257
293
  def sp_executesql_sql_param(attr)
258
- case attr.value_for_database
294
+ case value = attr.value_for_database
259
295
  when Type::Binary::Data,
260
296
  ActiveRecord::Type::SQLServer::Data
261
- quote(attr.value_for_database)
297
+ quote(value)
262
298
  else
263
- quote(type_cast(attr.value_for_database))
299
+ quote(type_cast(value))
264
300
  end
265
301
  end
266
302
 
@@ -282,7 +318,14 @@ module ActiveRecord
282
318
  def raw_connection_do(sql)
283
319
  case @connection_options[:mode]
284
320
  when :dblib
285
- @connection.execute(sql).do
321
+ result = @connection.execute(sql)
322
+
323
+ # TinyTDS returns false instead of raising an exception if connection fails.
324
+ # Getting around this by raising an exception ourselves while this PR
325
+ # https://github.com/rails-sqlserver/tiny_tds/pull/469 is not released.
326
+ raise TinyTds::Error, "failed to execute statement" if result.is_a?(FalseClass)
327
+
328
+ result.do
286
329
  end
287
330
  ensure
288
331
  @update_sql = false
@@ -306,7 +349,7 @@ module ActiveRecord
306
349
  end
307
350
 
308
351
  def exec_insert_requires_identity?(sql, pk, binds)
309
- query_requires_identity_insert?(sql) if pk && binds.map(&:name).include?(pk)
352
+ query_requires_identity_insert?(sql)
310
353
  end
311
354
 
312
355
  def query_requires_identity_insert?(sql)