activerecord-sqlserver-adapter 7.1.7 → 7.2.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.
- checksums.yaml +4 -4
- data/.devcontainer/Dockerfile +3 -3
- data/.github/workflows/ci.yml +10 -4
- data/CHANGELOG.md +5 -99
- data/Gemfile +4 -4
- data/README.md +43 -19
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +2 -2
- 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 +50 -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 +1 -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: b6356803690516019929168fed2c356f3250eb5ec8a9894b8117fc35db84b8c1
|
4
|
+
data.tar.gz: dbedbedb583e766c526d959459166edd195516700fb6f0b1be2769ea1d947233
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5079fd8e88a8e67b91f11de2f9ec158d686afe121461f2b2050ebdd1072f1ac0fc86356dd81da507e99b72b8f9266aa5a59031d886dcb8d119715cab4cbef1c8
|
7
|
+
data.tar.gz: d1a8f37563ba09c443242e83f75098b2cc74bd269c9b11b9c6834a5e2fa23c7791f93083c7884ec1d22acdeca3bdf75f752153bde565fa0d92c3988a6653565c
|
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
@@ -1,6 +1,12 @@
|
|
1
1
|
name: CI
|
2
2
|
|
3
|
-
on:
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ main ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ main ]
|
8
|
+
schedule:
|
9
|
+
- cron: '0 18 * * *'
|
4
10
|
|
5
11
|
jobs:
|
6
12
|
test:
|
@@ -14,9 +20,9 @@ jobs:
|
|
14
20
|
fail-fast: false
|
15
21
|
matrix:
|
16
22
|
ruby:
|
17
|
-
- 3.
|
18
|
-
- 3.
|
19
|
-
- 3.
|
23
|
+
- 3.1.6
|
24
|
+
- 3.2.4
|
25
|
+
- 3.3.2
|
20
26
|
|
21
27
|
steps:
|
22
28
|
- name: Checkout code
|
data/CHANGELOG.md
CHANGED
@@ -1,106 +1,12 @@
|
|
1
|
-
##
|
2
|
-
|
3
|
-
#### Fixed
|
4
|
-
|
5
|
-
- [#1210](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1210) Handle blank SQL when parsing table name
|
6
|
-
|
7
|
-
## v7.1.6
|
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
|
1
|
+
## Unreleased
|
14
2
|
|
15
3
|
#### Added
|
16
4
|
|
17
|
-
- [#
|
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
|
5
|
+
- [#1178](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1178) Support encrypting binary columns
|
25
6
|
|
26
7
|
#### Changed
|
27
8
|
|
28
|
-
- [#
|
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
|
51
|
-
|
52
|
-
#### Added
|
53
|
-
|
54
|
-
- [#1141](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1141) Added support for check constraints.
|
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.
|
71
|
-
|
72
|
-
#### Changed
|
73
|
-
|
74
|
-
* Configure Connection
|
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
|
-
```
|
92
|
-
|
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
|
-
```
|
9
|
+
- [#1153](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1153) Only support Ruby v3.1+
|
10
|
+
- [#1196](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1196) Use default inspect for database adapter
|
105
11
|
|
106
|
-
Please check [7-
|
12
|
+
Please check [7-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/7-1-stable/CHANGELOG.md) for previous changes.
|
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` | Active | [7-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-0-stable) |
|
22
|
+
| `6.1.x` | `6.1.x` | Active | [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
|
+
7.2.0
|
@@ -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
|
@@ -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,21 @@ 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
|
+
with_identity_insert_enabled(id_insert_table_name, conn) do
|
46
|
+
internal_exec_sql_query(sql, conn)
|
47
|
+
end
|
48
|
+
else
|
49
|
+
internal_exec_sql_query(sql, conn)
|
50
|
+
end
|
51
|
+
|
54
52
|
verified!
|
53
|
+
notification_payload[:row_count] = result.count
|
54
|
+
result
|
55
55
|
end
|
56
56
|
end
|
57
|
-
|
58
|
-
result
|
59
57
|
end
|
60
58
|
|
61
59
|
def internal_exec_sql_query(sql, conn)
|
@@ -153,10 +151,10 @@ module ActiveRecord
|
|
153
151
|
|
154
152
|
if returning = insert.send(:insert_all).returning
|
155
153
|
returning_sql = if returning.is_a?(String)
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
154
|
+
returning
|
155
|
+
else
|
156
|
+
returning.map { |column| "INSERTED.#{quote_column_name(column)}" }.join(", ")
|
157
|
+
end
|
160
158
|
sql << " OUTPUT #{returning_sql}"
|
161
159
|
end
|
162
160
|
|
@@ -174,7 +172,7 @@ module ActiveRecord
|
|
174
172
|
end.join(", ")
|
175
173
|
sql = "EXEC #{proc_name} #{vars}".strip
|
176
174
|
|
177
|
-
log(sql, "Execute Procedure") do
|
175
|
+
log(sql, "Execute Procedure") do |notification_payload|
|
178
176
|
with_raw_connection do |conn|
|
179
177
|
result = internal_raw_execute(sql, conn)
|
180
178
|
verified!
|
@@ -185,10 +183,11 @@ module ActiveRecord
|
|
185
183
|
yield(r) if block_given?
|
186
184
|
end
|
187
185
|
|
188
|
-
result.each.map { |row| row.is_a?(Hash) ? row.with_indifferent_access : row }
|
186
|
+
result = result.each.map { |row| row.is_a?(Hash) ? row.with_indifferent_access : row }
|
187
|
+
notification_payload[:row_count] = result.count
|
188
|
+
result
|
189
189
|
end
|
190
190
|
end
|
191
|
-
|
192
191
|
end
|
193
192
|
|
194
193
|
def with_identity_insert_enabled(table_name, conn)
|
@@ -329,11 +328,17 @@ module ActiveRecord
|
|
329
328
|
end
|
330
329
|
|
331
330
|
def sp_executesql_sql_type(attr)
|
332
|
-
|
333
|
-
|
331
|
+
if attr.respond_to?(:type)
|
332
|
+
return attr.type.sqlserver_type if attr.type.respond_to?(:sqlserver_type)
|
334
333
|
|
335
|
-
|
336
|
-
|
334
|
+
if attr.type.is_a?(ActiveRecord::Encryption::EncryptedAttributeType) && attr.type.instance_variable_get(:@cast_type).respond_to?(:sqlserver_type)
|
335
|
+
return attr.type.instance_variable_get(:@cast_type).sqlserver_type
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
value = basic_attribute_type?(attr) ? attr : attr.value_for_database
|
340
|
+
|
341
|
+
if value.is_a?(Numeric)
|
337
342
|
value > 2_147_483_647 ? "bigint".freeze : "int".freeze
|
338
343
|
else
|
339
344
|
"nvarchar(max)".freeze
|
@@ -341,17 +346,26 @@ module ActiveRecord
|
|
341
346
|
end
|
342
347
|
|
343
348
|
def sp_executesql_sql_param(attr)
|
344
|
-
return quote(attr) if
|
349
|
+
return quote(attr) if basic_attribute_type?(attr)
|
345
350
|
|
346
351
|
case value = attr.value_for_database
|
347
|
-
when Type::Binary::Data,
|
348
|
-
ActiveRecord::Type::SQLServer::Data
|
352
|
+
when Type::Binary::Data, ActiveRecord::Type::SQLServer::Data
|
349
353
|
quote(value)
|
350
354
|
else
|
351
355
|
quote(type_cast(value))
|
352
356
|
end
|
353
357
|
end
|
354
358
|
|
359
|
+
def basic_attribute_type?(type)
|
360
|
+
type.is_a?(Symbol) ||
|
361
|
+
type.is_a?(String) ||
|
362
|
+
type.is_a?(Numeric) ||
|
363
|
+
type.is_a?(Time) ||
|
364
|
+
type.is_a?(TrueClass) ||
|
365
|
+
type.is_a?(FalseClass) ||
|
366
|
+
type.is_a?(NilClass)
|
367
|
+
end
|
368
|
+
|
355
369
|
def sp_executesql_sql(sql, types, params, name)
|
356
370
|
if name == "EXPLAIN"
|
357
371
|
params.each.with_index do |param, index|
|
@@ -424,7 +438,11 @@ module ActiveRecord
|
|
424
438
|
qo[:as] = (options[:ar_result] || options[:fetch] == :rows) ? :array : :hash
|
425
439
|
end
|
426
440
|
results = handle.each(query_options)
|
427
|
-
|
441
|
+
|
442
|
+
columns = handle.fields
|
443
|
+
# If query returns multiple result sets, only return the columns of the last one.
|
444
|
+
columns = columns.last if columns.any? && columns.all? { |e| e.is_a?(Array) }
|
445
|
+
columns = columns.map(&:downcase) if lowercase_schema_reflection
|
428
446
|
|
429
447
|
options[:ar_result] ? ActiveRecord::Result.new(columns, results) : results
|
430
448
|
end
|