activerecord-jdbc-alt-adapter 52.6.0-java → 60.0.0-java

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/.travis.yml +58 -37
  4. data/Gemfile +9 -2
  5. data/README.md +30 -14
  6. data/Rakefile +1 -1
  7. data/Rakefile.jdbc +8 -1
  8. data/activerecord-jdbc-adapter.gemspec +5 -8
  9. data/activerecord-jdbc-alt-adapter.gemspec +5 -8
  10. data/lib/arel/visitors/sqlserver.rb +33 -23
  11. data/lib/arjdbc/abstract/connection_management.rb +7 -0
  12. data/lib/arjdbc/abstract/core.rb +16 -23
  13. data/lib/arjdbc/abstract/database_statements.rb +24 -0
  14. data/lib/arjdbc/abstract/statement_cache.rb +2 -5
  15. data/lib/arjdbc/abstract/transaction_support.rb +5 -3
  16. data/lib/arjdbc/db2/column.rb +0 -39
  17. data/lib/arjdbc/derby/adapter.rb +1 -20
  18. data/lib/arjdbc/firebird/adapter.rb +0 -21
  19. data/lib/arjdbc/h2/adapter.rb +0 -15
  20. data/lib/arjdbc/hsqldb/adapter.rb +0 -14
  21. data/lib/arjdbc/informix/adapter.rb +0 -23
  22. data/lib/arjdbc/jdbc/adapter.rb +3 -1
  23. data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
  24. data/lib/arjdbc/jdbc/base_ext.rb +3 -1
  25. data/lib/arjdbc/jdbc/callbacks.rb +2 -0
  26. data/lib/arjdbc/jdbc/column.rb +2 -0
  27. data/lib/arjdbc/jdbc/connection.rb +2 -0
  28. data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
  29. data/lib/arjdbc/jdbc/error.rb +2 -0
  30. data/lib/arjdbc/jdbc/extension.rb +2 -0
  31. data/lib/arjdbc/jdbc/java.rb +3 -1
  32. data/lib/arjdbc/jdbc/railtie.rb +3 -1
  33. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
  34. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
  35. data/lib/arjdbc/jdbc/type_cast.rb +2 -0
  36. data/lib/arjdbc/jdbc/type_converter.rb +2 -0
  37. data/lib/arjdbc/mssql.rb +3 -1
  38. data/lib/arjdbc/mssql/adapter.rb +105 -36
  39. data/lib/arjdbc/mssql/column.rb +5 -1
  40. data/lib/arjdbc/mssql/connection_methods.rb +8 -2
  41. data/lib/arjdbc/mssql/database_limits.rb +2 -0
  42. data/lib/arjdbc/mssql/database_statements.rb +43 -5
  43. data/lib/arjdbc/mssql/errors.rb +2 -0
  44. data/lib/arjdbc/mssql/explain_support.rb +3 -1
  45. data/lib/arjdbc/mssql/extensions/attribute_methods.rb +5 -1
  46. data/lib/arjdbc/mssql/extensions/calculations.rb +2 -0
  47. data/lib/arjdbc/mssql/quoting.rb +38 -0
  48. data/lib/arjdbc/mssql/schema_creation.rb +24 -2
  49. data/lib/arjdbc/mssql/schema_definitions.rb +10 -0
  50. data/lib/arjdbc/mssql/schema_dumper.rb +2 -0
  51. data/lib/arjdbc/mssql/schema_statements.rb +63 -21
  52. data/lib/arjdbc/mssql/transaction.rb +2 -0
  53. data/lib/arjdbc/mssql/types.rb +2 -0
  54. data/lib/arjdbc/mssql/types/binary_types.rb +2 -0
  55. data/lib/arjdbc/mssql/types/date_and_time_types.rb +2 -0
  56. data/lib/arjdbc/mssql/types/deprecated_types.rb +2 -0
  57. data/lib/arjdbc/mssql/types/numeric_types.rb +2 -0
  58. data/lib/arjdbc/mssql/types/string_types.rb +2 -0
  59. data/lib/arjdbc/mssql/utils.rb +2 -0
  60. data/lib/arjdbc/mysql/adapter.rb +47 -18
  61. data/lib/arjdbc/postgresql/adapter.rb +220 -213
  62. data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
  63. data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
  64. data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
  65. data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
  66. data/lib/arjdbc/postgresql/column.rb +6 -4
  67. data/lib/arjdbc/postgresql/name.rb +2 -0
  68. data/lib/arjdbc/postgresql/oid_types.rb +2 -0
  69. data/lib/arjdbc/sqlite3/adapter.rb +175 -180
  70. data/lib/arjdbc/sqlite3/connection_methods.rb +15 -4
  71. data/lib/arjdbc/tasks/databases.rake +13 -10
  72. data/lib/arjdbc/tasks/mssql_database_tasks.rb +49 -5
  73. data/lib/arjdbc/util/quoted_cache.rb +3 -1
  74. data/lib/arjdbc/util/serialized_attributes.rb +3 -1
  75. data/lib/arjdbc/util/table_copier.rb +3 -1
  76. data/lib/arjdbc/version.rb +1 -1
  77. data/pom.xml +4 -4
  78. data/rakelib/01-tomcat.rake +2 -2
  79. data/src/java/arjdbc/ArJdbcModule.java +5 -5
  80. data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
  81. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +406 -629
  82. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +37 -51
  83. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
  84. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +31 -24
  85. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +94 -99
  86. data/src/java/arjdbc/util/DateTimeUtils.java +12 -4
  87. metadata +8 -16
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # Represents exceptions that have propagated up through the JDBC API.
3
5
  class JDBCError < WrappedDatabaseException
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArJdbc
2
4
 
3
5
  # Defines an AR-JDBC extension. An extension consists of a declaration using
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'java'
2
4
  require 'arjdbc/jdbc/adapter_java'
3
5
 
@@ -10,4 +12,4 @@ module ActiveRecord
10
12
  Types = ::Java::JavaSql::Types
11
13
  end
12
14
  end
13
- end
15
+ end
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'arjdbc/railtie'
2
- ArJdbc.deprecate "require 'arjdbc/railtie' instead of 'arjdbc/jdbc/railtie'"
4
+ ArJdbc.deprecate "require 'arjdbc/railtie' instead of 'arjdbc/jdbc/railtie'"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  load 'arjdbc/tasks.rb'
2
4
 
3
- ArJdbc.deprecate "load 'arjdbc/tasks.rb' instead of 'arjdbc/jdbc/rake_tasks.rb'"
5
+ ArJdbc.deprecate "load 'arjdbc/tasks.rb' instead of 'arjdbc/jdbc/rake_tasks.rb'"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'arjdbc/util/serialized_attributes'
2
4
 
3
- ArJdbc.deprecate "require 'arjdbc/util/serialized_attributes' instead of 'arjdbc/jdbc/serialized_attributes_helper'"
5
+ ArJdbc.deprecate "require 'arjdbc/util/serialized_attributes' instead of 'arjdbc/jdbc/serialized_attributes_helper'"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record/connection_adapters/column'
2
4
 
3
5
  module ActiveRecord::ConnectionAdapters
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  # I want to use JDBC's DatabaseMetaData#getTypeInfo to choose the best native types to
data/lib/arjdbc/mssql.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'arjdbc'
2
2
  require 'arjdbc/mssql/adapter'
3
3
  require 'arjdbc/mssql/connection_methods'
4
+
4
5
  module ArJdbc
5
6
  MsSQL = MSSQL # compatibility with 1.2
6
7
  end
7
- ArJdbc.warn_unsupported_adapter 'mssql', [5, 2] # warns on AR >= 4.2
8
+
9
+ ArJdbc.warn_unsupported_adapter 'mssql', [6, 0] # warns on AR >= 4.2
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
 
3
3
  ArJdbc.load_java_part :MSSQL
4
4
 
@@ -68,8 +68,19 @@ module ActiveRecord
68
68
  # configure_connection happens in super
69
69
  super(connection, logger, config)
70
70
 
71
- unless mssql_major_version >= 11
72
- raise "Your MSSQL #{mssql_version_year} is too old. This adapter supports MSSQL >= 2012."
71
+ if database_version < '11'
72
+ raise "Your #{mssql_product_name} #{mssql_version_year} is too old. This adapter supports #{mssql_product_name} >= 2012."
73
+ end
74
+ end
75
+
76
+ def self.database_exists?(config)
77
+ !!ActiveRecord::Base.sqlserver_connection(config)
78
+ rescue ActiveRecord::JDBCError => e
79
+ case e.message
80
+ when /Cannot open database .* requested by the login/
81
+ false
82
+ else
83
+ raise
73
84
  end
74
85
  end
75
86
 
@@ -101,6 +112,14 @@ module ActiveRecord
101
112
  true
102
113
  end
103
114
 
115
+ def supports_savepoints?
116
+ true
117
+ end
118
+
119
+ def supports_lazy_transactions?
120
+ true
121
+ end
122
+
104
123
  # The MSSQL datetime type doe have precision.
105
124
  def supports_datetime_with_precision?
106
125
  true
@@ -121,12 +140,23 @@ module ActiveRecord
121
140
  true
122
141
  end
123
142
 
143
+ def supports_insert_on_conflict?
144
+ false
145
+ end
146
+ alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
147
+ alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
148
+ alias supports_insert_conflict_target? supports_insert_on_conflict?
149
+
150
+ def build_insert_sql(insert) # :nodoc:
151
+ # TODO: hope we can implement an upsert like feature
152
+ "INSERT #{insert.into} #{insert.values_list}"
153
+ end
154
+
124
155
  # Overrides abstract method which always returns false
125
156
  def valid_type?(type)
126
157
  !native_database_types[type].nil?
127
158
  end
128
159
 
129
- # FIXME: to be reviewed.
130
160
  def clear_cache!
131
161
  reload_type_map
132
162
  super
@@ -170,22 +200,6 @@ module ActiveRecord
170
200
  result
171
201
  end
172
202
 
173
- def arel_visitor # :nodoc:
174
- ::Arel::Visitors::SQLServer.new(self)
175
- end
176
-
177
- def schema_creation # :nodoc:
178
- MSSQL::SchemaCreation.new(self)
179
- end
180
-
181
- def create_table_definition(*args) # :nodoc:
182
- MSSQL::TableDefinition.new(*args)
183
- end
184
-
185
- def update_table_definition(table_name, base) #:nodoc:
186
- MSSQL::Table.new(table_name, base)
187
- end
188
-
189
203
  # Returns the name of the current security context
190
204
  def current_user
191
205
  @current_user ||= select_value('SELECT CURRENT_USER')
@@ -208,15 +222,25 @@ module ActiveRecord
208
222
 
209
223
  alias_method :current_schema=, :default_schema=
210
224
 
211
- # Overrides method in abstract adapter
212
- # FIXME: This needs to be fixed the we find a way how to
213
- # get the collation per column basis. At the moment we only use
214
- # the global database collation
215
- def case_sensitive_comparison(table, attribute, column, value)
216
- if [:string, :text].include?(column.type) && collation && !collation.match(/_CS/)
217
- table[attribute].eq(Arel::Nodes::Bin.new(value))
218
- # elsif value.acts_like?(:string)
219
- # table[attribute].eq(Arel::Nodes::Bin.new(Arel::Nodes::BindParam.new))
225
+ # FIXME: This needs to be fixed when we implement the collation per
226
+ # column basis. At the moment we only use the global database collation
227
+ def default_uniqueness_comparison(attribute, value, klass) # :nodoc:
228
+ column = column_for_attribute(attribute)
229
+
230
+ if [:string, :text].include?(column.type) && collation && !collation.match(/_CS/) && !value.nil?
231
+ # NOTE: there is a deprecation warning here in the mysql adapter
232
+ # no sure if it's required.
233
+ attribute.eq(Arel::Nodes::Bin.new(value))
234
+ else
235
+ super
236
+ end
237
+ end
238
+
239
+ def case_sensitive_comparison(attribute, value)
240
+ column = column_for_attribute(attribute)
241
+
242
+ if [:string, :text].include?(column.type) && collation && !collation.match(/_CS/) && !value.nil?
243
+ attribute.eq(Arel::Nodes::Bin.new(value))
220
244
  else
221
245
  super
222
246
  end
@@ -248,6 +272,27 @@ module ActiveRecord
248
272
  MSSQL_VERSION_YEAR[mssql_major_version.to_i]
249
273
  end
250
274
 
275
+ def mssql_product_version
276
+ return @mssql_product_version if defined? @mssql_product_version
277
+
278
+ @mssql_product_version = @connection.database_product_version
279
+ end
280
+
281
+ def mssql_product_name
282
+ return @mssql_product_name if defined? @mssql_product_name
283
+
284
+ @mssql_product_name = @connection.database_product_name
285
+ end
286
+
287
+ def get_database_version # :nodoc:
288
+ MSSQLAdapter::Version.new(mssql_product_version)
289
+ end
290
+
291
+ def check_version # :nodoc:
292
+ # NOTE: hitting the database from here causes trouble when adapter
293
+ # uses JNDI or Data Source setup.
294
+ end
295
+
251
296
  def tables_with_referential_integrity
252
297
  schema_and_tables_sql = %(
253
298
  SELECT s.name, o.name
@@ -266,20 +311,22 @@ module ActiveRecord
266
311
 
267
312
  private
268
313
 
269
- def translate_exception(exception, message)
314
+ def translate_exception(exception, message:, sql:, binds:)
270
315
  case message
271
316
  when /(cannot insert duplicate key .* with unique index) | (violation of unique key constraint)/i
272
- RecordNotUnique.new(message)
317
+ RecordNotUnique.new(message, sql: sql, binds: binds)
273
318
  when /Lock request time out period exceeded/i
274
- LockTimeout.new(message)
319
+ LockTimeout.new(message, sql: sql, binds: binds)
275
320
  when /The .* statement conflicted with the FOREIGN KEY constraint/
276
- ActiveRecord::InvalidForeignKey.new(message)
321
+ InvalidForeignKey.new(message, sql: sql, binds: binds)
322
+ when /The .* statement conflicted with the REFERENCE constraint/
323
+ InvalidForeignKey.new(message, sql: sql, binds: binds)
277
324
  when /(String or binary data would be truncated)/i
278
- ActiveRecord::ValueTooLong.new(message)
325
+ ValueTooLong.new(message, sql: sql, binds: binds)
279
326
  when /Cannot insert the value NULL into column .* does not allow nulls/
280
- ActiveRecord::NotNullViolation.new(message)
327
+ NotNullViolation.new(message, sql: sql, binds: binds)
281
328
  when /Arithmetic overflow error converting expression/
282
- ActiveRecord::RangeError.new(message)
329
+ RangeError.new(message, sql: sql, binds: binds)
283
330
  else
284
331
  super
285
332
  end
@@ -387,6 +434,28 @@ module ActiveRecord
387
434
  map.register_type 'ntext', MSSQL::Type::Ntext.new
388
435
  map.register_type 'image', MSSQL::Type::Image.new
389
436
  end
437
+
438
+ # Returns an array of Column objects for the table specified by +table_name+.
439
+ # See the concrete implementation for details on the expected parameter values.
440
+ # NOTE: This is ready, all implemented in the java part of adapter,
441
+ # it uses MSSQLColumn, SqlTypeMetadata, etc.
442
+ def column_definitions(table_name)
443
+ log('JDBC: GETCOLUMNS', 'SCHEMA') { @connection.columns(table_name) }
444
+ rescue => e
445
+ # raise translate_exception_class(e, nil)
446
+ # FIXME: this breaks one arjdbc test but fixes activerecord tests
447
+ # (table name alias). Also it behaves similarly to the CRuby adapter
448
+ # which returns an empty array too. (postgres throws a exception)
449
+ []
450
+ end
451
+
452
+ def arel_visitor # :nodoc:
453
+ ::Arel::Visitors::SQLServer.new(self)
454
+ end
455
+
456
+ def build_statement_pool
457
+ # NOTE: @statements is set in StatementCache module
458
+ end
390
459
  end
391
460
  end
392
461
  end
@@ -1,11 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  # MSSQL specific extensions to column definitions in a table.
4
6
  class MSSQLColumn < Column
7
+ attr_reader :table_name
5
8
  def initialize(name, raw_default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
9
+ @table_name = table_name
6
10
  default = extract_default(raw_default)
7
11
 
8
- super(name, default, sql_type_metadata, null, table_name, default_function, collation, comment: comment)
12
+ super(name, default, sql_type_metadata, null, default_function, collation: collation, comment: comment)
9
13
  end
10
14
 
11
15
  def extract_default(value)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ArJdbc::ConnectionMethods.module_eval do
2
4
 
3
5
  # Default connection method for MS-SQL adapter (`adapter: mssql`),
@@ -11,6 +13,8 @@ ArJdbc::ConnectionMethods.module_eval do
11
13
  return sqlserver_connection(config)
12
14
  end
13
15
 
16
+ config = config.deep_dup
17
+
14
18
  config[:adapter_spec] ||= ::ArJdbc::MSSQL
15
19
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::MSSQLAdapter unless config.key?(:adapter_class)
16
20
 
@@ -31,7 +35,8 @@ ArJdbc::ConnectionMethods.module_eval do
31
35
  config[:connection_alive_sql] ||= 'SELECT 1'
32
36
 
33
37
  config[:url] ||= begin
34
- url = "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
38
+ url = ''.dup
39
+ url << "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
35
40
  # Instance is often a preferrable alternative to port when dynamic ports are used.
36
41
  # If instance is specified then port is essentially ignored.
37
42
  url << ";instance=#{config[:instance]}" if config[:instance]
@@ -65,7 +70,8 @@ ArJdbc::ConnectionMethods.module_eval do
65
70
  config[:lock_timeout] ||= 5000
66
71
 
67
72
  config[:url] ||= begin
68
- url = "jdbc:sqlserver://#{config[:host]}"
73
+ url = ''.dup
74
+ url << "jdbc:sqlserver://#{config[:host]}"
69
75
  url << ( config[:port] ? ":#{config[:port]};" : ';' )
70
76
  url << "databaseName=#{config[:database]};" if config[:database]
71
77
  url << "instanceName=#{config[:instance]};" if config[:instance]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
@@ -23,6 +25,15 @@ module ActiveRecord
23
25
  end
24
26
  alias_method :execute_procedure, :exec_proc # AR-SQLServer-Adapter naming
25
27
 
28
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
29
+ :begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback, :with
30
+ ) # :nodoc:
31
+ private_constant :READ_QUERY
32
+
33
+ def write_query?(sql) # :nodoc:
34
+ !READ_QUERY.match?(sql)
35
+ end
36
+
26
37
  def execute(sql, name = nil)
27
38
  # with identity insert on block
28
39
  if insert_sql?(sql)
@@ -52,11 +63,6 @@ module ActiveRecord
52
63
  end
53
64
  end
54
65
 
55
- # Implements the truncate method.
56
- def truncate(table_name, name = nil)
57
- execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
58
- end
59
-
60
66
  # Not a rails method, own method to test different isolation
61
67
  # levels supported by the mssql adapter.
62
68
  def supports_transaction_isolation_level?(level)
@@ -95,8 +101,40 @@ module ActiveRecord
95
101
  end
96
102
  end
97
103
 
104
+ # Implements the truncate method.
105
+ def truncate(table_name, name = nil)
106
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
107
+ end
108
+
109
+ def truncate_tables(*table_names) # :nodoc:
110
+ return if table_names.empty?
111
+
112
+ disable_referential_integrity do
113
+ table_names.each do |table_name|
114
+ mssql_truncate(table_name)
115
+ end
116
+ end
117
+ end
118
+
98
119
  private
99
120
 
121
+ # It seems the truncate_tables is mostly used for testing
122
+ # this a workaround to the fact that SQL Server truncate tables
123
+ # referenced by a foreign key, it may not be required to reset
124
+ # the identity column too, more at:
125
+ # https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-ver15
126
+ # TODO: improve is with pure T-SQL, use statements
127
+ # such as TRY CATCH and reset identity with DBCC CHECKIDENT
128
+ def mssql_truncate(table_name)
129
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", 'Truncate Tables'
130
+ rescue => e
131
+ if e.message =~ /Cannot truncate table .* because it is being referenced by a FOREIGN KEY constraint/
132
+ execute "DELETE FROM #{quote_table_name(table_name)}", 'Truncate Tables with Delete'
133
+ else
134
+ raise
135
+ end
136
+ end
137
+
100
138
  # Overrides method in abstract class, combining the sqls with semicolon
101
139
  # affects disable_referential_integrity in mssql specially when multiple
102
140
  # tables are involved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # Error raised when adapter determines the database could not acquire
3
5
  # a necessary lock before timing out
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/string'
2
4
 
3
5
  module ActiveRecord
@@ -108,7 +110,7 @@ module ActiveRecord
108
110
  end
109
111
 
110
112
  def build_separator
111
- '+' << @widths.map {|w| '-' * (w + (cell_padding * 2))}.join('+') << '+'
113
+ '+'.dup << @widths.map {|w| '-' * (w + (cell_padding * 2))}.join('+') << '+'
112
114
  end
113
115
 
114
116
  def build_cells(items)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file contains extensions, overrides, and monkey patches to core parts
2
4
  # of active record to allow SQL Server work properly.
3
5
  #
@@ -15,7 +17,9 @@ module ActiveRecord
15
17
  # this behaviour, even the current comments for that method says that
16
18
  # it rejects primary key but it doesn't (maybe a rails bug?)
17
19
  def attributes_for_update(attribute_names)
18
- attribute_names.reject do |name|
20
+ attribute_names &= self.class.column_names
21
+
22
+ attribute_names.delete_if do |name|
19
23
  # It seems is only required to check if column in identity or not.
20
24
  # This allows to update rails custom primary keys
21
25
  next true if readonly_attribute?(name)