activerecord-sqlserver-adapter 8.0.7 → 8.0.8
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/.github/workflows/ci.yml +1 -0
- data/CHANGELOG.md +10 -0
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +7 -8
- data/test/cases/adapter_test_sqlserver.rb +26 -5
- data/test/cases/change_column_index_test_sqlserver.rb +108 -0
- data/test/cases/temp_test_sqlserver.rb +9 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10e87da3715b8059e900f1ecf18af7cd8b0a03ce48b2bd7e79399c4dacba6cfb
|
4
|
+
data.tar.gz: fb175a99c32dcfc1ad7fac35ab53086b97bf75a5e6f6d113ba031a20d4b38ede
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8319785b8064c84b42848ada06ddcd67e3318b6566f44c6339ad5037a18c5e409ed88d23d11f995220c1ccc34d8aff7af8b95b2c50235e36e279577de801323
|
7
|
+
data.tar.gz: c33591032fc453c2dad5b2acfd0aa83f5e13816291b0c5a867df1eb192c41b9f73e143c1347702b24e99e792c8c060f225958e78e9c6b032ba239277323da93a
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## v8.0.8
|
2
|
+
|
3
|
+
#### Changed
|
4
|
+
|
5
|
+
- [#1342](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1342) Support more Azure services by changing language source.
|
6
|
+
|
7
|
+
#### Fixed
|
8
|
+
- [#1345](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1345) Maintain index options during `change_column` operations.
|
9
|
+
- [#1357](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1357) Support cross database inserts.
|
10
|
+
|
1
11
|
## v8.0.7
|
2
12
|
|
3
13
|
#### Fixed
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
8.0.
|
1
|
+
8.0.8
|
@@ -259,7 +259,7 @@ module ActiveRecord
|
|
259
259
|
|
260
260
|
def user_options_dateformat
|
261
261
|
if sqlserver_azure?
|
262
|
-
select_value "SELECT [dateformat] FROM [sys].[syslanguages] WHERE [
|
262
|
+
select_value "SELECT [dateformat] FROM [sys].[syslanguages] WHERE [name] = @@LANGUAGE", "SCHEMA"
|
263
263
|
else
|
264
264
|
user_options["dateformat"]
|
265
265
|
end
|
@@ -182,12 +182,14 @@ module ActiveRecord
|
|
182
182
|
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)}"
|
183
183
|
end
|
184
184
|
|
185
|
+
sql_commands.each { |c| execute(c) }
|
186
|
+
|
185
187
|
# Add any removed indexes back
|
186
188
|
indexes.each do |index|
|
187
|
-
|
189
|
+
create_index_def = CreateIndexDefinition.new(index)
|
190
|
+
execute schema_creation.accept(create_index_def)
|
188
191
|
end
|
189
192
|
|
190
|
-
sql_commands.each { |c| execute(c) }
|
191
193
|
clear_cache!
|
192
194
|
end
|
193
195
|
|
@@ -592,6 +594,7 @@ module ActiveRecord
|
|
592
594
|
end
|
593
595
|
|
594
596
|
def column_definitions_sql(database, identifier)
|
597
|
+
database = "TEMPDB" if identifier.temporary_table?
|
595
598
|
schema_name = "schema_name()"
|
596
599
|
|
597
600
|
if prepared_statements
|
@@ -602,12 +605,8 @@ module ActiveRecord
|
|
602
605
|
schema_name = quote(identifier.schema) if identifier.schema.present?
|
603
606
|
end
|
604
607
|
|
605
|
-
object_id_arg = identifier.schema.present? ? "CONCAT(
|
606
|
-
|
607
|
-
if identifier.temporary_table?
|
608
|
-
database = "TEMPDB"
|
609
|
-
object_id_arg = "CONCAT('#{database}','..',#{object_name})"
|
610
|
-
end
|
608
|
+
object_id_arg = identifier.schema.present? ? "CONCAT('.',#{schema_name},'.',#{object_name})" : "CONCAT('..',#{object_name})"
|
609
|
+
object_id_arg = "CONCAT('#{database}',#{object_id_arg})"
|
611
610
|
|
612
611
|
%{
|
613
612
|
SELECT
|
@@ -7,11 +7,18 @@ require "models/post"
|
|
7
7
|
require "models/subscriber"
|
8
8
|
require "models/minimalistic"
|
9
9
|
require "models/college"
|
10
|
+
require "models/dog"
|
11
|
+
require "models/other_dog"
|
10
12
|
require "models/discount"
|
11
13
|
|
12
14
|
class AdapterTestSQLServer < ActiveRecord::TestCase
|
13
15
|
fixtures :tasks
|
14
16
|
|
17
|
+
let(:arunit_connection) { Topic.lease_connection }
|
18
|
+
let(:arunit2_connection) { College.lease_connection }
|
19
|
+
let(:arunit_database) { arunit_connection.pool.db_config.database }
|
20
|
+
let(:arunit2_database) { arunit2_connection.pool.db_config.database }
|
21
|
+
|
15
22
|
let(:basic_insert_sql) { "INSERT INTO [funny_jokes] ([name]) VALUES('Knock knock')" }
|
16
23
|
let(:basic_merge_sql) { "MERGE INTO [ships] WITH (UPDLOCK, HOLDLOCK) AS target USING ( SELECT * FROM ( SELECT [id], [name], ROW_NUMBER() OVER ( PARTITION BY [id] ORDER BY [id] DESC ) AS rn_0 FROM ( VALUES (101, N'RSS Sir David Attenborough') ) AS t1 ([id], [name]) ) AS ranked_source WHERE rn_0 = 1 ) AS source ON (target.[id] = source.[id]) WHEN MATCHED THEN UPDATE SET target.[name] = source.[name]" }
|
17
24
|
let(:basic_update_sql) { "UPDATE [customers] SET [address_street] = NULL WHERE [id] = 2" }
|
@@ -52,8 +59,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
|
|
52
59
|
assert Topic.table_exists?, "Topics table name of 'dbo.topics' should return true for exists."
|
53
60
|
|
54
61
|
# Test when database and owner included in table name.
|
55
|
-
|
56
|
-
Topic.table_name = "#{db_config.database}.dbo.topics"
|
62
|
+
Topic.table_name = "#{arunit_database}.dbo.topics"
|
57
63
|
assert Topic.table_exists?, "Topics table name of '[DATABASE].dbo.topics' should return true for exists."
|
58
64
|
ensure
|
59
65
|
Topic.table_name = "topics"
|
@@ -225,6 +231,9 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
|
|
225
231
|
@identity_insert_sql_non_dbo_sp = "EXEC sp_executesql N'INSERT INTO [test].[aliens] ([id],[name]) VALUES (@0, @1)', N'@0 int, @1 nvarchar(255)', @0 = 420, @1 = N'Mork'"
|
226
232
|
@identity_insert_sql_non_dbo_unquoted_sp = "EXEC sp_executesql N'INSERT INTO test.aliens (id, name) VALUES (@0, @1)', N'@0 int, @1 nvarchar(255)', @0 = 420, @1 = N'Mork'"
|
227
233
|
@identity_insert_sql_non_dbo_unordered_sp = "EXEC sp_executesql N'INSERT INTO [test].[aliens] ([name],[id]) VALUES (@0, @1)', N'@0 nvarchar(255), @1 int', @0 = N'Mork', @1 = 420"
|
234
|
+
|
235
|
+
@non_identity_insert_sql_cross_database = "INSERT INTO #{arunit2_database}.dbo.dogs SELECT * FROM #{arunit_database}.dbo.dogs"
|
236
|
+
@identity_insert_sql_cross_database = "INSERT INTO #{arunit2_database}.dbo.dogs(id) SELECT id FROM #{arunit_database}.dbo.dogs"
|
228
237
|
end
|
229
238
|
|
230
239
|
it "return quoted table_name to #query_requires_identity_insert? when INSERT sql contains id column" do
|
@@ -245,20 +254,32 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
|
|
245
254
|
assert_equal "[test].[aliens]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_non_dbo_sp)
|
246
255
|
assert_equal "[test].[aliens]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_non_dbo_unquoted_sp)
|
247
256
|
assert_equal "[test].[aliens]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_non_dbo_unordered_sp)
|
257
|
+
|
258
|
+
assert_equal "[#{arunit2_database}].[dbo].[dogs]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_cross_database)
|
248
259
|
end
|
249
260
|
|
250
261
|
it "return false to #query_requires_identity_insert? for normal SQL" do
|
251
|
-
[basic_insert_sql, basic_merge_sql, basic_update_sql, basic_select_sql].each do |sql|
|
262
|
+
[basic_insert_sql, basic_merge_sql, basic_update_sql, basic_select_sql, @non_identity_insert_sql_cross_database].each do |sql|
|
252
263
|
assert !connection.send(:query_requires_identity_insert?, sql), "SQL was #{sql}"
|
253
264
|
end
|
254
265
|
end
|
255
266
|
|
256
|
-
it "find identity column
|
267
|
+
it "find identity column" do
|
257
268
|
task_id_column = Task.columns_hash["id"]
|
258
269
|
assert_equal task_id_column.name, connection.send(:identity_columns, Task.table_name).first.name
|
259
270
|
assert_equal task_id_column.sql_type, connection.send(:identity_columns, Task.table_name).first.sql_type
|
260
271
|
end
|
261
272
|
|
273
|
+
it "find identity column cross database" do
|
274
|
+
id_column = Dog.columns_hash["id"]
|
275
|
+
assert_equal id_column.name, arunit2_connection.send(:identity_columns, Dog.table_name).first.name
|
276
|
+
assert_equal id_column.sql_type, arunit2_connection.send(:identity_columns, Dog.table_name).first.sql_type
|
277
|
+
|
278
|
+
id_column = OtherDog.columns_hash["id"]
|
279
|
+
assert_equal id_column.name, arunit_connection.send(:identity_columns, OtherDog.table_name).first.name
|
280
|
+
assert_equal id_column.sql_type, arunit_connection.send(:identity_columns, OtherDog.table_name).first.sql_type
|
281
|
+
end
|
282
|
+
|
262
283
|
it "return an empty array when calling #identity_columns for a table_name with no identity" do
|
263
284
|
_(connection.send(:identity_columns, Subscriber.table_name)).must_equal []
|
264
285
|
end
|
@@ -616,7 +637,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
|
|
616
637
|
end
|
617
638
|
|
618
639
|
it 'raises an error when the foreign key is mismatched' do
|
619
|
-
|
640
|
+
error = assert_raises(ActiveRecord::MismatchedForeignKey) do
|
620
641
|
@conn.add_reference :engines, :old_car
|
621
642
|
@conn.add_foreign_key :engines, :old_cars
|
622
643
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cases/helper_sqlserver"
|
4
|
+
|
5
|
+
class ChangeColumnIndexTestSqlServer < ActiveRecord::TestCase
|
6
|
+
class CreateClientsWithUniqueIndex < ActiveRecord::Migration[8.0]
|
7
|
+
def up
|
8
|
+
create_table :clients do |t|
|
9
|
+
t.string :name, limit: 15
|
10
|
+
end
|
11
|
+
add_index :clients, :name, unique: true
|
12
|
+
end
|
13
|
+
|
14
|
+
def down
|
15
|
+
drop_table :clients
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class CreateBlogPostsWithMultipleIndexesOnTheSameColumn < ActiveRecord::Migration[8.0]
|
20
|
+
def up
|
21
|
+
create_table :blog_posts do |t|
|
22
|
+
t.string :title, limit: 15
|
23
|
+
t.string :subtitle
|
24
|
+
end
|
25
|
+
add_index :blog_posts, :title, unique: true, where: "([blog_posts].[title] IS NOT NULL)", name: "custom_index_name"
|
26
|
+
add_index :blog_posts, [:title, :subtitle], unique: true
|
27
|
+
end
|
28
|
+
|
29
|
+
def down
|
30
|
+
drop_table :blog_posts
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class ChangeClientsNameLength < ActiveRecord::Migration[8.0]
|
35
|
+
def up
|
36
|
+
change_column :clients, :name, :string, limit: 30
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ChangeBlogPostsTitleLength < ActiveRecord::Migration[8.0]
|
41
|
+
def up
|
42
|
+
change_column :blog_posts, :title, :string, limit: 30
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
before do
|
47
|
+
@old_verbose = ActiveRecord::Migration.verbose
|
48
|
+
ActiveRecord::Migration.verbose = false
|
49
|
+
|
50
|
+
CreateClientsWithUniqueIndex.new.up
|
51
|
+
CreateBlogPostsWithMultipleIndexesOnTheSameColumn.new.up
|
52
|
+
end
|
53
|
+
|
54
|
+
after do
|
55
|
+
CreateClientsWithUniqueIndex.new.down
|
56
|
+
CreateBlogPostsWithMultipleIndexesOnTheSameColumn.new.down
|
57
|
+
|
58
|
+
ActiveRecord::Migration.verbose = @old_verbose
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_index_uniqueness_is_maintained_after_column_change
|
62
|
+
indexes = ActiveRecord::Base.connection.indexes("clients")
|
63
|
+
columns = ActiveRecord::Base.connection.columns("clients")
|
64
|
+
assert_equal columns.find { |column| column.name == "name" }.limit, 15
|
65
|
+
assert_equal indexes.size, 1
|
66
|
+
assert_equal indexes.first.name, "index_clients_on_name"
|
67
|
+
assert indexes.first.unique
|
68
|
+
|
69
|
+
ChangeClientsNameLength.new.up
|
70
|
+
|
71
|
+
indexes = ActiveRecord::Base.connection.indexes("clients")
|
72
|
+
columns = ActiveRecord::Base.connection.columns("clients")
|
73
|
+
assert_equal columns.find { |column| column.name == "name" }.limit, 30
|
74
|
+
assert_equal indexes.size, 1
|
75
|
+
assert_equal indexes.first.name, "index_clients_on_name"
|
76
|
+
assert indexes.first.unique
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_multiple_index_options_are_maintained_after_column_change
|
80
|
+
indexes = ActiveRecord::Base.connection.indexes("blog_posts")
|
81
|
+
columns = ActiveRecord::Base.connection.columns("blog_posts")
|
82
|
+
assert_equal columns.find { |column| column.name == "title" }.limit, 15
|
83
|
+
assert_equal indexes.size, 2
|
84
|
+
|
85
|
+
index_1 = indexes.find { |index| index.columns == ["title"] }
|
86
|
+
assert_equal index_1.name, "custom_index_name"
|
87
|
+
assert_equal index_1.where, "([blog_posts].[title] IS NOT NULL)"
|
88
|
+
assert index_1.unique
|
89
|
+
|
90
|
+
index_2 = indexes.find { |index| index.columns == ["title", "subtitle"] }
|
91
|
+
assert index_2.unique
|
92
|
+
|
93
|
+
ChangeBlogPostsTitleLength.new.up
|
94
|
+
|
95
|
+
indexes = ActiveRecord::Base.connection.indexes("blog_posts")
|
96
|
+
columns = ActiveRecord::Base.connection.columns("blog_posts")
|
97
|
+
assert_equal columns.find { |column| column.name == "title" }.limit, 30
|
98
|
+
assert_equal indexes.size, 2
|
99
|
+
|
100
|
+
index_1 = indexes.find { |index| index.columns == ["title"] }
|
101
|
+
assert_equal index_1.name, "custom_index_name"
|
102
|
+
assert_equal index_1.where, "([blog_posts].[title] IS NOT NULL)"
|
103
|
+
assert index_1.unique
|
104
|
+
|
105
|
+
index_2 = indexes.find { |index| index.columns == ["title", "subtitle"] }
|
106
|
+
assert index_2.unique
|
107
|
+
end
|
108
|
+
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: 8.0.
|
4
|
+
version: 8.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken Collins
|
@@ -149,6 +149,7 @@ files:
|
|
149
149
|
- test/cases/active_schema_test_sqlserver.rb
|
150
150
|
- test/cases/adapter_test_sqlserver.rb
|
151
151
|
- test/cases/change_column_collation_test_sqlserver.rb
|
152
|
+
- test/cases/change_column_index_test_sqlserver.rb
|
152
153
|
- test/cases/change_column_null_test_sqlserver.rb
|
153
154
|
- test/cases/coerced_tests.rb
|
154
155
|
- test/cases/column_test_sqlserver.rb
|
@@ -176,6 +177,7 @@ files:
|
|
176
177
|
- test/cases/schema_test_sqlserver.rb
|
177
178
|
- test/cases/showplan_test_sqlserver.rb
|
178
179
|
- test/cases/specific_schema_test_sqlserver.rb
|
180
|
+
- test/cases/temp_test_sqlserver.rb
|
179
181
|
- test/cases/temporary_table_test_sqlserver.rb
|
180
182
|
- test/cases/transaction_test_sqlserver.rb
|
181
183
|
- test/cases/trigger_test_sqlserver.rb
|
@@ -241,8 +243,8 @@ licenses:
|
|
241
243
|
- MIT
|
242
244
|
metadata:
|
243
245
|
bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
|
244
|
-
changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v8.0.
|
245
|
-
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v8.0.
|
246
|
+
changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v8.0.8/CHANGELOG.md
|
247
|
+
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v8.0.8
|
246
248
|
rdoc_options: []
|
247
249
|
require_paths:
|
248
250
|
- lib
|
@@ -269,6 +271,7 @@ test_files:
|
|
269
271
|
- test/cases/active_schema_test_sqlserver.rb
|
270
272
|
- test/cases/adapter_test_sqlserver.rb
|
271
273
|
- test/cases/change_column_collation_test_sqlserver.rb
|
274
|
+
- test/cases/change_column_index_test_sqlserver.rb
|
272
275
|
- test/cases/change_column_null_test_sqlserver.rb
|
273
276
|
- test/cases/coerced_tests.rb
|
274
277
|
- test/cases/column_test_sqlserver.rb
|
@@ -296,6 +299,7 @@ test_files:
|
|
296
299
|
- test/cases/schema_test_sqlserver.rb
|
297
300
|
- test/cases/showplan_test_sqlserver.rb
|
298
301
|
- test/cases/specific_schema_test_sqlserver.rb
|
302
|
+
- test/cases/temp_test_sqlserver.rb
|
299
303
|
- test/cases/temporary_table_test_sqlserver.rb
|
300
304
|
- test/cases/transaction_test_sqlserver.rb
|
301
305
|
- test/cases/trigger_test_sqlserver.rb
|