activerecord-sqlserver-adapter 4.1.8 → 4.2.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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