activerecord-sqlserver-adapter 4.1.8 → 4.2.0.pre

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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/CHANGELOG.md +60 -0
  4. data/Gemfile +45 -0
  5. data/Guardfile +29 -0
  6. data/MIT-LICENSE +5 -5
  7. data/README.md +193 -0
  8. data/RUNNING_UNIT_TESTS.md +95 -0
  9. data/Rakefile +48 -0
  10. data/activerecord-sqlserver-adapter.gemspec +28 -0
  11. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +5 -15
  12. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +25 -0
  13. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +6 -4
  14. data/lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb +9 -3
  15. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +3 -1
  16. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +130 -151
  17. data/lib/active_record/connection_adapters/sqlserver/errors.rb +0 -25
  18. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +39 -78
  19. data/lib/active_record/connection_adapters/sqlserver/schema_cache.rb +71 -47
  20. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +14 -30
  21. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +112 -108
  22. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +4 -2
  23. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +1 -1
  24. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +1 -1
  25. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +52 -7
  26. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +52 -0
  27. data/lib/active_record/connection_adapters/sqlserver/type.rb +46 -0
  28. data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +15 -0
  29. data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +15 -0
  30. data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +13 -0
  31. data/lib/active_record/connection_adapters/sqlserver/type/castable.rb +15 -0
  32. data/lib/active_record/connection_adapters/sqlserver/type/char.rb +15 -0
  33. data/lib/active_record/connection_adapters/sqlserver/type/core_ext/value.rb +39 -0
  34. data/lib/active_record/connection_adapters/sqlserver/type/date.rb +14 -0
  35. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +37 -0
  36. data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +13 -0
  37. data/lib/active_record/connection_adapters/sqlserver/type/float.rb +17 -0
  38. data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +13 -0
  39. data/lib/active_record/connection_adapters/sqlserver/type/money.rb +21 -0
  40. data/lib/active_record/connection_adapters/sqlserver/type/quoter.rb +32 -0
  41. data/lib/active_record/connection_adapters/sqlserver/type/real.rb +17 -0
  42. data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +13 -0
  43. data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +21 -0
  44. data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +24 -0
  45. data/lib/active_record/connection_adapters/sqlserver/type/string.rb +12 -0
  46. data/lib/active_record/connection_adapters/sqlserver/type/text.rb +15 -0
  47. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +59 -0
  48. data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +15 -0
  49. data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +22 -0
  50. data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +15 -0
  51. data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +12 -0
  52. data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +15 -0
  53. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +20 -0
  54. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +20 -0
  55. data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +23 -0
  56. data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +20 -0
  57. data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +20 -0
  58. data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +20 -0
  59. data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +20 -0
  60. data/lib/active_record/connection_adapters/sqlserver/utils.rb +118 -12
  61. data/lib/active_record/connection_adapters/sqlserver/version.rb +11 -0
  62. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +133 -198
  63. data/lib/active_record/connection_adapters/sqlserver_column.rb +15 -86
  64. data/lib/active_record/sqlserver_base.rb +2 -0
  65. data/lib/arel/visitors/sqlserver.rb +120 -393
  66. data/lib/{arel/arel_sqlserver.rb → arel_sqlserver.rb} +1 -3
  67. data/test/cases/adapter_test_sqlserver.rb +420 -0
  68. data/test/cases/coerced_tests.rb +642 -0
  69. data/test/cases/column_test_sqlserver.rb +703 -0
  70. data/test/cases/connection_test_sqlserver.rb +216 -0
  71. data/test/cases/database_statements_test_sqlserver.rb +57 -0
  72. data/test/cases/execute_procedure_test_sqlserver.rb +38 -0
  73. data/test/cases/helper_sqlserver.rb +36 -0
  74. data/test/cases/migration_test_sqlserver.rb +66 -0
  75. data/test/cases/order_test_sqlserver.rb +147 -0
  76. data/test/cases/pessimistic_locking_test_sqlserver.rb +90 -0
  77. data/test/cases/schema_dumper_test_sqlserver.rb +175 -0
  78. data/test/cases/schema_test_sqlserver.rb +54 -0
  79. data/test/cases/scratchpad_test_sqlserver.rb +9 -0
  80. data/test/cases/showplan_test_sqlserver.rb +65 -0
  81. data/test/cases/specific_schema_test_sqlserver.rb +118 -0
  82. data/test/cases/transaction_test_sqlserver.rb +61 -0
  83. data/test/cases/utils_test_sqlserver.rb +91 -0
  84. data/test/cases/uuid_test_sqlserver.rb +41 -0
  85. data/test/config.yml +35 -0
  86. data/test/fixtures/1px.gif +0 -0
  87. data/test/migrations/transaction_table/1_table_will_never_be_created.rb +11 -0
  88. data/test/models/sqlserver/customers_view.rb +3 -0
  89. data/test/models/sqlserver/datatype.rb +3 -0
  90. data/test/models/sqlserver/datatype_migration.rb +3 -0
  91. data/test/models/sqlserver/dollar_table_name.rb +3 -0
  92. data/test/models/sqlserver/edge_schema.rb +13 -0
  93. data/test/models/sqlserver/fk_has_fk.rb +3 -0
  94. data/test/models/sqlserver/fk_has_pk.rb +3 -0
  95. data/test/models/sqlserver/natural_pk_data.rb +4 -0
  96. data/test/models/sqlserver/natural_pk_int_data.rb +3 -0
  97. data/test/models/sqlserver/no_pk_data.rb +3 -0
  98. data/test/models/sqlserver/quoted_table.rb +7 -0
  99. data/test/models/sqlserver/quoted_view_1.rb +3 -0
  100. data/test/models/sqlserver/quoted_view_2.rb +3 -0
  101. data/test/models/sqlserver/string_default.rb +3 -0
  102. data/test/models/sqlserver/string_defaults_big_view.rb +3 -0
  103. data/test/models/sqlserver/string_defaults_view.rb +3 -0
  104. data/test/models/sqlserver/tinyint_pk.rb +3 -0
  105. data/test/models/sqlserver/upper.rb +3 -0
  106. data/test/models/sqlserver/uppered.rb +3 -0
  107. data/test/models/sqlserver/uuid.rb +3 -0
  108. data/test/schema/datatypes/2012.sql +64 -0
  109. data/test/schema/sqlserver_specific_schema.rb +181 -0
  110. data/test/support/coerceable_test_sqlserver.rb +45 -0
  111. data/test/support/load_schema_sqlserver.rb +29 -0
  112. data/test/support/minitest_sqlserver.rb +1 -0
  113. data/test/support/paths_sqlserver.rb +48 -0
  114. data/test/support/rake_helpers.rb +41 -0
  115. data/test/support/sql_counter_sqlserver.rb +32 -0
  116. metadata +271 -21
  117. data/CHANGELOG +0 -39
  118. data/VERSION +0 -1
  119. data/lib/active_record/connection_adapters/sqlserver/core_ext/relation.rb +0 -17
  120. data/lib/active_record/sqlserver_test_case.rb +0 -17
  121. data/lib/arel/nodes_sqlserver.rb +0 -14
  122. data/lib/arel/select_manager_sqlserver.rb +0 -62
@@ -0,0 +1,61 @@
1
+ require 'cases/helper_sqlserver'
2
+ require 'models/ship'
3
+ require 'models/developer'
4
+
5
+ class TransactionTestSQLServer < ActiveRecord::TestCase
6
+
7
+ self.use_transactional_fixtures = false
8
+
9
+ before { delete_ships }
10
+
11
+ it 'allow ActiveRecord::Rollback to work in 1 transaction block' do
12
+ Ship.transaction do
13
+ Ship.create! name: 'Black Pearl'
14
+ raise ActiveRecord::Rollback
15
+ end
16
+ assert_no_ships
17
+ end
18
+
19
+ it 'allow nested transactions to totally rollback' do
20
+ begin
21
+ Ship.transaction do
22
+ Ship.create! name: 'Black Pearl'
23
+ Ship.transaction do
24
+ Ship.create! name: 'Flying Dutchman'
25
+ raise 'HELL'
26
+ end
27
+ end
28
+ rescue Exception => e
29
+ assert_no_ships
30
+ end
31
+ end
32
+
33
+ it 'can use an isolation level and reverts back to starting isolation level' do
34
+ begin
35
+ in_level = nil
36
+ begin_level = connection.user_options_isolation_level
37
+ begin_level.must_match %r{read committed}
38
+ Ship.transaction(isolation: :serializable) do
39
+ Ship.create! name: 'Black Pearl'
40
+ in_level = connection.user_options_isolation_level
41
+ end
42
+ after_level = connection.user_options_isolation_level
43
+ in_level.must_match %r{serializable}i
44
+ after_level.must_match %r{read committed}
45
+ ensure
46
+ connection.set_transaction_isolation_level 'READ COMMITTED'
47
+ end
48
+ end
49
+
50
+
51
+ protected
52
+
53
+ def delete_ships
54
+ Ship.delete_all
55
+ end
56
+
57
+ def assert_no_ships
58
+ assert Ship.count.zero?, "Expected Ship to have no models but it did have:\n#{Ship.all.inspect}"
59
+ end
60
+
61
+ end
@@ -0,0 +1,91 @@
1
+ require 'cases/helper_sqlserver'
2
+
3
+ class UtilsTestSQLServer < ActiveRecord::TestCase
4
+
5
+ it '.quote_string' do
6
+ SQLServer::Utils.quote_string("I'll store this in C:\\Users").must_equal "I''ll store this in C:\\Users"
7
+ end
8
+
9
+ it '.unquote_string' do
10
+ SQLServer::Utils.unquote_string("I''ll store this in C:\\Users").must_equal "I'll store this in C:\\Users"
11
+ end
12
+
13
+ describe '.extract_identifiers constructor and thus SQLServer::Utils::Name value object' do
14
+
15
+ let(:valid_names) { valid_names_unquoted + valid_names_quoted }
16
+
17
+ let(:valid_names_unquoted) {[
18
+ 'server.database.schema.object',
19
+ 'server.database..object',
20
+ 'server..schema.object',
21
+ 'server...object',
22
+ 'database.schema.object',
23
+ 'database..object',
24
+ 'schema.object',
25
+ 'object'
26
+ ]}
27
+
28
+ let(:valid_names_quoted) {[
29
+ '[server].[database].[schema].[object]',
30
+ '[server].[database]..[object]',
31
+ '[server]..[schema].[object]',
32
+ '[server]...[object]',
33
+ '[database].[schema].[object]',
34
+ '[database]..[object]',
35
+ '[schema].[object]',
36
+ '[object]'
37
+ ]}
38
+
39
+ let(:server_names) { valid_names.partition { |name| name =~ /server/ } }
40
+ let(:database_names) { valid_names.partition { |name| name =~ /database/ } }
41
+ let(:schema_names) { valid_names.partition { |name| name =~ /schema/ } }
42
+
43
+ it 'extracts and returns #object identifier unquoted by default or quoted as needed' do
44
+ valid_names.each do |n|
45
+ name = SQLServer::Utils.extract_identifiers(n)
46
+ name.object.must_equal 'object', "With #{n.inspect} for #object"
47
+ name.object_quoted.must_equal '[object]', "With #{n.inspect} for #object_quoted"
48
+ end
49
+ end
50
+
51
+ [:schema, :database, :server].each do |part|
52
+
53
+ it "extracts and returns #{part} identifier unquoted by default or quoted as needed" do
54
+ present, blank = send(:"#{part}_names")
55
+ present.each do |n|
56
+ name = SQLServer::Utils.extract_identifiers(n)
57
+ name.send(:"#{part}").must_equal "#{part}", "With #{n.inspect} for ##{part} method"
58
+ name.send(:"#{part}_quoted").must_equal "[#{part}]", "With #{n.inspect} for ##{part}_quoted method"
59
+ end
60
+ blank.each do |n|
61
+ name = SQLServer::Utils.extract_identifiers(n)
62
+ name.send(:"#{part}").must_be_nil "With #{n.inspect} for ##{part} method"
63
+ name.send(:"#{part}_quoted").must_be_nil "With #{n.inspect} for ##{part}_quoted method"
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ it 'does not blow up on nil or blank string name' do
70
+ SQLServer::Utils.extract_identifiers(nil).object.must_be_nil
71
+ SQLServer::Utils.extract_identifiers(' ').object.must_be_nil
72
+ end
73
+
74
+ it 'has a #quoted that returns a fully quoted name with all identifiers as orginially passed in' do
75
+ SQLServer::Utils.extract_identifiers('object').quoted.must_equal '[object]'
76
+ SQLServer::Utils.extract_identifiers('server.database..object').quoted.must_equal '[server].[database]..[object]'
77
+ SQLServer::Utils.extract_identifiers('[server]...[object]').quoted.must_equal '[server]...[object]'
78
+ end
79
+
80
+ it 'can take a symbol argument' do
81
+ SQLServer::Utils.extract_identifiers(:object).object.must_equal 'object'
82
+ end
83
+
84
+ it 'allows identifiers with periods to work' do
85
+ SQLServer::Utils.extract_identifiers('[obj.name]').quoted.must_equal '[obj.name]'
86
+ SQLServer::Utils.extract_identifiers('[obj.name].[foo]').quoted.must_equal '[obj.name].[foo]'
87
+ end
88
+
89
+ end
90
+
91
+ end
@@ -0,0 +1,41 @@
1
+ require 'cases/helper_sqlserver'
2
+
3
+ class SQLServerUuidTest < ActiveRecord::TestCase
4
+
5
+ let(:acceptable_uuid) { ActiveRecord::ConnectionAdapters::SQLServer::Type::Uuid::ACCEPTABLE_UUID }
6
+
7
+ it 'has a uuid primary key' do
8
+ SSTestUuid.columns_hash['id'].type.must_equal :uuid
9
+ assert SSTestUuid.primary_key
10
+ end
11
+
12
+ it 'can create with a new pk' do
13
+ obj = SSTestUuid.create!
14
+ obj.id.must_be :present?
15
+ obj.id.must_match acceptable_uuid
16
+ end
17
+
18
+ it 'can create other uuid column on reload' do
19
+ obj = SSTestUuid.create!
20
+ obj.reload
21
+ obj.other_uuid.must_match acceptable_uuid
22
+ end
23
+
24
+ it 'can find uuid pk via connection' do
25
+ connection.primary_key(SSTestUuid.table_name).must_equal 'id'
26
+ end
27
+
28
+ it 'changing column default' do
29
+ table_name = SSTestUuid.table_name
30
+ connection.add_column table_name, :thingy, :uuid, null: false, default: "NEWSEQUENTIALID()"
31
+ SSTestUuid.reset_column_information
32
+ column = SSTestUuid.columns_hash['thingy']
33
+ column.default_function.must_equal "newsequentialid()"
34
+ # Now to a different function.
35
+ connection.change_column table_name, :thingy, :uuid, null: false, default: "NEWID()"
36
+ SSTestUuid.reset_column_information
37
+ column = SSTestUuid.columns_hash['thingy']
38
+ column.default_function.must_equal "newid()"
39
+ end
40
+
41
+ end
data/test/config.yml ADDED
@@ -0,0 +1,35 @@
1
+ default_connection: dblib
2
+
3
+ default_connection_info: &default_connection_info
4
+ adapter: sqlserver
5
+ mode: <%= ENV['ARCONN'] || 'dblib' %>
6
+ host: <%= ENV['ACTIVERECORD_UNITTEST_HOST'] || 'localhost' %>
7
+ port: <%= ENV['ACTIVERECORD_UNITTEST_PORT'] %>
8
+ database: activerecord_unittest
9
+ username: <%= ENV['ACTIVERECORD_UNITTEST_USER'] || 'rails' %>
10
+ password: <%= ENV['ACTIVERECORD_UNITTEST_PASS'] || '' %>
11
+ azure: <%= !ENV['ACTIVERECORD_UNITTEST_AZURE'].nil? %>
12
+ collation: <%= ENV['ACTIVERECORD_UNITTEST_COLLATION'] || nil %>
13
+
14
+ connections:
15
+
16
+ dblib:
17
+ arunit:
18
+ <<: *default_connection_info
19
+ appname: SQLServerAdptrUnit
20
+ dataserver: <%= ENV['ACTIVERECORD_UNITTEST_DATASERVER'] %>
21
+ arunit2:
22
+ <<: *default_connection_info
23
+ database: activerecord_unittest2
24
+ appname: SQLServerAdptrUnit2
25
+ dataserver: <%= ENV['ACTIVERECORD_UNITTEST_DATASERVER'] %>
26
+
27
+ odbc:
28
+ arunit:
29
+ <<: *default_connection_info
30
+ dsn: <%= ENV['ACTIVERECORD_UNITTEST_DSN'] || 'activerecord_unittest' %>
31
+ arunit2:
32
+ <<: *default_connection_info
33
+ database: activerecord_unittest2
34
+ dsn: <%= ENV['ACTIVERECORD_UNITTEST2_DSN'] || 'activerecord_unittest2' %>
35
+
Binary file
@@ -0,0 +1,11 @@
1
+ class TableWillNeverBeCreated < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ create_table(:sqlserver_trans_table1) { }
5
+ create_table(:sqlserver_trans_table2) { raise ActiveRecord::StatementInvalid }
6
+ end
7
+
8
+ def self.down
9
+ end
10
+
11
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestCustomersView < ActiveRecord::Base
2
+ self.table_name = 'sst_customers_view'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestDatatype < ActiveRecord::Base
2
+ self.table_name = :sst_datatypes
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestDatatypeMigration < ActiveRecord::Base
2
+ self.table_name = :sst_datatypes_migration
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestDollarTableName < ActiveRecord::Base
2
+ self.table_name = 'sst_my$strange_table'
3
+ end
@@ -0,0 +1,13 @@
1
+ class SSTestEdgeSchema < ActiveRecord::Base
2
+
3
+ self.table_name = 'sst_edge_schemas'
4
+
5
+ def with_spaces
6
+ read_attribute :'with spaces'
7
+ end
8
+
9
+ def with_spaces=(value)
10
+ write_attribute :'with spaces', value
11
+ end
12
+
13
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestHasFk < ActiveRecord::Base
2
+ self.table_name = 'sst_has_fks'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestHasPk < ActiveRecord::Base
2
+ self.table_name = 'sst_has_pks'
3
+ end
@@ -0,0 +1,4 @@
1
+ class SSTestNaturalPkData < ActiveRecord::Base
2
+ self.table_name = 'sst_natural_pk_data'
3
+ self.primary_key = 'legacy_id'
4
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestNaturalPkIntData < ActiveRecord::Base
2
+ self.table_name = 'sst_natural_pk_int_data'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestNoPkData < ActiveRecord::Base
2
+ self.table_name = 'sst_no_pk_data'
3
+ end
@@ -0,0 +1,7 @@
1
+ class SSTestQuotedTable < ActiveRecord::Base
2
+ self.table_name = '[sst_quoted-table]'
3
+ end
4
+
5
+ class SSTestQuotedTableUser < ActiveRecord::Base
6
+ self.table_name = '[dbo].[sst_quoted-table]'
7
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestQuotedView1 < ActiveRecord::Base
2
+ self.table_name = 'sst_quoted-view1'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestQuotedView2 < ActiveRecord::Base
2
+ self.table_name = 'sst_quoted-view2'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestStringDefault < ActiveRecord::Base
2
+ self.table_name = 'sst_string_defaults'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestStringDefaultsBigView < ActiveRecord::Base
2
+ self.table_name = 'sst_string_defaults_big_view'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestStringDefaultsView < ActiveRecord::Base
2
+ self.table_name = 'sst_string_defaults_view'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestTinyintPk < ActiveRecord::Base
2
+ self.table_name = 'sst_tinyint_pk'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestUpper < ActiveRecord::Base
2
+ self.table_name = 'sst_upper_tests'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestUppered < ActiveRecord::Base
2
+ self.table_name = 'SST_UPPER_TESTS'
3
+ end
@@ -0,0 +1,3 @@
1
+ class SSTestUuid < ActiveRecord::Base
2
+ self.table_name = 'sst_uuids'
3
+ end
@@ -0,0 +1,64 @@
1
+
2
+ IF EXISTS (
3
+ SELECT TABLE_NAME
4
+ FROM INFORMATION_SCHEMA.TABLES
5
+ WHERE TABLE_NAME = N'sst_datatypes'
6
+ ) DROP TABLE [sst_datatypes]
7
+
8
+ CREATE TABLE [sst_datatypes] (
9
+ -- Exact Numerics
10
+ [id] [int] NOT NULL IDENTITY(1,1) PRIMARY KEY,
11
+ [bigint] [bigint] NULL DEFAULT 42,
12
+ [int] [int] NULL DEFAULT 42,
13
+ [smallint] [smallint] NULL DEFAULT 42,
14
+ [tinyint] [tinyint] NULL DEFAULT 42,
15
+ [bit] [bit] NULL DEFAULT 1,
16
+ [decimal_9_2] [decimal](9, 2) NULL DEFAULT 12345.01,
17
+ [decimal_16_4] [decimal](16, 4) NULL DEFAULT 1234567.89,
18
+ [numeric_18_0] [numeric](18, 0) NULL DEFAULT 191,
19
+ [numeric_36_2] [numeric](36, 2) NULL DEFAULT 12345678901234567890.01,
20
+ [money] [money] NULL DEFAULT 4.20,
21
+ [smallmoney] [smallmoney] NULL DEFAULT 4.20,
22
+ -- Approximate Numerics
23
+ [float] [float] NULL DEFAULT 123.00000001,
24
+ [real] [real] NULL DEFAULT 123.45,
25
+ -- Date and Time
26
+ [date] [date] NULL DEFAULT '0001-01-01',
27
+ [datetime] [datetime] NULL DEFAULT '1753-01-01T00:00:00.000',
28
+ [smalldatetime] [smalldatetime] NULL DEFAULT '1901-01-01T15:45:00.000Z',
29
+ [time_2] [time](2) NULL,
30
+ [time_7] [time](7) NULL,
31
+ -- Character Strings
32
+ [char_10] [char](10) NULL DEFAULT '1234567890',
33
+ [varchar_50] [varchar](50) NULL DEFAULT 'test varchar_50',
34
+ [varchar_max] [varchar](max) NULL DEFAULT 'test varchar_max',
35
+ [text] [text] NULL DEFAULT 'test text',
36
+ -- Unicode Character Strings
37
+ [nchar_10] [nchar](10) NULL DEFAULT N'12345678åå',
38
+ [nvarchar_50] [nvarchar](50) NULL DEFAULT N'test nvarchar_50 åå',
39
+ [nvarchar_max] [nvarchar](max) NULL DEFAULT N'test nvarchar_max åå',
40
+ [ntext] [ntext] NULL DEFAULT N'test ntext åå',
41
+ -- Binary Strings
42
+ [binary_49] [binary](49) NULL,
43
+ [varbinary_49] [varbinary](49) NULL,
44
+ [varbinary_max] [varbinary](max) NULL,
45
+ -- Other Data Types
46
+ [uniqueidentifier] [uniqueidentifier] NULL DEFAULT NEWID(),
47
+ [timestamp] [timestamp] NULL,
48
+ ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
49
+
50
+ -- Date and Time (TODO)
51
+ -- --------------------
52
+ -- [datetime2_7] [datetime2](7) NULL,
53
+ -- [datetimeoffset_2] [datetimeoffset](2) NULL,
54
+ -- [datetimeoffset_7] [datetimeoffset](7) NULL,
55
+ --
56
+ -- INSERT INTO [sst_datatypes] ([id], [datetime2_7]) VALUES ( 71, '0001-01-01T00:00:00.0000000Z' )
57
+ -- INSERT INTO [sst_datatypes] ([id], [datetime2_7]) VALUES ( 72, '1984-01-24T04:20:00.0000000-08:00' )
58
+ -- INSERT INTO [sst_datatypes] ([id], [datetime2_7]) VALUES ( 73, '9999-12-31T23:59:59.9999999Z' )
59
+ -- INSERT INTO [sst_datatypes] ([id], [datetimeoffset_2]) VALUES ( 81, '1984-01-24T04:20:00.0000000-08:00' ) -- 1984-01-24 04:20:00.00 -08:00
60
+ -- INSERT INTO [sst_datatypes] ([id], [datetimeoffset_2]) VALUES ( 82, '1984-01-24T04:20:00.0000000Z' ) -- 1984-01-24 04:20:00.00 +00:00
61
+ -- INSERT INTO [sst_datatypes] ([id], [datetimeoffset_2]) VALUES ( 83, '9999-12-31T23:59:59.9999999Z' ) -- 9999-12-31 23:59:59.99 +00:00
62
+ -- INSERT INTO [sst_datatypes] ([id], [datetimeoffset_7]) VALUES ( 84, '1984-01-24T04:20:00.0000000-08:00' ) -- 1984-01-24 04:20:00.0000000 -08:00
63
+ -- INSERT INTO [sst_datatypes] ([id], [datetimeoffset_7]) VALUES ( 85, '1984-01-24T04:20:00.0000000Z' ) -- 1984-01-24 04:20:00.0000000 +00:00
64
+ -- INSERT INTO [sst_datatypes] ([id], [datetimeoffset_7]) VALUES ( 86, '9999-12-31T23:59:59.9999999Z' ) -- 9999-12-31 23:59:59.9999999 +00:00
@@ -0,0 +1,181 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ # Exhaustive Data Types
4
+
5
+ execute File.read(ARTest::SQLServer.schema_datatypes_2012_file)
6
+
7
+ create_table :sst_datatypes_migration, force: true do |t|
8
+ # Simple Rails conventions.
9
+ t.integer :integer_col
10
+ t.bigint :bigint_col
11
+ t.boolean :boolean_col
12
+ t.decimal :decimal_col
13
+ t.float :float_col
14
+ t.string :string_col
15
+ t.text :text_col
16
+ t.datetime :datetime_col
17
+ t.timestamp :timestamp_col
18
+ t.time :time_col
19
+ t.date :date_col
20
+ t.binary :binary_col
21
+ # Our type methods.
22
+ t.real :real_col
23
+ t.money :money_col
24
+ t.smallmoney :smallmoney_col
25
+ t.char :char_col
26
+ t.varchar :varchar_col
27
+ t.text_basic :text_basic_col
28
+ t.nchar :nchar_col
29
+ t.ntext :ntext_col
30
+ t.binary_basic :binary_basic_col
31
+ t.varbinary :varbinary_col
32
+ t.uuid :uuid_col
33
+ t.ss_timestamp :sstimestamp_col
34
+ end
35
+
36
+ # Edge Cases
37
+
38
+ create_table 'sst_uuids', force: true, id: :uuid do |t|
39
+ t.string :name
40
+ t.uuid :other_uuid, default: 'NEWID()'
41
+ t.uuid :uuid_nil_default, default: nil
42
+ end
43
+
44
+ create_table 'sst_my$strange_table', force: true do |t|
45
+ t.string :name
46
+ end
47
+
48
+ create_table :SST_UPPER_TESTS, force: true do |t|
49
+ t.column :COLUMN1, :string
50
+ t.column :COLUMN2, :integer
51
+ end
52
+
53
+ create_table :sst_no_pk_data, force: true, id: false do |t|
54
+ t.string :name
55
+ end
56
+
57
+ create_table 'sst_quoted-table', force: true do |t|
58
+ end
59
+ execute "IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'sst_quoted-view1') DROP VIEW [sst_quoted-view1]"
60
+ execute "CREATE VIEW [sst_quoted-view1] AS SELECT * FROM [sst_quoted-table]"
61
+ execute "IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'sst_quoted-view2') DROP VIEW [sst_quoted-view2]"
62
+ execute "CREATE VIEW [sst_quoted-view2] AS \n /*#{'x'*4000}}*/ \n SELECT * FROM [sst_quoted-table]"
63
+
64
+ create_table :sst_string_defaults, force: true do |t|
65
+ t.column :string_with_null_default, :string, default: nil
66
+ t.column :string_with_pretend_null_one, :string, default: 'null'
67
+ t.column :string_with_pretend_null_two, :string, default: '(null)'
68
+ t.column :string_with_pretend_null_three, :string, default: 'NULL'
69
+ t.column :string_with_pretend_null_four, :string, default: '(NULL)'
70
+ t.column :string_with_pretend_paren_three, :string, default: '(3)'
71
+ t.column :string_with_multiline_default, :string, default: "Some long default with a\nnew line."
72
+ end
73
+
74
+ create_table :sst_edge_schemas, force: true do |t|
75
+ t.string :description
76
+ t.column 'crazy]]quote', :string
77
+ t.column 'with spaces', :string
78
+ end
79
+
80
+ execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_natural_pk_data') DROP TABLE sst_natural_pk_data"
81
+ execute <<-NATURALPKTABLESQL
82
+ CREATE TABLE sst_natural_pk_data(
83
+ parent_id int,
84
+ name nvarchar(255),
85
+ description nvarchar(1000),
86
+ legacy_id nvarchar(10) NOT NULL PRIMARY KEY
87
+ )
88
+ NATURALPKTABLESQL
89
+
90
+ execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_natural_pk_int_data') DROP TABLE sst_natural_pk_int_data"
91
+ execute <<-NATURALPKINTTABLESQL
92
+ CREATE TABLE sst_natural_pk_int_data(
93
+ legacy_id int NOT NULL PRIMARY KEY,
94
+ parent_id int,
95
+ name nvarchar(255),
96
+ description nvarchar(1000)
97
+ )
98
+ NATURALPKINTTABLESQL
99
+
100
+ execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_tinyint_pk') DROP TABLE sst_tinyint_pk"
101
+ execute <<-TINYITPKTABLE
102
+ CREATE TABLE sst_tinyint_pk(
103
+ id tinyint IDENTITY NOT NULL PRIMARY KEY,
104
+ name nvarchar(255)
105
+ )
106
+ TINYITPKTABLE
107
+
108
+ # Constraints
109
+
110
+ create_table(:sst_has_fks, force: true) { |t| t.column(:fk_id, :integer, null: false) }
111
+ create_table(:sst_has_pks, force: true) { }
112
+ execute <<-ADDFKSQL
113
+ ALTER TABLE sst_has_fks
114
+ ADD CONSTRAINT FK__sst_has_fks_id
115
+ FOREIGN KEY ([fk_id])
116
+ REFERENCES [sst_has_pks] ([id])
117
+ ADDFKSQL
118
+
119
+ # Views
120
+
121
+ execute "IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'sst_customers_view') DROP VIEW sst_customers_view"
122
+ execute <<-CUSTOMERSVIEW
123
+ CREATE VIEW sst_customers_view AS
124
+ SELECT id, name, balance
125
+ FROM customers
126
+ CUSTOMERSVIEW
127
+
128
+ execute "IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'sst_string_defaults_view') DROP VIEW sst_string_defaults_view"
129
+ execute <<-STRINGDEFAULTSVIEW
130
+ CREATE VIEW sst_string_defaults_view AS
131
+ SELECT id, string_with_pretend_null_one as pretend_null
132
+ FROM sst_string_defaults
133
+ STRINGDEFAULTSVIEW
134
+
135
+ execute "IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'sst_string_defaults_big_view') DROP VIEW sst_string_defaults_big_view"
136
+ execute <<-STRINGDEFAULTSBIGVIEW
137
+ CREATE VIEW sst_string_defaults_big_view AS
138
+ SELECT id, string_with_pretend_null_one as pretend_null
139
+ /*#{'x'*4000}}*/
140
+ FROM sst_string_defaults
141
+ STRINGDEFAULTSBIGVIEW
142
+
143
+ # Another schema.
144
+
145
+ create_table :sst_schema_columns, force: true do |t|
146
+ t.column :field1 , :integer
147
+ end
148
+
149
+ execute "IF NOT EXISTS(SELECT * FROM sys.schemas WHERE name = 'test') EXEC sp_executesql N'CREATE SCHEMA test'"
150
+ execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_schema_columns' and TABLE_SCHEMA = 'test') DROP TABLE test.sst_schema_columns"
151
+ execute <<-SIMILIARTABLEINOTHERSCHEMA
152
+ CREATE TABLE test.sst_schema_columns(
153
+ id int IDENTITY NOT NULL primary key,
154
+ filed_1 int,
155
+ field_2 int,
156
+ name varchar(255),
157
+ description varchar(1000),
158
+ n_name nvarchar(255),
159
+ n_description nvarchar(1000)
160
+ )
161
+ SIMILIARTABLEINOTHERSCHEMA
162
+
163
+ execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_schema_identity' and TABLE_SCHEMA = 'test') DROP TABLE test.sst_schema_identity"
164
+ execute <<-SIMILIARTABLEINOTHERSCHEMA
165
+ CREATE TABLE test.sst_schema_identity(
166
+ id int IDENTITY NOT NULL primary key,
167
+ filed_1 int
168
+ )
169
+ SIMILIARTABLEINOTHERSCHEMA
170
+
171
+ execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_schema_natural_id' and TABLE_SCHEMA = 'test') DROP TABLE test.sst_schema_natural_id"
172
+ execute <<-NATURALPKTABLESQLINOTHERSCHEMA
173
+ CREATE TABLE test.sst_schema_natural_id(
174
+ parent_id int,
175
+ name nvarchar(255),
176
+ description nvarchar(1000),
177
+ legacy_id nvarchar(10) NOT NULL PRIMARY KEY,
178
+ )
179
+ NATURALPKTABLESQLINOTHERSCHEMA
180
+
181
+ end