activerecord-sqlserver-adapter 7.0.3.0 → 7.0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/MIT-LICENSE +1 -1
- data/README.md +3 -2
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +1 -1
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +26 -7
- data/test/cases/coerced_tests.rb +40 -4
- data/test/cases/migration_test_sqlserver.rb +18 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41b4642838dbc7178a170c4b002937e5481bf0c7154446d43cff2dae7800a938
|
4
|
+
data.tar.gz: fa20040c55e79a8417ec58c414b5ad6617acaa2fe808c5b48fc44c6e3187c5d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7786aeaaf3f90af8a69208e76901c1263e20ef1c4f410948319108531e128ff2d5247838efb10cbcda0fe6b035d1b130576647824e027a668b0fc3df1988305
|
7
|
+
data.tar.gz: 3d9db5b28f4b8b8468b71049b14b7000e25c7aa7afcac55f6fec0ec234f0e4cdf76c4158069328da464ad0a718f45ee9b45b2b6f19f00fc058b7d4ab87071308
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## v7.0.4.0
|
2
|
+
|
3
|
+
#### Changed
|
4
|
+
|
5
|
+
- [#1073](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1073) Improve performance of view default function lookup
|
6
|
+
|
7
|
+
#### Fixed
|
8
|
+
|
9
|
+
- [#1088](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1088) Fix creation of stored procedures that contain insert statements
|
10
|
+
- [#1089](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1089) When changing columns set date-time columns to datetime(6) by default
|
11
|
+
|
1
12
|
## v7.0.3.0
|
2
13
|
|
3
14
|
#### Fixed
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -13,7 +13,7 @@ Interested in older versions? We follow a rational versioning policy that tracks
|
|
13
13
|
|
14
14
|
| Adapter Version | Rails Version | Support |
|
15
15
|
|-----------------| ------------- | ------------------------------------------------------------------------------------------- |
|
16
|
-
| `7.0.
|
16
|
+
| `7.0.4.0` | `7.0.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
|
17
17
|
| `6.1.2.1` | `6.1.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-1-stable) |
|
18
18
|
| `6.0.3` | `6.0.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-0-stable) |
|
19
19
|
| `5.2.1` | `5.2.x` | [ended](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-2-stable) |
|
@@ -190,6 +190,7 @@ Many many people have contributed. If you do not see your name here and it shoul
|
|
190
190
|
|
191
191
|
You can see an up-to-date list of contributors here: http://github.com/rails-sqlserver/activerecord-sqlserver-adapter/contributors
|
192
192
|
|
193
|
+
|
193
194
|
## License
|
194
195
|
|
195
|
-
|
196
|
+
ActiveRecord SQL Server Adapter is released under the [MIT License](https://opensource.org/licenses/MIT).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
7.0.
|
1
|
+
7.0.4.0
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.required_ruby_version = ">= 2.7.0"
|
11
11
|
|
12
12
|
spec.license = "MIT"
|
13
|
-
spec.authors = ["Ken Collins", "Anna Carey", "Will Bond", "Murray Steele", "Shawn Balestracci", "Joe Rafaniello", "Tom Ward"]
|
13
|
+
spec.authors = ["Ken Collins", "Anna Carey", "Will Bond", "Murray Steele", "Shawn Balestracci", "Joe Rafaniello", "Tom Ward", "Aidan Haran"]
|
14
14
|
spec.email = ["ken@metaskills.net", "will@wbond.net"]
|
15
15
|
spec.homepage = "http://github.com/rails-sqlserver/activerecord-sqlserver-adapter"
|
16
16
|
spec.summary = "ActiveRecord SQL Server Adapter."
|
@@ -143,6 +143,15 @@ module ActiveRecord
|
|
143
143
|
def change_column(table_name, column_name, type, options = {})
|
144
144
|
sql_commands = []
|
145
145
|
indexes = []
|
146
|
+
|
147
|
+
if type == :datetime
|
148
|
+
# If no precision then default it to 6.
|
149
|
+
options[:precision] = 6 unless options.key?(:precision)
|
150
|
+
|
151
|
+
# If there is precision then column must be of type 'datetime2'.
|
152
|
+
type = :datetime2 unless options[:precision].nil?
|
153
|
+
end
|
154
|
+
|
146
155
|
column_object = schema_cache.columns(table_name).find { |c| c.name.to_s == column_name.to_s }
|
147
156
|
without_constraints = options.key?(:default) || options.key?(:limit)
|
148
157
|
default = if !options.key?(:default) && column_object
|
@@ -150,24 +159,29 @@ module ActiveRecord
|
|
150
159
|
else
|
151
160
|
options[:default]
|
152
161
|
end
|
162
|
+
|
153
163
|
if without_constraints || (column_object && column_object.type != type.to_sym)
|
154
164
|
remove_default_constraint(table_name, column_name)
|
155
165
|
indexes = indexes(table_name).select { |index| index.columns.include?(column_name.to_s) }
|
156
166
|
remove_indexes(table_name, column_name)
|
157
167
|
end
|
168
|
+
|
158
169
|
sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_expression(options[:default], column_object)} WHERE #{quote_column_name(column_name)} IS NULL" if !options[:null].nil? && options[:null] == false && !options[:default].nil?
|
159
170
|
alter_command = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}"
|
160
171
|
alter_command += " COLLATE #{options[:collation]}" if options[:collation].present?
|
161
172
|
alter_command += " NOT NULL" if !options[:null].nil? && options[:null] == false
|
162
173
|
sql_commands << alter_command
|
174
|
+
|
163
175
|
if without_constraints
|
164
176
|
default = quote_default_expression(default, column_object || column_for(table_name, column_name))
|
165
177
|
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{default} FOR #{quote_column_name(column_name)}"
|
166
178
|
end
|
179
|
+
|
167
180
|
# Add any removed indexes back
|
168
181
|
indexes.each do |index|
|
169
182
|
sql_commands << "CREATE INDEX #{quote_table_name(index.name)} ON #{quote_table_name(table_name)} (#{index.columns.map { |c| quote_column_name(c) }.join(', ')})"
|
170
183
|
end
|
184
|
+
|
171
185
|
sql_commands.each { |c| do_execute(c) }
|
172
186
|
clear_cache!
|
173
187
|
end
|
@@ -229,6 +243,7 @@ module ActiveRecord
|
|
229
243
|
def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
|
230
244
|
type_limitable = %w(string integer float char nchar varchar nvarchar).include?(type.to_s)
|
231
245
|
limit = nil unless type_limitable
|
246
|
+
|
232
247
|
case type.to_s
|
233
248
|
when "integer"
|
234
249
|
case limit
|
@@ -371,6 +386,15 @@ module ActiveRecord
|
|
371
386
|
view_exists = view_exists?(table_name)
|
372
387
|
view_tblnm = view_table_name(table_name) if view_exists
|
373
388
|
|
389
|
+
if view_exists
|
390
|
+
results = sp_executesql %{
|
391
|
+
SELECT c.COLUMN_NAME AS [name], c.COLUMN_DEFAULT AS [default]
|
392
|
+
FROM #{database}.INFORMATION_SCHEMA.COLUMNS c
|
393
|
+
WHERE c.TABLE_NAME = #{quote(view_tblnm)}
|
394
|
+
}.squish, "SCHEMA", []
|
395
|
+
default_functions = results.each.with_object({}) {|row, out| out[row["name"]] = row["default"] }.compact
|
396
|
+
end
|
397
|
+
|
374
398
|
sql = column_definitions_sql(database, identifier)
|
375
399
|
|
376
400
|
binds = []
|
@@ -402,13 +426,8 @@ module ActiveRecord
|
|
402
426
|
ci[:default_function] = begin
|
403
427
|
default = ci[:default_value]
|
404
428
|
if default.nil? && view_exists
|
405
|
-
|
406
|
-
|
407
|
-
FROM #{database}.INFORMATION_SCHEMA.COLUMNS c
|
408
|
-
WHERE
|
409
|
-
c.TABLE_NAME = '#{view_tblnm}'
|
410
|
-
AND c.COLUMN_NAME = '#{views_real_column_name(table_name, ci[:name])}'
|
411
|
-
}.squish, "SCHEMA"
|
429
|
+
view_column = views_real_column_name(table_name, ci[:name])
|
430
|
+
default = default_functions[view_column] if view_column.present?
|
412
431
|
end
|
413
432
|
case default
|
414
433
|
when nil
|
data/test/cases/coerced_tests.rb
CHANGED
@@ -1310,9 +1310,26 @@ class RelationTest < ActiveRecord::TestCase
|
|
1310
1310
|
# We are not doing order duplicate removal anymore.
|
1311
1311
|
coerce_tests! :test_default_scope_order_with_scope_order
|
1312
1312
|
|
1313
|
-
#
|
1313
|
+
# Order column must be in the GROUP clause.
|
1314
1314
|
coerce_tests! :test_multiple_where_and_having_clauses
|
1315
|
+
def test_multiple_where_and_having_clauses_coerced
|
1316
|
+
post = Post.first
|
1317
|
+
having_then_where = Post.having(id: post.id).where(title: post.title)
|
1318
|
+
.having(id: post.id).where(title: post.title).group(:id).select(:id)
|
1319
|
+
|
1320
|
+
assert_equal [post], having_then_where
|
1321
|
+
end
|
1322
|
+
|
1323
|
+
# Order column must be in the GROUP clause.
|
1315
1324
|
coerce_tests! :test_having_with_binds_for_both_where_and_having
|
1325
|
+
def test_having_with_binds_for_both_where_and_having
|
1326
|
+
post = Post.first
|
1327
|
+
having_then_where = Post.having(id: post.id).where(title: post.title).group(:id).select(:id)
|
1328
|
+
where_then_having = Post.where(title: post.title).having(id: post.id).group(:id).select(:id)
|
1329
|
+
|
1330
|
+
assert_equal [post], having_then_where
|
1331
|
+
assert_equal [post], where_then_having
|
1332
|
+
end
|
1316
1333
|
|
1317
1334
|
# Find any limit via our expression.
|
1318
1335
|
coerce_tests! %r{relations don't load all records in #inspect}
|
@@ -1322,10 +1339,18 @@ class RelationTest < ActiveRecord::TestCase
|
|
1322
1339
|
end
|
1323
1340
|
end
|
1324
1341
|
|
1325
|
-
#
|
1326
|
-
# However, this pull request on Rails core drops order on exists relation. https://github.com/rails/rails/pull/28699
|
1327
|
-
# so we are skipping all together.
|
1342
|
+
# Order column must be in the GROUP clause.
|
1328
1343
|
coerce_tests! :test_empty_complex_chained_relations
|
1344
|
+
def test_empty_complex_chained_relations_coerced
|
1345
|
+
posts = Post.select("comments_count").where("id is not null").group("author_id", "id").where("legacy_comments_count > 0")
|
1346
|
+
|
1347
|
+
assert_queries(1) { assert_equal false, posts.empty? }
|
1348
|
+
assert_not_predicate posts, :loaded?
|
1349
|
+
|
1350
|
+
no_posts = posts.where(title: "")
|
1351
|
+
assert_queries(1) { assert_equal true, no_posts.empty? }
|
1352
|
+
assert_not_predicate no_posts, :loaded?
|
1353
|
+
end
|
1329
1354
|
|
1330
1355
|
# Can't apply offset without ORDER
|
1331
1356
|
coerce_tests! %r{using a custom table affects the wheres}
|
@@ -2120,6 +2145,17 @@ class FieldOrderedValuesTest < ActiveRecord::TestCase
|
|
2120
2145
|
Book.where(author_id: nil, name: nil).delete_all
|
2121
2146
|
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
2122
2147
|
end
|
2148
|
+
|
2149
|
+
# Need to remove index as SQL Server considers NULLs on a unique-index to be equal unlike PostgreSQL/MySQL/SQLite.
|
2150
|
+
coerce_tests! :test_in_order_of_with_nil
|
2151
|
+
def test_in_order_of_with_nil_coerced
|
2152
|
+
Book.connection.remove_index(:books, column: [:author_id, :name])
|
2153
|
+
|
2154
|
+
original_test_in_order_of_with_nil
|
2155
|
+
ensure
|
2156
|
+
Book.where(author_id: nil, name: nil).delete_all
|
2157
|
+
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
2158
|
+
end
|
2123
2159
|
end
|
2124
2160
|
|
2125
2161
|
require "models/dashboard"
|
@@ -115,4 +115,22 @@ class MigrationTestSQLServer < ActiveRecord::TestCase
|
|
115
115
|
refute_includes schemas, { "name" => "some schema" }
|
116
116
|
end
|
117
117
|
end
|
118
|
+
|
119
|
+
describe 'creating stored procedure' do
|
120
|
+
it 'stored procedure contains inserts are created successfully' do
|
121
|
+
sql = <<-SQL
|
122
|
+
CREATE OR ALTER PROCEDURE do_some_task
|
123
|
+
AS
|
124
|
+
IF NOT EXISTS(SELECT * FROM sys.objects WHERE type = 'U' AND name = 'SomeTableName')
|
125
|
+
BEGIN
|
126
|
+
CREATE TABLE SomeTableName (SomeNum int PRIMARY KEY CLUSTERED);
|
127
|
+
INSERT INTO SomeTableName(SomeNum) VALUES(1);
|
128
|
+
END
|
129
|
+
SQL
|
130
|
+
|
131
|
+
assert_nothing_raised { connection.execute(sql) }
|
132
|
+
ensure
|
133
|
+
connection.execute("DROP PROCEDURE IF EXISTS dbo.do_some_task;")
|
134
|
+
end
|
135
|
+
end
|
118
136
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-sqlserver-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.0.
|
4
|
+
version: 7.0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken Collins
|
@@ -11,10 +11,11 @@ authors:
|
|
11
11
|
- Shawn Balestracci
|
12
12
|
- Joe Rafaniello
|
13
13
|
- Tom Ward
|
14
|
+
- Aidan Haran
|
14
15
|
autorequire:
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
|
-
date: 2023-
|
18
|
+
date: 2023-09-19 00:00:00.000000000 Z
|
18
19
|
dependencies:
|
19
20
|
- !ruby/object:Gem::Dependency
|
20
21
|
name: activerecord
|
@@ -229,8 +230,8 @@ licenses:
|
|
229
230
|
- MIT
|
230
231
|
metadata:
|
231
232
|
bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
|
232
|
-
changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.0.
|
233
|
-
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.0.
|
233
|
+
changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.0.4.0/CHANGELOG.md
|
234
|
+
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.0.4.0
|
234
235
|
post_install_message:
|
235
236
|
rdoc_options: []
|
236
237
|
require_paths:
|
@@ -246,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
246
247
|
- !ruby/object:Gem::Version
|
247
248
|
version: '0'
|
248
249
|
requirements: []
|
249
|
-
rubygems_version: 3.4.
|
250
|
+
rubygems_version: 3.4.10
|
250
251
|
signing_key:
|
251
252
|
specification_version: 4
|
252
253
|
summary: ActiveRecord SQL Server Adapter.
|