activerecord 6.0.0.beta1 → 6.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +99 -2
- data/lib/active_record.rb +7 -0
- data/lib/active_record/associations/association.rb +17 -0
- data/lib/active_record/associations/collection_association.rb +5 -6
- data/lib/active_record/associations/collection_proxy.rb +12 -41
- data/lib/active_record/associations/has_many_association.rb +1 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +11 -6
- data/lib/active_record/associations/preloader/association.rb +3 -4
- data/lib/active_record/associations/preloader/through_association.rb +9 -20
- data/lib/active_record/callbacks.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +25 -12
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +17 -9
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +5 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +47 -33
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +16 -8
- data/lib/active_record/connection_adapters/abstract/transaction.rb +5 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +6 -4
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +28 -65
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +59 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +98 -89
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +30 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +27 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +8 -5
- data/lib/active_record/connection_handling.rb +9 -4
- data/lib/active_record/core.rb +13 -1
- data/lib/active_record/database_configurations.rb +30 -10
- data/lib/active_record/database_configurations/hash_config.rb +1 -1
- data/lib/active_record/database_configurations/url_config.rb +9 -4
- data/lib/active_record/errors.rb +17 -12
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +90 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/migration/compatibility.rb +62 -63
- data/lib/active_record/persistence.rb +6 -6
- data/lib/active_record/querying.rb +2 -3
- data/lib/active_record/railtie.rb +9 -0
- data/lib/active_record/railties/collection_cache_association_loading.rb +3 -3
- data/lib/active_record/reflection.rb +15 -29
- data/lib/active_record/relation.rb +86 -15
- data/lib/active_record/relation/calculations.rb +2 -4
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +8 -4
- data/lib/active_record/relation/query_attribute.rb +5 -3
- data/lib/active_record/relation/query_methods.rb +28 -8
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +1 -5
- data/lib/active_record/scoping.rb +6 -7
- data/lib/active_record/scoping/default.rb +1 -8
- data/lib/active_record/scoping/named.rb +9 -1
- data/lib/active_record/test_fixtures.rb +2 -2
- data/lib/active_record/timestamp.rb +9 -3
- data/lib/active_record/validations/uniqueness.rb +3 -1
- data/lib/arel.rb +7 -0
- data/lib/arel/nodes/and.rb +1 -1
- data/lib/arel/nodes/case.rb +1 -1
- metadata +11 -8
@@ -95,7 +95,7 @@ module ActiveRecord
|
|
95
95
|
#
|
96
96
|
# private
|
97
97
|
# def delete_parents
|
98
|
-
# self.class.
|
98
|
+
# self.class.delete_by(parent_id: id)
|
99
99
|
# end
|
100
100
|
# end
|
101
101
|
#
|
@@ -324,7 +324,7 @@ module ActiveRecord
|
|
324
324
|
|
325
325
|
private
|
326
326
|
|
327
|
-
def create_or_update(
|
327
|
+
def create_or_update(**)
|
328
328
|
_run_save_callbacks { super }
|
329
329
|
end
|
330
330
|
|
@@ -332,7 +332,7 @@ module ActiveRecord
|
|
332
332
|
_run_create_callbacks { super }
|
333
333
|
end
|
334
334
|
|
335
|
-
def _update_record
|
335
|
+
def _update_record
|
336
336
|
_run_update_callbacks { super }
|
337
337
|
end
|
338
338
|
end
|
@@ -185,7 +185,7 @@ module ActiveRecord
|
|
185
185
|
def wait_poll(timeout)
|
186
186
|
@num_waiting += 1
|
187
187
|
|
188
|
-
t0 =
|
188
|
+
t0 = Concurrent.monotonic_time
|
189
189
|
elapsed = 0
|
190
190
|
loop do
|
191
191
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
@@ -194,7 +194,7 @@ module ActiveRecord
|
|
194
194
|
|
195
195
|
return remove if any?
|
196
196
|
|
197
|
-
elapsed =
|
197
|
+
elapsed = Concurrent.monotonic_time - t0
|
198
198
|
if elapsed >= timeout
|
199
199
|
msg = "could not obtain a connection from the pool within %0.3f seconds (waited %0.3f seconds); all pooled connections were in use" %
|
200
200
|
[timeout, elapsed]
|
@@ -686,13 +686,13 @@ module ActiveRecord
|
|
686
686
|
end
|
687
687
|
|
688
688
|
newly_checked_out = []
|
689
|
-
timeout_time =
|
689
|
+
timeout_time = Concurrent.monotonic_time + (@checkout_timeout * 2)
|
690
690
|
|
691
691
|
@available.with_a_bias_for(Thread.current) do
|
692
692
|
loop do
|
693
693
|
synchronize do
|
694
694
|
return if collected_conns.size == @connections.size && @now_connecting == 0
|
695
|
-
remaining_timeout = timeout_time -
|
695
|
+
remaining_timeout = timeout_time - Concurrent.monotonic_time
|
696
696
|
remaining_timeout = 0 if remaining_timeout < 0
|
697
697
|
conn = checkout_for_exclusive_access(remaining_timeout)
|
698
698
|
collected_conns << conn
|
@@ -915,6 +915,16 @@ module ActiveRecord
|
|
915
915
|
# about the model. The model needs to pass a specification name to the handler,
|
916
916
|
# in order to look up the correct connection pool.
|
917
917
|
class ConnectionHandler
|
918
|
+
def self.create_owner_to_pool # :nodoc:
|
919
|
+
Concurrent::Map.new(initial_capacity: 2) do |h, k|
|
920
|
+
# Discard the parent's connection pools immediately; we have no need
|
921
|
+
# of them
|
922
|
+
discard_unowned_pools(h)
|
923
|
+
|
924
|
+
h[k] = Concurrent::Map.new(initial_capacity: 2)
|
925
|
+
end
|
926
|
+
end
|
927
|
+
|
918
928
|
def self.unowned_pool_finalizer(pid_map) # :nodoc:
|
919
929
|
lambda do |_|
|
920
930
|
discard_unowned_pools(pid_map)
|
@@ -929,13 +939,7 @@ module ActiveRecord
|
|
929
939
|
|
930
940
|
def initialize
|
931
941
|
# These caches are keyed by spec.name (ConnectionSpecification#name).
|
932
|
-
@owner_to_pool =
|
933
|
-
# Discard the parent's connection pools immediately; we have no need
|
934
|
-
# of them
|
935
|
-
ConnectionHandler.discard_unowned_pools(h)
|
936
|
-
|
937
|
-
h[k] = Concurrent::Map.new(initial_capacity: 2)
|
938
|
-
end
|
942
|
+
@owner_to_pool = ConnectionHandler.create_owner_to_pool
|
939
943
|
|
940
944
|
# Backup finalizer: if the forked child never needed a pool, the above
|
941
945
|
# early discard has not occurred
|
@@ -1006,7 +1010,16 @@ module ActiveRecord
|
|
1006
1010
|
# for (not necessarily the current class).
|
1007
1011
|
def retrieve_connection(spec_name) #:nodoc:
|
1008
1012
|
pool = retrieve_connection_pool(spec_name)
|
1009
|
-
|
1013
|
+
|
1014
|
+
unless pool
|
1015
|
+
# multiple database application
|
1016
|
+
if ActiveRecord::Base.connection_handler != ActiveRecord::Base.default_connection_handler
|
1017
|
+
raise ConnectionNotEstablished, "No connection pool with '#{spec_name}' found for the '#{ActiveRecord::Base.current_role}' role."
|
1018
|
+
else
|
1019
|
+
raise ConnectionNotEstablished, "No connection pool with '#{spec_name}' found."
|
1020
|
+
end
|
1021
|
+
end
|
1022
|
+
|
1010
1023
|
pool.connection
|
1011
1024
|
end
|
1012
1025
|
|
@@ -20,9 +20,22 @@ module ActiveRecord
|
|
20
20
|
raise "Passing bind parameters with an arel AST is forbidden. " \
|
21
21
|
"The values must be stored on the AST directly"
|
22
22
|
end
|
23
|
-
|
24
|
-
|
23
|
+
|
24
|
+
if prepared_statements
|
25
|
+
sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
|
26
|
+
|
27
|
+
if binds.length > bind_params_length
|
28
|
+
unprepared_statement do
|
29
|
+
sql, binds = to_sql_and_binds(arel_or_sql_string)
|
30
|
+
visitor.preparable = false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
else
|
34
|
+
sql = visitor.compile(arel_or_sql_string.ast, collector)
|
35
|
+
end
|
36
|
+
[sql.freeze, binds]
|
25
37
|
else
|
38
|
+
visitor.preparable = false if prepared_statements
|
26
39
|
[arel_or_sql_string.dup.freeze, binds]
|
27
40
|
end
|
28
41
|
end
|
@@ -47,13 +60,8 @@ module ActiveRecord
|
|
47
60
|
arel = arel_from_relation(arel)
|
48
61
|
sql, binds = to_sql_and_binds(arel, binds)
|
49
62
|
|
50
|
-
if
|
51
|
-
preparable = false
|
52
|
-
elsif binds.length > bind_params_length
|
53
|
-
sql, binds = unprepared_statement { to_sql_and_binds(arel) }
|
54
|
-
preparable = false
|
55
|
-
else
|
56
|
-
preparable = visitor.preparable
|
63
|
+
if preparable.nil?
|
64
|
+
preparable = prepared_statements ? visitor.preparable : false
|
57
65
|
end
|
58
66
|
|
59
67
|
if prepared_statements && preparable
|
@@ -17,7 +17,7 @@ module ActiveRecord
|
|
17
17
|
method_names.each do |method_name|
|
18
18
|
base.class_eval <<-end_code, __FILE__, __LINE__ + 1
|
19
19
|
def #{method_name}(*)
|
20
|
-
|
20
|
+
ActiveRecord::Base.clear_query_caches_for_current_thread if @query_cache_enabled
|
21
21
|
super
|
22
22
|
end
|
23
23
|
end_code
|
@@ -96,6 +96,11 @@ module ActiveRecord
|
|
96
96
|
if @query_cache_enabled && !locked?(arel)
|
97
97
|
arel = arel_from_relation(arel)
|
98
98
|
sql, binds = to_sql_and_binds(arel, binds)
|
99
|
+
|
100
|
+
if preparable.nil?
|
101
|
+
preparable = prepared_statements ? visitor.preparable : false
|
102
|
+
end
|
103
|
+
|
99
104
|
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
|
100
105
|
else
|
101
106
|
super
|
@@ -15,7 +15,7 @@ module ActiveRecord
|
|
15
15
|
end
|
16
16
|
|
17
17
|
delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
|
18
|
-
:options_include_default?, :supports_indexes_in_create?, :
|
18
|
+
:options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options,
|
19
19
|
to: :@conn, private: true
|
20
20
|
|
21
21
|
private
|
@@ -50,7 +50,7 @@ module ActiveRecord
|
|
50
50
|
statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
|
51
51
|
end
|
52
52
|
|
53
|
-
if
|
53
|
+
if supports_foreign_keys?
|
54
54
|
statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
|
55
55
|
end
|
56
56
|
|
@@ -127,6 +127,9 @@ module ActiveRecord
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def foreign_key_in_create(from_table, to_table, options)
|
130
|
+
prefix = ActiveRecord::Base.table_name_prefix
|
131
|
+
suffix = ActiveRecord::Base.table_name_suffix
|
132
|
+
to_table = "#{prefix}#{to_table}#{suffix}"
|
130
133
|
options = foreign_key_options(from_table, to_table, options)
|
131
134
|
accept ForeignKeyDefinition.new(from_table, to_table, options)
|
132
135
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/deprecation"
|
4
|
-
|
5
3
|
module ActiveRecord
|
6
4
|
module ConnectionAdapters #:nodoc:
|
7
5
|
# Abstract representation of an index definition on a table. Instances of
|
@@ -104,7 +102,7 @@ module ActiveRecord
|
|
104
102
|
alias validated? validate?
|
105
103
|
|
106
104
|
def export_name_on_schema_dump?
|
107
|
-
|
105
|
+
!ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
|
108
106
|
end
|
109
107
|
|
110
108
|
def defined_for?(to_table_ord = nil, to_table: nil, **options)
|
@@ -200,41 +198,44 @@ module ActiveRecord
|
|
200
198
|
end
|
201
199
|
|
202
200
|
module ColumnMethods
|
201
|
+
extend ActiveSupport::Concern
|
202
|
+
|
203
203
|
# Appends a primary key definition to the table definition.
|
204
204
|
# Can be called multiple times, but this is probably not a good idea.
|
205
205
|
def primary_key(name, type = :primary_key, **options)
|
206
206
|
column(name, type, options.merge(primary_key: true))
|
207
207
|
end
|
208
208
|
|
209
|
+
##
|
210
|
+
# :method: column
|
211
|
+
# :call-seq: column(name, type, **options)
|
212
|
+
#
|
209
213
|
# Appends a column or columns of a specified type.
|
210
214
|
#
|
211
215
|
# t.string(:goat)
|
212
216
|
# t.string(:goat, :sheep)
|
213
217
|
#
|
214
218
|
# See TableDefinition#column
|
215
|
-
|
216
|
-
|
217
|
-
:binary,
|
218
|
-
|
219
|
-
|
220
|
-
:
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
:
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
def #{column_type}(*args, **options)
|
233
|
-
args.each { |name| column(name, :#{column_type}, options) }
|
219
|
+
|
220
|
+
included do
|
221
|
+
define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
|
222
|
+
:float, :integer, :json, :string, :text, :time, :timestamp, :virtual
|
223
|
+
|
224
|
+
alias :numeric :decimal
|
225
|
+
end
|
226
|
+
|
227
|
+
class_methods do
|
228
|
+
private def define_column_methods(*column_types) # :nodoc:
|
229
|
+
column_types.each do |column_type|
|
230
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
231
|
+
def #{column_type}(*names, **options)
|
232
|
+
raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
|
233
|
+
names.each { |name| column(name, :#{column_type}, options) }
|
234
|
+
end
|
235
|
+
RUBY
|
234
236
|
end
|
235
|
-
|
237
|
+
end
|
236
238
|
end
|
237
|
-
alias_method :numeric, :decimal
|
238
239
|
end
|
239
240
|
|
240
241
|
# Represents the schema of an SQL table in an abstract way. This class
|
@@ -259,10 +260,9 @@ module ActiveRecord
|
|
259
260
|
include ColumnMethods
|
260
261
|
|
261
262
|
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
|
262
|
-
attr_writer :indexes
|
263
|
-
deprecate :indexes=
|
264
263
|
|
265
264
|
def initialize(
|
265
|
+
conn,
|
266
266
|
name,
|
267
267
|
temporary: false,
|
268
268
|
if_not_exists: false,
|
@@ -271,6 +271,7 @@ module ActiveRecord
|
|
271
271
|
comment: nil,
|
272
272
|
**
|
273
273
|
)
|
274
|
+
@conn = conn
|
274
275
|
@columns_hash = {}
|
275
276
|
@indexes = []
|
276
277
|
@foreign_keys = []
|
@@ -363,7 +364,7 @@ module ActiveRecord
|
|
363
364
|
# t.references :tagger, polymorphic: true
|
364
365
|
# t.references :taggable, polymorphic: { default: 'Photo' }, index: false
|
365
366
|
# end
|
366
|
-
def column(name, type, options
|
367
|
+
def column(name, type, **options)
|
367
368
|
name = name.to_s
|
368
369
|
type = type.to_sym if type
|
369
370
|
options = options.dup
|
@@ -397,10 +398,7 @@ module ActiveRecord
|
|
397
398
|
end
|
398
399
|
|
399
400
|
def foreign_key(table_name, options = {}) # :nodoc:
|
400
|
-
|
401
|
-
table_name_suffix = ActiveRecord::Base.table_name_suffix
|
402
|
-
table_name = "#{table_name_prefix}#{table_name}#{table_name_suffix}"
|
403
|
-
foreign_keys.push([table_name, options])
|
401
|
+
foreign_keys << [table_name, options]
|
404
402
|
end
|
405
403
|
|
406
404
|
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
|
@@ -410,6 +408,10 @@ module ActiveRecord
|
|
410
408
|
def timestamps(**options)
|
411
409
|
options[:null] = false if options[:null].nil?
|
412
410
|
|
411
|
+
if !options.key?(:precision) && @conn.supports_datetime_with_precision?
|
412
|
+
options[:precision] = 6
|
413
|
+
end
|
414
|
+
|
413
415
|
column(:created_at, :datetime, options)
|
414
416
|
column(:updated_at, :datetime, options)
|
415
417
|
end
|
@@ -517,6 +519,7 @@ module ActiveRecord
|
|
517
519
|
# t.json
|
518
520
|
# t.virtual
|
519
521
|
# t.remove
|
522
|
+
# t.remove_foreign_key
|
520
523
|
# t.remove_references
|
521
524
|
# t.remove_belongs_to
|
522
525
|
# t.remove_index
|
@@ -538,7 +541,7 @@ module ActiveRecord
|
|
538
541
|
# t.column(:name, :string)
|
539
542
|
#
|
540
543
|
# See TableDefinition#column for details of the options you can use.
|
541
|
-
def column(column_name, type, options
|
544
|
+
def column(column_name, type, **options)
|
542
545
|
index_options = options.delete(:index)
|
543
546
|
@base.add_column(name, column_name, type, options)
|
544
547
|
index(column_name, index_options.is_a?(Hash) ? index_options : {}) if index_options
|
@@ -680,15 +683,26 @@ module ActiveRecord
|
|
680
683
|
end
|
681
684
|
alias :remove_belongs_to :remove_references
|
682
685
|
|
683
|
-
# Adds a foreign key.
|
686
|
+
# Adds a foreign key to the table using a supplied table name.
|
684
687
|
#
|
685
688
|
# t.foreign_key(:authors)
|
689
|
+
# t.foreign_key(:authors, column: :author_id, primary_key: "id")
|
686
690
|
#
|
687
691
|
# See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
|
688
692
|
def foreign_key(*args)
|
689
693
|
@base.add_foreign_key(name, *args)
|
690
694
|
end
|
691
695
|
|
696
|
+
# Removes the given foreign key from the table.
|
697
|
+
#
|
698
|
+
# t.remove_foreign_key(:authors)
|
699
|
+
# t.remove_foreign_key(column: :author_id)
|
700
|
+
#
|
701
|
+
# See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
|
702
|
+
def remove_foreign_key(*args)
|
703
|
+
@base.remove_foreign_key(name, *args)
|
704
|
+
end
|
705
|
+
|
692
706
|
# Checks to see if a foreign key exists.
|
693
707
|
#
|
694
708
|
# t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
|
@@ -130,11 +130,11 @@ module ActiveRecord
|
|
130
130
|
# column_exists?(:suppliers, :name, :string, null: false)
|
131
131
|
# column_exists?(:suppliers, :tax, :decimal, precision: 8, scale: 2)
|
132
132
|
#
|
133
|
-
def column_exists?(table_name, column_name, type = nil, options
|
133
|
+
def column_exists?(table_name, column_name, type = nil, **options)
|
134
134
|
column_name = column_name.to_s
|
135
135
|
checks = []
|
136
136
|
checks << lambda { |c| c.name == column_name }
|
137
|
-
checks << lambda { |c| c.type == type } if type
|
137
|
+
checks << lambda { |c| c.type == type.to_sym rescue nil } if type
|
138
138
|
column_options_keys.each do |attr|
|
139
139
|
checks << lambda { |c| c.send(attr) == options[attr] } if options.key?(attr)
|
140
140
|
end
|
@@ -584,7 +584,7 @@ module ActiveRecord
|
|
584
584
|
# # Defines a column with a database-specific type.
|
585
585
|
# add_column(:shapes, :triangle, 'polygon')
|
586
586
|
# # ALTER TABLE "shapes" ADD "triangle" polygon
|
587
|
-
def add_column(table_name, column_name, type, options
|
587
|
+
def add_column(table_name, column_name, type, **options)
|
588
588
|
at = create_alter_table table_name
|
589
589
|
at.add_column(column_name, type, options)
|
590
590
|
execute schema_creation.accept at
|
@@ -852,7 +852,7 @@ module ActiveRecord
|
|
852
852
|
# [<tt>:null</tt>]
|
853
853
|
# Whether the column allows nulls. Defaults to true.
|
854
854
|
#
|
855
|
-
# ====== Create a user_id bigint column without
|
855
|
+
# ====== Create a user_id bigint column without an index
|
856
856
|
#
|
857
857
|
# add_reference(:products, :user, index: false)
|
858
858
|
#
|
@@ -1029,9 +1029,7 @@ module ActiveRecord
|
|
1029
1029
|
end
|
1030
1030
|
|
1031
1031
|
def foreign_key_column_for(table_name) # :nodoc:
|
1032
|
-
|
1033
|
-
suffix = Base.table_name_suffix
|
1034
|
-
name = table_name.to_s =~ /#{prefix}(.+)#{suffix}/ ? $1 : table_name.to_s
|
1032
|
+
name = strip_table_name_prefix_and_suffix(table_name)
|
1035
1033
|
"#{name.singularize}_id"
|
1036
1034
|
end
|
1037
1035
|
|
@@ -1129,6 +1127,10 @@ module ActiveRecord
|
|
1129
1127
|
def add_timestamps(table_name, options = {})
|
1130
1128
|
options[:null] = false if options[:null].nil?
|
1131
1129
|
|
1130
|
+
if !options.key?(:precision) && supports_datetime_with_precision?
|
1131
|
+
options[:precision] = 6
|
1132
|
+
end
|
1133
|
+
|
1132
1134
|
add_column table_name, :created_at, :datetime, options
|
1133
1135
|
add_column table_name, :updated_at, :datetime, options
|
1134
1136
|
end
|
@@ -1290,7 +1292,7 @@ module ActiveRecord
|
|
1290
1292
|
end
|
1291
1293
|
|
1292
1294
|
def create_table_definition(*args)
|
1293
|
-
TableDefinition.new(*args)
|
1295
|
+
TableDefinition.new(self, *args)
|
1294
1296
|
end
|
1295
1297
|
|
1296
1298
|
def create_alter_table(name)
|
@@ -1324,6 +1326,12 @@ module ActiveRecord
|
|
1324
1326
|
{ column: column_names }
|
1325
1327
|
end
|
1326
1328
|
|
1329
|
+
def strip_table_name_prefix_and_suffix(table_name)
|
1330
|
+
prefix = Base.table_name_prefix
|
1331
|
+
suffix = Base.table_name_suffix
|
1332
|
+
table_name.to_s =~ /#{prefix}(.+)#{suffix}/ ? $1 : table_name.to_s
|
1333
|
+
end
|
1334
|
+
|
1327
1335
|
def foreign_key_name(table_name, options)
|
1328
1336
|
options.fetch(:name) do
|
1329
1337
|
identifier = "#{table_name}_#{options.fetch(:column)}_fk"
|
@@ -205,9 +205,12 @@ module ActiveRecord
|
|
205
205
|
run_commit_callbacks: run_commit_callbacks)
|
206
206
|
end
|
207
207
|
|
208
|
-
|
208
|
+
if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && options[:_lazy] != false
|
209
|
+
@has_unmaterialized_transactions = true
|
210
|
+
else
|
211
|
+
transaction.materialize!
|
212
|
+
end
|
209
213
|
@stack.push(transaction)
|
210
|
-
@has_unmaterialized_transactions = true if @connection.supports_lazy_transactions?
|
211
214
|
transaction
|
212
215
|
end
|
213
216
|
end
|