activerecord-sqlserver-adapter 7.1.7 → 7.2.1
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.
- checksums.yaml +4 -4
- data/.devcontainer/Dockerfile +3 -3
- data/.github/workflows/ci.yml +4 -4
- data/CHANGELOG.md +7 -94
- data/Dockerfile.ci +1 -1
- data/Gemfile +4 -4
- data/README.md +43 -19
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +2 -2
- data/docker-compose.ci.yml +1 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +6 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +6 -5
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +7 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +6 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +14 -12
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +53 -32
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +44 -46
- data/lib/active_record/connection_adapters/sqlserver/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +2 -5
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +38 -32
- data/lib/arel/visitors/sqlserver.rb +57 -12
- data/test/cases/active_schema_test_sqlserver.rb +6 -6
- data/test/cases/adapter_test_sqlserver.rb +17 -18
- data/test/cases/coerced_tests.rb +279 -167
- data/test/cases/disconnected_test_sqlserver.rb +9 -3
- data/test/cases/eager_load_too_many_ids_test_sqlserver.rb +1 -1
- data/test/cases/enum_test_sqlserver.rb +1 -1
- data/test/cases/execute_procedure_test_sqlserver.rb +9 -5
- data/test/cases/helper_sqlserver.rb +11 -5
- data/test/cases/index_test_sqlserver.rb +8 -6
- data/test/cases/json_test_sqlserver.rb +1 -1
- data/test/cases/lateral_test_sqlserver.rb +2 -2
- data/test/cases/migration_test_sqlserver.rb +1 -1
- data/test/cases/optimizer_hints_test_sqlserver.rb +12 -12
- data/test/cases/pessimistic_locking_test_sqlserver.rb +8 -7
- data/test/cases/primary_keys_test_sqlserver.rb +2 -2
- data/test/cases/rake_test_sqlserver.rb +8 -4
- data/test/cases/schema_dumper_test_sqlserver.rb +4 -5
- data/test/cases/showplan_test_sqlserver.rb +7 -7
- data/test/cases/specific_schema_test_sqlserver.rb +17 -13
- data/test/cases/view_test_sqlserver.rb +9 -1
- data/test/schema/sqlserver_specific_schema.rb +4 -4
- data/test/support/connection_reflection.rb +1 -1
- data/test/support/core_ext/query_cache.rb +2 -2
- data/test/support/query_assertions.rb +49 -0
- data/test/support/table_definition_sqlserver.rb +24 -0
- data/test/support/test_in_memory_oltp.rb +2 -2
- metadata +12 -13
- data/lib/active_record/sqlserver_base.rb +0 -13
- data/test/cases/scratchpad_test_sqlserver.rb +0 -8
- data/test/support/sql_counter_sqlserver.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73bbb76f7c1a620edbaf0aa6e69c5a8fcb9ba2f7c7c14716bb2663f776b8cb0d
|
4
|
+
data.tar.gz: a6d9ac56dbcddd486bd0111da5db2e2d0cc6c2bbc3519041a73fffa5cfc3fddb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 921bd35d9de85b363190dee9b001373fbae60b0c1e99755ff4b172c9f51510d7353b49fb39d636b4acc015755067846bfed6ca4f984eb75d91def007679154da
|
7
|
+
data.tar.gz: 384e76d966178e7c8bdc4f84cc03e3739bcfec1291fd42e57d8eb4804b7df37e4311f94ee659efa4d6b76a82ae833f8cd741f66bb667abf7a1e0c2f182107be9
|
data/.devcontainer/Dockerfile
CHANGED
@@ -6,9 +6,9 @@ FROM mcr.microsoft.com/devcontainers/ruby:${VARIANT}
|
|
6
6
|
|
7
7
|
# TinyTDS
|
8
8
|
RUN apt-get -y install libc6-dev \
|
9
|
-
&& wget http://www.freetds.org/files/stable/freetds-1.
|
10
|
-
&& tar -xzf freetds-1.
|
11
|
-
&& cd freetds-1.
|
9
|
+
&& wget http://www.freetds.org/files/stable/freetds-1.4.14.tar.gz \
|
10
|
+
&& tar -xzf freetds-1.4.14.tar.gz \
|
11
|
+
&& cd freetds-1.4.14 \
|
12
12
|
&& ./configure --prefix=/usr/local --with-tdsver=7.3 \
|
13
13
|
&& make \
|
14
14
|
&& make install
|
data/.github/workflows/ci.yml
CHANGED
@@ -5,7 +5,7 @@ on: [push, pull_request]
|
|
5
5
|
jobs:
|
6
6
|
test:
|
7
7
|
name: Run test suite
|
8
|
-
runs-on: ubuntu-latest
|
8
|
+
runs-on: ubuntu-20.04 # TODO: Change back to 'ubuntu-latest' when https://github.com/microsoft/mssql-docker/issues/899 resolved.
|
9
9
|
|
10
10
|
env:
|
11
11
|
COMPOSE_FILE: docker-compose.ci.yml
|
@@ -14,9 +14,9 @@ jobs:
|
|
14
14
|
fail-fast: false
|
15
15
|
matrix:
|
16
16
|
ruby:
|
17
|
-
- 3.
|
18
|
-
- 3.
|
19
|
-
- 3.
|
17
|
+
- 3.1.6
|
18
|
+
- 3.2.4
|
19
|
+
- 3.3.2
|
20
20
|
|
21
21
|
steps:
|
22
22
|
- name: Checkout code
|
data/CHANGELOG.md
CHANGED
@@ -1,106 +1,19 @@
|
|
1
|
-
## v7.1
|
1
|
+
## v7.2.1
|
2
2
|
|
3
3
|
#### Fixed
|
4
4
|
|
5
|
-
- [#
|
5
|
+
- [#1231](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1231) Enable identity insert on view's base table
|
6
6
|
|
7
|
-
## v7.
|
8
|
-
|
9
|
-
#### Fixed
|
10
|
-
|
11
|
-
- [#1208](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1208) Exclude "guest" schema in schema dumper
|
12
|
-
|
13
|
-
## v7.1.5
|
14
|
-
|
15
|
-
#### Added
|
16
|
-
|
17
|
-
- [#1201](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1201) Support non-dbo schemas in schema dumper
|
18
|
-
- [#1206](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1206) Support table names containing spaces
|
19
|
-
|
20
|
-
## v7.1.4
|
21
|
-
|
22
|
-
#### Fixed
|
23
|
-
|
24
|
-
- [#1164](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1164) Fix composite primary key with different data type with triggers
|
25
|
-
|
26
|
-
#### Changed
|
27
|
-
|
28
|
-
- [#1199](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1199) Remove ActiveRecord::Relation#calculate patch
|
29
|
-
|
30
|
-
## v7.1.3
|
31
|
-
|
32
|
-
#### Fixed
|
33
|
-
|
34
|
-
- [#1152](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1152) Fix Composite Key Inserts with Triggers
|
35
|
-
|
36
|
-
## v7.1.2
|
37
|
-
|
38
|
-
#### Fixed
|
39
|
-
|
40
|
-
- [#1151](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1151) FROM subquery should work if order provided
|
41
|
-
|
42
|
-
## v7.1.1
|
43
|
-
|
44
|
-
#### Fixed
|
45
|
-
|
46
|
-
- [#1145](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1145) Ensure correct order of COLLATE and NOT NULL in CREATE TABLE statements
|
47
|
-
- [#1144](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1144) Fix precision handling in time migration
|
48
|
-
- [#1143](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1143) Fix precision handling for datetimeoffset migration
|
49
|
-
|
50
|
-
## v7.1.0
|
7
|
+
## v7.2.0
|
51
8
|
|
52
9
|
#### Added
|
53
10
|
|
54
|
-
- [#
|
55
|
-
|
56
|
-
## v7.1.0.rc2
|
57
|
-
|
58
|
-
#### Added
|
59
|
-
|
60
|
-
- [#1136](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1136) Prevent marking broken connections as verified
|
61
|
-
- [#1138](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1138) Cache quoted names
|
62
|
-
|
63
|
-
## v7.1.0.rc1
|
64
|
-
|
65
|
-
#### Added
|
66
|
-
|
67
|
-
* Rails 7.1 Support
|
68
|
-
|
69
|
-
The adapter supports new Rails 7.1 features such as composite primary keys. See the
|
70
|
-
[Rails 7.1 release notes](https://guides.rubyonrails.org/7_1_release_notes.html) for more information.
|
11
|
+
- [#1178](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1178) Support encrypting binary columns
|
71
12
|
|
72
13
|
#### Changed
|
73
14
|
|
74
|
-
|
75
|
-
|
76
|
-
If you require additional connection configuration you now need to call `super` within the `configure_connection`
|
77
|
-
method so that the default configuration is also applied.
|
78
|
-
|
79
|
-
v7.1.x adapter:
|
80
|
-
```ruby
|
81
|
-
module ActiveRecord
|
82
|
-
module ConnectionAdapters
|
83
|
-
class SQLServerAdapter < AbstractAdapter
|
84
|
-
def configure_connection
|
85
|
-
super
|
86
|
-
raw_connection_do "SET TEXTSIZE #{64.megabytes}"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
```
|
15
|
+
- [#1153](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1153) Only support Ruby v3.1+
|
16
|
+
- [#1196](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1196) Use default inspect for database adapter
|
92
17
|
|
93
|
-
v7.0.x adapter:
|
94
|
-
```ruby
|
95
|
-
module ActiveRecord
|
96
|
-
module ConnectionAdapters
|
97
|
-
class SQLServerAdapter < AbstractAdapter
|
98
|
-
def configure_connection
|
99
|
-
raw_connection_do "SET TEXTSIZE #{64.megabytes}"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
```
|
105
18
|
|
106
|
-
Please check [7-
|
19
|
+
Please check [7-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/7-1-stable/CHANGELOG.md) for previous changes.
|
data/Dockerfile.ci
CHANGED
@@ -9,6 +9,6 @@ WORKDIR $WORKDIR
|
|
9
9
|
|
10
10
|
COPY . $WORKDIR
|
11
11
|
|
12
|
-
RUN bundle install --jobs `expr $(cat /proc/cpuinfo | grep -c "cpu cores") - 1` --retry 3
|
12
|
+
RUN RAILS_BRANCH=7-2-stable bundle install --jobs `expr $(cat /proc/cpuinfo | grep -c "cpu cores") - 1` --retry 3
|
13
13
|
|
14
14
|
CMD ["sh"]
|
data/Gemfile
CHANGED
@@ -8,16 +8,16 @@ gemspec
|
|
8
8
|
|
9
9
|
gem "bcrypt"
|
10
10
|
gem "pg", ">= 0.18.0"
|
11
|
-
gem "sqlite3", "
|
11
|
+
gem "sqlite3", ">= 1.6.6"
|
12
12
|
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
13
13
|
gem "benchmark-ips"
|
14
|
-
gem "minitest", ">= 5.15.0"
|
14
|
+
gem "minitest", ">= 5.15.0"
|
15
15
|
gem "msgpack", ">= 1.7.0"
|
16
16
|
|
17
17
|
if ENV["RAILS_SOURCE"]
|
18
18
|
gemspec path: ENV["RAILS_SOURCE"]
|
19
|
-
elsif ENV["
|
20
|
-
gem "rails", github: "rails/rails", branch:
|
19
|
+
elsif ENV["RAILS_BRANCH"]
|
20
|
+
gem "rails", github: "rails/rails", branch: ENV["RAILS_BRANCH"]
|
21
21
|
else
|
22
22
|
# Need to get rails source because the gem doesn't include tests
|
23
23
|
version = ENV["RAILS_VERSION"] || begin
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# ActiveRecord SQL Server Adapter. For SQL Server 2012 And Higher.
|
2
2
|
|
3
3
|
* [](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/actions/workflows/ci.yml) - CI
|
4
|
-
* [](https://ci.appveyor.com/project/rails-sqlserver/activerecord-sqlserver-adapter/branch/master) - Appveyor
|
5
4
|
* [](https://rubygems.org/gems/activerecord-sqlserver-adapter) - Gem Version
|
6
5
|
* [](https://gitter.im/rails-sqlserver/activerecord-sqlserver-adapter) - Community
|
7
6
|
|
@@ -9,21 +8,25 @@
|
|
9
8
|
|
10
9
|
The SQL Server adapter for ActiveRecord using SQL Server 2012 or higher.
|
11
10
|
|
12
|
-
Interested in older versions? We follow a rational versioning policy that tracks Rails. That means that our 7.x version
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
|
19
|
-
|
20
|
-
| `
|
21
|
-
| `
|
22
|
-
| `
|
23
|
-
| `
|
24
|
-
| `
|
25
|
-
|
26
|
-
|
11
|
+
Interested in older versions? We follow a rational versioning policy that tracks Rails. That means that our 7.x version
|
12
|
+
of the adapter is only for the latest 7.x version of Rails. If you need the adapter for SQL Server 2008 or 2005, you
|
13
|
+
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
|
14
|
+
version. We also have stable branches for each major/minor release of ActiveRecord. For older versions, please check
|
15
|
+
their stable branches.
|
16
|
+
|
17
|
+
| Adapter Version | Rails Version | Support | Branch |
|
18
|
+
|-----------------|---------------|----------------|-------------------------------------------------------------------------------------------------|
|
19
|
+
| `7.2.x` | `7.2.x` | Active | [main](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
|
20
|
+
| `7.1.x` | `7.1.x` | Active | [7-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-1-stable) |
|
21
|
+
| `7.0.x` | `7.0.x` | Ended | [7-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-0-stable) |
|
22
|
+
| `6.1.x` | `6.1.x` | Ended | [6-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-1-stable) |
|
23
|
+
| `6.0.x` | `6.0.x` | Ended | [6-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-0-stable) |
|
24
|
+
| `5.2.x` | `5.2.x` | Ended | [5-2-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-2-stable) |
|
25
|
+
| `5.1.x` | `5.1.x` | Ended | [5-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-1-stable) |
|
26
|
+
| `4.2.x` | `4.2.x` | Ended | [4-2-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/4-2-stable) |
|
27
|
+
| `4.1.x` | `4.1.x` | Ended | [4-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/4-1-stable) |
|
28
|
+
|
29
|
+
See [Rubygems](https://rubygems.org/gems/activerecord-sqlserver-adapter/versions) for the latest version of the adapter for each Rails release.
|
27
30
|
|
28
31
|
#### Native Data Type Support
|
29
32
|
|
@@ -168,14 +171,35 @@ ActiveRecord::ConnectionAdapters::SQLServerAdapter.showplan_option = 'SHOWPLAN_X
|
|
168
171
|
|
169
172
|
## New Rails Applications
|
170
173
|
|
171
|
-
When creating a new Rails application you
|
174
|
+
When creating a new Rails application you need to perform the following steps to connect a Rails application to a
|
175
|
+
SQL Server instance.
|
172
176
|
|
177
|
+
1. Create new Rails application, the database defaults to `sqlite`.
|
178
|
+
|
179
|
+
```bash
|
180
|
+
rails new my_app
|
173
181
|
```
|
174
|
-
|
182
|
+
|
183
|
+
2. Update the Gemfile to install the adapter instead of the SQLite adapter. Remove the `sqlite3` gem from the Gemfile.
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
gem 'activerecord-sqlserver-adapter'
|
175
187
|
```
|
176
188
|
|
177
|
-
|
189
|
+
3. Connect the application to your SQL Server instance by editing the `config/database.yml` file with the username,
|
190
|
+
password and host of your SQL Server instance.
|
191
|
+
|
192
|
+
Example:
|
178
193
|
|
194
|
+
```yaml
|
195
|
+
development:
|
196
|
+
adapter: sqlserver
|
197
|
+
host: 'localhost'
|
198
|
+
port: 1433
|
199
|
+
database: my_app_development
|
200
|
+
username: 'frank_castle'
|
201
|
+
password: 'secret'
|
202
|
+
```
|
179
203
|
|
180
204
|
## Installation
|
181
205
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
7.1
|
1
|
+
7.2.1
|
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.platform = Gem::Platform::RUBY
|
8
8
|
spec.version = version
|
9
9
|
|
10
|
-
spec.required_ruby_version = ">=
|
10
|
+
spec.required_ruby_version = ">= 3.1.0"
|
11
11
|
|
12
12
|
spec.license = "MIT"
|
13
13
|
spec.authors = ["Ken Collins", "Anna Carey", "Will Bond", "Murray Steele", "Shawn Balestracci", "Joe Rafaniello", "Tom Ward", "Aidan Haran"]
|
@@ -27,6 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
|
30
|
-
spec.add_dependency "activerecord", "~> 7.
|
30
|
+
spec.add_dependency "activerecord", "~> 7.2.0"
|
31
31
|
spec.add_dependency "tiny_tds"
|
32
32
|
end
|
data/docker-compose.ci.yml
CHANGED
@@ -10,11 +10,13 @@ module ActiveRecord
|
|
10
10
|
private
|
11
11
|
|
12
12
|
def attributes_for_update(attribute_names)
|
13
|
-
|
13
|
+
self.class.with_connection do |connection|
|
14
|
+
return super(attribute_names) unless connection.sqlserver?
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
super(attribute_names).reject do |name|
|
17
|
+
column = self.class.columns_hash[name]
|
18
|
+
column && column.respond_to?(:is_identity?) && column.is_identity?
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -8,13 +8,14 @@ module ActiveRecord
|
|
8
8
|
module SQLServer
|
9
9
|
module CoreExt
|
10
10
|
module Calculations
|
11
|
-
|
12
|
-
private
|
13
11
|
|
12
|
+
private
|
13
|
+
|
14
14
|
def build_count_subquery(relation, column_name, distinct)
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
klass.with_connection do |connection|
|
16
|
+
relation = relation.unscope(:order) if connection.sqlserver?
|
17
|
+
super(relation, column_name, distinct)
|
18
|
+
end
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -9,12 +9,15 @@ module ActiveRecord
|
|
9
9
|
SQLSERVER_STATEMENT_REGEXP = /N'(.+)', N'(.+)', (.+)/
|
10
10
|
|
11
11
|
def exec_explain(queries, options = [])
|
12
|
-
|
12
|
+
with_connection do |connection|
|
13
|
+
return super(queries, options) unless connection.sqlserver?
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
unprepared_queries = queries.map do |(sql, binds)|
|
16
|
+
[unprepare_sqlserver_statement(sql, binds), binds]
|
17
|
+
end
|
18
|
+
|
19
|
+
super(unprepared_queries, options)
|
16
20
|
end
|
17
|
-
super(unprepared_queries, options)
|
18
21
|
end
|
19
22
|
|
20
23
|
private
|
@@ -11,10 +11,12 @@ module ActiveRecord
|
|
11
11
|
private
|
12
12
|
|
13
13
|
def construct_relation_for_exists(conditions)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
klass.with_connection do |connection|
|
15
|
+
if connection.sqlserver?
|
16
|
+
_construct_relation_for_exists(conditions)
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
@@ -8,23 +8,25 @@ module ActiveRecord
|
|
8
8
|
module CoreExt
|
9
9
|
module LoaderQuery
|
10
10
|
def load_records_for_keys(keys, &block)
|
11
|
-
|
11
|
+
scope.with_connection do |connection|
|
12
|
+
return super unless connection.sqlserver?
|
12
13
|
|
13
|
-
|
14
|
+
return [] if keys.empty?
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
if association_key_name.is_a?(Array)
|
17
|
+
query_constraints = Hash.new { |hsh, key| hsh[key] = Set.new }
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
keys.each_with_object(query_constraints) do |values_set, constraints|
|
20
|
+
association_key_name.zip(values_set).each do |key_name, value|
|
21
|
+
constraints[key_name] << value
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
scope.where(query_constraints).load(&block)
|
26
|
+
else
|
27
|
+
keys.each_slice(in_clause_length).flat_map do |slice|
|
28
|
+
scope.where(association_key_name => slice).load(&block).records
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
@@ -14,9 +14,7 @@ module ActiveRecord
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
|
17
|
-
|
18
|
-
|
19
|
-
log(sql, name, async: async) do
|
17
|
+
log(sql, name, async: async) do |notification_payload|
|
20
18
|
with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
|
21
19
|
result = if id_insert_table_name = query_requires_identity_insert?(sql)
|
22
20
|
with_identity_insert_enabled(id_insert_table_name, conn) { internal_raw_execute(sql, conn, perform_do: true) }
|
@@ -24,14 +22,13 @@ module ActiveRecord
|
|
24
22
|
internal_raw_execute(sql, conn, perform_do: true)
|
25
23
|
end
|
26
24
|
verified!
|
25
|
+
notification_payload[:row_count] = result
|
26
|
+
result
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
30
|
-
result
|
31
29
|
end
|
32
30
|
|
33
|
-
def internal_exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)
|
34
|
-
result = nil
|
31
|
+
def internal_exec_query(sql, name = "SQL", binds = [], prepare: false, async: false, allow_retry: false)
|
35
32
|
sql = transform_query(sql)
|
36
33
|
|
37
34
|
check_if_write_query(sql)
|
@@ -42,20 +39,24 @@ module ActiveRecord
|
|
42
39
|
sql = sp_executesql_sql(sql, types, params, name)
|
43
40
|
end
|
44
41
|
|
45
|
-
log(sql, name, binds, async: async) do
|
42
|
+
log(sql, name, binds, async: async) do |notification_payload|
|
46
43
|
with_raw_connection do |conn|
|
47
|
-
if id_insert_table_name = query_requires_identity_insert?(sql)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
result = if id_insert_table_name = query_requires_identity_insert?(sql)
|
45
|
+
# If the table name is a view, we need to get the base table name for enabling identity insert.
|
46
|
+
id_insert_table_name = view_table_name(id_insert_table_name) if view_exists?(id_insert_table_name)
|
47
|
+
|
48
|
+
with_identity_insert_enabled(id_insert_table_name, conn) do
|
49
|
+
internal_exec_sql_query(sql, conn)
|
50
|
+
end
|
51
|
+
else
|
52
|
+
internal_exec_sql_query(sql, conn)
|
53
|
+
end
|
54
|
+
|
54
55
|
verified!
|
56
|
+
notification_payload[:row_count] = result.count
|
57
|
+
result
|
55
58
|
end
|
56
59
|
end
|
57
|
-
|
58
|
-
result
|
59
60
|
end
|
60
61
|
|
61
62
|
def internal_exec_sql_query(sql, conn)
|
@@ -153,10 +154,10 @@ module ActiveRecord
|
|
153
154
|
|
154
155
|
if returning = insert.send(:insert_all).returning
|
155
156
|
returning_sql = if returning.is_a?(String)
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
157
|
+
returning
|
158
|
+
else
|
159
|
+
returning.map { |column| "INSERTED.#{quote_column_name(column)}" }.join(", ")
|
160
|
+
end
|
160
161
|
sql << " OUTPUT #{returning_sql}"
|
161
162
|
end
|
162
163
|
|
@@ -174,7 +175,7 @@ module ActiveRecord
|
|
174
175
|
end.join(", ")
|
175
176
|
sql = "EXEC #{proc_name} #{vars}".strip
|
176
177
|
|
177
|
-
log(sql, "Execute Procedure") do
|
178
|
+
log(sql, "Execute Procedure") do |notification_payload|
|
178
179
|
with_raw_connection do |conn|
|
179
180
|
result = internal_raw_execute(sql, conn)
|
180
181
|
verified!
|
@@ -185,10 +186,11 @@ module ActiveRecord
|
|
185
186
|
yield(r) if block_given?
|
186
187
|
end
|
187
188
|
|
188
|
-
result.each.map { |row| row.is_a?(Hash) ? row.with_indifferent_access : row }
|
189
|
+
result = result.each.map { |row| row.is_a?(Hash) ? row.with_indifferent_access : row }
|
190
|
+
notification_payload[:row_count] = result.count
|
191
|
+
result
|
189
192
|
end
|
190
193
|
end
|
191
|
-
|
192
194
|
end
|
193
195
|
|
194
196
|
def with_identity_insert_enabled(table_name, conn)
|
@@ -329,11 +331,17 @@ module ActiveRecord
|
|
329
331
|
end
|
330
332
|
|
331
333
|
def sp_executesql_sql_type(attr)
|
332
|
-
|
333
|
-
|
334
|
+
if attr.respond_to?(:type)
|
335
|
+
return attr.type.sqlserver_type if attr.type.respond_to?(:sqlserver_type)
|
334
336
|
|
335
|
-
|
336
|
-
|
337
|
+
if attr.type.is_a?(ActiveRecord::Encryption::EncryptedAttributeType) && attr.type.instance_variable_get(:@cast_type).respond_to?(:sqlserver_type)
|
338
|
+
return attr.type.instance_variable_get(:@cast_type).sqlserver_type
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
value = basic_attribute_type?(attr) ? attr : attr.value_for_database
|
343
|
+
|
344
|
+
if value.is_a?(Numeric)
|
337
345
|
value > 2_147_483_647 ? "bigint".freeze : "int".freeze
|
338
346
|
else
|
339
347
|
"nvarchar(max)".freeze
|
@@ -341,17 +349,26 @@ module ActiveRecord
|
|
341
349
|
end
|
342
350
|
|
343
351
|
def sp_executesql_sql_param(attr)
|
344
|
-
return quote(attr) if
|
352
|
+
return quote(attr) if basic_attribute_type?(attr)
|
345
353
|
|
346
354
|
case value = attr.value_for_database
|
347
|
-
when Type::Binary::Data,
|
348
|
-
ActiveRecord::Type::SQLServer::Data
|
355
|
+
when Type::Binary::Data, ActiveRecord::Type::SQLServer::Data
|
349
356
|
quote(value)
|
350
357
|
else
|
351
358
|
quote(type_cast(value))
|
352
359
|
end
|
353
360
|
end
|
354
361
|
|
362
|
+
def basic_attribute_type?(type)
|
363
|
+
type.is_a?(Symbol) ||
|
364
|
+
type.is_a?(String) ||
|
365
|
+
type.is_a?(Numeric) ||
|
366
|
+
type.is_a?(Time) ||
|
367
|
+
type.is_a?(TrueClass) ||
|
368
|
+
type.is_a?(FalseClass) ||
|
369
|
+
type.is_a?(NilClass)
|
370
|
+
end
|
371
|
+
|
355
372
|
def sp_executesql_sql(sql, types, params, name)
|
356
373
|
if name == "EXPLAIN"
|
357
374
|
params.each.with_index do |param, index|
|
@@ -424,7 +441,11 @@ module ActiveRecord
|
|
424
441
|
qo[:as] = (options[:ar_result] || options[:fetch] == :rows) ? :array : :hash
|
425
442
|
end
|
426
443
|
results = handle.each(query_options)
|
427
|
-
|
444
|
+
|
445
|
+
columns = handle.fields
|
446
|
+
# If query returns multiple result sets, only return the columns of the last one.
|
447
|
+
columns = columns.last if columns.any? && columns.all? { |e| e.is_a?(Array) }
|
448
|
+
columns = columns.map(&:downcase) if lowercase_schema_reflection
|
428
449
|
|
429
450
|
options[:ar_result] ? ActiveRecord::Result.new(columns, results) : results
|
430
451
|
end
|