activerecord 5.0.7 → 5.1.7
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 +5 -5
- data/CHANGELOG.md +657 -2080
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/examples/performance.rb +28 -28
- data/examples/simple.rb +3 -3
- data/lib/active_record/aggregations.rb +244 -244
- data/lib/active_record/association_relation.rb +5 -5
- data/lib/active_record/associations/alias_tracker.rb +10 -11
- data/lib/active_record/associations/association.rb +23 -5
- data/lib/active_record/associations/association_scope.rb +95 -81
- data/lib/active_record/associations/belongs_to_association.rb +7 -4
- data/lib/active_record/associations/builder/belongs_to.rb +30 -16
- data/lib/active_record/associations/builder/collection_association.rb +1 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
- data/lib/active_record/associations/collection_association.rb +36 -205
- data/lib/active_record/associations/collection_proxy.rb +132 -63
- data/lib/active_record/associations/has_many_association.rb +10 -19
- data/lib/active_record/associations/has_many_through_association.rb +12 -4
- data/lib/active_record/associations/has_one_association.rb +24 -28
- data/lib/active_record/associations/has_one_through_association.rb +5 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +4 -28
- data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +121 -118
- data/lib/active_record/associations/preloader/association.rb +64 -64
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
- data/lib/active_record/associations/preloader/collection_association.rb +6 -6
- data/lib/active_record/associations/preloader/has_many.rb +0 -2
- data/lib/active_record/associations/preloader/singular_association.rb +6 -8
- data/lib/active_record/associations/preloader/through_association.rb +41 -41
- data/lib/active_record/associations/preloader.rb +94 -94
- data/lib/active_record/associations/singular_association.rb +8 -25
- data/lib/active_record/associations/through_association.rb +2 -5
- data/lib/active_record/associations.rb +1591 -1562
- data/lib/active_record/attribute/user_provided_default.rb +4 -2
- data/lib/active_record/attribute.rb +98 -71
- data/lib/active_record/attribute_assignment.rb +61 -61
- data/lib/active_record/attribute_decorators.rb +35 -13
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
- data/lib/active_record/attribute_methods/dirty.rb +229 -46
- data/lib/active_record/attribute_methods/primary_key.rb +74 -73
- data/lib/active_record/attribute_methods/read.rb +39 -35
- data/lib/active_record/attribute_methods/serialization.rb +7 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
- data/lib/active_record/attribute_methods/write.rb +30 -33
- data/lib/active_record/attribute_methods.rb +56 -65
- data/lib/active_record/attribute_mutation_tracker.rb +63 -11
- data/lib/active_record/attribute_set/builder.rb +27 -33
- data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
- data/lib/active_record/attribute_set.rb +9 -6
- data/lib/active_record/attributes.rb +22 -22
- data/lib/active_record/autosave_association.rb +18 -13
- data/lib/active_record/base.rb +24 -22
- data/lib/active_record/callbacks.rb +56 -14
- data/lib/active_record/coders/yaml_column.rb +9 -11
- data/lib/active_record/collection_cache_key.rb +3 -4
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +330 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +39 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +32 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -51
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +10 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +74 -79
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +120 -100
- data/lib/active_record/connection_adapters/abstract/transaction.rb +49 -43
- data/lib/active_record/connection_adapters/abstract_adapter.rb +165 -135
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +404 -424
- data/lib/active_record/connection_adapters/column.rb +26 -4
- data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
- data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -28
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +7 -6
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +23 -27
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +32 -53
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +0 -10
- data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +32 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
- data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -35
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +182 -222
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +6 -4
- data/lib/active_record/connection_adapters/postgresql/utils.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +198 -167
- data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +32 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +184 -167
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
- data/lib/active_record/connection_handling.rb +14 -26
- data/lib/active_record/core.rb +109 -93
- data/lib/active_record/counter_cache.rb +60 -13
- data/lib/active_record/define_callbacks.rb +20 -0
- data/lib/active_record/dynamic_matchers.rb +80 -79
- data/lib/active_record/enum.rb +8 -6
- data/lib/active_record/errors.rb +64 -15
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/explain_registry.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +7 -4
- data/lib/active_record/fixture_set/file.rb +11 -8
- data/lib/active_record/fixtures.rb +66 -53
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +93 -79
- data/lib/active_record/integration.rb +7 -7
- data/lib/active_record/internal_metadata.rb +3 -16
- data/lib/active_record/legacy_yaml_adapter.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +69 -74
- data/lib/active_record/locking/pessimistic.rb +10 -1
- data/lib/active_record/log_subscriber.rb +23 -28
- data/lib/active_record/migration/command_recorder.rb +94 -94
- data/lib/active_record/migration/compatibility.rb +100 -47
- data/lib/active_record/migration/join_table.rb +6 -6
- data/lib/active_record/migration.rb +153 -155
- data/lib/active_record/model_schema.rb +94 -107
- data/lib/active_record/nested_attributes.rb +200 -199
- data/lib/active_record/null_relation.rb +11 -34
- data/lib/active_record/persistence.rb +65 -50
- data/lib/active_record/query_cache.rb +2 -6
- data/lib/active_record/querying.rb +3 -4
- data/lib/active_record/railtie.rb +16 -17
- data/lib/active_record/railties/controller_runtime.rb +6 -2
- data/lib/active_record/railties/databases.rake +105 -133
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +2 -2
- data/lib/active_record/reflection.rb +154 -108
- data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
- data/lib/active_record/relation/batches.rb +80 -51
- data/lib/active_record/relation/calculations.rb +169 -162
- data/lib/active_record/relation/delegation.rb +32 -31
- data/lib/active_record/relation/finder_methods.rb +197 -231
- data/lib/active_record/relation/merger.rb +58 -62
- data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
- data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
- data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
- data/lib/active_record/relation/predicate_builder.rb +92 -89
- data/lib/active_record/relation/query_attribute.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +255 -293
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +4 -5
- data/lib/active_record/relation/where_clause.rb +80 -65
- data/lib/active_record/relation/where_clause_factory.rb +47 -8
- data/lib/active_record/relation.rb +93 -119
- data/lib/active_record/result.rb +41 -32
- data/lib/active_record/runtime_registry.rb +3 -3
- data/lib/active_record/sanitization.rb +176 -192
- data/lib/active_record/schema.rb +3 -3
- data/lib/active_record/schema_dumper.rb +15 -38
- data/lib/active_record/schema_migration.rb +8 -4
- data/lib/active_record/scoping/default.rb +90 -90
- data/lib/active_record/scoping/named.rb +11 -11
- data/lib/active_record/scoping.rb +6 -6
- data/lib/active_record/secure_token.rb +2 -2
- data/lib/active_record/statement_cache.rb +13 -15
- data/lib/active_record/store.rb +31 -32
- data/lib/active_record/suppressor.rb +2 -1
- data/lib/active_record/table_metadata.rb +9 -5
- data/lib/active_record/tasks/database_tasks.rb +65 -55
- data/lib/active_record/tasks/mysql_database_tasks.rb +76 -73
- data/lib/active_record/tasks/postgresql_database_tasks.rb +72 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
- data/lib/active_record/timestamp.rb +46 -25
- data/lib/active_record/touch_later.rb +1 -2
- data/lib/active_record/transactions.rb +97 -109
- data/lib/active_record/type/adapter_specific_registry.rb +46 -42
- data/lib/active_record/type/decimal_without_scale.rb +13 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
- data/lib/active_record/type/internal/abstract_json.rb +4 -0
- data/lib/active_record/type/serialized.rb +14 -8
- data/lib/active_record/type/text.rb +9 -0
- data/lib/active_record/type/time.rb +0 -1
- data/lib/active_record/type/type_map.rb +11 -15
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type.rb +17 -13
- data/lib/active_record/type_caster/connection.rb +8 -6
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.rb +2 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +8 -39
- data/lib/active_record/validations.rb +4 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +20 -20
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
- data/lib/rails/generators/active_record/migration.rb +1 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
- data/lib/rails/generators/active_record.rb +4 -4
- metadata +24 -13
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -60,13 +60,7 @@ module ActiveRecord
|
|
60
60
|
end
|
61
61
|
|
62
62
|
private
|
63
|
-
def
|
64
|
-
lock_col = self.class.locking_column
|
65
|
-
previous_lock_value = send(lock_col).to_i
|
66
|
-
send(lock_col + '=', previous_lock_value + 1)
|
67
|
-
end
|
68
|
-
|
69
|
-
def _create_record(attribute_names = self.attribute_names, *) # :nodoc:
|
63
|
+
def _create_record(attribute_names = self.attribute_names, *)
|
70
64
|
if locking_enabled?
|
71
65
|
# We always want to persist the locking version, even if we don't detect
|
72
66
|
# a change from the default, since the database might have no default
|
@@ -75,38 +69,37 @@ module ActiveRecord
|
|
75
69
|
super
|
76
70
|
end
|
77
71
|
|
78
|
-
def
|
72
|
+
def _touch_row(attribute_names, time)
|
73
|
+
super
|
74
|
+
ensure
|
75
|
+
clear_attribute_change(self.class.locking_column) if locking_enabled?
|
76
|
+
end
|
77
|
+
|
78
|
+
def _update_row(attribute_names, attempted_action = "update")
|
79
79
|
return super unless locking_enabled?
|
80
|
-
return 0 if attribute_names.empty?
|
81
80
|
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
begin
|
82
|
+
locking_column = self.class.locking_column
|
83
|
+
previous_lock_value = read_attribute_before_type_cast(locking_column)
|
84
|
+
attribute_names << locking_column
|
85
85
|
|
86
|
-
|
87
|
-
attribute_names.uniq!
|
86
|
+
self[locking_column] += 1
|
88
87
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
self.class.primary_key => id,
|
94
|
-
lock_col => previous_lock_value,
|
95
|
-
).update_all(
|
96
|
-
attributes_for_update(attribute_names).map do |name|
|
97
|
-
[name, _read_attribute(name)]
|
98
|
-
end.to_h
|
88
|
+
affected_rows = self.class.unscoped._update_record(
|
89
|
+
arel_attributes_with_values(attribute_names),
|
90
|
+
self.class.primary_key => id_in_database,
|
91
|
+
locking_column => previous_lock_value
|
99
92
|
)
|
100
93
|
|
101
|
-
|
102
|
-
raise ActiveRecord::StaleObjectError.new(self,
|
94
|
+
if affected_rows != 1
|
95
|
+
raise ActiveRecord::StaleObjectError.new(self, attempted_action)
|
103
96
|
end
|
104
97
|
|
105
98
|
affected_rows
|
106
99
|
|
107
|
-
# If something went wrong, revert the
|
100
|
+
# If something went wrong, revert the locking_column value.
|
108
101
|
rescue Exception
|
109
|
-
|
102
|
+
self[locking_column] = previous_lock_value.to_i
|
110
103
|
raise
|
111
104
|
end
|
112
105
|
end
|
@@ -126,67 +119,69 @@ module ActiveRecord
|
|
126
119
|
|
127
120
|
if locking_enabled?
|
128
121
|
locking_column = self.class.locking_column
|
129
|
-
relation = relation.where(locking_column =>
|
122
|
+
relation = relation.where(locking_column => read_attribute_before_type_cast(locking_column))
|
130
123
|
end
|
131
124
|
|
132
125
|
relation
|
133
126
|
end
|
134
127
|
|
135
|
-
|
136
|
-
|
128
|
+
module ClassMethods
|
129
|
+
DEFAULT_LOCKING_COLUMN = "lock_version"
|
137
130
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
131
|
+
# Returns true if the +lock_optimistically+ flag is set to true
|
132
|
+
# (which it is, by default) and the table includes the
|
133
|
+
# +locking_column+ column (defaults to +lock_version+).
|
134
|
+
def locking_enabled?
|
135
|
+
lock_optimistically && columns_hash[locking_column]
|
136
|
+
end
|
144
137
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
138
|
+
# Set the column to use for optimistic locking. Defaults to +lock_version+.
|
139
|
+
def locking_column=(value)
|
140
|
+
reload_schema_from_cache
|
141
|
+
@locking_column = value.to_s
|
142
|
+
end
|
150
143
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
144
|
+
# The version column used for optimistic locking. Defaults to +lock_version+.
|
145
|
+
def locking_column
|
146
|
+
@locking_column = DEFAULT_LOCKING_COLUMN unless defined?(@locking_column)
|
147
|
+
@locking_column
|
148
|
+
end
|
156
149
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
150
|
+
# Reset the column used for optimistic locking back to the +lock_version+ default.
|
151
|
+
def reset_locking_column
|
152
|
+
self.locking_column = DEFAULT_LOCKING_COLUMN
|
153
|
+
end
|
161
154
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
155
|
+
# Make sure the lock version column gets updated when counters are
|
156
|
+
# updated.
|
157
|
+
def update_counters(id, counters)
|
158
|
+
counters = counters.merge(locking_column => 1) if locking_enabled?
|
159
|
+
super
|
160
|
+
end
|
168
161
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
162
|
+
private
|
163
|
+
|
164
|
+
# We need to apply this decorator here, rather than on module inclusion. The closure
|
165
|
+
# created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
|
166
|
+
# sub class being decorated. As such, changes to `lock_optimistically`, or
|
167
|
+
# `locking_column` would not be picked up.
|
168
|
+
def inherited(subclass)
|
169
|
+
subclass.class_eval do
|
170
|
+
is_lock_column = ->(name, _) { lock_optimistically && name == locking_column }
|
171
|
+
decorate_matching_attribute_types(is_lock_column, :_optimistic_locking) do |type|
|
172
|
+
LockingType.new(type)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
super
|
180
176
|
end
|
181
|
-
end
|
182
|
-
super
|
183
177
|
end
|
184
|
-
end
|
185
178
|
end
|
186
179
|
|
180
|
+
# In de/serialize we change `nil` to 0, so that we can allow passing
|
181
|
+
# `nil` values to `lock_version`, and not result in `ActiveRecord::StaleObjectError`
|
182
|
+
# during update record.
|
187
183
|
class LockingType < DelegateClass(Type::Value) # :nodoc:
|
188
184
|
def deserialize(value)
|
189
|
-
# `nil` *should* be changed to 0
|
190
185
|
super.to_i
|
191
186
|
end
|
192
187
|
|
@@ -195,11 +190,11 @@ module ActiveRecord
|
|
195
190
|
end
|
196
191
|
|
197
192
|
def init_with(coder)
|
198
|
-
__setobj__(coder[
|
193
|
+
__setobj__(coder["subtype"])
|
199
194
|
end
|
200
195
|
|
201
196
|
def encode_with(coder)
|
202
|
-
coder[
|
197
|
+
coder["subtype"] = __getobj__
|
203
198
|
end
|
204
199
|
end
|
205
200
|
end
|
@@ -59,7 +59,16 @@ module ActiveRecord
|
|
59
59
|
# or pass true for "FOR UPDATE" (the default, an exclusive row lock). Returns
|
60
60
|
# the locked record.
|
61
61
|
def lock!(lock = true)
|
62
|
-
|
62
|
+
if persisted?
|
63
|
+
if has_changes_to_save?
|
64
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
65
|
+
Locking a record with unpersisted changes is deprecated and will raise an
|
66
|
+
exception in Rails 5.2. Use `save` to persist the changes, or `reload` to
|
67
|
+
discard them explicitly.
|
68
|
+
MSG
|
69
|
+
end
|
70
|
+
reload(lock: lock)
|
71
|
+
end
|
63
72
|
self
|
64
73
|
end
|
65
74
|
|
@@ -15,11 +15,6 @@ module ActiveRecord
|
|
15
15
|
rt
|
16
16
|
end
|
17
17
|
|
18
|
-
def initialize
|
19
|
-
super
|
20
|
-
@odd = false
|
21
|
-
end
|
22
|
-
|
23
18
|
def sql(event)
|
24
19
|
self.class.runtime += event.duration
|
25
20
|
return unless logger.debug?
|
@@ -29,6 +24,7 @@ module ActiveRecord
|
|
29
24
|
return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
|
30
25
|
|
31
26
|
name = "#{payload[:name]} (#{event.duration.round(1)}ms)"
|
27
|
+
name = "CACHE #{name}" if payload[:cached]
|
32
28
|
sql = payload[:sql]
|
33
29
|
binds = nil
|
34
30
|
|
@@ -46,31 +42,30 @@ module ActiveRecord
|
|
46
42
|
end
|
47
43
|
|
48
44
|
private
|
45
|
+
def type_casted_binds(casted_binds)
|
46
|
+
casted_binds.respond_to?(:call) ? casted_binds.call : casted_binds
|
47
|
+
end
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
def render_bind(attr, value)
|
50
|
+
if attr.is_a?(Array)
|
51
|
+
attr = attr.first
|
52
|
+
elsif attr.type.binary? && attr.value
|
53
|
+
value = "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
|
54
|
+
end
|
53
55
|
|
54
|
-
|
55
|
-
if attr.is_a?(Array)
|
56
|
-
attr = attr.first
|
57
|
-
elsif attr.type.binary? && attr.value
|
58
|
-
value = "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
|
56
|
+
[attr && attr.name, value]
|
59
57
|
end
|
60
58
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
else
|
68
|
-
color(name, CYAN, true)
|
59
|
+
def colorize_payload_name(name, payload_name)
|
60
|
+
if payload_name.blank? || payload_name == "SQL" # SQL vs Model Load/Exists
|
61
|
+
color(name, MAGENTA, true)
|
62
|
+
else
|
63
|
+
color(name, CYAN, true)
|
64
|
+
end
|
69
65
|
end
|
70
|
-
end
|
71
66
|
|
72
|
-
|
73
|
-
|
67
|
+
def sql_color(sql)
|
68
|
+
case sql
|
74
69
|
when /\A\s*rollback/mi
|
75
70
|
RED
|
76
71
|
when /select .*for update/mi, /\A\s*lock/mi
|
@@ -87,12 +82,12 @@ module ActiveRecord
|
|
87
82
|
CYAN
|
88
83
|
else
|
89
84
|
MAGENTA
|
85
|
+
end
|
90
86
|
end
|
91
|
-
end
|
92
87
|
|
93
|
-
|
94
|
-
|
95
|
-
|
88
|
+
def logger
|
89
|
+
ActiveRecord::Base.logger
|
90
|
+
end
|
96
91
|
end
|
97
92
|
end
|
98
93
|
|
@@ -92,7 +92,7 @@ module ActiveRecord
|
|
92
92
|
send(method, args, &block)
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
95
|
+
def respond_to_missing?(*args) # :nodoc:
|
96
96
|
super || delegate.respond_to?(*args)
|
97
97
|
end
|
98
98
|
|
@@ -112,127 +112,127 @@ module ActiveRecord
|
|
112
112
|
|
113
113
|
private
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
115
|
+
module StraightReversions
|
116
|
+
private
|
117
|
+
{ transaction: :transaction,
|
118
|
+
execute_block: :execute_block,
|
119
|
+
create_table: :drop_table,
|
120
|
+
create_join_table: :drop_join_table,
|
121
|
+
add_column: :remove_column,
|
122
|
+
add_timestamps: :remove_timestamps,
|
123
|
+
add_reference: :remove_reference,
|
124
|
+
enable_extension: :disable_extension
|
125
|
+
}.each do |cmd, inv|
|
126
|
+
[[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
|
127
|
+
class_eval <<-EOV, __FILE__, __LINE__ + 1
|
128
|
+
def invert_#{method}(args, &block) # def invert_create_table(args, &block)
|
129
|
+
[:#{inverse}, args, block] # [:drop_table, args, block]
|
130
|
+
end # end
|
131
|
+
EOV
|
132
|
+
end
|
133
|
+
end
|
133
134
|
end
|
134
|
-
end
|
135
135
|
|
136
|
-
|
136
|
+
include StraightReversions
|
137
137
|
|
138
|
-
|
139
|
-
|
140
|
-
|
138
|
+
def invert_drop_table(args, &block)
|
139
|
+
if args.size == 1 && block == nil
|
140
|
+
raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
|
141
|
+
end
|
142
|
+
super
|
141
143
|
end
|
142
|
-
super
|
143
|
-
end
|
144
144
|
|
145
|
-
|
146
|
-
|
147
|
-
|
145
|
+
def invert_rename_table(args)
|
146
|
+
[:rename_table, args.reverse]
|
147
|
+
end
|
148
148
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
149
|
+
def invert_remove_column(args)
|
150
|
+
raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
|
151
|
+
super
|
152
|
+
end
|
153
153
|
|
154
|
-
|
155
|
-
|
156
|
-
|
154
|
+
def invert_rename_index(args)
|
155
|
+
[:rename_index, [args.first] + args.last(2).reverse]
|
156
|
+
end
|
157
157
|
|
158
|
-
|
159
|
-
|
160
|
-
|
158
|
+
def invert_rename_column(args)
|
159
|
+
[:rename_column, [args.first] + args.last(2).reverse]
|
160
|
+
end
|
161
161
|
|
162
|
-
|
163
|
-
|
164
|
-
|
162
|
+
def invert_add_index(args)
|
163
|
+
table, columns, options = *args
|
164
|
+
options ||= {}
|
165
165
|
|
166
|
-
|
167
|
-
|
166
|
+
index_name = options[:name]
|
167
|
+
options_hash = index_name ? { name: index_name } : { column: columns }
|
168
168
|
|
169
|
-
|
170
|
-
|
169
|
+
[:remove_index, [table, options_hash]]
|
170
|
+
end
|
171
171
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
172
|
+
def invert_remove_index(args)
|
173
|
+
table, options_or_column = *args
|
174
|
+
if (options = options_or_column).is_a?(Hash)
|
175
|
+
unless options[:column]
|
176
|
+
raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option."
|
177
|
+
end
|
178
|
+
options = options.dup
|
179
|
+
[:add_index, [table, options.delete(:column), options]]
|
180
|
+
elsif (column = options_or_column).present?
|
181
|
+
[:add_index, [table, column]]
|
177
182
|
end
|
178
|
-
options = options.dup
|
179
|
-
[:add_index, [table, options.delete(:column), options]]
|
180
|
-
elsif (column = options_or_column).present?
|
181
|
-
[:add_index, [table, column]]
|
182
183
|
end
|
183
|
-
end
|
184
184
|
|
185
|
-
|
186
|
-
|
185
|
+
alias :invert_add_belongs_to :invert_add_reference
|
186
|
+
alias :invert_remove_belongs_to :invert_remove_reference
|
187
|
+
|
188
|
+
def invert_change_column_default(args)
|
189
|
+
table, column, options = *args
|
187
190
|
|
188
|
-
|
189
|
-
|
191
|
+
unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
|
192
|
+
raise ActiveRecord::IrreversibleMigration, "change_column_default is only reversible if given a :from and :to option."
|
193
|
+
end
|
190
194
|
|
191
|
-
|
192
|
-
raise ActiveRecord::IrreversibleMigration, "change_column_default is only reversible if given a :from and :to option."
|
195
|
+
[:change_column_default, [table, column, from: options[:to], to: options[:from]]]
|
193
196
|
end
|
194
197
|
|
195
|
-
|
196
|
-
|
198
|
+
def invert_change_column_null(args)
|
199
|
+
args[2] = !args[2]
|
200
|
+
[:change_column_null, args]
|
201
|
+
end
|
197
202
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
end
|
203
|
+
def invert_add_foreign_key(args)
|
204
|
+
from_table, to_table, add_options = args
|
205
|
+
add_options ||= {}
|
202
206
|
|
203
|
-
|
204
|
-
|
205
|
-
|
207
|
+
if add_options[:name]
|
208
|
+
options = { name: add_options[:name] }
|
209
|
+
elsif add_options[:column]
|
210
|
+
options = { column: add_options[:column] }
|
211
|
+
else
|
212
|
+
options = to_table
|
213
|
+
end
|
206
214
|
|
207
|
-
|
208
|
-
options = { name: add_options[:name] }
|
209
|
-
elsif add_options[:column]
|
210
|
-
options = { column: add_options[:column] }
|
211
|
-
else
|
212
|
-
options = to_table
|
215
|
+
[:remove_foreign_key, [from_table, options]]
|
213
216
|
end
|
214
217
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
def invert_remove_foreign_key(args)
|
219
|
-
from_table, to_table, remove_options = args
|
220
|
-
raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil? || to_table.is_a?(Hash)
|
218
|
+
def invert_remove_foreign_key(args)
|
219
|
+
from_table, to_table, remove_options = args
|
220
|
+
raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil? || to_table.is_a?(Hash)
|
221
221
|
|
222
|
-
|
223
|
-
|
222
|
+
reversed_args = [from_table, to_table]
|
223
|
+
reversed_args << remove_options if remove_options
|
224
224
|
|
225
|
-
|
226
|
-
|
225
|
+
[:add_foreign_key, reversed_args]
|
226
|
+
end
|
227
227
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
228
|
+
# Forwards any missing method call to the \target.
|
229
|
+
def method_missing(method, *args, &block)
|
230
|
+
if @delegate.respond_to?(method)
|
231
|
+
@delegate.send(method, *args, &block)
|
232
|
+
else
|
233
|
+
super
|
234
|
+
end
|
234
235
|
end
|
235
|
-
end
|
236
236
|
end
|
237
237
|
end
|
238
238
|
end
|