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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a8fb3b90e33355b2f91c6b6cd6e7494f822a0f348881f385bbaee8fbe3b2eee
4
- data.tar.gz: a1a24523b114d48249c543c445d15c77b50239c39aa022468f9f06efe378efeb
3
+ metadata.gz: 41b4642838dbc7178a170c4b002937e5481bf0c7154446d43cff2dae7800a938
4
+ data.tar.gz: fa20040c55e79a8417ec58c414b5ad6617acaa2fe808c5b48fc44c6e3187c5d7
5
5
  SHA512:
6
- metadata.gz: 813a2f3bf0752a8c9f310997d01e1ffb7a4216381bcd58cb082c811370f36f81e2c8c17a84b2aafc23493afcda7e86af499cc609721e59f0e0bd4b2931709b90
7
- data.tar.gz: d99ed863a56ab7d9036e433521b64fb04d0e8f2764c01d1109d6767a9f62beb46adbacbb36709d6702dc27f31afd0cdbf0adec148cdd5952a1a343f6392bf90d
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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008-2022
1
+ Copyright (c) Ken Collins
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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.3.0` | `7.0.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
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
- Copyright © 2008-2022. It is free software, and may be redistributed under the terms specified in the [MIT-LICENSE](MIT-LICENSE) file.
196
+ ActiveRecord SQL Server Adapter is released under the [MIT License](https://opensource.org/licenses/MIT).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.0.3.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."
@@ -406,7 +406,7 @@ module ActiveRecord
406
406
  end
407
407
 
408
408
  def insert_sql?(sql)
409
- !(sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)/i).nil?
409
+ !(sql =~ /\A\s*(INSERT|EXEC sp_executesql N'INSERT)/i).nil?
410
410
  end
411
411
 
412
412
  def identity_columns(table_name)
@@ -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
- default = select_value %{
406
- SELECT c.COLUMN_DEFAULT
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
@@ -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
- # Leave it up to users to format selects/functions so HAVING works correctly.
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
- # I wanted to add `.order("author_id")` scope to avoid error: Column "posts.id" is invalid in the ORDER BY
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.3.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-06-12 00:00:00.000000000 Z
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.3.0/CHANGELOG.md
233
- source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.0.3.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.6
250
+ rubygems_version: 3.4.10
250
251
  signing_key:
251
252
  specification_version: 4
252
253
  summary: ActiveRecord SQL Server Adapter.