activerecord-sqlserver-adapter 6.0.0.rc1 → 6.0.0.rc2
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/.gitignore +1 -0
- data/.rubocop.yml +29 -0
- data/CHANGELOG.md +20 -0
- data/Gemfile +11 -5
- data/Guardfile +9 -8
- data/Rakefile +12 -16
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +3 -3
- data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +0 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +1 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +3 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +1 -3
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +35 -32
- data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +7 -12
- data/lib/active_record/connection_adapters/sqlserver/errors.rb +0 -3
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +8 -8
- data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +7 -7
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +106 -103
- data/lib/active_record/connection_adapters/sqlserver/showplan.rb +6 -8
- data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +1 -4
- data/lib/active_record/connection_adapters/sqlserver/transaction.rb +4 -8
- data/lib/active_record/connection_adapters/sqlserver/type.rb +35 -35
- data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/char.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/data.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/float.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/json.rb +0 -1
- data/lib/active_record/connection_adapters/sqlserver/type/money.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/real.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/string.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/text.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/time.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +6 -9
- data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +1 -3
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +1 -2
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +1 -3
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +1 -3
- data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/utils.rb +8 -11
- data/lib/active_record/connection_adapters/sqlserver/version.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +85 -83
- data/lib/active_record/connection_adapters/sqlserver_column.rb +0 -2
- data/lib/active_record/sqlserver_base.rb +1 -1
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +26 -32
- data/lib/activerecord-sqlserver-adapter.rb +1 -1
- data/lib/arel/visitors/sqlserver.rb +18 -14
- data/lib/arel_sqlserver.rb +2 -2
- data/test/cases/adapter_test_sqlserver.rb +161 -182
- data/test/cases/change_column_null_test_sqlserver.rb +12 -12
- data/test/cases/coerced_tests.rb +88 -270
- data/test/cases/column_test_sqlserver.rb +281 -283
- data/test/cases/connection_test_sqlserver.rb +15 -20
- data/test/cases/execute_procedure_test_sqlserver.rb +18 -20
- data/test/cases/fetch_test_sqlserver.rb +14 -22
- data/test/cases/fully_qualified_identifier_test_sqlserver.rb +12 -18
- data/test/cases/helper_sqlserver.rb +13 -15
- data/test/cases/in_clause_test_sqlserver.rb +9 -9
- data/test/cases/index_test_sqlserver.rb +13 -15
- data/test/cases/json_test_sqlserver.rb +23 -25
- data/test/cases/migration_test_sqlserver.rb +22 -28
- data/test/cases/order_test_sqlserver.rb +51 -54
- data/test/cases/pessimistic_locking_test_sqlserver.rb +25 -33
- data/test/cases/rake_test_sqlserver.rb +31 -45
- data/test/cases/schema_dumper_test_sqlserver.rb +104 -108
- data/test/cases/schema_test_sqlserver.rb +18 -26
- data/test/cases/scratchpad_test_sqlserver.rb +2 -4
- data/test/cases/showplan_test_sqlserver.rb +24 -33
- data/test/cases/specific_schema_test_sqlserver.rb +66 -65
- data/test/cases/transaction_test_sqlserver.rb +16 -19
- data/test/cases/trigger_test_sqlserver.rb +12 -12
- data/test/cases/utils_test_sqlserver.rb +68 -70
- data/test/cases/uuid_test_sqlserver.rb +11 -13
- data/test/debug.rb +6 -6
- data/test/migrations/create_clients_and_change_column_null.rb +1 -1
- data/test/migrations/transaction_table/1_table_will_never_be_created.rb +2 -4
- data/test/models/sqlserver/booking.rb +1 -1
- data/test/models/sqlserver/customers_view.rb +1 -1
- data/test/models/sqlserver/dollar_table_name.rb +1 -1
- data/test/models/sqlserver/edge_schema.rb +1 -3
- data/test/models/sqlserver/fk_has_fk.rb +1 -1
- data/test/models/sqlserver/fk_has_pk.rb +1 -1
- data/test/models/sqlserver/natural_pk_data.rb +2 -2
- data/test/models/sqlserver/natural_pk_int_data.rb +1 -1
- data/test/models/sqlserver/no_pk_data.rb +1 -1
- data/test/models/sqlserver/object_default.rb +1 -1
- data/test/models/sqlserver/quoted_table.rb +2 -2
- data/test/models/sqlserver/quoted_view_1.rb +1 -1
- data/test/models/sqlserver/quoted_view_2.rb +1 -1
- data/test/models/sqlserver/sst_memory.rb +1 -1
- data/test/models/sqlserver/string_default.rb +1 -1
- data/test/models/sqlserver/string_defaults_big_view.rb +1 -1
- data/test/models/sqlserver/string_defaults_view.rb +1 -1
- data/test/models/sqlserver/tinyint_pk.rb +1 -1
- data/test/models/sqlserver/trigger.rb +2 -2
- data/test/models/sqlserver/trigger_history.rb +1 -1
- data/test/models/sqlserver/upper.rb +1 -1
- data/test/models/sqlserver/uppered.rb +1 -1
- data/test/models/sqlserver/uuid.rb +1 -1
- data/test/schema/sqlserver_specific_schema.rb +20 -22
- data/test/support/coerceable_test_sqlserver.rb +1 -4
- data/test/support/connection_reflection.rb +1 -2
- data/test/support/core_ext/query_cache.rb +1 -1
- data/test/support/load_schema_sqlserver.rb +3 -5
- data/test/support/minitest_sqlserver.rb +1 -1
- data/test/support/paths_sqlserver.rb +9 -11
- data/test/support/rake_helpers.rb +12 -10
- data/test/support/sql_counter_sqlserver.rb +0 -4
- data/test/support/test_in_memory_oltp.rb +7 -7
- metadata +5 -4
|
@@ -1,32 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "cases/helper_sqlserver"
|
|
4
4
|
|
|
5
5
|
class SchemaTestSQLServer < ActiveRecord::TestCase
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
it 'find primary key for tables with odd schema' do
|
|
10
|
-
_(connection.primary_key('sst_natural_pk_data')).must_equal 'legacy_id'
|
|
6
|
+
describe "When table is dbo schema" do
|
|
7
|
+
it "find primary key for tables with odd schema" do
|
|
8
|
+
_(connection.primary_key("sst_natural_pk_data")).must_equal "legacy_id"
|
|
11
9
|
end
|
|
12
|
-
|
|
13
10
|
end
|
|
14
11
|
|
|
15
|
-
describe
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
assert connection.data_source_exists?(
|
|
19
|
-
assert connection.data_source_exists?('[test].[sst_schema_natural_id]')
|
|
12
|
+
describe "When table is in non-dbo schema" do
|
|
13
|
+
it "work with table exists" do
|
|
14
|
+
assert connection.data_source_exists?("test.sst_schema_natural_id")
|
|
15
|
+
assert connection.data_source_exists?("[test].[sst_schema_natural_id]")
|
|
20
16
|
end
|
|
21
17
|
|
|
22
|
-
it
|
|
23
|
-
_(connection.primary_key(
|
|
18
|
+
it "find primary key for tables with odd schema" do
|
|
19
|
+
_(connection.primary_key("test.sst_schema_natural_id")).must_equal "legacy_id"
|
|
24
20
|
end
|
|
25
21
|
|
|
26
22
|
it "have only one identity column" do
|
|
27
23
|
columns = connection.columns("test.sst_schema_identity")
|
|
28
24
|
assert_equal 2, columns.size
|
|
29
|
-
assert_equal 1, columns.select{ |c| c.is_identity? }.size
|
|
25
|
+
assert_equal 1, columns.select { |c| c.is_identity? }.size
|
|
30
26
|
end
|
|
31
27
|
|
|
32
28
|
it "read only column properties for table in specific schema" do
|
|
@@ -36,21 +32,17 @@ class SchemaTestSQLServer < ActiveRecord::TestCase
|
|
|
36
32
|
assert_equal 7, test_columns.size
|
|
37
33
|
assert_equal 2, dbo_columns.size
|
|
38
34
|
assert_equal 2, columns.size
|
|
39
|
-
assert_equal 1, test_columns.select{ |c| c.is_identity? }.size
|
|
40
|
-
assert_equal 1, dbo_columns.select{ |c| c.is_identity? }.size
|
|
41
|
-
assert_equal 1, columns.select{ |c| c.is_identity? }.size
|
|
35
|
+
assert_equal 1, test_columns.select { |c| c.is_identity? }.size
|
|
36
|
+
assert_equal 1, dbo_columns.select { |c| c.is_identity? }.size
|
|
37
|
+
assert_equal 1, columns.select { |c| c.is_identity? }.size
|
|
42
38
|
end
|
|
43
39
|
|
|
44
40
|
it "return correct varchar and nvarchar column limit length when table is in non dbo schema" do
|
|
45
41
|
columns = connection.columns("test.sst_schema_columns")
|
|
46
|
-
assert_equal 255, columns.find {|c| c.name ==
|
|
47
|
-
assert_equal 1000, columns.find {|c| c.name ==
|
|
48
|
-
assert_equal 255, columns.find {|c| c.name ==
|
|
49
|
-
assert_equal 1000, columns.find {|c| c.name ==
|
|
42
|
+
assert_equal 255, columns.find { |c| c.name == "name" }.limit
|
|
43
|
+
assert_equal 1000, columns.find { |c| c.name == "description" }.limit
|
|
44
|
+
assert_equal 255, columns.find { |c| c.name == "n_name" }.limit
|
|
45
|
+
assert_equal 1000, columns.find { |c| c.name == "n_description" }.limit
|
|
50
46
|
end
|
|
51
|
-
|
|
52
47
|
end
|
|
53
|
-
|
|
54
|
-
|
|
55
48
|
end
|
|
56
|
-
|
|
@@ -1,71 +1,63 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "cases/helper_sqlserver"
|
|
4
|
+
require "models/car"
|
|
5
5
|
|
|
6
6
|
class ShowplanTestSQLServer < ActiveRecord::TestCase
|
|
7
|
-
|
|
8
7
|
fixtures :cars
|
|
9
8
|
|
|
10
|
-
describe
|
|
11
|
-
|
|
12
|
-
it 'from simple statement' do
|
|
9
|
+
describe "Unprepare previously prepared SQL" do
|
|
10
|
+
it "from simple statement" do
|
|
13
11
|
plan = Car.where(id: 1).explain
|
|
14
12
|
_(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] = 1"
|
|
15
|
-
_(plan).must_include "Clustered Index Seek",
|
|
13
|
+
_(plan).must_include "Clustered Index Seek", "make sure we do not showplan the sp_executesql"
|
|
16
14
|
end
|
|
17
15
|
|
|
18
|
-
it
|
|
16
|
+
it "from multiline statement" do
|
|
19
17
|
plan = Car.where("\n id = 1 \n").explain
|
|
20
18
|
_(plan).must_include "SELECT [cars].* FROM [cars] WHERE (\n id = 1 \n)"
|
|
21
|
-
_(plan).must_include "Clustered Index Seek",
|
|
19
|
+
_(plan).must_include "Clustered Index Seek", "make sure we do not showplan the sp_executesql"
|
|
22
20
|
end
|
|
23
21
|
|
|
24
|
-
it
|
|
25
|
-
plan = Car.where(name:
|
|
22
|
+
it "from prepared statement" do
|
|
23
|
+
plan = Car.where(name: ",").limit(1).explain
|
|
26
24
|
_(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[name]"
|
|
27
|
-
_(plan).must_include "TOP EXPRESSION",
|
|
28
|
-
_(plan).must_include "Clustered Index Scan",
|
|
25
|
+
_(plan).must_include "TOP EXPRESSION", "make sure we do not showplan the sp_executesql"
|
|
26
|
+
_(plan).must_include "Clustered Index Scan", "make sure we do not showplan the sp_executesql"
|
|
29
27
|
end
|
|
30
28
|
|
|
31
|
-
it
|
|
29
|
+
it "from array condition using index" do
|
|
32
30
|
plan = Car.where(id: [1, 2]).explain
|
|
33
31
|
_(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] IN (1, 2)"
|
|
34
|
-
_(plan).must_include "Clustered Index Seek",
|
|
32
|
+
_(plan).must_include "Clustered Index Seek", "make sure we do not showplan the sp_executesql"
|
|
35
33
|
end
|
|
36
34
|
|
|
37
|
-
it
|
|
38
|
-
plan = Car.where(name: [
|
|
35
|
+
it "from array condition" do
|
|
36
|
+
plan = Car.where(name: ["honda", "zyke"]).explain
|
|
39
37
|
_(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name] IN (N'honda', N'zyke')"
|
|
40
|
-
_(plan).must_include "Clustered Index Scan",
|
|
38
|
+
_(plan).must_include "Clustered Index Scan", "make sure we do not showplan the sp_executesql"
|
|
41
39
|
end
|
|
42
|
-
|
|
43
40
|
end
|
|
44
41
|
|
|
45
|
-
describe
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
with_showplan_option('SHOWPLAN_TEXT') do
|
|
42
|
+
describe "With SHOWPLAN_TEXT option" do
|
|
43
|
+
it "use simple table printer" do
|
|
44
|
+
with_showplan_option("SHOWPLAN_TEXT") do
|
|
49
45
|
plan = Car.where(id: 1).explain
|
|
50
46
|
_(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id]"
|
|
51
|
-
_(plan).must_include "Clustered Index Seek",
|
|
47
|
+
_(plan).must_include "Clustered Index Seek", "make sure we do not showplan the sp_executesql"
|
|
52
48
|
end
|
|
53
49
|
end
|
|
54
|
-
|
|
55
50
|
end
|
|
56
51
|
|
|
57
|
-
describe
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
with_showplan_option('SHOWPLAN_XML') do
|
|
52
|
+
describe "With SHOWPLAN_XML option" do
|
|
53
|
+
it "show formatted xml" do
|
|
54
|
+
with_showplan_option("SHOWPLAN_XML") do
|
|
61
55
|
plan = Car.where(id: 1).explain
|
|
62
|
-
_(plan).must_include
|
|
56
|
+
_(plan).must_include "ShowPlanXML"
|
|
63
57
|
end
|
|
64
58
|
end
|
|
65
|
-
|
|
66
59
|
end
|
|
67
60
|
|
|
68
|
-
|
|
69
61
|
private
|
|
70
62
|
|
|
71
63
|
def with_showplan_option(option)
|
|
@@ -75,5 +67,4 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase
|
|
|
75
67
|
ensure
|
|
76
68
|
ActiveRecord::ConnectionAdapters::SQLServerAdapter.showplan_option = old_option
|
|
77
69
|
end
|
|
78
|
-
|
|
79
70
|
end
|
|
@@ -1,73 +1,75 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "cases/helper_sqlserver"
|
|
4
4
|
|
|
5
5
|
class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
6
|
-
|
|
7
6
|
after { SSTestEdgeSchema.delete_all }
|
|
8
7
|
|
|
9
|
-
it
|
|
8
|
+
it "handle dollar symbols" do
|
|
10
9
|
SSTestDollarTableName.create!
|
|
11
10
|
SSTestDollarTableName.limit(20).offset(1)
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
it
|
|
15
|
-
obj = SSTestTinyintPk.create! name:
|
|
16
|
-
_([
|
|
13
|
+
it "models can use tinyint pk tables" do
|
|
14
|
+
obj = SSTestTinyintPk.create! name: "1"
|
|
15
|
+
_(["Fixnum", "Integer"]).must_include obj.id.class.name
|
|
17
16
|
_(SSTestTinyintPk.find(obj.id)).must_equal obj
|
|
18
17
|
end
|
|
19
18
|
|
|
20
|
-
it
|
|
19
|
+
it "be able to complex count tables with no primary key" do
|
|
21
20
|
SSTestNoPkData.delete_all
|
|
22
21
|
10.times { |n| SSTestNoPkData.create! name: "Test#{n}" }
|
|
23
|
-
assert_equal 1, SSTestNoPkData.where(name:
|
|
22
|
+
assert_equal 1, SSTestNoPkData.where(name: "Test5").count
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
it
|
|
27
|
-
|
|
25
|
+
it "quote table names properly even when they are views" do
|
|
26
|
+
SSTestQuotedTable.create!
|
|
28
27
|
assert_nothing_raised { assert SSTestQuotedTable.first }
|
|
29
|
-
|
|
28
|
+
|
|
29
|
+
SSTestQuotedTableUser.create!
|
|
30
30
|
assert_nothing_raised { assert SSTestQuotedTableUser.first }
|
|
31
|
-
|
|
31
|
+
|
|
32
|
+
SSTestQuotedView1.create!
|
|
32
33
|
assert_nothing_raised { assert SSTestQuotedView1.first }
|
|
33
|
-
|
|
34
|
+
|
|
35
|
+
SSTestQuotedView2.create!
|
|
34
36
|
assert_nothing_raised { assert SSTestQuotedView2.first }
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
it
|
|
39
|
+
it "cope with multi line defaults" do
|
|
38
40
|
default = SSTestStringDefault.new
|
|
39
41
|
assert_equal "Some long default with a\nnew line.", default.string_with_multiline_default
|
|
40
42
|
end
|
|
41
43
|
|
|
42
|
-
it
|
|
44
|
+
it "default strings before save" do
|
|
43
45
|
default = SSTestStringDefault.new
|
|
44
46
|
assert_nil default.string_with_null_default
|
|
45
|
-
assert_equal
|
|
46
|
-
assert_equal
|
|
47
|
-
assert_equal
|
|
48
|
-
assert_equal
|
|
49
|
-
assert_equal
|
|
47
|
+
assert_equal "null", default.string_with_pretend_null_one
|
|
48
|
+
assert_equal "(null)", default.string_with_pretend_null_two
|
|
49
|
+
assert_equal "NULL", default.string_with_pretend_null_three
|
|
50
|
+
assert_equal "(NULL)", default.string_with_pretend_null_four
|
|
51
|
+
assert_equal "(3)", default.string_with_pretend_paren_three
|
|
50
52
|
end
|
|
51
53
|
|
|
52
|
-
it
|
|
54
|
+
it "default strings after save" do
|
|
53
55
|
default = SSTestStringDefault.create
|
|
54
56
|
assert_nil default.string_with_null_default
|
|
55
|
-
assert_equal
|
|
56
|
-
assert_equal
|
|
57
|
-
assert_equal
|
|
58
|
-
assert_equal
|
|
57
|
+
assert_equal "null", default.string_with_pretend_null_one
|
|
58
|
+
assert_equal "(null)", default.string_with_pretend_null_two
|
|
59
|
+
assert_equal "NULL", default.string_with_pretend_null_three
|
|
60
|
+
assert_equal "(NULL)", default.string_with_pretend_null_four
|
|
59
61
|
end
|
|
60
62
|
|
|
61
|
-
it
|
|
62
|
-
obj = SSTestObjectDefault.create! name:
|
|
63
|
-
_(obj.date).must_be_nil
|
|
63
|
+
it "default objects work" do
|
|
64
|
+
obj = SSTestObjectDefault.create! name: "MetaSkills"
|
|
65
|
+
_(obj.date).must_be_nil "since this is set on insert"
|
|
64
66
|
_(obj.reload.date).must_be_instance_of Date
|
|
65
67
|
end
|
|
66
68
|
|
|
67
|
-
it
|
|
68
|
-
_(SSTestBooking.columns_hash[
|
|
69
|
-
_(SSTestBooking.columns_hash[
|
|
70
|
-
obj1 = SSTestBooking.new name:
|
|
69
|
+
it "allows datetime2 as timestamps" do
|
|
70
|
+
_(SSTestBooking.columns_hash["created_at"].sql_type).must_equal "datetime2(7)"
|
|
71
|
+
_(SSTestBooking.columns_hash["updated_at"].sql_type).must_equal "datetime2(7)"
|
|
72
|
+
obj1 = SSTestBooking.new name: "test1"
|
|
71
73
|
obj1.save!
|
|
72
74
|
_(obj1.created_at).must_be_instance_of Time
|
|
73
75
|
_(obj1.updated_at).must_be_instance_of Time
|
|
@@ -75,35 +77,35 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
|
75
77
|
|
|
76
78
|
# Natural primary keys.
|
|
77
79
|
|
|
78
|
-
it
|
|
79
|
-
record = SSTestNaturalPkData.new name:
|
|
80
|
-
record.id =
|
|
80
|
+
it "work with identity inserts" do
|
|
81
|
+
record = SSTestNaturalPkData.new name: "Test", description: "Natural identity inserts."
|
|
82
|
+
record.id = "12345ABCDE"
|
|
81
83
|
assert record.save
|
|
82
|
-
assert_equal
|
|
84
|
+
assert_equal "12345ABCDE", record.reload.id
|
|
83
85
|
end
|
|
84
86
|
|
|
85
|
-
it
|
|
86
|
-
record = SSTestNaturalPkIntData.new name:
|
|
87
|
+
it "work with identity inserts when the key is an int" do
|
|
88
|
+
record = SSTestNaturalPkIntData.new name: "Test", description: "Natural identity inserts."
|
|
87
89
|
record.id = 12
|
|
88
90
|
assert record.save
|
|
89
91
|
assert_equal 12, record.reload.id
|
|
90
92
|
end
|
|
91
93
|
|
|
92
|
-
it
|
|
94
|
+
it "use primary key for row table order in pagination sql" do
|
|
93
95
|
sql = /ORDER BY \[sst_natural_pk_data\]\.\[legacy_id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY/
|
|
94
96
|
assert_sql(sql) { SSTestNaturalPkData.limit(5).offset(5).load }
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
# Special quoted column
|
|
98
100
|
|
|
99
|
-
it
|
|
101
|
+
it "work as normal" do
|
|
100
102
|
SSTestEdgeSchema.delete_all
|
|
101
|
-
r = SSTestEdgeSchema.create!
|
|
102
|
-
assert SSTestEdgeSchema.columns_hash[
|
|
103
|
-
assert_equal r, SSTestEdgeSchema.where(
|
|
103
|
+
r = SSTestEdgeSchema.create! "crazy]]quote" => "crazyqoute"
|
|
104
|
+
assert SSTestEdgeSchema.columns_hash["crazy]]quote"]
|
|
105
|
+
assert_equal r, SSTestEdgeSchema.where("crazy]]quote" => "crazyqoute").first
|
|
104
106
|
end
|
|
105
107
|
|
|
106
|
-
it
|
|
108
|
+
it "various methods to bypass national quoted columns for any column, but primarily useful for char/varchar" do
|
|
107
109
|
value = Class.new do
|
|
108
110
|
def quoted_id
|
|
109
111
|
"'T'"
|
|
@@ -115,14 +117,14 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
|
115
117
|
# Using our custom char type data.
|
|
116
118
|
type = ActiveRecord::Type::SQLServer::Char
|
|
117
119
|
data = ActiveRecord::Type::SQLServer::Data
|
|
118
|
-
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: data.new(
|
|
119
|
-
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: data.new(
|
|
120
|
+
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: data.new("T", type.new)).first }
|
|
121
|
+
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: data.new("T", type.new)).first }
|
|
120
122
|
# Taking care of everything.
|
|
121
|
-
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col:
|
|
122
|
-
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col:
|
|
123
|
+
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: "T").first }
|
|
124
|
+
assert_sql(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: "T").first }
|
|
123
125
|
end
|
|
124
126
|
|
|
125
|
-
it
|
|
127
|
+
it "can update and hence properly quoted non-national char/varchar columns" do
|
|
126
128
|
o = SSTestDatatypeMigration.create!
|
|
127
129
|
o.varchar_col = "O'Reilly"
|
|
128
130
|
o.save!
|
|
@@ -134,28 +136,28 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
|
134
136
|
|
|
135
137
|
# With column names that have spaces
|
|
136
138
|
|
|
137
|
-
it
|
|
138
|
-
value =
|
|
139
|
+
it "create record using a custom attribute reader and be able to load it back in" do
|
|
140
|
+
value = "Saved value into a column that has a space in the name."
|
|
139
141
|
record = SSTestEdgeSchema.create! with_spaces: value
|
|
140
142
|
assert_equal value, SSTestEdgeSchema.find(record.id).with_spaces
|
|
141
143
|
end
|
|
142
144
|
|
|
143
145
|
# With description column
|
|
144
146
|
|
|
145
|
-
it
|
|
146
|
-
SSTestEdgeSchema.create! description:
|
|
147
|
-
SSTestEdgeSchema.create! description:
|
|
148
|
-
SSTestEdgeSchema.create! description:
|
|
149
|
-
assert_equal [
|
|
150
|
-
assert_equal [
|
|
151
|
-
assert_equal [
|
|
152
|
-
assert_equal [
|
|
153
|
-
assert_equal [
|
|
147
|
+
it "allow all sorts of ordering without adapter munging it up with special description column" do
|
|
148
|
+
SSTestEdgeSchema.create! description: "A"
|
|
149
|
+
SSTestEdgeSchema.create! description: "B"
|
|
150
|
+
SSTestEdgeSchema.create! description: "C"
|
|
151
|
+
assert_equal ["A", "B", "C"], SSTestEdgeSchema.order("description").map(&:description)
|
|
152
|
+
assert_equal ["A", "B", "C"], SSTestEdgeSchema.order("description asc").map(&:description)
|
|
153
|
+
assert_equal ["A", "B", "C"], SSTestEdgeSchema.order("description ASC").map(&:description)
|
|
154
|
+
assert_equal ["C", "B", "A"], SSTestEdgeSchema.order("description desc").map(&:description)
|
|
155
|
+
assert_equal ["C", "B", "A"], SSTestEdgeSchema.order("description DESC").map(&:description)
|
|
154
156
|
end
|
|
155
157
|
|
|
156
158
|
# For uniqueidentifier model helpers
|
|
157
159
|
|
|
158
|
-
it
|
|
160
|
+
it "returns a new id via connection newid_function" do
|
|
159
161
|
acceptable_uuid = ActiveRecord::ConnectionAdapters::SQLServer::Type::Uuid::ACCEPTABLE_UUID
|
|
160
162
|
db_uuid = ActiveRecord::Base.connection.newid_function
|
|
161
163
|
_(db_uuid).must_match(acceptable_uuid)
|
|
@@ -163,10 +165,9 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
|
163
165
|
|
|
164
166
|
# with similar table definition in two schemas
|
|
165
167
|
|
|
166
|
-
it
|
|
168
|
+
it "returns the correct primary columns" do
|
|
167
169
|
connection = ActiveRecord::Base.connection
|
|
168
|
-
assert_equal
|
|
169
|
-
assert_equal
|
|
170
|
+
assert_equal "field_1", connection.columns("test.sst_schema_test_mulitple_schema").detect(&:is_primary?).name
|
|
171
|
+
assert_equal "field_2", connection.columns("test2.sst_schema_test_mulitple_schema").detect(&:is_primary?).name
|
|
170
172
|
end
|
|
171
|
-
|
|
172
173
|
end
|
|
@@ -1,43 +1,42 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
3
|
+
require "cases/helper_sqlserver"
|
|
4
|
+
require "models/ship"
|
|
5
|
+
require "models/developer"
|
|
6
6
|
|
|
7
7
|
class TransactionTestSQLServer < ActiveRecord::TestCase
|
|
8
|
-
|
|
9
8
|
self.use_transactional_tests = false
|
|
10
9
|
|
|
11
10
|
before { delete_ships }
|
|
12
11
|
|
|
13
|
-
it
|
|
12
|
+
it "allow ActiveRecord::Rollback to work in 1 transaction block" do
|
|
14
13
|
Ship.transaction do
|
|
15
|
-
Ship.create! name:
|
|
14
|
+
Ship.create! name: "Black Pearl"
|
|
16
15
|
raise ActiveRecord::Rollback
|
|
17
16
|
end
|
|
18
17
|
assert_no_ships
|
|
19
18
|
end
|
|
20
19
|
|
|
21
|
-
it
|
|
20
|
+
it "allow nested transactions to totally rollback" do
|
|
22
21
|
begin
|
|
23
22
|
Ship.transaction do
|
|
24
|
-
Ship.create! name:
|
|
23
|
+
Ship.create! name: "Black Pearl"
|
|
25
24
|
Ship.transaction do
|
|
26
|
-
Ship.create! name:
|
|
27
|
-
raise
|
|
25
|
+
Ship.create! name: "Flying Dutchman"
|
|
26
|
+
raise "HELL"
|
|
28
27
|
end
|
|
29
28
|
end
|
|
30
|
-
rescue Exception
|
|
29
|
+
rescue Exception
|
|
31
30
|
assert_no_ships
|
|
32
31
|
end
|
|
33
32
|
end
|
|
34
33
|
|
|
35
|
-
it
|
|
34
|
+
it "can use an isolation level and reverts back to starting isolation level" do
|
|
36
35
|
in_level = nil
|
|
37
36
|
begin_level = connection.user_options_isolation_level
|
|
38
37
|
_(begin_level).must_match %r{read committed}i
|
|
39
38
|
Ship.transaction(isolation: :serializable) do
|
|
40
|
-
Ship.create! name:
|
|
39
|
+
Ship.create! name: "Black Pearl"
|
|
41
40
|
in_level = connection.user_options_isolation_level
|
|
42
41
|
end
|
|
43
42
|
after_level = connection.user_options_isolation_level
|
|
@@ -45,7 +44,7 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
|
|
|
45
44
|
_(after_level).must_match %r{read committed}i
|
|
46
45
|
end
|
|
47
46
|
|
|
48
|
-
it
|
|
47
|
+
it "can use an isolation level and reverts back to starting isolation level under exceptions" do
|
|
49
48
|
_(connection.user_options_isolation_level).must_match %r{read committed}i
|
|
50
49
|
_(lambda {
|
|
51
50
|
Ship.transaction(isolation: :serializable) { Ship.create! }
|
|
@@ -53,7 +52,7 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
|
|
|
53
52
|
_(connection.user_options_isolation_level).must_match %r{read committed}i
|
|
54
53
|
end
|
|
55
54
|
|
|
56
|
-
describe
|
|
55
|
+
describe "when READ_COMMITTED_SNAPSHOT is set" do
|
|
57
56
|
before do
|
|
58
57
|
connection.execute "ALTER DATABASE [#{connection.current_database}] SET ALLOW_SNAPSHOT_ISOLATION ON"
|
|
59
58
|
connection.execute "ALTER DATABASE [#{connection.current_database}] SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE"
|
|
@@ -64,11 +63,11 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
|
|
|
64
63
|
connection.execute "ALTER DATABASE [#{connection.current_database}] SET READ_COMMITTED_SNAPSHOT OFF WITH ROLLBACK IMMEDIATE"
|
|
65
64
|
end
|
|
66
65
|
|
|
67
|
-
it
|
|
66
|
+
it "should use READ COMMITTED as an isolation level" do
|
|
68
67
|
_(connection.user_options_isolation_level).must_match "read committed snapshot"
|
|
69
68
|
|
|
70
69
|
Ship.transaction(isolation: :serializable) do
|
|
71
|
-
Ship.create! name:
|
|
70
|
+
Ship.create! name: "Black Pearl"
|
|
72
71
|
end
|
|
73
72
|
|
|
74
73
|
# We're actually testing that the isolation level was correctly reset to
|
|
@@ -78,7 +77,6 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
|
|
|
78
77
|
end
|
|
79
78
|
end
|
|
80
79
|
|
|
81
|
-
|
|
82
80
|
protected
|
|
83
81
|
|
|
84
82
|
def delete_ships
|
|
@@ -88,5 +86,4 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
|
|
|
88
86
|
def assert_no_ships
|
|
89
87
|
assert Ship.count.zero?, "Expected Ship to have no models but it did have:\n#{Ship.all.inspect}"
|
|
90
88
|
end
|
|
91
|
-
|
|
92
89
|
end
|