activerecord 2.3.18 → 3.0.0.beta
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.
- data/CHANGELOG +105 -34
- data/examples/performance.rb +3 -39
- data/examples/simple.rb +14 -0
- data/lib/active_record.rb +81 -47
- data/lib/active_record/aggregations.rb +1 -3
- data/lib/active_record/association_preload.rb +39 -54
- data/lib/active_record/associations.rb +262 -419
- data/lib/active_record/associations/association_collection.rb +85 -100
- data/lib/active_record/associations/association_proxy.rb +20 -18
- data/lib/active_record/associations/belongs_to_association.rb +8 -8
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +13 -35
- data/lib/active_record/associations/has_many_association.rb +11 -19
- data/lib/active_record/associations/has_many_through_association.rb +30 -183
- data/lib/active_record/associations/has_one_association.rb +10 -10
- data/lib/active_record/associations/has_one_through_association.rb +13 -11
- data/lib/active_record/associations/through_association_scope.rb +153 -0
- data/lib/active_record/attribute_methods.rb +17 -370
- data/lib/active_record/attribute_methods/before_type_cast.rb +33 -0
- data/lib/active_record/attribute_methods/dirty.rb +87 -0
- data/lib/active_record/attribute_methods/primary_key.rb +44 -0
- data/lib/active_record/attribute_methods/query.rb +37 -0
- data/lib/active_record/attribute_methods/read.rb +116 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +60 -0
- data/lib/active_record/attribute_methods/write.rb +37 -0
- data/lib/active_record/autosave_association.rb +20 -41
- data/lib/active_record/base.rb +357 -1180
- data/lib/active_record/batches.rb +10 -16
- data/lib/active_record/callbacks.rb +66 -126
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +17 -13
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +5 -25
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +4 -43
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +18 -72
- data/lib/active_record/connection_adapters/abstract_adapter.rb +16 -49
- data/lib/active_record/connection_adapters/mysql_adapter.rb +15 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +84 -46
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +9 -3
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +34 -65
- data/lib/active_record/fixtures.rb +21 -25
- data/lib/active_record/locale/en.yml +9 -27
- data/lib/active_record/locking/optimistic.rb +16 -48
- data/lib/active_record/migration.rb +59 -46
- data/lib/active_record/named_scope.rb +85 -92
- data/lib/active_record/nested_attributes.rb +18 -24
- data/lib/active_record/observer.rb +18 -94
- data/lib/active_record/railtie.rb +83 -0
- data/lib/active_record/railties/controller_runtime.rb +38 -0
- data/lib/active_record/railties/databases.rake +477 -0
- data/lib/active_record/railties/subscriber.rb +27 -0
- data/lib/active_record/reflection.rb +2 -15
- data/lib/active_record/relation.rb +339 -0
- data/lib/active_record/relation/calculations.rb +259 -0
- data/lib/active_record/relation/finder_methods.rb +315 -0
- data/lib/active_record/relation/predicate_builder.rb +46 -0
- data/lib/active_record/relation/query_methods.rb +218 -0
- data/lib/active_record/relation/spawn_methods.rb +102 -0
- data/lib/active_record/schema_dumper.rb +10 -6
- data/lib/active_record/serialization.rb +31 -74
- data/lib/active_record/serializers/xml_serializer.rb +33 -121
- data/lib/active_record/session_store.rb +1 -9
- data/lib/active_record/test_case.rb +1 -3
- data/lib/active_record/timestamp.rb +7 -5
- data/lib/active_record/transactions.rb +9 -9
- data/lib/active_record/validations.rb +51 -1100
- data/lib/active_record/validations/associated.rb +47 -0
- data/lib/active_record/validations/uniqueness.rb +181 -0
- data/lib/active_record/version.rb +3 -3
- data/lib/generators/active_record.rb +30 -0
- data/lib/generators/active_record/migration/migration_generator.rb +25 -0
- data/lib/generators/active_record/migration/templates/migration.rb +11 -0
- data/lib/generators/active_record/model/model_generator.rb +33 -0
- data/lib/generators/active_record/model/templates/migration.rb +16 -0
- data/lib/generators/active_record/model/templates/model.rb +5 -0
- data/lib/generators/active_record/observer/observer_generator.rb +15 -0
- data/lib/generators/active_record/observer/templates/observer.rb +2 -0
- data/lib/generators/active_record/session_migration/session_migration_generator.rb +24 -0
- data/lib/generators/active_record/session_migration/templates/migration.rb +16 -0
- metadata +67 -325
- data/RUNNING_UNIT_TESTS +0 -36
- data/Rakefile +0 -268
- data/install.rb +0 -30
- data/lib/active_record/calculations.rb +0 -321
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -57
- data/lib/active_record/dirty.rb +0 -183
- data/lib/active_record/serializers/json_serializer.rb +0 -91
- data/lib/activerecord.rb +0 -2
- data/test/assets/example.log +0 -1
- data/test/assets/flowers.jpg +0 -0
- data/test/cases/aaa_create_tables_test.rb +0 -24
- data/test/cases/active_schema_test_mysql.rb +0 -122
- data/test/cases/active_schema_test_postgresql.rb +0 -24
- data/test/cases/adapter_test.rb +0 -144
- data/test/cases/aggregations_test.rb +0 -167
- data/test/cases/ar_schema_test.rb +0 -32
- data/test/cases/associations/belongs_to_associations_test.rb +0 -438
- data/test/cases/associations/callbacks_test.rb +0 -161
- data/test/cases/associations/cascaded_eager_loading_test.rb +0 -131
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +0 -36
- data/test/cases/associations/eager_load_nested_include_test.rb +0 -131
- data/test/cases/associations/eager_load_nested_polymorphic_include.rb +0 -19
- data/test/cases/associations/eager_singularization_test.rb +0 -145
- data/test/cases/associations/eager_test.rb +0 -852
- data/test/cases/associations/extension_test.rb +0 -62
- data/test/cases/associations/habtm_join_table_test.rb +0 -56
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +0 -827
- data/test/cases/associations/has_many_associations_test.rb +0 -1273
- data/test/cases/associations/has_many_through_associations_test.rb +0 -360
- data/test/cases/associations/has_one_associations_test.rb +0 -330
- data/test/cases/associations/has_one_through_associations_test.rb +0 -209
- data/test/cases/associations/inner_join_association_test.rb +0 -93
- data/test/cases/associations/inverse_associations_test.rb +0 -566
- data/test/cases/associations/join_model_test.rb +0 -712
- data/test/cases/associations_test.rb +0 -282
- data/test/cases/attribute_methods_test.rb +0 -305
- data/test/cases/autosave_association_test.rb +0 -1218
- data/test/cases/base_test.rb +0 -2166
- data/test/cases/batches_test.rb +0 -81
- data/test/cases/binary_test.rb +0 -30
- data/test/cases/calculations_test.rb +0 -360
- data/test/cases/callbacks_observers_test.rb +0 -38
- data/test/cases/callbacks_test.rb +0 -438
- data/test/cases/class_inheritable_attributes_test.rb +0 -32
- data/test/cases/column_alias_test.rb +0 -17
- data/test/cases/column_definition_test.rb +0 -70
- data/test/cases/connection_pool_test.rb +0 -25
- data/test/cases/connection_test_firebird.rb +0 -8
- data/test/cases/connection_test_mysql.rb +0 -65
- data/test/cases/copy_table_test_sqlite.rb +0 -80
- data/test/cases/counter_cache_test.rb +0 -84
- data/test/cases/database_statements_test.rb +0 -12
- data/test/cases/datatype_test_postgresql.rb +0 -204
- data/test/cases/date_time_test.rb +0 -37
- data/test/cases/default_test_firebird.rb +0 -16
- data/test/cases/defaults_test.rb +0 -111
- data/test/cases/deprecated_finder_test.rb +0 -30
- data/test/cases/dirty_test.rb +0 -316
- data/test/cases/finder_respond_to_test.rb +0 -76
- data/test/cases/finder_test.rb +0 -1098
- data/test/cases/fixtures_test.rb +0 -661
- data/test/cases/helper.rb +0 -68
- data/test/cases/i18n_test.rb +0 -46
- data/test/cases/inheritance_test.rb +0 -262
- data/test/cases/invalid_date_test.rb +0 -24
- data/test/cases/json_serialization_test.rb +0 -219
- data/test/cases/lifecycle_test.rb +0 -193
- data/test/cases/locking_test.rb +0 -350
- data/test/cases/method_scoping_test.rb +0 -704
- data/test/cases/migration_test.rb +0 -1649
- data/test/cases/migration_test_firebird.rb +0 -124
- data/test/cases/mixin_test.rb +0 -96
- data/test/cases/modules_test.rb +0 -109
- data/test/cases/multiple_db_test.rb +0 -85
- data/test/cases/named_scope_test.rb +0 -372
- data/test/cases/nested_attributes_test.rb +0 -840
- data/test/cases/pk_test.rb +0 -119
- data/test/cases/pooled_connections_test.rb +0 -103
- data/test/cases/query_cache_test.rb +0 -129
- data/test/cases/readonly_test.rb +0 -107
- data/test/cases/reflection_test.rb +0 -234
- data/test/cases/reload_models_test.rb +0 -22
- data/test/cases/repair_helper.rb +0 -50
- data/test/cases/reserved_word_test_mysql.rb +0 -176
- data/test/cases/sanitize_test.rb +0 -25
- data/test/cases/schema_authorization_test_postgresql.rb +0 -75
- data/test/cases/schema_dumper_test.rb +0 -211
- data/test/cases/schema_test_postgresql.rb +0 -178
- data/test/cases/serialization_test.rb +0 -47
- data/test/cases/sp_test_mysql.rb +0 -16
- data/test/cases/synonym_test_oracle.rb +0 -17
- data/test/cases/timestamp_test.rb +0 -75
- data/test/cases/transactions_test.rb +0 -543
- data/test/cases/unconnected_test.rb +0 -32
- data/test/cases/validations_i18n_test.rb +0 -925
- data/test/cases/validations_test.rb +0 -1684
- data/test/cases/xml_serialization_test.rb +0 -240
- data/test/cases/yaml_serialization_test.rb +0 -11
- data/test/config.rb +0 -5
- data/test/connections/jdbc_jdbcderby/connection.rb +0 -18
- data/test/connections/jdbc_jdbch2/connection.rb +0 -18
- data/test/connections/jdbc_jdbchsqldb/connection.rb +0 -18
- data/test/connections/jdbc_jdbcmysql/connection.rb +0 -26
- data/test/connections/jdbc_jdbcpostgresql/connection.rb +0 -26
- data/test/connections/jdbc_jdbcsqlite3/connection.rb +0 -25
- data/test/connections/native_db2/connection.rb +0 -25
- data/test/connections/native_firebird/connection.rb +0 -26
- data/test/connections/native_frontbase/connection.rb +0 -27
- data/test/connections/native_mysql/connection.rb +0 -25
- data/test/connections/native_openbase/connection.rb +0 -21
- data/test/connections/native_oracle/connection.rb +0 -27
- data/test/connections/native_postgresql/connection.rb +0 -21
- data/test/connections/native_sqlite/connection.rb +0 -25
- data/test/connections/native_sqlite3/connection.rb +0 -25
- data/test/connections/native_sqlite3/in_memory_connection.rb +0 -18
- data/test/connections/native_sybase/connection.rb +0 -23
- data/test/fixtures/accounts.yml +0 -29
- data/test/fixtures/all/developers.yml +0 -0
- data/test/fixtures/all/people.csv +0 -0
- data/test/fixtures/all/tasks.yml +0 -0
- data/test/fixtures/author_addresses.yml +0 -5
- data/test/fixtures/author_favorites.yml +0 -4
- data/test/fixtures/authors.yml +0 -9
- data/test/fixtures/binaries.yml +0 -132
- data/test/fixtures/books.yml +0 -7
- data/test/fixtures/categories.yml +0 -14
- data/test/fixtures/categories/special_categories.yml +0 -9
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +0 -4
- data/test/fixtures/categories_ordered.yml +0 -7
- data/test/fixtures/categories_posts.yml +0 -23
- data/test/fixtures/categorizations.yml +0 -17
- data/test/fixtures/clubs.yml +0 -6
- data/test/fixtures/comments.yml +0 -59
- data/test/fixtures/companies.yml +0 -56
- data/test/fixtures/computers.yml +0 -4
- data/test/fixtures/courses.yml +0 -7
- data/test/fixtures/customers.yml +0 -26
- data/test/fixtures/developers.yml +0 -21
- data/test/fixtures/developers_projects.yml +0 -17
- data/test/fixtures/edges.yml +0 -6
- data/test/fixtures/entrants.yml +0 -14
- data/test/fixtures/faces.yml +0 -11
- data/test/fixtures/fk_test_has_fk.yml +0 -3
- data/test/fixtures/fk_test_has_pk.yml +0 -2
- data/test/fixtures/funny_jokes.yml +0 -10
- data/test/fixtures/interests.yml +0 -33
- data/test/fixtures/items.yml +0 -4
- data/test/fixtures/jobs.yml +0 -7
- data/test/fixtures/legacy_things.yml +0 -3
- data/test/fixtures/mateys.yml +0 -4
- data/test/fixtures/member_types.yml +0 -6
- data/test/fixtures/members.yml +0 -6
- data/test/fixtures/memberships.yml +0 -20
- data/test/fixtures/men.yml +0 -5
- data/test/fixtures/minimalistics.yml +0 -2
- data/test/fixtures/mixed_case_monkeys.yml +0 -6
- data/test/fixtures/mixins.yml +0 -29
- data/test/fixtures/movies.yml +0 -7
- data/test/fixtures/naked/csv/accounts.csv +0 -1
- data/test/fixtures/naked/yml/accounts.yml +0 -1
- data/test/fixtures/naked/yml/companies.yml +0 -1
- data/test/fixtures/naked/yml/courses.yml +0 -1
- data/test/fixtures/organizations.yml +0 -5
- data/test/fixtures/owners.yml +0 -7
- data/test/fixtures/parrots.yml +0 -27
- data/test/fixtures/parrots_pirates.yml +0 -7
- data/test/fixtures/people.yml +0 -15
- data/test/fixtures/pets.yml +0 -14
- data/test/fixtures/pirates.yml +0 -9
- data/test/fixtures/polymorphic_designs.yml +0 -19
- data/test/fixtures/polymorphic_prices.yml +0 -19
- data/test/fixtures/posts.yml +0 -52
- data/test/fixtures/price_estimates.yml +0 -7
- data/test/fixtures/projects.yml +0 -7
- data/test/fixtures/readers.yml +0 -9
- data/test/fixtures/references.yml +0 -17
- data/test/fixtures/reserved_words/distinct.yml +0 -5
- data/test/fixtures/reserved_words/distincts_selects.yml +0 -11
- data/test/fixtures/reserved_words/group.yml +0 -14
- data/test/fixtures/reserved_words/select.yml +0 -8
- data/test/fixtures/reserved_words/values.yml +0 -7
- data/test/fixtures/ships.yml +0 -5
- data/test/fixtures/sponsors.yml +0 -9
- data/test/fixtures/subscribers.yml +0 -7
- data/test/fixtures/subscriptions.yml +0 -12
- data/test/fixtures/taggings.yml +0 -28
- data/test/fixtures/tags.yml +0 -7
- data/test/fixtures/tasks.yml +0 -7
- data/test/fixtures/tees.yml +0 -4
- data/test/fixtures/ties.yml +0 -4
- data/test/fixtures/topics.yml +0 -42
- data/test/fixtures/toys.yml +0 -4
- data/test/fixtures/treasures.yml +0 -10
- data/test/fixtures/vertices.yml +0 -4
- data/test/fixtures/warehouse-things.yml +0 -3
- data/test/fixtures/zines.yml +0 -5
- data/test/migrations/broken/100_migration_that_raises_exception.rb +0 -10
- data/test/migrations/decimal/1_give_me_big_numbers.rb +0 -15
- data/test/migrations/duplicate/1_people_have_last_names.rb +0 -9
- data/test/migrations/duplicate/2_we_need_reminders.rb +0 -12
- data/test/migrations/duplicate/3_foo.rb +0 -7
- data/test/migrations/duplicate/3_innocent_jointable.rb +0 -12
- data/test/migrations/duplicate_names/20080507052938_chunky.rb +0 -7
- data/test/migrations/duplicate_names/20080507053028_chunky.rb +0 -7
- data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +0 -12
- data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +0 -9
- data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +0 -12
- data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +0 -9
- data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +0 -8
- data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +0 -12
- data/test/migrations/missing/1000_people_have_middle_names.rb +0 -9
- data/test/migrations/missing/1_people_have_last_names.rb +0 -9
- data/test/migrations/missing/3_we_need_reminders.rb +0 -12
- data/test/migrations/missing/4_innocent_jointable.rb +0 -12
- data/test/migrations/valid/1_people_have_last_names.rb +0 -9
- data/test/migrations/valid/2_we_need_reminders.rb +0 -12
- data/test/migrations/valid/3_innocent_jointable.rb +0 -12
- data/test/models/author.rb +0 -151
- data/test/models/auto_id.rb +0 -4
- data/test/models/binary.rb +0 -2
- data/test/models/bird.rb +0 -9
- data/test/models/book.rb +0 -4
- data/test/models/categorization.rb +0 -5
- data/test/models/category.rb +0 -34
- data/test/models/citation.rb +0 -6
- data/test/models/club.rb +0 -13
- data/test/models/column_name.rb +0 -3
- data/test/models/comment.rb +0 -29
- data/test/models/company.rb +0 -173
- data/test/models/company_in_module.rb +0 -78
- data/test/models/computer.rb +0 -3
- data/test/models/contact.rb +0 -16
- data/test/models/contract.rb +0 -5
- data/test/models/course.rb +0 -3
- data/test/models/customer.rb +0 -73
- data/test/models/default.rb +0 -2
- data/test/models/developer.rb +0 -101
- data/test/models/edge.rb +0 -5
- data/test/models/entrant.rb +0 -3
- data/test/models/essay.rb +0 -3
- data/test/models/event.rb +0 -3
- data/test/models/event_author.rb +0 -8
- data/test/models/face.rb +0 -7
- data/test/models/guid.rb +0 -2
- data/test/models/interest.rb +0 -5
- data/test/models/invoice.rb +0 -4
- data/test/models/item.rb +0 -7
- data/test/models/job.rb +0 -5
- data/test/models/joke.rb +0 -3
- data/test/models/keyboard.rb +0 -3
- data/test/models/legacy_thing.rb +0 -3
- data/test/models/line_item.rb +0 -3
- data/test/models/man.rb +0 -9
- data/test/models/matey.rb +0 -4
- data/test/models/member.rb +0 -12
- data/test/models/member_detail.rb +0 -5
- data/test/models/member_type.rb +0 -3
- data/test/models/membership.rb +0 -9
- data/test/models/minimalistic.rb +0 -2
- data/test/models/mixed_case_monkey.rb +0 -3
- data/test/models/movie.rb +0 -5
- data/test/models/order.rb +0 -4
- data/test/models/organization.rb +0 -6
- data/test/models/owner.rb +0 -5
- data/test/models/parrot.rb +0 -22
- data/test/models/person.rb +0 -16
- data/test/models/pet.rb +0 -5
- data/test/models/pirate.rb +0 -80
- data/test/models/polymorphic_design.rb +0 -3
- data/test/models/polymorphic_price.rb +0 -3
- data/test/models/post.rb +0 -102
- data/test/models/price_estimate.rb +0 -3
- data/test/models/project.rb +0 -30
- data/test/models/reader.rb +0 -4
- data/test/models/reference.rb +0 -4
- data/test/models/reply.rb +0 -46
- data/test/models/ship.rb +0 -19
- data/test/models/ship_part.rb +0 -7
- data/test/models/sponsor.rb +0 -4
- data/test/models/subject.rb +0 -4
- data/test/models/subscriber.rb +0 -8
- data/test/models/subscription.rb +0 -4
- data/test/models/tag.rb +0 -7
- data/test/models/tagging.rb +0 -10
- data/test/models/task.rb +0 -3
- data/test/models/tee.rb +0 -4
- data/test/models/tie.rb +0 -4
- data/test/models/topic.rb +0 -80
- data/test/models/toy.rb +0 -6
- data/test/models/treasure.rb +0 -8
- data/test/models/vertex.rb +0 -9
- data/test/models/warehouse_thing.rb +0 -5
- data/test/models/zine.rb +0 -3
- data/test/schema/mysql_specific_schema.rb +0 -31
- data/test/schema/postgresql_specific_schema.rb +0 -114
- data/test/schema/schema.rb +0 -550
- data/test/schema/schema2.rb +0 -6
- data/test/schema/sqlite_specific_schema.rb +0 -25
@@ -1,8 +1,6 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Batches # :nodoc:
|
3
|
-
|
4
|
-
base.extend(ClassMethods)
|
5
|
-
end
|
3
|
+
extend ActiveSupport::Concern
|
6
4
|
|
7
5
|
# When processing large numbers of records, it's often a good idea to do
|
8
6
|
# so in batches to prevent memory ballooning.
|
@@ -59,23 +57,19 @@ module ActiveRecord
|
|
59
57
|
start = options.delete(:start).to_i
|
60
58
|
batch_size = options.delete(:batch_size) || 1000
|
61
59
|
|
62
|
-
|
63
|
-
|
60
|
+
with_scope(:find => options.merge(:order => batch_order, :limit => batch_size)) do
|
61
|
+
records = find(:all, :conditions => [ "#{table_name}.#{primary_key} >= ?", start ])
|
64
62
|
|
65
|
-
|
66
|
-
|
63
|
+
while records.any?
|
64
|
+
yield records
|
67
65
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
raise "You must include the primary key if you define a select" unless last_value.present?
|
73
|
-
|
74
|
-
records = proxy.find(:all, :conditions => [ "#{table_name}.#{primary_key} > ?", last_value ])
|
66
|
+
break if records.size < batch_size
|
67
|
+
records = find(:all, :conditions => [ "#{table_name}.#{primary_key} > ?", records.last.id ])
|
68
|
+
end
|
75
69
|
end
|
76
70
|
end
|
77
|
-
|
78
|
-
|
71
|
+
|
72
|
+
|
79
73
|
private
|
80
74
|
def batch_order
|
81
75
|
"#{table_name}.#{primary_key} ASC"
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'observer'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
# Callbacks are hooks into the lifecycle of an Active Record object that allow you to trigger logic
|
5
3
|
# before or after an alteration of the object state. This can be used to make sure that associated and
|
@@ -10,19 +8,16 @@ module ActiveRecord
|
|
10
8
|
# * (-) <tt>save</tt>
|
11
9
|
# * (-) <tt>valid</tt>
|
12
10
|
# * (1) <tt>before_validation</tt>
|
13
|
-
# * (2) <tt>before_validation_on_create</tt>
|
14
11
|
# * (-) <tt>validate</tt>
|
15
|
-
# * (
|
16
|
-
# * (3) <tt>
|
17
|
-
# * (4) <tt>
|
18
|
-
# * (5) <tt>before_save</tt>
|
19
|
-
# * (6) <tt>before_create</tt>
|
12
|
+
# * (2) <tt>after_validation</tt>
|
13
|
+
# * (3) <tt>before_save</tt>
|
14
|
+
# * (4) <tt>before_create</tt>
|
20
15
|
# * (-) <tt>create</tt>
|
21
|
-
# * (
|
22
|
-
# * (
|
16
|
+
# * (5) <tt>after_create</tt>
|
17
|
+
# * (6) <tt>after_save</tt>
|
23
18
|
#
|
24
19
|
# That's a total of eight callbacks, which gives you immense power to react and prepare for each state in the
|
25
|
-
# Active Record lifecycle. The sequence for calling <tt>Base#save</tt> an existing record is similar, except that each
|
20
|
+
# Active Record lifecycle. The sequence for calling <tt>Base#save</tt> for an existing record is similar, except that each
|
26
21
|
# <tt>_on_create</tt> callback is replaced by the corresponding <tt>_on_update</tt> callback.
|
27
22
|
#
|
28
23
|
# Examples:
|
@@ -211,150 +206,95 @@ module ActiveRecord
|
|
211
206
|
# needs to be aware of it because an ordinary +save+ will raise such exception
|
212
207
|
# instead of quietly returning +false+.
|
213
208
|
module Callbacks
|
214
|
-
|
215
|
-
after_find after_initialize before_save after_save before_create after_create before_update after_update before_validation
|
216
|
-
after_validation before_validation_on_create after_validation_on_create before_validation_on_update
|
217
|
-
after_validation_on_update before_destroy after_destroy
|
218
|
-
)
|
209
|
+
extend ActiveSupport::Concern
|
219
210
|
|
220
|
-
|
221
|
-
|
211
|
+
CALLBACKS = [
|
212
|
+
:after_initialize, :after_find, :before_validation, :after_validation,
|
213
|
+
:before_save, :around_save, :after_save, :before_create, :around_create,
|
214
|
+
:after_create, :before_update, :around_update, :after_update,
|
215
|
+
:before_destroy, :around_destroy, :after_destroy
|
216
|
+
]
|
222
217
|
|
218
|
+
included do
|
223
219
|
[:create_or_update, :valid?, :create, :update, :destroy].each do |method|
|
224
|
-
|
220
|
+
alias_method_chain method, :callbacks
|
225
221
|
end
|
226
222
|
|
227
|
-
|
228
|
-
|
223
|
+
extend ActiveModel::Callbacks
|
224
|
+
|
225
|
+
define_callbacks :validation, :terminator => "result == false", :scope => [:kind, :name]
|
226
|
+
|
227
|
+
define_model_callbacks :initialize, :find, :only => :after
|
228
|
+
define_model_callbacks :save, :create, :update, :destroy
|
229
229
|
end
|
230
230
|
|
231
|
-
|
232
|
-
|
231
|
+
module ClassMethods
|
232
|
+
def method_added(meth)
|
233
|
+
super
|
234
|
+
if CALLBACKS.include?(meth.to_sym)
|
235
|
+
ActiveSupport::Deprecation.warn("Base##{meth} has been deprecated, please use Base.#{meth} :method instead", caller[0,1])
|
236
|
+
send(meth.to_sym, meth.to_sym)
|
237
|
+
end
|
238
|
+
end
|
233
239
|
|
234
|
-
|
235
|
-
|
240
|
+
def before_validation(*args, &block)
|
241
|
+
options = args.last
|
242
|
+
if options.is_a?(Hash) && options[:on]
|
243
|
+
options[:if] = Array(options[:if])
|
244
|
+
options[:if] << "@_on_validate == :#{options[:on]}"
|
245
|
+
end
|
246
|
+
set_callback(:validation, :before, *args, &block)
|
247
|
+
end
|
236
248
|
|
237
|
-
|
238
|
-
|
249
|
+
def after_validation(*args, &block)
|
250
|
+
options = args.extract_options!
|
251
|
+
options[:prepend] = true
|
252
|
+
options[:if] = Array(options[:if])
|
253
|
+
options[:if] << "!halted && value != false"
|
254
|
+
options[:if] << "@_on_validate == :#{options[:on]}" if options[:on]
|
255
|
+
set_callback(:validation, :after, *(args << options), &block)
|
256
|
+
end
|
257
|
+
end
|
239
258
|
|
240
|
-
# Is called _after_ <tt>Base.save</tt> (regardless of whether it's a +create+ or +update+ save).
|
241
|
-
# Note that this callback is still wrapped in the transaction around +save+. For example, if you
|
242
|
-
# invoke an external indexer at this point it won't see the changes in the database.
|
243
|
-
#
|
244
|
-
# class Contact < ActiveRecord::Base
|
245
|
-
# after_save { logger.info( 'New contact saved!' ) }
|
246
|
-
# end
|
247
|
-
def after_save() end
|
248
259
|
def create_or_update_with_callbacks #:nodoc:
|
249
|
-
|
250
|
-
|
251
|
-
callback(:after_save)
|
260
|
+
_run_save_callbacks do
|
261
|
+
create_or_update_without_callbacks
|
252
262
|
end
|
253
|
-
result
|
254
263
|
end
|
255
264
|
private :create_or_update_with_callbacks
|
256
265
|
|
257
|
-
# Is called _before_ <tt>Base.save</tt> on new objects that haven't been saved yet (no record exists).
|
258
|
-
def before_create() end
|
259
|
-
|
260
|
-
# Is called _after_ <tt>Base.save</tt> on new objects that haven't been saved yet (no record exists).
|
261
|
-
# Note that this callback is still wrapped in the transaction around +save+. For example, if you
|
262
|
-
# invoke an external indexer at this point it won't see the changes in the database.
|
263
|
-
def after_create() end
|
264
266
|
def create_with_callbacks #:nodoc:
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
result
|
267
|
+
_run_create_callbacks do
|
268
|
+
create_without_callbacks
|
269
|
+
end
|
269
270
|
end
|
270
271
|
private :create_with_callbacks
|
271
272
|
|
272
|
-
# Is called _before_ <tt>Base.save</tt> on existing objects that have a record.
|
273
|
-
def before_update() end
|
274
|
-
|
275
|
-
# Is called _after_ <tt>Base.save</tt> on existing objects that have a record.
|
276
|
-
# Note that this callback is still wrapped in the transaction around +save+. For example, if you
|
277
|
-
# invoke an external indexer at this point it won't see the changes in the database.
|
278
|
-
def after_update() end
|
279
|
-
|
280
273
|
def update_with_callbacks(*args) #:nodoc:
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
result
|
274
|
+
_run_update_callbacks do
|
275
|
+
update_without_callbacks(*args)
|
276
|
+
end
|
285
277
|
end
|
286
278
|
private :update_with_callbacks
|
287
279
|
|
288
|
-
# Is called _before_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call).
|
289
|
-
def before_validation() end
|
290
|
-
|
291
|
-
# Is called _after_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call).
|
292
|
-
def after_validation() end
|
293
|
-
|
294
|
-
# Is called _before_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call) on new objects
|
295
|
-
# that haven't been saved yet (no record exists).
|
296
|
-
def before_validation_on_create() end
|
297
|
-
|
298
|
-
# Is called _after_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call) on new objects
|
299
|
-
# that haven't been saved yet (no record exists).
|
300
|
-
def after_validation_on_create() end
|
301
|
-
|
302
|
-
# Is called _before_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call) on
|
303
|
-
# existing objects that have a record.
|
304
|
-
def before_validation_on_update() end
|
305
|
-
|
306
|
-
# Is called _after_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call) on
|
307
|
-
# existing objects that have a record.
|
308
|
-
def after_validation_on_update() end
|
309
|
-
|
310
280
|
def valid_with_callbacks? #:nodoc:
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
result = valid_without_callbacks?
|
316
|
-
|
317
|
-
callback(:after_validation)
|
318
|
-
if new_record? then callback(:after_validation_on_create) else callback(:after_validation_on_update) end
|
319
|
-
|
320
|
-
return result
|
281
|
+
@_on_validate = new_record? ? :create : :update
|
282
|
+
_run_validation_callbacks do
|
283
|
+
valid_without_callbacks?
|
284
|
+
end
|
321
285
|
end
|
322
286
|
|
323
|
-
# Is called _before_ <tt>Base.destroy</tt>.
|
324
|
-
#
|
325
|
-
# Note: If you need to _destroy_ or _nullify_ associated records first,
|
326
|
-
# use the <tt>:dependent</tt> option on your associations.
|
327
|
-
def before_destroy() end
|
328
|
-
|
329
|
-
# Is called _after_ <tt>Base.destroy</tt> (and all the attributes have been frozen).
|
330
|
-
#
|
331
|
-
# class Contact < ActiveRecord::Base
|
332
|
-
# after_destroy { |record| logger.info( "Contact #{record.id} was destroyed." ) }
|
333
|
-
# end
|
334
|
-
def after_destroy() end
|
335
287
|
def destroy_with_callbacks #:nodoc:
|
336
|
-
|
337
|
-
|
338
|
-
callback(:after_destroy)
|
339
|
-
result
|
340
|
-
end
|
341
|
-
|
342
|
-
private
|
343
|
-
def callback(method)
|
344
|
-
result = run_callbacks(method) { |result, object| false == result }
|
345
|
-
|
346
|
-
if result != false && respond_to_without_attributes?(method)
|
347
|
-
result = send(method)
|
348
|
-
end
|
349
|
-
|
350
|
-
notify(method)
|
351
|
-
|
352
|
-
return result
|
288
|
+
_run_destroy_callbacks do
|
289
|
+
destroy_without_callbacks
|
353
290
|
end
|
291
|
+
end
|
354
292
|
|
355
|
-
|
356
|
-
|
357
|
-
|
293
|
+
def deprecated_callback_method(symbol) #:nodoc:
|
294
|
+
if respond_to?(symbol, true)
|
295
|
+
ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base##{symbol} :method_name instead")
|
296
|
+
send(symbol)
|
358
297
|
end
|
298
|
+
end
|
359
299
|
end
|
360
300
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'monitor'
|
2
2
|
require 'set'
|
3
|
+
require 'active_support/core_ext/module/synchronization'
|
3
4
|
|
4
5
|
module ActiveRecord
|
5
6
|
# Raised when a connection could not be obtained within the connection
|
@@ -55,7 +56,7 @@ module ActiveRecord
|
|
55
56
|
# * +wait_timeout+: number of seconds to block and wait for a connection
|
56
57
|
# before giving up and raising a timeout error (default 5 seconds).
|
57
58
|
class ConnectionPool
|
58
|
-
attr_reader :spec
|
59
|
+
attr_reader :spec, :connections
|
59
60
|
|
60
61
|
# Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
|
61
62
|
# object which describes database connection information (e.g. adapter,
|
@@ -107,13 +108,14 @@ module ActiveRecord
|
|
107
108
|
checkin conn if conn
|
108
109
|
end
|
109
110
|
|
110
|
-
#
|
111
|
-
#
|
111
|
+
# If a connection already exists yield it to the block. If no connection
|
112
|
+
# exists checkout a connection, yield it to the block, and checkin the
|
113
|
+
# connection when finished.
|
112
114
|
def with_connection
|
113
|
-
|
114
|
-
yield
|
115
|
+
fresh_connection = true unless @reserved_connections[current_connection_id]
|
116
|
+
yield connection
|
115
117
|
ensure
|
116
|
-
|
118
|
+
release_connection if fresh_connection
|
117
119
|
end
|
118
120
|
|
119
121
|
# Returns true if a connection has already been opened.
|
@@ -209,9 +211,10 @@ module ActiveRecord
|
|
209
211
|
# calling +checkout+ on this pool.
|
210
212
|
def checkin(conn)
|
211
213
|
@connection_mutex.synchronize do
|
212
|
-
conn.run_callbacks :checkin
|
213
|
-
|
214
|
-
|
214
|
+
conn.run_callbacks :checkin do
|
215
|
+
@checked_out.delete conn
|
216
|
+
@queue.signal
|
217
|
+
end
|
215
218
|
end
|
216
219
|
end
|
217
220
|
|
@@ -253,9 +256,10 @@ module ActiveRecord
|
|
253
256
|
end
|
254
257
|
|
255
258
|
def checkout_and_verify(c)
|
256
|
-
c.
|
257
|
-
|
258
|
-
|
259
|
+
c.run_callbacks :checkout do
|
260
|
+
c.verify!
|
261
|
+
@checked_out << c
|
262
|
+
end
|
259
263
|
c
|
260
264
|
end
|
261
265
|
end
|
@@ -360,7 +364,7 @@ module ActiveRecord
|
|
360
364
|
def call(env)
|
361
365
|
@app.call(env)
|
362
366
|
ensure
|
363
|
-
# Don't return connection (and
|
367
|
+
# Don't return connection (and perform implicit rollback) if
|
364
368
|
# this request is a part of integration test
|
365
369
|
unless env.key?("rack.test")
|
366
370
|
ActiveRecord::Base.clear_active_connections!
|
@@ -10,8 +10,8 @@ module ActiveRecord
|
|
10
10
|
##
|
11
11
|
# :singleton-method:
|
12
12
|
# The connection handler
|
13
|
-
|
14
|
-
|
13
|
+
cattr_accessor :connection_handler, :instance_writer => false
|
14
|
+
@@connection_handler = ConnectionAdapters::ConnectionHandler.new
|
15
15
|
|
16
16
|
# Returns the connection currently associated with the class. This can
|
17
17
|
# also be used to "borrow" the connection to do database work that isn't
|
@@ -51,10 +51,10 @@ module ActiveRecord
|
|
51
51
|
def self.establish_connection(spec = nil)
|
52
52
|
case spec
|
53
53
|
when nil
|
54
|
-
raise AdapterNotSpecified unless defined?
|
55
|
-
establish_connection(
|
54
|
+
raise AdapterNotSpecified unless defined?(Rails.env)
|
55
|
+
establish_connection(Rails.env)
|
56
56
|
when ConnectionSpecification
|
57
|
-
|
57
|
+
@@connection_handler.establish_connection(name, spec)
|
58
58
|
when Symbol, String
|
59
59
|
if configuration = configurations[spec.to_s]
|
60
60
|
establish_connection(configuration)
|
@@ -88,26 +88,6 @@ module ActiveRecord
|
|
88
88
|
end
|
89
89
|
|
90
90
|
class << self
|
91
|
-
# Deprecated and no longer has any effect.
|
92
|
-
def allow_concurrency
|
93
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_concurrency has been deprecated and no longer has any effect. Please remove all references to allow_concurrency.")
|
94
|
-
end
|
95
|
-
|
96
|
-
# Deprecated and no longer has any effect.
|
97
|
-
def allow_concurrency=(flag)
|
98
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_concurrency= has been deprecated and no longer has any effect. Please remove all references to allow_concurrency=.")
|
99
|
-
end
|
100
|
-
|
101
|
-
# Deprecated and no longer has any effect.
|
102
|
-
def verification_timeout
|
103
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.verification_timeout has been deprecated and no longer has any effect. Please remove all references to verification_timeout.")
|
104
|
-
end
|
105
|
-
|
106
|
-
# Deprecated and no longer has any effect.
|
107
|
-
def verification_timeout=(flag)
|
108
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.verification_timeout= has been deprecated and no longer has any effect. Please remove all references to verification_timeout=.")
|
109
|
-
end
|
110
|
-
|
111
91
|
# Returns the connection currently associated with the class. This can
|
112
92
|
# also be used to "borrow" the connection to do database work unrelated
|
113
93
|
# to any of the specific Active Records.
|
@@ -53,7 +53,7 @@ module ActiveRecord
|
|
53
53
|
def delete(sql, name = nil)
|
54
54
|
delete_sql(sql, name)
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
# Checks whether there is currently no transaction active. This is done
|
58
58
|
# by querying the database driver, and does not use the transaction
|
59
59
|
# house-keeping information recorded by #increment_open_transactions and
|
@@ -170,7 +170,7 @@ module ActiveRecord
|
|
170
170
|
end
|
171
171
|
end
|
172
172
|
end
|
173
|
-
|
173
|
+
|
174
174
|
# Begins the transaction (and turns off auto-committing).
|
175
175
|
def begin_db_transaction() end
|
176
176
|
|
@@ -181,45 +181,6 @@ module ActiveRecord
|
|
181
181
|
# done if the transaction block raises an exception or returns false.
|
182
182
|
def rollback_db_transaction() end
|
183
183
|
|
184
|
-
# Alias for <tt>add_limit_offset!</tt>.
|
185
|
-
def add_limit!(sql, options)
|
186
|
-
add_limit_offset!(sql, options) if options
|
187
|
-
end
|
188
|
-
|
189
|
-
# Appends +LIMIT+ and +OFFSET+ options to an SQL statement, or some SQL
|
190
|
-
# fragment that has the same semantics as LIMIT and OFFSET.
|
191
|
-
#
|
192
|
-
# +options+ must be a Hash which contains a +:limit+ option (required)
|
193
|
-
# and an +:offset+ option (optional).
|
194
|
-
#
|
195
|
-
# This method *modifies* the +sql+ parameter.
|
196
|
-
#
|
197
|
-
# ===== Examples
|
198
|
-
# add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
|
199
|
-
# generates
|
200
|
-
# SELECT * FROM suppliers LIMIT 10 OFFSET 50
|
201
|
-
def add_limit_offset!(sql, options)
|
202
|
-
if limit = options[:limit]
|
203
|
-
sql << " LIMIT #{sanitize_limit(limit)}"
|
204
|
-
if offset = options[:offset]
|
205
|
-
sql << " OFFSET #{offset.to_i}"
|
206
|
-
end
|
207
|
-
end
|
208
|
-
sql
|
209
|
-
end
|
210
|
-
|
211
|
-
# Appends a locking clause to an SQL statement.
|
212
|
-
# This method *modifies* the +sql+ parameter.
|
213
|
-
# # SELECT * FROM suppliers FOR UPDATE
|
214
|
-
# add_lock! 'SELECT * FROM suppliers', :lock => true
|
215
|
-
# add_lock! 'SELECT * FROM suppliers', :lock => ' FOR UPDATE'
|
216
|
-
def add_lock!(sql, options)
|
217
|
-
case lock = options[:lock]
|
218
|
-
when true; sql << ' FOR UPDATE'
|
219
|
-
when String; sql << " #{lock}"
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
184
|
def default_sequence_name(table, column)
|
224
185
|
nil
|
225
186
|
end
|
@@ -235,8 +196,8 @@ module ActiveRecord
|
|
235
196
|
execute "INSERT INTO #{quote_table_name(table_name)} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
|
236
197
|
end
|
237
198
|
|
238
|
-
def
|
239
|
-
"
|
199
|
+
def empty_insert_statement_value
|
200
|
+
"VALUES(DEFAULT)"
|
240
201
|
end
|
241
202
|
|
242
203
|
def case_sensitive_equality_operator
|