activerecord 4.1.8 → 4.2.11.3
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.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1165 -1591
- data/README.rdoc +15 -10
- data/lib/active_record/aggregations.rb +15 -8
- data/lib/active_record/association_relation.rb +13 -0
- data/lib/active_record/associations/alias_tracker.rb +3 -12
- data/lib/active_record/associations/association.rb +16 -4
- data/lib/active_record/associations/association_scope.rb +84 -43
- data/lib/active_record/associations/belongs_to_association.rb +28 -10
- data/lib/active_record/associations/builder/association.rb +16 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -29
- data/lib/active_record/associations/builder/collection_association.rb +5 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +9 -14
- data/lib/active_record/associations/builder/has_many.rb +1 -1
- data/lib/active_record/associations/builder/has_one.rb +2 -2
- data/lib/active_record/associations/builder/singular_association.rb +8 -1
- data/lib/active_record/associations/collection_association.rb +87 -30
- data/lib/active_record/associations/collection_proxy.rb +33 -35
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +83 -22
- data/lib/active_record/associations/has_many_through_association.rb +49 -26
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +25 -15
- data/lib/active_record/associations/join_dependency/join_part.rb +0 -1
- data/lib/active_record/associations/join_dependency.rb +26 -12
- data/lib/active_record/associations/preloader/association.rb +14 -10
- data/lib/active_record/associations/preloader/through_association.rb +4 -3
- data/lib/active_record/associations/preloader.rb +37 -26
- data/lib/active_record/associations/singular_association.rb +17 -2
- data/lib/active_record/associations/through_association.rb +16 -12
- data/lib/active_record/associations.rb +158 -49
- data/lib/active_record/attribute.rb +163 -0
- data/lib/active_record/attribute_assignment.rb +20 -12
- data/lib/active_record/attribute_decorators.rb +66 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +107 -43
- data/lib/active_record/attribute_methods/primary_key.rb +7 -8
- data/lib/active_record/attribute_methods/query.rb +1 -1
- data/lib/active_record/attribute_methods/read.rb +22 -59
- data/lib/active_record/attribute_methods/serialization.rb +16 -150
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -28
- data/lib/active_record/attribute_methods/write.rb +9 -24
- data/lib/active_record/attribute_methods.rb +57 -95
- data/lib/active_record/attribute_set/builder.rb +106 -0
- data/lib/active_record/attribute_set.rb +81 -0
- data/lib/active_record/attributes.rb +147 -0
- data/lib/active_record/autosave_association.rb +30 -12
- data/lib/active_record/base.rb +13 -24
- data/lib/active_record/callbacks.rb +6 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +85 -53
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +52 -50
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +60 -60
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +39 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +139 -57
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -34
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +271 -74
- data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -118
- data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -60
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +295 -141
- data/lib/active_record/connection_adapters/column.rb +29 -240
- data/lib/active_record/connection_adapters/connection_specification.rb +15 -24
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +17 -33
- data/lib/active_record/connection_adapters/mysql_adapter.rb +68 -145
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +15 -27
- data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -25
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +100 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +29 -385
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +46 -136
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +134 -43
- data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -477
- data/lib/active_record/connection_adapters/schema_cache.rb +14 -28
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -75
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +163 -40
- data/lib/active_record/counter_cache.rb +60 -6
- data/lib/active_record/enum.rb +10 -12
- data/lib/active_record/errors.rb +53 -30
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixtures.rb +62 -74
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +35 -10
- data/lib/active_record/integration.rb +4 -4
- data/lib/active_record/legacy_yaml_adapter.rb +30 -0
- data/lib/active_record/locking/optimistic.rb +46 -26
- data/lib/active_record/migration/command_recorder.rb +19 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +79 -47
- data/lib/active_record/model_schema.rb +52 -58
- data/lib/active_record/nested_attributes.rb +18 -8
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +48 -27
- data/lib/active_record/query_cache.rb +3 -3
- data/lib/active_record/querying.rb +10 -7
- data/lib/active_record/railtie.rb +19 -14
- data/lib/active_record/railties/databases.rake +55 -56
- data/lib/active_record/readonly_attributes.rb +0 -1
- data/lib/active_record/reflection.rb +281 -117
- data/lib/active_record/relation/batches.rb +0 -1
- data/lib/active_record/relation/calculations.rb +41 -37
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +71 -48
- data/lib/active_record/relation/merger.rb +39 -29
- data/lib/active_record/relation/predicate_builder/array_handler.rb +32 -13
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +42 -12
- data/lib/active_record/relation/query_methods.rb +130 -73
- data/lib/active_record/relation/spawn_methods.rb +10 -3
- data/lib/active_record/relation.rb +57 -25
- data/lib/active_record/result.rb +18 -7
- data/lib/active_record/sanitization.rb +12 -2
- data/lib/active_record/schema.rb +0 -1
- data/lib/active_record/schema_dumper.rb +59 -28
- data/lib/active_record/schema_migration.rb +5 -4
- data/lib/active_record/scoping/default.rb +6 -4
- data/lib/active_record/scoping/named.rb +4 -0
- data/lib/active_record/serializers/xml_serializer.rb +3 -7
- data/lib/active_record/statement_cache.rb +95 -10
- data/lib/active_record/store.rb +5 -5
- data/lib/active_record/tasks/database_tasks.rb +61 -8
- data/lib/active_record/tasks/mysql_database_tasks.rb +32 -17
- data/lib/active_record/tasks/postgresql_database_tasks.rb +20 -9
- data/lib/active_record/timestamp.rb +9 -7
- data/lib/active_record/transactions.rb +54 -28
- data/lib/active_record/type/big_integer.rb +13 -0
- data/lib/active_record/type/binary.rb +50 -0
- data/lib/active_record/type/boolean.rb +31 -0
- data/lib/active_record/type/date.rb +50 -0
- data/lib/active_record/type/date_time.rb +54 -0
- data/lib/active_record/type/decimal.rb +64 -0
- data/lib/active_record/type/decimal_without_scale.rb +11 -0
- data/lib/active_record/type/decorator.rb +14 -0
- data/lib/active_record/type/float.rb +19 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
- data/lib/active_record/type/integer.rb +59 -0
- data/lib/active_record/type/mutable.rb +16 -0
- data/lib/active_record/type/numeric.rb +36 -0
- data/lib/active_record/type/serialized.rb +62 -0
- data/lib/active_record/type/string.rb +40 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +26 -0
- data/lib/active_record/type/time_value.rb +38 -0
- data/lib/active_record/type/type_map.rb +64 -0
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type/value.rb +110 -0
- data/lib/active_record/type.rb +23 -0
- data/lib/active_record/validations/associated.rb +5 -3
- data/lib/active_record/validations/presence.rb +5 -3
- data/lib/active_record/validations/uniqueness.rb +24 -20
- data/lib/active_record/validations.rb +25 -19
- data/lib/active_record.rb +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -4
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb +1 -1
- metadata +66 -11
- data/lib/active_record/connection_adapters/postgresql/cast.rb +0 -168
@@ -36,6 +36,23 @@ module ActiveRecord
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
# Creates an object (or multiple objects) and saves it to the database,
|
40
|
+
# if validations pass. Raises a RecordInvalid error if validations fail,
|
41
|
+
# unlike Base#create.
|
42
|
+
#
|
43
|
+
# The +attributes+ parameter can be either a Hash or an Array of Hashes.
|
44
|
+
# These describe which attributes to be created on the object, or
|
45
|
+
# multiple objects when given an Array of Hashes.
|
46
|
+
def create!(attributes = nil, &block)
|
47
|
+
if attributes.is_a?(Array)
|
48
|
+
attributes.collect { |attr| create!(attr, &block) }
|
49
|
+
else
|
50
|
+
object = new(attributes, &block)
|
51
|
+
object.save!
|
52
|
+
object
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
39
56
|
# Given an attributes hash, +instantiate+ returns a new instance of
|
40
57
|
# the appropriate class. Accepts only keys as strings.
|
41
58
|
#
|
@@ -48,8 +65,8 @@ module ActiveRecord
|
|
48
65
|
# how this "single-table" inheritance mapping is implemented.
|
49
66
|
def instantiate(attributes, column_types = {})
|
50
67
|
klass = discriminate_class_for_record(attributes)
|
51
|
-
|
52
|
-
klass.allocate.init_with('attributes' => attributes, '
|
68
|
+
attributes = klass.attributes_builder.build_from_database(attributes, column_types)
|
69
|
+
klass.allocate.init_with('attributes' => attributes, 'new_record' => false)
|
53
70
|
end
|
54
71
|
|
55
72
|
private
|
@@ -122,7 +139,7 @@ module ActiveRecord
|
|
122
139
|
# Attributes marked as readonly are silently ignored if the record is
|
123
140
|
# being updated.
|
124
141
|
def save!(*)
|
125
|
-
create_or_update || raise(RecordNotSaved)
|
142
|
+
create_or_update || raise(RecordNotSaved.new("Failed to save the record", self))
|
126
143
|
end
|
127
144
|
|
128
145
|
# Deletes the record in the database and freezes this instance to
|
@@ -149,8 +166,9 @@ module ActiveRecord
|
|
149
166
|
# and <tt>destroy</tt> returns +false+. See
|
150
167
|
# ActiveRecord::Callbacks for further details.
|
151
168
|
def destroy
|
152
|
-
raise ReadOnlyRecord if readonly?
|
169
|
+
raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
|
153
170
|
destroy_associations
|
171
|
+
self.class.connection.add_transaction_record(self)
|
154
172
|
destroy_row if persisted?
|
155
173
|
@destroyed = true
|
156
174
|
freeze
|
@@ -164,7 +182,7 @@ module ActiveRecord
|
|
164
182
|
# and <tt>destroy!</tt> raises ActiveRecord::RecordNotDestroyed. See
|
165
183
|
# ActiveRecord::Callbacks for further details.
|
166
184
|
def destroy!
|
167
|
-
destroy || raise(
|
185
|
+
destroy || raise(RecordNotDestroyed.new("Failed to destroy the record", self))
|
168
186
|
end
|
169
187
|
|
170
188
|
# Returns an instance of the specified +klass+ with the attributes of the
|
@@ -180,8 +198,8 @@ module ActiveRecord
|
|
180
198
|
def becomes(klass)
|
181
199
|
became = klass.new
|
182
200
|
became.instance_variable_set("@attributes", @attributes)
|
183
|
-
|
184
|
-
became.instance_variable_set("@changed_attributes",
|
201
|
+
changed_attributes = @changed_attributes if defined?(@changed_attributes)
|
202
|
+
became.instance_variable_set("@changed_attributes", changed_attributes || {})
|
185
203
|
became.instance_variable_set("@new_record", new_record?)
|
186
204
|
became.instance_variable_set("@destroyed", destroyed?)
|
187
205
|
became.instance_variable_set("@errors", errors)
|
@@ -214,6 +232,8 @@ module ActiveRecord
|
|
214
232
|
#
|
215
233
|
# This method raises an +ActiveRecord::ActiveRecordError+ if the
|
216
234
|
# attribute is marked as readonly.
|
235
|
+
#
|
236
|
+
# See also +update_column+.
|
217
237
|
def update_attribute(name, value)
|
218
238
|
name = name.to_s
|
219
239
|
verify_readonly_attribute(name)
|
@@ -269,7 +289,8 @@ module ActiveRecord
|
|
269
289
|
# This method raises an +ActiveRecord::ActiveRecordError+ when called on new
|
270
290
|
# objects, or when at least one of the attributes is marked as readonly.
|
271
291
|
def update_columns(attributes)
|
272
|
-
raise ActiveRecordError, "cannot update
|
292
|
+
raise ActiveRecordError, "cannot update a new record" if new_record?
|
293
|
+
raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
|
273
294
|
|
274
295
|
attributes.each_key do |key|
|
275
296
|
verify_readonly_attribute(key.to_s)
|
@@ -348,7 +369,7 @@ module ActiveRecord
|
|
348
369
|
# # => #<Account id: 1, email: 'account@example.com'>
|
349
370
|
#
|
350
371
|
# Attributes are reloaded from the database, and caches busted, in
|
351
|
-
# particular the associations cache.
|
372
|
+
# particular the associations cache and the QueryCache.
|
352
373
|
#
|
353
374
|
# If the record no longer exists in the database <tt>ActiveRecord::RecordNotFound</tt>
|
354
375
|
# is raised. Otherwise, in addition to the in-place modification the method
|
@@ -386,6 +407,7 @@ module ActiveRecord
|
|
386
407
|
def reload(options = nil)
|
387
408
|
clear_aggregation_cache
|
388
409
|
clear_association_cache
|
410
|
+
self.class.connection.clear_query_cache
|
389
411
|
|
390
412
|
fresh_object =
|
391
413
|
if options && options[:lock]
|
@@ -394,25 +416,24 @@ module ActiveRecord
|
|
394
416
|
self.class.unscoped { self.class.find(id) }
|
395
417
|
end
|
396
418
|
|
397
|
-
@attributes
|
398
|
-
|
399
|
-
@column_types = self.class.column_types
|
400
|
-
@column_types_override = fresh_object.instance_variable_get('@column_types_override')
|
401
|
-
@attributes_cache = {}
|
402
|
-
@new_record = false
|
419
|
+
@attributes = fresh_object.instance_variable_get('@attributes')
|
420
|
+
@new_record = false
|
403
421
|
self
|
404
422
|
end
|
405
423
|
|
406
424
|
# Saves the record with the updated_at/on attributes set to the current time.
|
407
425
|
# Please note that no validation is performed and only the +after_touch+,
|
408
426
|
# +after_commit+ and +after_rollback+ callbacks are executed.
|
409
|
-
# If an attribute name is passed, that attribute is updated along with
|
410
|
-
# updated_at/on attributes.
|
411
427
|
#
|
412
|
-
#
|
413
|
-
#
|
428
|
+
# If attribute names are passed, they are updated along with updated_at/on
|
429
|
+
# attributes.
|
430
|
+
#
|
431
|
+
# product.touch # updates updated_at/on
|
432
|
+
# product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
|
433
|
+
# product.touch(:started_at, :ended_at) # updates started_at, ended_at and updated_at/on attributes
|
414
434
|
#
|
415
|
-
# If used along with +belongs_to+ then +touch+ will invoke +touch+ method on
|
435
|
+
# If used along with +belongs_to+ then +touch+ will invoke +touch+ method on
|
436
|
+
# associated object.
|
416
437
|
#
|
417
438
|
# class Brake < ActiveRecord::Base
|
418
439
|
# belongs_to :car, touch: true
|
@@ -431,11 +452,11 @@ module ActiveRecord
|
|
431
452
|
# ball = Ball.new
|
432
453
|
# ball.touch(:updated_at) # => raises ActiveRecordError
|
433
454
|
#
|
434
|
-
def touch(
|
455
|
+
def touch(*names)
|
435
456
|
raise ActiveRecordError, "cannot touch on a new record object" unless persisted?
|
436
457
|
|
437
458
|
attributes = timestamp_attributes_for_update_in_model
|
438
|
-
attributes
|
459
|
+
attributes.concat(names)
|
439
460
|
|
440
461
|
unless attributes.empty?
|
441
462
|
current_time = current_time_from_proper_timezone
|
@@ -448,7 +469,7 @@ module ActiveRecord
|
|
448
469
|
|
449
470
|
changes[self.class.locking_column] = increment_lock if locking_enabled?
|
450
471
|
|
451
|
-
|
472
|
+
clear_attribute_changes(changes.keys)
|
452
473
|
primary_key = self.class.primary_key
|
453
474
|
self.class.unscoped.where(primary_key => self[primary_key]).update_all(changes) == 1
|
454
475
|
else
|
@@ -469,7 +490,7 @@ module ActiveRecord
|
|
469
490
|
def relation_for_destroy
|
470
491
|
pk = self.class.primary_key
|
471
492
|
column = self.class.columns_hash[pk]
|
472
|
-
substitute = self.class.connection.substitute_at(column
|
493
|
+
substitute = self.class.connection.substitute_at(column)
|
473
494
|
|
474
495
|
relation = self.class.unscoped.where(
|
475
496
|
self.class.arel_table[pk].eq(substitute))
|
@@ -479,14 +500,14 @@ module ActiveRecord
|
|
479
500
|
end
|
480
501
|
|
481
502
|
def create_or_update
|
482
|
-
raise ReadOnlyRecord if readonly?
|
503
|
+
raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
|
483
504
|
result = new_record? ? _create_record : _update_record
|
484
505
|
result != false
|
485
506
|
end
|
486
507
|
|
487
508
|
# Updates the associated record with values matching those of the instance attributes.
|
488
509
|
# Returns the number of affected rows.
|
489
|
-
def _update_record(attribute_names =
|
510
|
+
def _update_record(attribute_names = self.attribute_names)
|
490
511
|
attributes_values = arel_attributes_with_values_for_update(attribute_names)
|
491
512
|
if attributes_values.empty?
|
492
513
|
0
|
@@ -497,7 +518,7 @@ module ActiveRecord
|
|
497
518
|
|
498
519
|
# Creates a record with values matching those of the instance attributes
|
499
520
|
# and returns its id.
|
500
|
-
def _create_record(attribute_names =
|
521
|
+
def _create_record(attribute_names = self.attribute_names)
|
501
522
|
attributes_values = arel_attributes_with_values_for_create(attribute_names)
|
502
523
|
|
503
524
|
new_id = self.class.unscoped.insert attributes_values
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module ActiveRecord
|
3
2
|
# = Active Record Query Cache
|
4
3
|
class QueryCache
|
@@ -29,9 +28,10 @@ module ActiveRecord
|
|
29
28
|
end
|
30
29
|
|
31
30
|
def call(env)
|
32
|
-
|
31
|
+
connection = ActiveRecord::Base.connection
|
32
|
+
enabled = connection.query_cache_enabled
|
33
33
|
connection_id = ActiveRecord::Base.connection_id
|
34
|
-
|
34
|
+
connection.enable_query_cache!
|
35
35
|
|
36
36
|
response = @app.call(env)
|
37
37
|
response[2] = Rack::BodyProxy.new(response[2]) do
|
@@ -37,15 +37,18 @@ module ActiveRecord
|
|
37
37
|
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
|
38
38
|
def find_by_sql(sql, binds = [])
|
39
39
|
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds)
|
40
|
-
column_types =
|
40
|
+
column_types = result_set.column_types.dup
|
41
|
+
columns_hash.each_key { |k| column_types.delete k }
|
42
|
+
message_bus = ActiveSupport::Notifications.instrumenter
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
44
|
+
payload = {
|
45
|
+
record_count: result_set.length,
|
46
|
+
class_name: name
|
47
|
+
}
|
47
48
|
|
48
|
-
|
49
|
+
message_bus.instrument('instantiation.active_record', payload) do
|
50
|
+
result_set.map { |record| instantiate(record, column_types) }
|
51
|
+
end
|
49
52
|
end
|
50
53
|
|
51
54
|
# Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
|
@@ -36,8 +36,6 @@ module ActiveRecord
|
|
36
36
|
config.eager_load_namespaces << ActiveRecord
|
37
37
|
|
38
38
|
rake_tasks do
|
39
|
-
require "active_record/base"
|
40
|
-
|
41
39
|
namespace :db do
|
42
40
|
task :load_config do
|
43
41
|
ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
|
@@ -59,8 +57,10 @@ module ActiveRecord
|
|
59
57
|
console do |app|
|
60
58
|
require "active_record/railties/console_sandbox" if app.sandbox?
|
61
59
|
require "active_record/base"
|
62
|
-
|
63
|
-
|
60
|
+
unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
|
61
|
+
console = ActiveSupport::Logger.new(STDERR)
|
62
|
+
Rails.logger.extend ActiveSupport::Logger.broadcast console
|
63
|
+
end
|
64
64
|
end
|
65
65
|
|
66
66
|
runner do
|
@@ -116,17 +116,22 @@ module ActiveRecord
|
|
116
116
|
# and then establishes the connection.
|
117
117
|
initializer "active_record.initialize_database" do |app|
|
118
118
|
ActiveSupport.on_load(:active_record) do
|
119
|
+
self.configurations = Rails.application.config.database_configuration
|
119
120
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
126
|
-
end
|
121
|
+
begin
|
122
|
+
establish_connection
|
123
|
+
rescue ActiveRecord::NoDatabaseError
|
124
|
+
warn <<-end_warning
|
125
|
+
Oops - You have a database configured, but it doesn't exist yet!
|
127
126
|
|
128
|
-
|
129
|
-
|
127
|
+
Here's how to get started:
|
128
|
+
|
129
|
+
1. Configure your database in config/database.yml.
|
130
|
+
2. Run `bin/rake db:create` to create the database.
|
131
|
+
3. Run `bin/rake db:setup` to load your database schema.
|
132
|
+
end_warning
|
133
|
+
raise
|
134
|
+
end
|
130
135
|
end
|
131
136
|
end
|
132
137
|
|
@@ -144,8 +149,8 @@ module ActiveRecord
|
|
144
149
|
ActiveSupport.on_load(:active_record) do
|
145
150
|
ActionDispatch::Reloader.send(hook) do
|
146
151
|
if ActiveRecord::Base.connected?
|
147
|
-
ActiveRecord::Base.clear_reloadable_connections!
|
148
152
|
ActiveRecord::Base.clear_cache!
|
153
|
+
ActiveRecord::Base.clear_reloadable_connections!
|
149
154
|
end
|
150
155
|
end
|
151
156
|
end
|
@@ -28,21 +28,32 @@ db_namespace = namespace :db do
|
|
28
28
|
ActiveRecord::Tasks::DatabaseTasks.drop_current
|
29
29
|
end
|
30
30
|
|
31
|
+
namespace :purge do
|
32
|
+
task :all => :load_config do
|
33
|
+
ActiveRecord::Tasks::DatabaseTasks.purge_all
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases."
|
38
|
+
task :purge => [:load_config] do
|
39
|
+
ActiveRecord::Tasks::DatabaseTasks.purge_current
|
40
|
+
end
|
41
|
+
|
31
42
|
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
32
43
|
task :migrate => [:environment, :load_config] do
|
33
|
-
ActiveRecord::
|
34
|
-
|
35
|
-
ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
|
36
|
-
end
|
37
|
-
db_namespace['_dump'].invoke if ActiveRecord::Base.dump_schema_after_migration
|
44
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
45
|
+
db_namespace['_dump'].invoke
|
38
46
|
end
|
39
47
|
|
48
|
+
# IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false
|
40
49
|
task :_dump do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
50
|
+
if ActiveRecord::Base.dump_schema_after_migration
|
51
|
+
case ActiveRecord::Base.schema_format
|
52
|
+
when :ruby then db_namespace["schema:dump"].invoke
|
53
|
+
when :sql then db_namespace["structure:dump"].invoke
|
54
|
+
else
|
55
|
+
raise "unknown schema format #{ActiveRecord::Base.schema_format}"
|
56
|
+
end
|
46
57
|
end
|
47
58
|
# Allow this task to be called as many times as required. An example is the
|
48
59
|
# migrate:redo task, which calls other two internally that depend on this one.
|
@@ -52,6 +63,8 @@ db_namespace = namespace :db do
|
|
52
63
|
namespace :migrate do
|
53
64
|
# desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
|
54
65
|
task :redo => [:environment, :load_config] do
|
66
|
+
raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
|
67
|
+
|
55
68
|
if ENV['VERSION']
|
56
69
|
db_namespace['migrate:down'].invoke
|
57
70
|
db_namespace['migrate:up'].invoke
|
@@ -66,48 +79,34 @@ db_namespace = namespace :db do
|
|
66
79
|
|
67
80
|
# desc 'Runs the "up" for a given migration VERSION.'
|
68
81
|
task :up => [:environment, :load_config] do
|
82
|
+
raise "VERSION is required" if ENV["VERSION"] && ENV["VERSION"].empty?
|
83
|
+
|
69
84
|
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
70
|
-
raise 'VERSION is required' unless version
|
71
85
|
ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, version)
|
72
86
|
db_namespace['_dump'].invoke
|
73
87
|
end
|
74
88
|
|
75
89
|
# desc 'Runs the "down" for a given migration VERSION.'
|
76
90
|
task :down => [:environment, :load_config] do
|
91
|
+
raise "VERSION is required - To go down one migration, use db:rollback" if ENV["VERSION"] && ENV["VERSION"].empty?
|
77
92
|
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
78
|
-
raise 'VERSION is required - To go down one migration, run db:rollback' unless version
|
79
93
|
ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_paths, version)
|
80
94
|
db_namespace['_dump'].invoke
|
81
95
|
end
|
82
96
|
|
83
97
|
desc 'Display status of migrations'
|
84
98
|
task :status => [:environment, :load_config] do
|
85
|
-
unless ActiveRecord::
|
86
|
-
|
87
|
-
next # means "return" for rake task
|
88
|
-
end
|
89
|
-
db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
|
90
|
-
db_list.map! { |version| ActiveRecord::SchemaMigration.normalize_migration_number(version) }
|
91
|
-
file_list = []
|
92
|
-
ActiveRecord::Migrator.migrations_paths.each do |path|
|
93
|
-
Dir.foreach(path) do |file|
|
94
|
-
# match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
|
95
|
-
if match_data = /^(\d{3,})_(.+)\.rb$/.match(file)
|
96
|
-
version = ActiveRecord::SchemaMigration.normalize_migration_number(match_data[1])
|
97
|
-
status = db_list.delete(version) ? 'up' : 'down'
|
98
|
-
file_list << [status, version, match_data[2].humanize]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
db_list.map! do |version|
|
103
|
-
['up', version, '********** NO FILE **********']
|
99
|
+
unless ActiveRecord::SchemaMigration.table_exists?
|
100
|
+
abort 'Schema migrations table does not exist yet.'
|
104
101
|
end
|
102
|
+
|
105
103
|
# output
|
106
104
|
puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
|
107
105
|
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
108
106
|
puts "-" * 50
|
109
|
-
|
110
|
-
|
107
|
+
paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
|
108
|
+
ActiveRecord::Migrator.migrations_status(paths).each do |status, version, name|
|
109
|
+
puts "#{status.center(8)} #{version.ljust(14)} #{name}"
|
111
110
|
end
|
112
111
|
puts
|
113
112
|
end
|
@@ -179,17 +178,22 @@ db_namespace = namespace :db do
|
|
179
178
|
task :load => [:environment, :load_config] do
|
180
179
|
require 'active_record/fixtures'
|
181
180
|
|
182
|
-
base_dir =
|
183
|
-
File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
|
184
|
-
else
|
185
|
-
ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
186
|
-
end
|
181
|
+
base_dir = ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
187
182
|
|
188
|
-
fixtures_dir =
|
183
|
+
fixtures_dir = if ENV['FIXTURES_DIR']
|
184
|
+
File.join base_dir, ENV['FIXTURES_DIR']
|
185
|
+
else
|
186
|
+
base_dir
|
187
|
+
end
|
189
188
|
|
190
|
-
|
191
|
-
|
192
|
-
|
189
|
+
fixture_files = if ENV['FIXTURES']
|
190
|
+
ENV['FIXTURES'].split(',')
|
191
|
+
else
|
192
|
+
# The use of String#[] here is to support namespaced fixtures
|
193
|
+
Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }
|
194
|
+
end
|
195
|
+
|
196
|
+
ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_files)
|
193
197
|
end
|
194
198
|
|
195
199
|
# desc "Search for a fixture given a LABEL or ID. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
|
@@ -201,16 +205,11 @@ db_namespace = namespace :db do
|
|
201
205
|
|
202
206
|
puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label
|
203
207
|
|
204
|
-
base_dir =
|
205
|
-
File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
|
206
|
-
else
|
207
|
-
ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
208
|
-
end
|
209
|
-
|
208
|
+
base_dir = ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
210
209
|
|
211
210
|
Dir["#{base_dir}/**/*.yml"].each do |file|
|
212
211
|
if data = YAML::load(ERB.new(IO.read(file)).result)
|
213
|
-
data.
|
212
|
+
data.each_key do |key|
|
214
213
|
key_id = ActiveRecord::FixtureSet.identify(key)
|
215
214
|
|
216
215
|
if key == label || key_id == id.to_i
|
@@ -279,8 +278,8 @@ db_namespace = namespace :db do
|
|
279
278
|
db_namespace['structure:dump'].reenable
|
280
279
|
end
|
281
280
|
|
282
|
-
|
283
|
-
task :load => [:
|
281
|
+
desc "Recreate the databases from the structure.sql file"
|
282
|
+
task :load => [:load_config] do
|
284
283
|
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:sql, ENV['DB_STRUCTURE'])
|
285
284
|
end
|
286
285
|
|
@@ -299,7 +298,7 @@ db_namespace = namespace :db do
|
|
299
298
|
end
|
300
299
|
|
301
300
|
# desc "Recreate the test database from the current schema"
|
302
|
-
task :load => %w(db:test:
|
301
|
+
task :load => %w(db:test:purge) do
|
303
302
|
case ActiveRecord::Base.schema_format
|
304
303
|
when :ruby
|
305
304
|
db_namespace["test:load_schema"].invoke
|
@@ -309,7 +308,7 @@ db_namespace = namespace :db do
|
|
309
308
|
end
|
310
309
|
|
311
310
|
# desc "Recreate the test database from an existent schema.rb file"
|
312
|
-
task :load_schema => %w(db:test:
|
311
|
+
task :load_schema => %w(db:test:purge) do
|
313
312
|
begin
|
314
313
|
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
315
314
|
ActiveRecord::Schema.verbose = false
|
@@ -322,7 +321,7 @@ db_namespace = namespace :db do
|
|
322
321
|
end
|
323
322
|
|
324
323
|
# desc "Recreate the test database from an existent structure.sql file"
|
325
|
-
task :load_structure => %w(db:test:
|
324
|
+
task :load_structure => %w(db:test:purge) do
|
326
325
|
ActiveRecord::Tasks::DatabaseTasks.load_schema_for ActiveRecord::Base.configurations['test'], :sql, ENV['SCHEMA']
|
327
326
|
end
|
328
327
|
|
@@ -343,12 +342,12 @@ db_namespace = namespace :db do
|
|
343
342
|
task :clone_structure => %w(db:test:deprecated db:structure:dump db:test:load_structure)
|
344
343
|
|
345
344
|
# desc "Empty the test database"
|
346
|
-
task :purge => %w(
|
345
|
+
task :purge => %w(environment load_config) do
|
347
346
|
ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
|
348
347
|
end
|
349
348
|
|
350
349
|
# desc 'Check for pending migrations and load the test schema'
|
351
|
-
task :prepare => %w(
|
350
|
+
task :prepare => %w(environment load_config) do
|
352
351
|
unless ActiveRecord::Base.configurations.blank?
|
353
352
|
db_namespace['test:load'].invoke
|
354
353
|
end
|