activerecord-sqlserver-adapter 5.0.8 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 604d2ce1e9d4b4cef171d452d9b3efa245c81a1d
4
- data.tar.gz: e2140ae987d61715d208c777e80c0cd906806aed
3
+ metadata.gz: 13700d5c59ccddfde7189f1bf0dfac4bbd276777
4
+ data.tar.gz: e9cafb310dfe9904c39dbf77ccc5bb86687f231a
5
5
  SHA512:
6
- metadata.gz: b35a88380f1e42ef73aecd645b0967216e1537536c3df627a85597ecf851e0171106cfa056d6cfdc7c3b41d8be72104f55ce2b998e09053d6f464c7566bc7a9c
7
- data.tar.gz: 3a82c5f018c28e58294766ad56777b023dda712fe0da2702b060351afa9935d8109c415605ae6a1efc08fc754554094c141894bbc61f783afa9d99586e15ab12
6
+ metadata.gz: 2cbb63f122e3ad2657532e7649c33728a0790f945043a12afdb078d171122970636a81dfa621485aa6a8abe7d30b9ab3892d2fef76fefd0a7ed6019fbda543dd
7
+ data.tar.gz: 220bc1f5a936151978885af18c38f7a25d7e684f0d7199c64d21d30922c4b33b8312e2a0db924f59d3040b0b147bbc6fa4dc564b5e1fbe6bb190daa522b322b4
@@ -0,0 +1,32 @@
1
+ # Backers
2
+
3
+ You can join in supporting TinyTDS and the Rails SQL Server Adapter development by [pledging on Patreon](https://www.patreon.com/metaskills)! Backers in the same pledge level appear in the order of pledge date.
4
+
5
+ ### $2000
6
+
7
+ [It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611218)
8
+
9
+
10
+ ### $500
11
+
12
+ [It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611209)
13
+
14
+
15
+ ### $250
16
+
17
+ [It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611199)
18
+
19
+
20
+ ### $100
21
+
22
+ [It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611196)
23
+
24
+
25
+ ### $50+
26
+
27
+ [It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611186)
28
+
29
+
30
+ ### $10+
31
+
32
+ [It could be you!](https://www.patreon.com/bePatron?c=765225&rid=1611149)
@@ -1,120 +1,12 @@
1
- ## v5.0.8
2
-
3
- * Memorized SQL Server Version to prevent a flood of SELECT @@version queries. Fixes #632
4
-
5
- ## v5.0.7
6
-
7
- * Add `WITH NO_INFOMSGS` to `user_options` method. Fixes #580
8
-
9
-
10
- ## v5.0.6
11
-
12
- #### Fixed
13
-
14
- * Performance w/inserts. Check binds & use schema cache for id inserts.
15
- Fixes #572. Thanks @noelr.
16
- * Add smalldatetime type for migrations. Fixes #507
17
-
18
- #### Changed
19
-
20
- * Misc index enhancements or testing. Fixes #570
21
- Enable `supports_index_sort_order?`, test `supports_partial_index?`, test how expression indexes work.
22
-
23
- #### Added
24
-
25
- * New `primary_key_nonclustered` type for easy In-Memory table creation.
26
- * Examples for an In-Memory table.
27
-
28
- ```ruby
29
- create_table :in_memory_table, id: false,
30
- options: 'WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA)' do |t|
31
- t.primary_key_nonclustered :id
32
- t.string :name
33
- t.timestamps
34
- end
35
- ```
36
-
37
- * Enable supports_json? Fixes #577.
38
-
39
- ```ruby
40
- create_table :users do |t|
41
- t.string :name, :email
42
- t.json :data # Creates a nvarchar(max) column.
43
- end
44
-
45
- class Users < ActiveRecord::Base
46
- attribute :data, ActiveRecord::Type::SQLServer::Json.new
47
- end
48
-
49
- User.create! name: 'Ken Collins', data: { 'admin' => true, 'foo' => 'bar' }
50
-
51
- admin = User.where("JSON_VALUE(data, '$.admin') = CAST(1 AS BIT)").first
52
- admin.data['foo'] # => "bar"
53
- ```
54
-
55
-
56
- ## v5.0.5
57
-
58
- #### Changed
59
-
60
- * Add TinyTDS as a runtime dependency.
61
-
62
-
63
- ## v5.0.4
1
+ ## v5.1.0
64
2
 
65
3
  #### Fixed
66
4
 
67
- * Allow `datetimeoffset` to be used in migrations and represented in schema.
68
- * Using transactions and resetting isolation level correctly when `READ_COMMITTED_SNAPSHOT` is set to `ON` Fixes #520
69
-
70
-
71
- ## v5.0.3
72
-
73
- #### Changed
74
-
75
- * Reduce view information reflection to per table vs. column. Fixes #552
76
- * The `user_options` parsing. Works for hash/array. Fixes #535
77
- * Pass the `:contained` option to TinyTDS. Fixes #527
78
-
79
-
80
- ## v5.0.2
81
-
82
- #### Fixed
83
-
84
- * Filter table constraints with matching table schema to column. Fixes #478
85
-
86
-
87
- ## v5.0.1
88
-
89
5
  #### Changed
90
6
 
91
- * Set `tds_version` fallback to `7.3`.
92
-
93
- #### Fixed
94
-
95
- * Support 2014, 2012 drop table statement.
96
-
97
-
98
- ## v5.0.0
7
+ * The `drop_table` with force cascade option now mimics in via pure SQL for us.
99
8
 
100
9
  #### Added
101
10
 
102
- * Support for `supports_datetime_with_precision`.
103
- * Support for `unprepared_statement` blocks on the connection.
104
-
105
- #### Changed
106
-
107
- * Major refactoring of all type objects. Especially time types.
108
-
109
- #### Deprecated
110
-
111
- * Support for a handful of standard Rails deprecations in 5-0-stable suite.
112
-
113
- #### Removed
114
-
115
- * ODBC connection mode. Not been maintained since Rails 4.0.
116
- * View table name detection in `with_identity_insert_enabled` method for fixtures. Perf hit.
117
-
118
- #### Fixed
11
+ * Support MismatchedForeignKey exception.
119
12
 
120
- * Do not output column collation in schema when same as database.
@@ -2,4 +2,24 @@
2
2
  ## Rails v5.1
3
3
 
4
4
  * BIGINT PK support. https://github.com/rails/rails/pull/26266
5
-
5
+ * Raise `ActiveRecord::NotNullViolation` when a record cannot be inserted
6
+ or updated because it would violate a not null constraint.
7
+ * Raise `ActiveRecord::RangeError` when values that executed are out of range.
8
+ * Allow passing extra flags to `db:structure:load` and `db:structure:dump`
9
+ Introduces `ActiveRecord::Tasks::DatabaseTasks.structure_(load|dump)_flags` to customize the
10
+ eventual commands run against the database, e.g. mysqldump/pg_dump.
11
+ * Set `:time` as a timezone aware type and remove deprecation when
12
+ `config.active_record.time_zone_aware_types` is not explicitly set.
13
+ * Remove deprecated support to passing a column to `#quote`.
14
+ * `#tables` and `#table_exists?` return only tables and not views.
15
+ All the deprecations on those methods were removed.
16
+ * Remove deprecated `original_exception` argument in `ActiveRecord::StatementInvalid#initialize`
17
+ and `ActiveRecord::StatementInvalid#original_exception`.
18
+ * Remove deprecated tasks: `db:test:clone`, `db:test:clone_schema`, `db:test:clone_structure`.
19
+ * Make `table_name=` reset current statement cache,
20
+ so queries are not run against the previous table name.
21
+ * Deprecate using `#quoted_id` in quoting.
22
+ * Deprecate `supports_migrations?` on connection adapters.
23
+ * Dig moving `Column#sqlserver_options` to `sql_type_metadata` delegate.
24
+ * Should we do like PG and add `options[:collation]` before `#add_column_options!`?
25
+ * Translated exceptions: `SerializationFailure` and `RangeError`.
data/README.md CHANGED
@@ -1,5 +1,3 @@
1
- [![Support via Gratipay](https://cdn.rawgit.com/gratipay/gratipay-badge/2.3.0/dist/gratipay.svg)](https://gratipay.com/metaskills/)
2
-
3
1
  # ActiveRecord SQL Server Adapter. For SQL Server 2012 And Higher.
4
2
 
5
3
  * [![TravisCI](https://travis-ci.org/rails-sqlserver/activerecord-sqlserver-adapter.svg?branch=master)](https://travis-ci.org/rails-sqlserver/activerecord-sqlserver-adapter) - TravisCI
@@ -9,6 +7,12 @@
9
7
  * [![Dependency Status](https://dependencyci.com/github/rails-sqlserver/activerecord-sqlserver-adapter/badge)](https://dependencyci.com/github/rails-sqlserver/activerecord-sqlserver-adapter) - Dependency Status
10
8
  * [![Gitter chat](https://img.shields.io/badge/%E2%8A%AA%20GITTER%20-JOIN%20CHAT%20%E2%86%92-brightgreen.svg?style=flat)](https://gitter.im/rails-sqlserver/activerecord-sqlserver-adapter) - Community
11
9
 
10
+ ## Supporting TinyTDS/Adapter
11
+
12
+ Both TinyTDS and the Rails SQL Server Adapter are MIT-licensed open source projects. Its ongoing development is made possible thanks to the support by these awesome [backers](https://github.com/rails-sqlserver/tiny_tds/blob/master/BACKERS.md). If you'd like to join them, check out our [Patreon Campaign](https://www.patreon.com/metaskills).
13
+
14
+
15
+ ## About The Adapter
12
16
 
13
17
  The SQL Server adapter for ActiveRecord v5.0 using SQL Server 2012 or higher.
14
18
 
@@ -129,7 +133,7 @@ If you would like to contribute a feature or bugfix, thanks! To make sure your f
129
133
  Many many people have contributed. If you do not see your name here and it should be let us know. Also, many thanks go out to those that have pledged financial contributions.
130
134
 
131
135
 
132
- ## Contributers
136
+ ## Contributors
133
137
 
134
138
  Up-to-date list of contributors: http://github.com/rails-sqlserver/activerecord-sqlserver-adapter/contributors
135
139
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 5.0.8
1
+ 5.1.0
@@ -16,6 +16,6 @@ Gem::Specification.new do |spec|
16
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ['lib']
19
- spec.add_dependency 'activerecord', '~> 5.0.0'
19
+ spec.add_dependency 'activerecord', '~> 5.1.0'
20
20
  spec.add_dependency 'tiny_tds'
21
21
  end
@@ -3,10 +3,6 @@ module ActiveRecord
3
3
  module SQLServer
4
4
  module DatabaseStatements
5
5
 
6
- def select_rows(sql, name = nil, binds = [])
7
- sp_executesql sql, name, binds, fetch: :rows
8
- end
9
-
10
6
  def execute(sql, name = nil)
11
7
  if id_insert_table_name = query_requires_identity_insert?(sql)
12
8
  with_identity_insert_enabled(id_insert_table_name) { do_execute(sql, name) }
@@ -19,22 +15,22 @@ module ActiveRecord
19
15
  sp_executesql(sql, name, binds, prepare: prepare)
20
16
  end
21
17
 
22
- def exec_insert(sql, name, binds, pk = nil, _sequence_name = nil)
18
+ def exec_insert(sql, name = nil, binds = [], pk = nil, _sequence_name = nil)
23
19
  if id_insert_table_name = exec_insert_requires_identity?(sql, pk, binds)
24
- with_identity_insert_enabled(id_insert_table_name) { exec_query(sql, name, binds) }
20
+ with_identity_insert_enabled(id_insert_table_name) { super(sql, name, binds, pk) }
25
21
  else
26
- exec_query(sql, name, binds)
22
+ super(sql, name, binds, pk)
27
23
  end
28
24
  end
29
25
 
30
26
  def exec_delete(sql, name, binds)
31
- sql << '; SELECT @@ROWCOUNT AS AffectedRows'
32
- super.rows.first.first
27
+ sql = sql.dup << '; SELECT @@ROWCOUNT AS AffectedRows'
28
+ super(sql, name, binds).rows.first.first
33
29
  end
34
30
 
35
31
  def exec_update(sql, name, binds)
36
- sql << '; SELECT @@ROWCOUNT AS AffectedRows'
37
- super.rows.first.first
32
+ sql = sql.dup << '; SELECT @@ROWCOUNT AS AffectedRows'
33
+ super(sql, name, binds).rows.first.first
38
34
  end
39
35
 
40
36
  def supports_statement_cache?
@@ -80,7 +76,7 @@ module ActiveRecord
80
76
  end
81
77
 
82
78
  def case_sensitive_comparison(table, attribute, column, value)
83
- if value && value.acts_like?(:string)
79
+ if column.collation && !column.case_sensitive?
84
80
  table[attribute].eq(Arel::Nodes::Bin.new(Arel::Nodes::BindParam.new))
85
81
  else
86
82
  super
@@ -198,7 +194,7 @@ module ActiveRecord
198
194
  end
199
195
  sql = if pk && self.class.use_output_inserted && !database_prefix_remote_server?
200
196
  quoted_pk = SQLServer::Utils.extract_identifiers(pk).quoted
201
- sql.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk}"
197
+ sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk}"
202
198
  else
203
199
  "#{sql}; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"
204
200
  end
@@ -261,7 +257,7 @@ module ActiveRecord
261
257
  if name == 'EXPLAIN'
262
258
  params.each.with_index do |param, index|
263
259
  substitute_at_finder = /(@#{index})(?=(?:[^']|'[^']*')*$)/ # Finds unquoted @n values.
264
- sql.sub! substitute_at_finder, param.to_s
260
+ sql = sql.sub substitute_at_finder, param.to_s
265
261
  end
266
262
  else
267
263
  types = quote(types.join(', '))
@@ -16,6 +16,20 @@ module ActiveRecord
16
16
  end
17
17
  end
18
18
 
19
+ def add_column_options!(sql, options)
20
+ sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
21
+ if options[:null] == false
22
+ sql << " NOT NULL"
23
+ end
24
+ if options[:is_identity] == true
25
+ sql << " IDENTITY(1,1)"
26
+ end
27
+ if options[:primary_key] == true
28
+ sql << " PRIMARY KEY"
29
+ end
30
+ sql
31
+ end
32
+
19
33
  def action_sql(action, dependency)
20
34
  case dependency
21
35
  when :restrict
@@ -28,6 +42,14 @@ module ActiveRecord
28
42
  end
29
43
  end
30
44
 
45
+ def options_include_default?(options)
46
+ super || options_primary_key_with_nil_default?(options)
47
+ end
48
+
49
+ def options_primary_key_with_nil_default?(options)
50
+ options[:primary_key] && options.include?(:default) && options[:default].nil?
51
+ end
52
+
31
53
  end
32
54
  end
33
55
  end
@@ -3,13 +3,34 @@ module ActiveRecord
3
3
  module SQLServer
4
4
  module SchemaDumper
5
5
 
6
+ SQLSEVER_NO_LIMIT_TYPES = [
7
+ 'text',
8
+ 'ntext',
9
+ 'varchar(max)',
10
+ 'nvarchar(max)',
11
+ 'varbinary(max)'
12
+ ].freeze
13
+
6
14
  private
7
15
 
16
+ def explicit_primary_key_default?(column)
17
+ column.is_primary? && !column.is_identity?
18
+ end
19
+
20
+ def schema_limit(column)
21
+ return if SQLSEVER_NO_LIMIT_TYPES.include?(column.sql_type)
22
+ super
23
+ end
24
+
8
25
  def schema_collation(column)
9
26
  return unless column.collation
10
27
  column.collation if column.collation != collation
11
28
  end
12
29
 
30
+ def default_primary_key?(column)
31
+ super && column.is_primary? && column.is_identity?
32
+ end
33
+
13
34
  end
14
35
  end
15
36
  end
@@ -7,35 +7,6 @@ module ActiveRecord
7
7
  @native_database_types ||= initialize_native_database_types.freeze
8
8
  end
9
9
 
10
- def tables(name = nil)
11
- ActiveSupport::Deprecation.warn 'Passing arguments to #tables is deprecated without replacement.' if name
12
- tables_sql('BASE TABLE')
13
- end
14
-
15
- def table_exists?(table_name)
16
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
17
- #table_exists? currently checks both tables and views.
18
- This behavior is deprecated and will be changed with Rails 5.1 to only check tables.
19
- Use #data_source_exists? instead.
20
- MSG
21
- data_source_exists?(table_name)
22
- end
23
-
24
- def data_source_exists?(table_name)
25
- return false if table_name.blank?
26
- unquoted_table_name = SQLServer::Utils.extract_identifiers(table_name).object
27
- super(unquoted_table_name)
28
- end
29
-
30
- def views
31
- tables_sql('VIEW')
32
- end
33
-
34
- def view_exists?(table_name)
35
- identifier = SQLServer::Utils.extract_identifiers(table_name)
36
- super(identifier.object)
37
- end
38
-
39
10
  def create_table(table_name, comment: nil, **options)
40
11
  res = super
41
12
  clear_cache!
@@ -43,6 +14,17 @@ module ActiveRecord
43
14
  end
44
15
 
45
16
  def drop_table(table_name, options = {})
17
+ # Mimic CASCADE option as best we can.
18
+ if options[:force] == :cascade
19
+ execute_procedure(:sp_fkeys, pktable_name: table_name).each do |fkdata|
20
+ fktable = fkdata['FKTABLE_NAME']
21
+ fkcolmn = fkdata['FKCOLUMN_NAME']
22
+ pktable = fkdata['PKTABLE_NAME']
23
+ pkcolmn = fkdata['PKCOLUMN_NAME']
24
+ remove_foreign_key fktable, name: fkdata['FK_NAME']
25
+ do_execute "DELETE FROM #{quote_table_name(fktable)} WHERE #{quote_column_name(fkcolmn)} IN ( SELECT #{quote_column_name(pkcolmn)} FROM #{quote_table_name(pktable)} )"
26
+ end
27
+ end
46
28
  if options[:if_exists] && @version_year != 2016
47
29
  execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = #{quote(table_name)}) DROP TABLE #{quote_table_name(table_name)}"
48
30
  else
@@ -103,10 +85,34 @@ module ActiveRecord
103
85
  end
104
86
 
105
87
  def primary_keys(table_name)
106
- primaries = schema_cache.columns(table_name).select(&:is_primary?).map(&:name)
88
+ primaries = primary_keys_select(table_name)
107
89
  primaries.present? ? primaries : identity_columns(table_name).map(&:name)
108
90
  end
109
91
 
92
+ def primary_keys_select(table_name)
93
+ identifier = database_prefix_identifier(table_name)
94
+ database = identifier.fully_qualified_database_quoted
95
+ sql = %{
96
+ SELECT KCU.COLUMN_NAME AS [name]
97
+ FROM #{database}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
98
+ LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
99
+ ON KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
100
+ AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
101
+ AND KCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG
102
+ AND KCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA
103
+ AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
104
+ WHERE KCU.TABLE_NAME = #{prepared_statements ? '@0' : quote(identifier.object)}
105
+ AND KCU.TABLE_SCHEMA = #{identifier.schema.blank? ? 'schema_name()' : (prepared_statements ? '@1' : quote(identifier.schema))}
106
+ AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
107
+ ORDER BY KCU.ORDINAL_POSITION ASC
108
+ }.gsub(/[[:space:]]/, ' ')
109
+ binds = []
110
+ nv128 = SQLServer::Type::UnicodeVarchar.new limit: 128
111
+ binds << Relation::QueryAttribute.new('TABLE_NAME', identifier.object, nv128)
112
+ binds << Relation::QueryAttribute.new('TABLE_SCHEMA', identifier.schema, nv128) unless identifier.schema.blank?
113
+ sp_executesql(sql, 'SCHEMA', binds).map { |r| r['name'] }
114
+ end
115
+
110
116
  def rename_table(table_name, new_name)
111
117
  do_execute "EXEC sp_rename '#{table_name}', '#{new_name}'"
112
118
  rename_table_indexes(table_name, new_name)
@@ -130,9 +136,11 @@ module ActiveRecord
130
136
  remove_indexes(table_name, column_name)
131
137
  end
132
138
  sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_expression(options[:default], column_object)} WHERE #{quote_column_name(column_name)} IS NULL" if !options[:null].nil? && options[:null] == false && !options[:default].nil?
133
- sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
134
- sql_commands[-1] << ' NOT NULL' if !options[:null].nil? && options[:null] == false
135
- if options_include_default?(options)
139
+ sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}"
140
+ sql_commands.last << ' NOT NULL' if !options[:null].nil? && options[:null] == false
141
+ if options.key?(:default) && default_constraint_name(table_name, column_name).present?
142
+ change_column_default(table_name, column_name, options[:default])
143
+ elsif options_include_default?(options)
136
144
  sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{quote_default_expression(options[:default], column_object)} FOR #{quote_column_name(column_name)}"
137
145
  end
138
146
  # Add any removed indexes back
@@ -140,6 +148,7 @@ module ActiveRecord
140
148
  sql_commands << "CREATE INDEX #{quote_table_name(index.name)} ON #{quote_table_name(table_name)} (#{index.columns.map { |c| quote_column_name(c) }.join(', ')})"
141
149
  end
142
150
  sql_commands.each { |c| do_execute(c) }
151
+ clear_cache!
143
152
  end
144
153
 
145
154
  def change_column_default(table_name, column_name, default_or_changes)
@@ -194,7 +203,7 @@ module ActiveRecord
194
203
  end
195
204
  end
196
205
 
197
- def type_to_sql(type, limit = nil, precision = nil, scale = nil)
206
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
198
207
  type_limitable = %w(string integer float char nchar varchar nvarchar).include?(type.to_s)
199
208
  limit = nil unless type_limitable
200
209
  case type.to_s
@@ -240,19 +249,40 @@ module ActiveRecord
240
249
  if !allow_null.nil? && allow_null == false && !default.nil?
241
250
  do_execute("UPDATE #{table_id} SET #{column_id}=#{quote(default)} WHERE #{column_id} IS NULL")
242
251
  end
243
- sql = "ALTER TABLE #{table_id} ALTER COLUMN #{column_id} #{type_to_sql column.type, column.limit, column.precision, column.scale}"
252
+ sql = "ALTER TABLE #{table_id} ALTER COLUMN #{column_id} #{type_to_sql column.type, limit: column.limit, precision: column.precision, scale: column.scale}"
244
253
  sql << ' NOT NULL' if !allow_null.nil? && allow_null == false
245
254
  do_execute sql
246
255
  end
247
256
 
257
+ private
248
258
 
249
- protected
259
+ def data_source_sql(name = nil, type: nil)
260
+ scope = quoted_scope name, type: type
261
+ table_name = lowercase_schema_reflection_sql 'TABLE_NAME'
262
+ sql = "SELECT #{table_name}"
263
+ sql << ' FROM INFORMATION_SCHEMA.TABLES'
264
+ sql << ' WHERE TABLE_CATALOG = DB_NAME()'
265
+ sql << " AND TABLE_SCHEMA = #{quote(scope[:schema])}"
266
+ sql << " AND TABLE_NAME = #{quote(scope[:name])}" if scope[:name]
267
+ sql << " AND TABLE_TYPE = #{quote(scope[:type])}" if scope[:type]
268
+ sql << " ORDER BY #{table_name}"
269
+ sql
270
+ end
271
+
272
+ def quoted_scope(name = nil, type: nil)
273
+ identifier = SQLServer::Utils.extract_identifiers(name)
274
+ {}.tap do |scope|
275
+ scope[:schema] = identifier.schema || 'dbo'
276
+ scope[:name] = identifier.object if identifier.object
277
+ scope[:type] = type if type
278
+ end
279
+ end
250
280
 
251
281
  # === SQLServer Specific ======================================== #
252
282
 
253
283
  def initialize_native_database_types
254
284
  {
255
- primary_key: 'int NOT NULL IDENTITY(1,1) PRIMARY KEY',
285
+ primary_key: 'bigint NOT NULL IDENTITY(1,1) PRIMARY KEY',
256
286
  primary_key_nonclustered: 'int NOT NULL IDENTITY(1,1) PRIMARY KEY NONCLUSTERED',
257
287
  integer: { name: 'int', limit: 4 },
258
288
  bigint: { name: 'bigint' },
@@ -286,18 +316,8 @@ module ActiveRecord
286
316
  }
287
317
  end
288
318
 
289
- def tables_sql(type)
290
- tn = lowercase_schema_reflection_sql 'TABLE_NAME'
291
- sql = "SELECT #{tn} FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = '#{type}' ORDER BY TABLE_NAME"
292
- select_values sql, 'SCHEMA'
293
- end
294
-
295
319
  def column_definitions(table_name)
296
- identifier = if database_prefix_remote_server?
297
- SQLServer::Utils.extract_identifiers("#{database_prefix}#{table_name}")
298
- else
299
- SQLServer::Utils.extract_identifiers(table_name)
300
- end
320
+ identifier = database_prefix_identifier(table_name)
301
321
  database = identifier.fully_qualified_database_quoted
302
322
  view_exists = view_exists?(table_name)
303
323
  view_tblnm = view_table_name(table_name) if view_exists
@@ -475,7 +495,7 @@ module ActiveRecord
475
495
  @view_information ||= {}
476
496
  @view_information[table_name] ||= begin
477
497
  identifier = SQLServer::Utils.extract_identifiers(table_name)
478
- view_info = select_one "SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = '#{identifier.object}'", 'SCHEMA'
498
+ view_info = select_one "SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = #{quote(identifier.object)}", 'SCHEMA'
479
499
  if view_info
480
500
  view_info = view_info.with_indifferent_access
481
501
  if view_info[:VIEW_DEFINITION].blank? || view_info[:VIEW_DEFINITION].length == 4000
@@ -498,8 +518,6 @@ module ActiveRecord
498
518
  match_data ? match_data[1] : column_name
499
519
  end
500
520
 
501
- private
502
-
503
521
  def create_table_definition(*args)
504
522
  SQLServer::TableDefinition.new(*args)
505
523
  end
@@ -5,10 +5,13 @@ module ActiveRecord
5
5
  module ColumnMethods
6
6
 
7
7
  def primary_key(name, type = :primary_key, **options)
8
- return super unless type == :uuid
9
- options[:default] = options.fetch(:default, 'NEWID()')
10
- options[:primary_key] = true
11
- column name, type, options
8
+ if [:integer, :bigint].include?(type)
9
+ options[:is_identity] = true unless options.key?(:default)
10
+ elsif type == :uuid
11
+ options[:default] = options.fetch(:default, 'NEWID()')
12
+ options[:primary_key] = true
13
+ end
14
+ super
12
15
  end
13
16
 
14
17
  def primary_key_nonclustered(*args, **options)
@@ -98,9 +101,14 @@ module ActiveRecord
98
101
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
99
102
  include ColumnMethods
100
103
 
101
- def new_column_definition(name, type, options)
102
- type = :datetime2 if type == :datetime && options[:precision]
103
- super name, type, options
104
+ def new_column_definition(name, type, **options)
105
+ case type
106
+ when :datetime
107
+ type = :datetime2 if options[:precision]
108
+ when :primary_key
109
+ options[:is_identity] = true
110
+ end
111
+ super
104
112
  end
105
113
  end
106
114
 
@@ -4,10 +4,6 @@ module ActiveRecord
4
4
  module Type
5
5
  class BigInteger < Integer
6
6
 
7
- def type
8
- :bigint
9
- end
10
-
11
7
  def sqlserver_type
12
8
  'bigint'.freeze
13
9
  end
@@ -23,6 +23,11 @@ module ActiveRecord
23
23
  @value.inspect
24
24
  end
25
25
 
26
+ def eql?(other)
27
+ self.class == other.class && self.value == other.value
28
+ end
29
+ alias :== :eql?
30
+
26
31
  end
27
32
  end
28
33
  end
@@ -73,14 +73,6 @@ module ActiveRecord
73
73
  SQLServer::SchemaCreation.new self
74
74
  end
75
75
 
76
- def supports_migrations?
77
- true
78
- end
79
-
80
- def supports_primary_key?
81
- true
82
- end
83
-
84
76
  def supports_ddl_transactions?
85
77
  true
86
78
  end
@@ -147,10 +139,10 @@ module ActiveRecord
147
139
 
148
140
  def disable_referential_integrity
149
141
  tables = tables_with_referential_integrity
150
- tables.each { |t| do_execute "ALTER TABLE #{t} NOCHECK CONSTRAINT ALL" }
142
+ tables.each { |t| do_execute "ALTER TABLE #{quote_table_name(t)} NOCHECK CONSTRAINT ALL" }
151
143
  yield
152
144
  ensure
153
- tables.each { |t| do_execute "ALTER TABLE #{t} CHECK CONSTRAINT ALL" }
145
+ tables.each { |t| do_execute "ALTER TABLE #{quote_table_name(t)} CHECK CONSTRAINT ALL" }
154
146
  end
155
147
 
156
148
  # === Abstract Adapter (Connection Management) ================== #
@@ -230,6 +222,14 @@ module ActiveRecord
230
222
  @connection_options[:database_prefix]
231
223
  end
232
224
 
225
+ def database_prefix_identifier(name)
226
+ if database_prefix_remote_server?
227
+ SQLServer::Utils.extract_identifiers("#{database_prefix}#{name}")
228
+ else
229
+ SQLServer::Utils.extract_identifiers(name)
230
+ end
231
+ end
232
+
233
233
  def version
234
234
  self.class::VERSION
235
235
  end
@@ -327,6 +327,20 @@ module ActiveRecord
327
327
  NoDatabaseError.new(message)
328
328
  when /data would be truncated/
329
329
  ValueTooLong.new(message)
330
+ when /Column '(.*)' is not the same data type as referencing column '(.*)' in foreign key/
331
+ pk_id, fk_id = SQLServer::Utils.extract_identifiers($1), SQLServer::Utils.extract_identifiers($2)
332
+ MismatchedForeignKey.new(
333
+ self,
334
+ message: message,
335
+ table: fk_id.schema,
336
+ foreign_key: fk_id.object,
337
+ target_table: pk_id.schema,
338
+ primary_key: pk_id.object
339
+ )
340
+ when /Cannot insert the value NULL into column.*does not allow nulls/
341
+ NotNullViolation.new(message)
342
+ when /Arithmetic overflow error/
343
+ RangeError.new(message)
330
344
  else
331
345
  super
332
346
  end
@@ -418,14 +432,11 @@ module ActiveRecord
418
432
  end
419
433
 
420
434
  def version_year
421
- return @version_year if defined?(@version_year)
422
- @version_year = begin
423
- vstring = _raw_select('SELECT @@version', fetch: :rows).first.first.to_s
424
- return 2016 if vstring =~ /vNext/
425
- /SQL Server (\d+)/.match(vstring).to_a.last.to_s.to_i
426
- rescue Exception => e
427
- 2016
428
- end
435
+ vstring = _raw_select('SELECT @@version', fetch: :rows).first.first.to_s
436
+ return 2016 if vstring =~ /vNext/
437
+ /SQL Server (\d+)/.match(vstring).to_a.last.to_s.to_i
438
+ rescue Exception => e
439
+ 2016
429
440
  end
430
441
 
431
442
  end
@@ -48,7 +48,7 @@ module ActiveRecord
48
48
  create true
49
49
  end
50
50
 
51
- def structure_dump(filename)
51
+ def structure_dump(filename, extra_flags)
52
52
  command = [
53
53
  "defncopy",
54
54
  "-S #{Shellwords.escape(configuration['host'])}",
@@ -71,7 +71,7 @@ module ActiveRecord
71
71
  File.open(filename, "w") { |file| file.puts dump }
72
72
  end
73
73
 
74
- def structure_load(filename)
74
+ def structure_load(filename, extra_flags)
75
75
  connection.execute File.read(filename)
76
76
  end
77
77
 
@@ -190,7 +190,8 @@ module Arel
190
190
 
191
191
  def primary_Key_From_Table t
192
192
  return unless t
193
- column_name = schema_cache.primary_keys(t.name) || column_cache(t.name).first.try(:second).try(:name)
193
+ column_name = @connection.schema_cache.primary_keys(t.name) ||
194
+ @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
194
195
  column_name ? t[column_name] : nil
195
196
  end
196
197
 
@@ -37,10 +37,6 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
37
37
  assert_equal 'SQLServer', connection.adapter_name
38
38
  end
39
39
 
40
- it 'supports migrations' do
41
- assert connection.supports_migrations?
42
- end
43
-
44
40
  it 'support DDL in transactions' do
45
41
  assert connection.supports_ddl_transactions?
46
42
  end
@@ -265,23 +261,23 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
265
261
  end
266
262
 
267
263
  it 'create integers when limit is 4' do
268
- assert_equal 'integer', connection.type_to_sql(:integer, 4)
264
+ assert_equal 'integer', connection.type_to_sql(:integer, limit: 4)
269
265
  end
270
266
 
271
267
  it 'create integers when limit is 3' do
272
- assert_equal 'integer', connection.type_to_sql(:integer, 3)
268
+ assert_equal 'integer', connection.type_to_sql(:integer, limit: 3)
273
269
  end
274
270
 
275
271
  it 'create smallints when limit is less than 3' do
276
- assert_equal 'smallint', connection.type_to_sql(:integer, 2)
277
- assert_equal 'smallint', connection.type_to_sql(:integer, 1)
272
+ assert_equal 'smallint', connection.type_to_sql(:integer, limit: 2)
273
+ assert_equal 'smallint', connection.type_to_sql(:integer, limit: 1)
278
274
  end
279
275
 
280
276
  it 'create bigints when limit is greateer than 4' do
281
- assert_equal 'bigint', connection.type_to_sql(:integer, 5)
282
- assert_equal 'bigint', connection.type_to_sql(:integer, 6)
283
- assert_equal 'bigint', connection.type_to_sql(:integer, 7)
284
- assert_equal 'bigint', connection.type_to_sql(:integer, 8)
277
+ assert_equal 'bigint', connection.type_to_sql(:integer, limit: 5)
278
+ assert_equal 'bigint', connection.type_to_sql(:integer, limit: 6)
279
+ assert_equal 'bigint', connection.type_to_sql(:integer, limit: 7)
280
+ assert_equal 'bigint', connection.type_to_sql(:integer, limit: 8)
285
281
  end
286
282
 
287
283
  it 'create floats when no limit supplied' do
@@ -31,6 +31,9 @@ end
31
31
  require 'models/event'
32
32
  module ActiveRecord
33
33
  class AdapterTest < ActiveRecord::TestCase
34
+ # I really dont think we can support legacy binds.
35
+ coerce_tests! :test_select_all_with_legacy_binds
36
+
34
37
  # As far as I can tell, SQL Server does not support null bytes in strings.
35
38
  coerce_tests! :test_update_prepared_statement
36
39
 
@@ -52,14 +55,14 @@ end
52
55
 
53
56
  require 'models/topic'
54
57
  class AttributeMethodsTest < ActiveRecord::TestCase
55
- coerce_tests! :test_typecast_attribute_from_select_to_false
58
+ coerce_tests! %r{typecast attribute from select to false}
56
59
  def test_typecast_attribute_from_select_to_false_coerced
57
60
  Topic.create(:title => 'Budget')
58
61
  topic = Topic.all.merge!(:select => "topics.*, IIF (1 = 2, 1, 0) as is_test").first
59
62
  assert !topic.is_test?
60
63
  end
61
64
 
62
- coerce_tests! :test_typecast_attribute_from_select_to_true
65
+ coerce_tests! %r{typecast attribute from select to true}
63
66
  def test_typecast_attribute_from_select_to_true_coerced
64
67
  Topic.create(:title => 'Budget')
65
68
  topic = Topic.all.merge!(:select => "topics.*, IIF (1 = 1, 1, 0) as is_test").first
@@ -118,6 +121,15 @@ end
118
121
 
119
122
 
120
123
  class CalculationsTest < ActiveRecord::TestCase
124
+ # This fails randomly due to schema cache being lost?
125
+ coerce_tests! :test_offset_is_kept
126
+ def test_offset_is_kept_coerced
127
+ Account.first
128
+ queries = assert_sql { Account.offset(1).count }
129
+ assert_equal 1, queries.length
130
+ assert_match(/OFFSET/, queries.first)
131
+ end
132
+
121
133
  # Are decimal, not integer.
122
134
  coerce_tests! :test_should_return_decimal_average_of_integer_field
123
135
  def test_should_return_decimal_average_of_integer_field_coerced
@@ -161,6 +173,29 @@ end
161
173
 
162
174
 
163
175
 
176
+ module ActiveRecord
177
+ module ConnectionAdapters
178
+ class QuoteARBaseTest < ActiveRecord::TestCase
179
+
180
+ # Use our date format.
181
+ coerce_tests! :test_quote_ar_object
182
+ def test_quote_ar_object_coerced
183
+ value = DatetimePrimaryKey.new(id: @time)
184
+ assert_equal "'02-14-2017 12:34:56.79'", @connection.quote(value)
185
+ end
186
+
187
+ # Use our date format.
188
+ coerce_tests! :test_type_cast_ar_object
189
+ def test_type_cast_ar_object_coerced
190
+ value = DatetimePrimaryKey.new(id: @time)
191
+ assert_equal "02-14-2017 12:34:56.79", @connection.type_cast(value)
192
+ end
193
+
194
+ end
195
+ end
196
+ end
197
+
198
+
164
199
 
165
200
  module ActiveRecord
166
201
  class Migration
@@ -289,6 +324,10 @@ end
289
324
 
290
325
 
291
326
  module ActiveRecord
327
+ class DatabaseTasksDumpSchemaCacheTest < ActiveRecord::TestCase
328
+ # Skip this test with /tmp/my_schema_cache.yml path on Windows.
329
+ coerce_tests! :test_dump_schema_cache if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
330
+ end
292
331
  class DatabaseTasksCreateAllTest < ActiveRecord::TestCase
293
332
  # We extend `local_database?` so that common VM IPs can be used.
294
333
  coerce_tests! :test_ignores_remote_databases, :test_warning_for_remote_databases
@@ -375,12 +414,6 @@ class FinderTest < ActiveRecord::TestCase
375
414
  end
376
415
  end
377
416
 
378
- coerce_tests! :test_string_sanitation
379
- def test_string_sanitation_coerced
380
- assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
381
- assert_equal "N'something; select table'", ActiveRecord::Base.sanitize("something; select table")
382
- end
383
-
384
417
  coerce_tests! :test_take_and_first_and_last_with_integer_should_use_sql_limit
385
418
  def test_take_and_first_and_last_with_integer_should_use_sql_limit_coerced
386
419
  assert_sql(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.* @0 = 3/) { Topic.take(3).entries }
@@ -576,6 +609,15 @@ end
576
609
 
577
610
 
578
611
 
612
+ class PrimaryKeysTest < ActiveRecord::TestCase
613
+ # Gonna trust Rails core for this. We end up with 2 querys vs 3 asserted
614
+ # but as far as I can tell, this is only one for us anyway.
615
+ coerce_tests! :test_create_without_primary_key_no_extra_query
616
+ end
617
+
618
+
619
+
620
+
579
621
  require 'models/task'
580
622
  class QueryCacheTest < ActiveRecord::TestCase
581
623
  coerce_tests! :test_cache_does_not_wrap_string_results_in_arrays
@@ -619,6 +661,26 @@ class RelationTest < ActiveRecord::TestCase
619
661
  # Leave it up to users to format selects/functions so HAVING works correctly.
620
662
  coerce_tests! :test_multiple_where_and_having_clauses
621
663
  coerce_tests! :test_having_with_binds_for_both_where_and_having
664
+
665
+ # Find any limit via our expression.
666
+ coerce_tests! %r{relations don't load all records in #inspect}
667
+ def test_relations_dont_load_all_records_in_inspect_coerced
668
+ assert_sql(/NEXT @0 ROWS.*@0 = \d+/) do
669
+ Post.all.inspect
670
+ end
671
+ end
672
+
673
+ # I wanted to add `.order("author_id")` scope to avoid error: Column "posts.id" is invalid in the ORDER BY
674
+ # However, this pull request on Rails core drops order on exists relation. https://github.com/rails/rails/pull/28699
675
+ # so we are skipping all together.
676
+ coerce_tests! :test_empty_complex_chained_relations
677
+
678
+ # Use LEN() vs length() function.
679
+ coerce_tests! :test_reverse_arel_assoc_order_with_function
680
+ def test_reverse_arel_assoc_order_with_function_coerced
681
+ topics = Topic.order(Arel.sql("LEN(title)") => :asc).reverse_order
682
+ assert_equal topics(:second).title, topics.first.title
683
+ end
622
684
  end
623
685
 
624
686
 
@@ -650,9 +712,6 @@ class SchemaDumperTest < ActiveRecord::TestCase
650
712
  assert_match %r{t.decimal\s+"atoms_in_universe",\s+precision: 38}, output
651
713
  end
652
714
 
653
- # This accidently returns the wrong number because of our tables too.
654
- coerce_tests! :test_types_line_up
655
-
656
715
  # This is a poorly written test and really does not catch the bottom'ness it is meant too. Ours throw it off.
657
716
  coerce_tests! :test_foreign_keys_are_dumped_at_the_bottom_to_circumvent_dependency_issues
658
717
 
@@ -816,3 +875,19 @@ module ActiveRecord
816
875
  coerce_tests! :test_find_does_not_use_statement_cache_if_table_name_is_changed
817
876
  end
818
877
  end
878
+
879
+
880
+
881
+
882
+ module ActiveRecord
883
+ module ConnectionAdapters
884
+ class SchemaCacheTest < ActiveRecord::TestCase
885
+ private
886
+ # We need to give the full path for this to work.
887
+ def schema_dump_path
888
+ File.join ARTest::SQLServer.root_activerecord, 'test/assets/schema_dump_5_1.yml'
889
+ end
890
+ end
891
+ end
892
+ end
893
+
@@ -36,7 +36,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
36
36
  it 'bigint(8)' do
37
37
  col = column('bigint')
38
38
  col.sql_type.must_equal 'bigint(8)'
39
- col.type.must_equal :bigint
39
+ col.type.must_equal :integer
40
40
  col.null.must_equal true
41
41
  col.default.must_equal 42
42
42
  obj.bigint.must_equal 42
@@ -23,9 +23,14 @@ module ActiveRecord
23
23
 
24
24
  let(:logger) { ActiveRecord::Base.logger }
25
25
 
26
+ setup :ensure_clean_rails_env
26
27
 
27
28
  private
28
29
 
30
+ def ensure_clean_rails_env
31
+ Rails.instance_variable_set(:@_env, nil) if defined?(::Rails)
32
+ end
33
+
29
34
  def host_windows?
30
35
  RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
31
36
  end
@@ -46,17 +46,6 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
46
46
  end
47
47
  end
48
48
 
49
- it 'reload with lock when #lock! called' do
50
- assert_nothing_raised do
51
- Person.transaction do
52
- person = Person.find 1
53
- old, person.first_name = person.first_name, 'fooman'
54
- person.lock!
55
- assert_equal old, person.first_name
56
- end
57
- end
58
- end
59
-
60
49
  it 'can add a custom lock directive' do
61
50
  assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(HOLDLOCK, ROWLOCK\)| do
62
51
  Person.lock('WITH(HOLDLOCK, ROWLOCK)').load
@@ -38,17 +38,17 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
38
38
  # Character Strings
39
39
  assert_line :char_10, type: 'char', limit: 10, precision: nil, scale: nil, default: "1234567890", collation: nil
40
40
  assert_line :varchar_50, type: 'varchar', limit: 50, precision: nil, scale: nil, default: "test varchar_50", collation: nil
41
- assert_line :varchar_max, type: 'varchar_max', limit: 2147483647, precision: nil, scale: nil, default: "test varchar_max", collation: nil
42
- assert_line :text, type: 'text_basic', limit: 2147483647, precision: nil, scale: nil, default: "test text", collation: nil
41
+ assert_line :varchar_max, type: 'varchar_max', limit: nil, precision: nil, scale: nil, default: "test varchar_max", collation: nil
42
+ assert_line :text, type: 'text_basic', limit: nil, precision: nil, scale: nil, default: "test text", collation: nil
43
43
  # Unicode Character Strings
44
44
  assert_line :nchar_10, type: 'nchar', limit: 10, precision: nil, scale: nil, default: "12345678åå", collation: nil
45
45
  assert_line :nvarchar_50, type: 'string', limit: 50, precision: nil, scale: nil, default: "test nvarchar_50 åå", collation: nil
46
- assert_line :nvarchar_max, type: 'text', limit: 2147483647, precision: nil, scale: nil, default: "test nvarchar_max åå", collation: nil
47
- assert_line :ntext, type: 'ntext', limit: 2147483647, precision: nil, scale: nil, default: "test ntext åå", collation: nil
46
+ assert_line :nvarchar_max, type: 'text', limit: nil, precision: nil, scale: nil, default: "test nvarchar_max åå", collation: nil
47
+ assert_line :ntext, type: 'ntext', limit: nil, precision: nil, scale: nil, default: "test ntext åå", collation: nil
48
48
  # Binary Strings
49
49
  assert_line :binary_49, type: 'binary_basic', limit: 49, precision: nil, scale: nil, default: nil
50
50
  assert_line :varbinary_49, type: 'varbinary', limit: 49, precision: nil, scale: nil, default: nil
51
- assert_line :varbinary_max, type: 'binary', limit: 2147483647, precision: nil, scale: nil, default: nil
51
+ assert_line :varbinary_max, type: 'binary', limit: nil, precision: nil, scale: nil, default: nil
52
52
  # Other Data Types
53
53
  assert_line :uniqueidentifier, type: 'uuid', limit: nil, precision: nil, scale: nil, default: -> { "newid()" }
54
54
  assert_line :timestamp, type: 'ss_timestamp', limit: nil, precision: nil, scale: nil, default: nil
@@ -76,12 +76,12 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
76
76
  assert_line :decimal_col, type: 'decimal', limit: nil, precision: 18, scale: 0, default: nil
77
77
  assert_line :float_col, type: 'float', limit: nil, precision: nil, scale: nil, default: nil
78
78
  assert_line :string_col, type: 'string', limit: nil, precision: nil, scale: nil, default: nil
79
- assert_line :text_col, type: 'text', limit: 2147483647, precision: nil, scale: nil, default: nil
79
+ assert_line :text_col, type: 'text', limit: nil, precision: nil, scale: nil, default: nil
80
80
  assert_line :datetime_col, type: 'datetime', limit: nil, precision: nil, scale: nil, default: nil
81
81
  assert_line :timestamp_col, type: 'datetime', limit: nil, precision: nil, scale: nil, default: nil
82
82
  assert_line :time_col, type: 'time', limit: nil, precision: 7, scale: nil, default: nil
83
83
  assert_line :date_col, type: 'date', limit: nil, precision: nil, scale: nil, default: nil
84
- assert_line :binary_col, type: 'binary', limit: 2147483647, precision: nil, scale: nil, default: nil
84
+ assert_line :binary_col, type: 'binary', limit: nil, precision: nil, scale: nil, default: nil
85
85
  # Our type methods.
86
86
  columns['real_col'].sql_type.must_equal 'real'
87
87
  columns['money_col'].sql_type.must_equal 'money'
@@ -107,14 +107,14 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
107
107
  assert_line :smallmoney_col, type: 'smallmoney', limit: nil, precision: 10, scale: 4, default: nil
108
108
  assert_line :char_col, type: 'char', limit: 1, precision: nil, scale: nil, default: nil
109
109
  assert_line :varchar_col, type: 'varchar', limit: nil, precision: nil, scale: nil, default: nil
110
- assert_line :text_basic_col, type: 'text_basic', limit: 2147483647, precision: nil, scale: nil, default: nil
110
+ assert_line :text_basic_col, type: 'text_basic', limit: nil, precision: nil, scale: nil, default: nil
111
111
  assert_line :nchar_col, type: 'nchar', limit: 1, precision: nil, scale: nil, default: nil
112
- assert_line :ntext_col, type: 'ntext', limit: 2147483647, precision: nil, scale: nil, default: nil
112
+ assert_line :ntext_col, type: 'ntext', limit: nil, precision: nil, scale: nil, default: nil
113
113
  assert_line :binary_basic_col, type: 'binary_basic', limit: 1, precision: nil, scale: nil, default: nil
114
114
  assert_line :varbinary_col, type: 'varbinary', limit: nil, precision: nil, scale: nil, default: nil
115
115
  assert_line :uuid_col, type: 'uuid', limit: nil, precision: nil, scale: nil, default: nil
116
116
  assert_line :sstimestamp_col, type: 'ss_timestamp', limit: nil, precision: nil, scale: nil, default: nil
117
- assert_line :json_col, type: 'text', limit: 2147483647, precision: nil, scale: nil, default: nil
117
+ assert_line :json_col, type: 'text', limit: nil, precision: nil, scale: nil, default: nil
118
118
  end
119
119
 
120
120
  # Special Cases
@@ -148,7 +148,7 @@ ActiveRecord::Schema.define do
148
148
 
149
149
  # Constraints
150
150
 
151
- create_table(:sst_has_fks, force: true) { |t| t.column(:fk_id, :integer, null: false) }
151
+ create_table(:sst_has_fks, force: true) { |t| t.column(:fk_id, :bigint, null: false) }
152
152
  create_table(:sst_has_pks, force: true) { }
153
153
  execute <<-ADDFKSQL
154
154
  ALTER TABLE sst_has_fks
@@ -13,7 +13,7 @@ module ARTest
13
13
  end
14
14
 
15
15
  ignored_sql = [
16
- /INFORMATION_SCHEMA\.(TABLES|VIEWS|COLUMNS)/im,
16
+ /INFORMATION_SCHEMA\.(TABLES|VIEWS|COLUMNS|KEY_COLUMN_USAGE)/im,
17
17
  /SELECT @@version/,
18
18
  /SELECT @@TRANCOUNT/,
19
19
  /(BEGIN|COMMIT|ROLLBACK|SAVE) TRANSACTION/,
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: 5.0.8
4
+ version: 5.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: 2017-12-30 00:00:00.000000000 Z
17
+ date: 2017-05-29 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: activerecord
@@ -22,14 +22,14 @@ dependencies:
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 5.0.0
25
+ version: 5.1.0
26
26
  type: :runtime
27
27
  prerelease: false
28
28
  version_requirements: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 5.0.0
32
+ version: 5.1.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: tiny_tds
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -54,6 +54,7 @@ extra_rdoc_files: []
54
54
  files:
55
55
  - ".gitignore"
56
56
  - ".travis.yml"
57
+ - BACKERS.md
57
58
  - CHANGELOG.md
58
59
  - CODE_OF_CONDUCT.md
59
60
  - Gemfile
@@ -288,3 +289,4 @@ test_files:
288
289
  - test/support/rake_helpers.rb
289
290
  - test/support/sql_counter_sqlserver.rb
290
291
  - test/support/test_in_memory_oltp.rb
292
+ has_rdoc: