activerecord-sqlserver-adapter 6.1.0.0 → 6.1.1.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 +14 -0
- data/README.md +1 -1
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +2 -1
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +14 -5
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +2 -1
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +0 -1
- data/lib/active_record/connection_adapters/sqlserver_column.rb +74 -35
- data/lib/arel/visitors/sqlserver.rb +15 -2
- data/test/cases/adapter_test_sqlserver.rb +2 -2
- data/test/cases/coerced_tests.rb +13 -0
- data/test/cases/column_test_sqlserver.rb +4 -0
- data/test/cases/fetch_test_sqlserver.rb +18 -0
- data/test/cases/rake_test_sqlserver.rb +35 -0
- data/test/models/sqlserver/composite_pk.rb +9 -0
- data/test/schema/sqlserver_specific_schema.rb +18 -0
- metadata +7 -6
- data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f481c462cbdd16314d87172f78c7a63f63f4c4f7f81df1ca84f110adcb3b6da8
|
4
|
+
data.tar.gz: cc79ad659b39244a0df7c37774922f22a537adf736adc9ba6344cdac6643c686
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0b3f273dfa36cc20e15d52384d8ba8d145f23c5816e7592b5c96324314a5204ea7d76879f6e27bd028cccf1be0411e0f7cbc60009f22b34831ff9383776b252
|
7
|
+
data.tar.gz: 6f34b2de7d27af451a8376501a46c65780ab960710632dceb939a4dbb39ac3a7754f48cf84da58e4f15064570d07792f8b779dde036720df74d483c462a7a5ed
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,23 @@
|
|
1
|
+
## v6.1.1.0
|
2
|
+
|
3
|
+
[Full changelog](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/compare/v6.1.0.0...v6.1.1.0)
|
4
|
+
|
5
|
+
#### Fixed
|
6
|
+
|
7
|
+
- [#933](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/933) Conditionally apply SQL Server monkey patches to ActiveRecord so that it is safe to use this gem alongside other database adapters (e.g. PostgreSQL) in a multi-database Rails app
|
8
|
+
- [#935](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/935) Fix schema cache generation
|
9
|
+
(**breaking change**)
|
10
|
+
- [#936](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/936) Fix deteministic fetch when table has a composite primary key
|
11
|
+
- [#938](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/938) Fix date columns serialization for range values
|
12
|
+
|
1
13
|
## v6.1.0.0
|
2
14
|
|
3
15
|
- No changes
|
4
16
|
|
5
17
|
## v6.1.0.0.rc1
|
6
18
|
|
19
|
+
[Full changelog](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/compare/6-0-stable...v6.1.0.0.rc1)
|
20
|
+
|
7
21
|
#### Fixed
|
8
22
|
|
9
23
|
- [#872](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/872) Use native String#start_with
|
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
|
-
| `6.1.
|
16
|
+
| `6.1.1.0` | `6.1.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
|
17
17
|
| `6.0.2` | `6.0.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-0-stable) |
|
18
18
|
| `5.2.1` | `5.2.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-2-stable) |
|
19
19
|
| `5.1.6` | `5.1.x` | [ended](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-1-stable) |
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
6.1.
|
1
|
+
6.1.1.0
|
@@ -10,6 +10,8 @@ module ActiveRecord
|
|
10
10
|
private
|
11
11
|
|
12
12
|
def attributes_for_update(attribute_names)
|
13
|
+
return super unless self.class.connection.adapter_name == "SQLServer"
|
14
|
+
|
13
15
|
super.reject do |name|
|
14
16
|
column = self.class.columns_hash[name]
|
15
17
|
column && column.respond_to?(:is_identity?) && column.is_identity?
|
@@ -10,6 +10,8 @@ module ActiveRecord
|
|
10
10
|
module Calculations
|
11
11
|
# Same as original except we don't perform PostgreSQL hack that removes ordering.
|
12
12
|
def calculate(operation, column_name)
|
13
|
+
return super unless klass.connection.adapter_name == "SQLServer"
|
14
|
+
|
13
15
|
if has_include?(column_name)
|
14
16
|
relation = apply_join_dependency
|
15
17
|
|
@@ -29,6 +31,8 @@ module ActiveRecord
|
|
29
31
|
private
|
30
32
|
|
31
33
|
def build_count_subquery(relation, column_name, distinct)
|
34
|
+
return super unless klass.connection.adapter_name == "SQLServer"
|
35
|
+
|
32
36
|
super(relation.unscope(:order), column_name, distinct)
|
33
37
|
end
|
34
38
|
end
|
@@ -39,5 +43,5 @@ end
|
|
39
43
|
|
40
44
|
ActiveSupport.on_load(:active_record) do
|
41
45
|
mod = ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::Calculations
|
42
|
-
ActiveRecord::Relation.
|
46
|
+
ActiveRecord::Relation.include(mod)
|
43
47
|
end
|
@@ -9,6 +9,8 @@ module ActiveRecord
|
|
9
9
|
SQLSERVER_STATEMENT_REGEXP = /N'(.+)', N'(.+)', (.+)/
|
10
10
|
|
11
11
|
def exec_explain(queries)
|
12
|
+
return super unless connection.adapter_name == "SQLServer"
|
13
|
+
|
12
14
|
unprepared_queries = queries.map do |(sql, binds)|
|
13
15
|
[unprepare_sqlserver_statement(sql, binds), binds]
|
14
16
|
end
|
@@ -12,6 +12,8 @@ module ActiveRecord
|
|
12
12
|
|
13
13
|
# Same as original except we order by values in distinct select if present.
|
14
14
|
def construct_relation_for_exists(conditions)
|
15
|
+
return super unless klass.connection.adapter_name == "SQLServer"
|
16
|
+
|
15
17
|
conditions = sanitize_forbidden_attributes(conditions)
|
16
18
|
|
17
19
|
if distinct_value && offset_value
|
@@ -10,6 +10,8 @@ module ActiveRecord
|
|
10
10
|
private
|
11
11
|
|
12
12
|
def records_for(ids)
|
13
|
+
return super unless klass.connection.adapter_name == "SQLServer"
|
14
|
+
|
13
15
|
ids.each_slice(in_clause_length).flat_map do |slice|
|
14
16
|
scope.where(association_key_name => slice).load do |record|
|
15
17
|
# Processing only the first owner
|
@@ -17,7 +17,8 @@ module ActiveRecord
|
|
17
17
|
precision: cast_type.precision,
|
18
18
|
scale: cast_type.scale
|
19
19
|
)
|
20
|
-
|
20
|
+
|
21
|
+
SQLServer::TypeMetadata.new(simple_type, **sqlserver_options)
|
21
22
|
end
|
22
23
|
|
23
24
|
def quote_string(s)
|
@@ -84,7 +84,7 @@ module ActiveRecord
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def new_column(name, default, sql_type_metadata, null, default_function = nil, collation = nil, comment = nil, sqlserver_options = {})
|
87
|
-
|
87
|
+
SQLServer::Column.new(
|
88
88
|
name,
|
89
89
|
default,
|
90
90
|
sql_type_metadata,
|
@@ -8,24 +8,33 @@ module ActiveRecord
|
|
8
8
|
|
9
9
|
include Deduplicable
|
10
10
|
|
11
|
-
attr_reader :
|
11
|
+
attr_reader :is_identity, :is_primary, :table_name, :ordinal_position
|
12
12
|
|
13
|
-
def initialize(type_metadata,
|
13
|
+
def initialize(type_metadata, is_identity: nil, is_primary: nil, table_name: nil, ordinal_position: nil)
|
14
14
|
super(type_metadata)
|
15
|
-
@
|
15
|
+
@is_identity = is_identity
|
16
|
+
@is_primary = is_primary
|
17
|
+
@table_name = table_name
|
18
|
+
@ordinal_position = ordinal_position
|
16
19
|
end
|
17
20
|
|
18
21
|
def ==(other)
|
19
22
|
other.is_a?(TypeMetadata) &&
|
20
23
|
__getobj__ == other.__getobj__ &&
|
21
|
-
|
24
|
+
is_identity == other.is_identity &&
|
25
|
+
is_primary == other.is_primary &&
|
26
|
+
table_name == other.table_name &&
|
27
|
+
ordinal_position == other.ordinal_position
|
22
28
|
end
|
23
29
|
alias eql? ==
|
24
30
|
|
25
31
|
def hash
|
26
32
|
TypeMetadata.hash ^
|
27
33
|
__getobj__.hash ^
|
28
|
-
|
34
|
+
is_identity.hash ^
|
35
|
+
is_primary.hash ^
|
36
|
+
table_name.hash ^
|
37
|
+
ordinal_position.hash
|
29
38
|
end
|
30
39
|
|
31
40
|
private
|
@@ -10,7 +10,6 @@ require "active_record/connection_adapters/sqlserver/core_ext/explain"
|
|
10
10
|
require "active_record/connection_adapters/sqlserver/core_ext/explain_subscriber"
|
11
11
|
require "active_record/connection_adapters/sqlserver/core_ext/attribute_methods"
|
12
12
|
require "active_record/connection_adapters/sqlserver/core_ext/finder_methods"
|
13
|
-
require "active_record/connection_adapters/sqlserver/core_ext/query_methods"
|
14
13
|
require "active_record/connection_adapters/sqlserver/core_ext/preloader"
|
15
14
|
require "active_record/connection_adapters/sqlserver/version"
|
16
15
|
require "active_record/connection_adapters/sqlserver/type"
|
@@ -2,48 +2,87 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
super
|
9
|
-
end
|
5
|
+
module SQLServer
|
6
|
+
class Column < ConnectionAdapters::Column
|
7
|
+
delegate :is_identity, :is_primary, :table_name, :ordinal_position, to: :sql_type_metadata
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
def initialize(*, is_identity: nil, is_primary: nil, table_name: nil, ordinal_position: nil, **)
|
10
|
+
super
|
11
|
+
@is_identity = is_identity
|
12
|
+
@is_primary = is_primary
|
13
|
+
@table_name = table_name
|
14
|
+
@ordinal_position = ordinal_position
|
15
|
+
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
def is_identity?
|
18
|
+
is_identity
|
19
|
+
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
def is_primary?
|
22
|
+
is_primary
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
def is_utf8?
|
26
|
+
sql_type =~ /nvarchar|ntext|nchar/i
|
27
|
+
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
def case_sensitive?
|
30
|
+
collation && collation.match(/_CS/)
|
31
|
+
end
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
33
|
+
def init_with(coder)
|
34
|
+
@is_identity = coder["is_identity"]
|
35
|
+
@is_primary = coder["is_primary"]
|
36
|
+
@table_name = coder["table_name"]
|
37
|
+
@ordinal_position = coder["ordinal_position"]
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
def encode_with(coder)
|
42
|
+
coder["is_identity"] = @is_identity
|
43
|
+
coder["is_primary"] = @is_primary
|
44
|
+
coder["table_name"] = @table_name
|
45
|
+
coder["ordinal_position"] = @ordinal_position
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
49
|
+
def ==(other)
|
50
|
+
other.is_a?(Column) &&
|
51
|
+
super &&
|
52
|
+
is_identity? == other.is_identity? &&
|
53
|
+
is_primary? == other.is_primary? &&
|
54
|
+
table_name == other.table_name &&
|
55
|
+
ordinal_position == other.ordinal_position
|
56
|
+
end
|
57
|
+
alias :eql? :==
|
58
|
+
|
59
|
+
def hash
|
60
|
+
Column.hash ^
|
61
|
+
super.hash ^
|
62
|
+
is_identity?.hash ^
|
63
|
+
is_primary?.hash ^
|
64
|
+
table_name.hash ^
|
65
|
+
ordinal_position.hash
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# In the Rails version of this method there is an assumption that the `default` value will always be a
|
71
|
+
# `String` class, which must be true for the MySQL/PostgreSQL/SQLite adapters. However, in the SQL Server
|
72
|
+
# adapter the `default` value can also be Boolean/Date/Time/etc. Changed the implementation of this method
|
73
|
+
# to handle non-String `default` objects.
|
74
|
+
def deduplicated
|
75
|
+
@name = -name
|
76
|
+
@sql_type_metadata = sql_type_metadata.deduplicate if sql_type_metadata
|
77
|
+
@default = (default.is_a?(String) ? -default : default.dup.freeze) if default
|
78
|
+
@default_function = -default_function if default_function
|
79
|
+
@collation = -collation if collation
|
80
|
+
@comment = -comment if comment
|
81
|
+
freeze
|
82
|
+
end
|
46
83
|
end
|
84
|
+
|
85
|
+
SQLServerColumn = SQLServer::Column
|
47
86
|
end
|
48
87
|
end
|
49
88
|
end
|
@@ -296,8 +296,21 @@ module Arel
|
|
296
296
|
def primary_Key_From_Table(t)
|
297
297
|
return unless t
|
298
298
|
|
299
|
-
|
300
|
-
|
299
|
+
primary_keys = @connection.schema_cache.primary_keys(t.name)
|
300
|
+
column_name = nil
|
301
|
+
|
302
|
+
case primary_keys
|
303
|
+
when NilClass
|
304
|
+
column_name = @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
|
305
|
+
when String
|
306
|
+
column_name = primary_keys
|
307
|
+
when Array
|
308
|
+
candidate_columns = @connection.schema_cache.columns_hash(t.name).slice(*primary_keys).values
|
309
|
+
candidate_column = candidate_columns.find(&:is_identity?)
|
310
|
+
candidate_column ||= candidate_columns.first
|
311
|
+
column_name = candidate_column.try(:name)
|
312
|
+
end
|
313
|
+
|
301
314
|
column_name ? t[column_name] : nil
|
302
315
|
end
|
303
316
|
|
@@ -377,7 +377,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
|
|
377
377
|
assert !SSTestCustomersView.columns.blank?
|
378
378
|
assert_equal columns.size, SSTestCustomersView.columns.size
|
379
379
|
columns.each do |colname|
|
380
|
-
assert_instance_of ActiveRecord::ConnectionAdapters::
|
380
|
+
assert_instance_of ActiveRecord::ConnectionAdapters::SQLServer::Column,
|
381
381
|
SSTestCustomersView.columns_hash[colname],
|
382
382
|
"Column name #{colname.inspect} was not found in these columns #{SSTestCustomersView.columns.map(&:name).inspect}"
|
383
383
|
end
|
@@ -404,7 +404,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
|
|
404
404
|
assert !SSTestStringDefaultsView.columns.blank?
|
405
405
|
assert_equal columns.size, SSTestStringDefaultsView.columns.size
|
406
406
|
columns.each do |colname|
|
407
|
-
assert_instance_of ActiveRecord::ConnectionAdapters::
|
407
|
+
assert_instance_of ActiveRecord::ConnectionAdapters::SQLServer::Column,
|
408
408
|
SSTestStringDefaultsView.columns_hash[colname],
|
409
409
|
"Column name #{colname.inspect} was not found in these columns #{SSTestStringDefaultsView.columns.map(&:name).inspect}"
|
410
410
|
end
|
data/test/cases/coerced_tests.rb
CHANGED
@@ -1521,6 +1521,7 @@ module ActiveRecord
|
|
1521
1521
|
|
1522
1522
|
original_test_statement_cache_values_differ
|
1523
1523
|
ensure
|
1524
|
+
Book.where(author_id: nil, name: 'my book').delete_all
|
1524
1525
|
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
1525
1526
|
end
|
1526
1527
|
end
|
@@ -1748,6 +1749,7 @@ class EnumTest < ActiveRecord::TestCase
|
|
1748
1749
|
|
1749
1750
|
send(:'original_enums are distinct per class')
|
1750
1751
|
ensure
|
1752
|
+
Book.where(author_id: nil, name: nil).delete_all
|
1751
1753
|
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
1752
1754
|
end
|
1753
1755
|
|
@@ -1758,6 +1760,7 @@ class EnumTest < ActiveRecord::TestCase
|
|
1758
1760
|
|
1759
1761
|
send(:'original_creating new objects with enum scopes')
|
1760
1762
|
ensure
|
1763
|
+
Book.where(author_id: nil, name: nil).delete_all
|
1761
1764
|
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
1762
1765
|
end
|
1763
1766
|
|
@@ -1768,6 +1771,7 @@ class EnumTest < ActiveRecord::TestCase
|
|
1768
1771
|
|
1769
1772
|
send(:'original_enums are inheritable')
|
1770
1773
|
ensure
|
1774
|
+
Book.where(author_id: nil, name: nil).delete_all
|
1771
1775
|
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
1772
1776
|
end
|
1773
1777
|
|
@@ -1778,6 +1782,7 @@ class EnumTest < ActiveRecord::TestCase
|
|
1778
1782
|
|
1779
1783
|
send(:'original_declare multiple enums at a time')
|
1780
1784
|
ensure
|
1785
|
+
Book.where(author_id: nil, name: nil).delete_all
|
1781
1786
|
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
1782
1787
|
end
|
1783
1788
|
end
|
@@ -1843,6 +1848,14 @@ class LogSubscriberTest < ActiveRecord::TestCase
|
|
1843
1848
|
def test_vebose_query_logs_coerced
|
1844
1849
|
original_test_vebose_query_logs
|
1845
1850
|
end
|
1851
|
+
|
1852
|
+
# Bindings logged slightly differently.
|
1853
|
+
coerce_tests! :test_where_in_binds_logging_include_attribute_names
|
1854
|
+
def test_where_in_binds_logging_include_attribute_names_coerced
|
1855
|
+
Developer.where(id: [1, 2, 3, 4, 5]).load
|
1856
|
+
wait
|
1857
|
+
assert_match(%{@0 = 1, @1 = 2, @2 = 3, @3 = 4, @4 = 5 [["id", nil], ["id", nil], ["id", nil], ["id", nil], ["id", nil]]}, @logger.logged(:debug).last)
|
1858
|
+
end
|
1846
1859
|
end
|
1847
1860
|
|
1848
1861
|
class ActiveRecordSchemaTest < ActiveRecord::TestCase
|
@@ -299,6 +299,8 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
299
299
|
_(obj.date).must_equal Date.civil(0001, 4, 1)
|
300
300
|
obj.reload
|
301
301
|
_(obj.date).must_equal Date.civil(0001, 4, 1)
|
302
|
+
# Can filter by date range
|
303
|
+
_(obj).must_equal obj.class.where(date: obj.date..Date::Infinity.new).first
|
302
304
|
# Can keep and return assigned date.
|
303
305
|
assert_obj_set_and_save :date, Date.civil(1972, 04, 14)
|
304
306
|
# Can accept and cast time objects.
|
@@ -333,6 +335,8 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
333
335
|
obj.reload
|
334
336
|
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>"
|
335
337
|
_(obj).must_equal obj.class.where(datetime: time).first
|
338
|
+
# Can filter by datetime range
|
339
|
+
_(obj).must_equal obj.class.where(datetime: time..DateTime::Infinity.new).first
|
336
340
|
# Will cast to true DB value on attribute write, save and return again.
|
337
341
|
time = Time.utc 2010, 04, 01, 12, 34, 56, 234567
|
338
342
|
time2 = Time.utc 2010, 04, 01, 12, 34, 56, 233000
|
@@ -49,3 +49,21 @@ class FetchTestSqlserver < ActiveRecord::TestCase
|
|
49
49
|
@books = (1..10).map { |i| Book.create! name: "Name-#{i}" }
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
class DeterministicFetchWithCompositePkTestSQLServer < ActiveRecord::TestCase
|
54
|
+
it "orders by the identity column if table has one" do
|
55
|
+
SSCompositePkWithIdentity.delete_all
|
56
|
+
SSCompositePkWithIdentity.create(pk_col_two: 2)
|
57
|
+
SSCompositePkWithIdentity.create(pk_col_two: 1)
|
58
|
+
|
59
|
+
_(SSCompositePkWithIdentity.take(1).map(&:pk_col_two)).must_equal [2]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "orders by the first column if table has no identity column" do
|
63
|
+
SSCompositePkWithoutIdentity.delete_all
|
64
|
+
SSCompositePkWithoutIdentity.create(pk_col_one: 2, pk_col_two: 2)
|
65
|
+
SSCompositePkWithoutIdentity.create(pk_col_one: 1, pk_col_two: 1)
|
66
|
+
|
67
|
+
_(SSCompositePkWithoutIdentity.take(1).map(&:pk_col_two)).must_equal [1]
|
68
|
+
end
|
69
|
+
end
|
@@ -156,3 +156,38 @@ class SQLServerRakeStructureDumpLoadTest < SQLServerRakeTest
|
|
156
156
|
_(connection.tables).must_include "users"
|
157
157
|
end
|
158
158
|
end
|
159
|
+
|
160
|
+
class SQLServerRakeSchemaCacheDumpLoadTest < SQLServerRakeTest
|
161
|
+
let(:filename) { File.join ARTest::SQLServer.test_root_sqlserver, "schema_cache.yml" }
|
162
|
+
let(:filedata) { File.read(filename) }
|
163
|
+
|
164
|
+
before do
|
165
|
+
quietly { db_tasks.create(configuration) }
|
166
|
+
|
167
|
+
connection.create_table :users, force: true do |t|
|
168
|
+
t.string :name, null: false
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
after do
|
173
|
+
FileUtils.rm_rf(filename)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "dumps schema cache with SQL Server metadata" do
|
177
|
+
quietly { db_tasks.dump_schema_cache connection, filename }
|
178
|
+
|
179
|
+
schema_cache = YAML.load(File.read(filename))
|
180
|
+
|
181
|
+
col_id, col_name = connection.schema_cache.columns("users")
|
182
|
+
|
183
|
+
assert col_id.is_identity
|
184
|
+
assert col_id.is_primary
|
185
|
+
assert_equal col_id.ordinal_position, 1
|
186
|
+
assert_equal col_id.table_name, "users"
|
187
|
+
|
188
|
+
assert_not col_name.is_identity
|
189
|
+
assert_not col_name.is_primary
|
190
|
+
assert_equal col_name.ordinal_position, 2
|
191
|
+
assert_equal col_name.table_name, "users"
|
192
|
+
end
|
193
|
+
end
|
@@ -294,4 +294,22 @@ ActiveRecord::Schema.define do
|
|
294
294
|
CONSTRAINT PK_UNIQUE_KEY PRIMARY KEY (id)
|
295
295
|
);
|
296
296
|
SQLSERVERUNIQUEKEYS
|
297
|
+
|
298
|
+
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_composite_without_identity') DROP TABLE sst_composite_without_identity"
|
299
|
+
execute <<-COMPOSITE_WITHOUT_IDENTITY
|
300
|
+
CREATE TABLE sst_composite_without_identity (
|
301
|
+
pk_col_one int NOT NULL,
|
302
|
+
pk_col_two int NOT NULL,
|
303
|
+
CONSTRAINT PK_sst_composite_without_identity PRIMARY KEY (pk_col_one, pk_col_two)
|
304
|
+
);
|
305
|
+
COMPOSITE_WITHOUT_IDENTITY
|
306
|
+
|
307
|
+
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_composite_with_identity') DROP TABLE sst_composite_with_identity"
|
308
|
+
execute <<-COMPOSITE_WITH_IDENTITY
|
309
|
+
CREATE TABLE sst_composite_with_identity (
|
310
|
+
pk_col_one int IDENTITY NOT NULL,
|
311
|
+
pk_col_two int NOT NULL,
|
312
|
+
CONSTRAINT PK_sst_composite_with_identity PRIMARY KEY (pk_col_one, pk_col_two)
|
313
|
+
);
|
314
|
+
COMPOSITE_WITH_IDENTITY
|
297
315
|
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: 6.1.
|
4
|
+
version: 6.1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken Collins
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2021-
|
17
|
+
date: 2021-08-11 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activerecord
|
@@ -78,7 +78,6 @@ files:
|
|
78
78
|
- lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb
|
79
79
|
- lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb
|
80
80
|
- lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb
|
81
|
-
- lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb
|
82
81
|
- lib/active_record/connection_adapters/sqlserver/database_limits.rb
|
83
82
|
- lib/active_record/connection_adapters/sqlserver/database_statements.rb
|
84
83
|
- lib/active_record/connection_adapters/sqlserver/database_tasks.rb
|
@@ -180,6 +179,7 @@ files:
|
|
180
179
|
- test/migrations/create_clients_and_change_column_null.rb
|
181
180
|
- test/migrations/transaction_table/1_table_will_never_be_created.rb
|
182
181
|
- test/models/sqlserver/booking.rb
|
182
|
+
- test/models/sqlserver/composite_pk.rb
|
183
183
|
- test/models/sqlserver/customers_view.rb
|
184
184
|
- test/models/sqlserver/datatype.rb
|
185
185
|
- test/models/sqlserver/datatype_migration.rb
|
@@ -224,8 +224,8 @@ licenses:
|
|
224
224
|
- MIT
|
225
225
|
metadata:
|
226
226
|
bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
|
227
|
-
changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v6.1.
|
228
|
-
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v6.1.
|
227
|
+
changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v6.1.1.0/CHANGELOG.md
|
228
|
+
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v6.1.1.0
|
229
229
|
post_install_message:
|
230
230
|
rdoc_options: []
|
231
231
|
require_paths:
|
@@ -241,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
241
241
|
- !ruby/object:Gem::Version
|
242
242
|
version: '0'
|
243
243
|
requirements: []
|
244
|
-
rubygems_version: 3.2.
|
244
|
+
rubygems_version: 3.2.22
|
245
245
|
signing_key:
|
246
246
|
specification_version: 4
|
247
247
|
summary: ActiveRecord SQL Server Adapter.
|
@@ -288,6 +288,7 @@ test_files:
|
|
288
288
|
- test/migrations/create_clients_and_change_column_null.rb
|
289
289
|
- test/migrations/transaction_table/1_table_will_never_be_created.rb
|
290
290
|
- test/models/sqlserver/booking.rb
|
291
|
+
- test/models/sqlserver/composite_pk.rb
|
291
292
|
- test/models/sqlserver/customers_view.rb
|
292
293
|
- test/models/sqlserver/datatype.rb
|
293
294
|
- test/models/sqlserver/datatype_migration.rb
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_record/relation"
|
4
|
-
require "active_record/version"
|
5
|
-
|
6
|
-
module ActiveRecord
|
7
|
-
module ConnectionAdapters
|
8
|
-
module SQLServer
|
9
|
-
module CoreExt
|
10
|
-
module QueryMethods
|
11
|
-
private
|
12
|
-
|
13
|
-
# Copy of original from Rails master.
|
14
|
-
# This patch can be removed when adapter supports Rails version greater than 6.0.2.2
|
15
|
-
def table_name_matches?(from)
|
16
|
-
table_name = Regexp.escape(table.name)
|
17
|
-
quoted_table_name = Regexp.escape(connection.quote_table_name(table.name))
|
18
|
-
/(?:\A|(?<!FROM)\s)(?:\b#{table_name}\b|#{quoted_table_name})(?!\.)/i.match?(from.to_s)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
ActiveSupport.on_load(:active_record) do
|
27
|
-
ActiveRecord::Relation.include(ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::QueryMethods)
|
28
|
-
end
|