ibm_db 3.0.0-x86-mingw32 → 3.0.1-x86-mingw32
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.
- checksums.yaml +4 -4
- data/CHANGES +4 -0
- data/MANIFEST +14 -14
- data/README +225 -225
- data/ext/Makefile.nt32 +181 -181
- data/ext/Makefile.nt32.191 +212 -212
- data/ext/OLD/extconf.rb +264 -0
- data/ext/{extconf_MacOS.rb → OLD/extconf_MacOS.rb} +269 -269
- data/ext/extconf.rb +291 -264
- data/ext/ibm_db.c +2 -2
- data/ext/ruby_ibm_db.h +241 -241
- data/ext/ruby_ibm_db_cli.h +500 -500
- data/init.rb +41 -41
- data/lib/IBM_DB.rb +27 -27
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +4 -4
- data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
- data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
- data/lib/mswin32/ibm_db.rb +115 -115
- data/test/active_record/connection_adapters/fake_adapter.rb +46 -0
- data/test/assets/example.log +1 -0
- data/test/assets/flowers.jpg +0 -0
- data/test/assets/test.txt +1 -0
- data/test/cases/adapter_test.rb +261 -207
- data/test/cases/aggregations_test.rb +158 -0
- data/test/cases/ar_schema_test.rb +161 -0
- data/test/cases/associations/association_scope_test.rb +21 -0
- data/test/cases/associations/belongs_to_associations_test.rb +1029 -711
- data/test/cases/associations/callbacks_test.rb +192 -0
- data/test/cases/associations/cascaded_eager_loading_test.rb +188 -181
- data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +26 -0
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -0
- data/test/cases/associations/eager_load_nested_include_test.rb +128 -0
- data/test/cases/associations/eager_singularization_test.rb +148 -0
- data/test/cases/associations/eager_test.rb +1411 -0
- data/test/cases/associations/extension_test.rb +82 -0
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +932 -851
- data/test/cases/associations/has_many_associations_test.rb +2162 -0
- data/test/cases/associations/has_many_through_associations_test.rb +1204 -0
- data/test/cases/associations/has_one_associations_test.rb +610 -0
- data/test/cases/associations/has_one_through_associations_test.rb +380 -0
- data/test/cases/associations/inner_join_association_test.rb +139 -0
- data/test/cases/associations/inverse_associations_test.rb +693 -0
- data/test/cases/associations/join_model_test.rb +754 -743
- data/test/cases/associations/nested_through_associations_test.rb +579 -0
- data/test/cases/associations/required_test.rb +82 -0
- data/test/cases/associations_test.rb +380 -0
- data/test/cases/attribute_decorators_test.rb +125 -0
- data/test/cases/attribute_methods/read_test.rb +60 -0
- data/test/cases/attribute_methods/serialization_test.rb +29 -0
- data/test/cases/attribute_methods_test.rb +952 -822
- data/test/cases/attribute_set_test.rb +200 -0
- data/test/cases/attribute_test.rb +180 -0
- data/test/cases/attributes_test.rb +136 -0
- data/test/cases/autosave_association_test.rb +1595 -0
- data/test/cases/base_test.rb +1638 -2133
- data/test/cases/batches_test.rb +212 -0
- data/test/cases/binary_test.rb +52 -0
- data/test/cases/bind_parameter_test.rb +100 -0
- data/test/cases/calculations_test.rb +646 -482
- data/test/cases/callbacks_test.rb +543 -0
- data/test/cases/clone_test.rb +40 -0
- data/test/cases/coders/yaml_column_test.rb +63 -0
- data/test/cases/column_alias_test.rb +17 -0
- data/test/cases/column_definition_test.rb +123 -0
- data/test/cases/connection_adapters/adapter_leasing_test.rb +54 -0
- data/test/cases/connection_adapters/connection_handler_test.rb +53 -0
- data/test/cases/connection_adapters/connection_specification_test.rb +12 -0
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +293 -0
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +65 -0
- data/test/cases/connection_adapters/quoting_test.rb +13 -0
- data/test/cases/connection_adapters/schema_cache_test.rb +56 -0
- data/test/cases/connection_adapters/type_lookup_test.rb +110 -0
- data/test/cases/connection_management_test.rb +122 -0
- data/test/cases/connection_pool_test.rb +346 -0
- data/test/cases/connection_specification/resolver_test.rb +116 -0
- data/test/cases/core_test.rb +112 -0
- data/test/cases/counter_cache_test.rb +209 -0
- data/test/cases/custom_locking_test.rb +17 -0
- data/test/cases/database_statements_test.rb +19 -0
- data/test/cases/date_time_test.rb +61 -0
- data/test/cases/defaults_test.rb +223 -0
- data/test/cases/dirty_test.rb +775 -0
- data/test/cases/disconnected_test.rb +28 -0
- data/test/cases/dup_test.rb +157 -0
- data/test/cases/enum_test.rb +290 -0
- data/test/cases/explain_subscriber_test.rb +64 -0
- data/test/cases/explain_test.rb +76 -0
- data/test/cases/finder_respond_to_test.rb +60 -0
- data/test/cases/finder_test.rb +1166 -0
- data/test/cases/fixture_set/file_test.rb +138 -0
- data/test/cases/fixtures_test.rb +897 -0
- data/test/cases/forbidden_attributes_protection_test.rb +99 -0
- data/test/cases/habtm_destroy_order_test.rb +61 -0
- data/test/cases/helper.rb +210 -0
- data/test/cases/hot_compatibility_test.rb +54 -0
- data/test/cases/i18n_test.rb +45 -0
- data/test/cases/inheritance_test.rb +375 -0
- data/test/cases/integration_test.rb +139 -0
- data/test/cases/invalid_connection_test.rb +22 -0
- data/test/cases/invalid_date_test.rb +32 -0
- data/test/cases/invertible_migration_test.rb +295 -0
- data/test/cases/json_serialization_test.rb +302 -0
- data/test/cases/locking_test.rb +477 -0
- data/test/cases/log_subscriber_test.rb +136 -0
- data/test/cases/migration/change_schema_test - Copy.rb +448 -0
- data/test/cases/migration/change_schema_test.rb +472 -0
- data/test/cases/migration/change_table_test.rb +224 -0
- data/test/cases/migration/column_attributes_test.rb +192 -0
- data/test/cases/migration/column_positioning_test.rb +56 -0
- data/test/cases/migration/columns_test.rb +304 -0
- data/test/cases/migration/command_recorder_test.rb +305 -0
- data/test/cases/migration/create_join_table_test.rb +148 -0
- data/test/cases/migration/foreign_key_test - Changed.rb +325 -0
- data/test/cases/migration/foreign_key_test.rb +360 -0
- data/test/cases/migration/helper.rb +39 -0
- data/test/cases/migration/index_test.rb +216 -0
- data/test/cases/migration/logger_test.rb +36 -0
- data/test/cases/migration/pending_migrations_test.rb +53 -0
- data/test/cases/migration/references_foreign_key_test.rb +214 -0
- data/test/cases/migration/references_index_test.rb +101 -0
- data/test/cases/migration/references_statements_test.rb +116 -0
- data/test/cases/migration/rename_table_test.rb +93 -0
- data/test/cases/migration/table_and_index_test.rb +24 -0
- data/test/cases/migration_test.rb +959 -2408
- data/test/cases/migrator_test.rb +388 -0
- data/test/cases/mixin_test.rb +70 -0
- data/test/cases/modules_test.rb +173 -0
- data/test/cases/multiparameter_attributes_test.rb +350 -0
- data/test/cases/multiple_db_test.rb +115 -0
- data/test/cases/nested_attributes_test.rb +1057 -0
- data/test/cases/nested_attributes_with_callbacks_test.rb +144 -0
- data/test/cases/persistence_test.rb +909 -642
- data/test/cases/pooled_connections_test.rb +81 -0
- data/test/cases/primary_keys_test.rb +237 -0
- data/test/cases/query_cache_test.rb +326 -257
- data/test/cases/quoting_test.rb +156 -0
- data/test/cases/readonly_test.rb +118 -0
- data/test/cases/reaper_test.rb +85 -0
- data/test/cases/reflection_test.rb +454 -0
- data/test/cases/relation/delegation_test.rb +68 -0
- data/test/cases/relation/merging_test.rb +161 -0
- data/test/cases/relation/mutation_test.rb +165 -0
- data/test/cases/relation/predicate_builder_test.rb +14 -0
- data/test/cases/relation/where_chain_test.rb +181 -0
- data/test/cases/relation/where_test.rb +300 -0
- data/test/cases/relation/where_test2.rb +36 -0
- data/test/cases/relation_test.rb +297 -0
- data/test/cases/relations_test.rb +1815 -1182
- data/test/cases/reload_models_test.rb +22 -0
- data/test/cases/result_test.rb +80 -0
- data/test/cases/sanitize_test.rb +83 -0
- data/test/cases/schema_dumper_test.rb +463 -256
- data/test/cases/scoping/default_scoping_test.rb +454 -0
- data/test/cases/scoping/named_scoping_test.rb +524 -0
- data/test/cases/scoping/relation_scoping_test.rb +357 -0
- data/test/cases/serialization_test.rb +104 -0
- data/test/cases/serialized_attribute_test.rb +277 -0
- data/test/cases/statement_cache_test.rb +98 -0
- data/test/cases/store_test.rb +194 -0
- data/test/cases/tasks/database_tasks_test.rb +396 -0
- data/test/cases/tasks/mysql_rake_test.rb +311 -0
- data/test/cases/tasks/postgresql_rake_test.rb +245 -0
- data/test/cases/tasks/sqlite_rake_test.rb +193 -0
- data/test/cases/test_case.rb +123 -0
- data/test/cases/timestamp_test.rb +468 -0
- data/test/cases/transaction_callbacks_test.rb +452 -300
- data/test/cases/transaction_isolation_test.rb +106 -0
- data/test/cases/transactions_test.rb +817 -0
- data/test/cases/type/decimal_test.rb +51 -0
- data/test/cases/type/integer_test.rb +121 -0
- data/test/cases/type/string_test.rb +36 -0
- data/test/cases/type/type_map_test.rb +177 -0
- data/test/cases/type/unsigned_integer_test.rb +18 -0
- data/test/cases/types_test.rb +141 -0
- data/test/cases/unconnected_test.rb +33 -0
- data/test/cases/validations/association_validation_test.rb +86 -0
- data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -0
- data/test/cases/validations/i18n_validation_test.rb +90 -0
- data/test/cases/validations/length_validation_test.rb +47 -0
- data/test/cases/validations/presence_validation_test.rb +68 -0
- data/test/cases/validations/uniqueness_validation_test.rb +434 -299
- data/test/cases/validations_repair_helper.rb +23 -0
- data/test/cases/validations_test.rb +165 -0
- data/test/cases/view_test.rb +113 -0
- data/test/cases/xml_serialization_test.rb +457 -408
- data/test/cases/yaml_serialization_test.rb +86 -0
- data/test/config.rb +5 -0
- data/test/config.yml +154 -154
- data/test/connections/native_ibm_db/connection.rb +43 -43
- data/test/fixtures/accounts.yml +29 -0
- data/test/fixtures/admin/accounts.yml +2 -0
- data/test/fixtures/admin/randomly_named_a9.yml +7 -0
- data/test/fixtures/admin/randomly_named_b0.yml +7 -0
- data/test/fixtures/admin/users.yml +10 -0
- data/test/fixtures/all/admin +1 -0
- data/test/fixtures/all/developers.yml +0 -0
- data/test/fixtures/all/people.yml +0 -0
- data/test/fixtures/all/tasks.yml +0 -0
- data/test/fixtures/author_addresses.yml +18 -0
- data/test/fixtures/author_favorites.yml +4 -0
- data/test/fixtures/authors.yml +23 -0
- data/test/fixtures/binaries.yml +133 -0
- data/test/fixtures/books.yml +11 -0
- data/test/fixtures/bulbs.yml +5 -0
- data/test/fixtures/cars.yml +9 -0
- data/test/fixtures/categories.yml +19 -0
- data/test/fixtures/categories/special_categories.yml +9 -0
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
- data/test/fixtures/categories_ordered.yml +7 -0
- data/test/fixtures/categories_posts.yml +31 -0
- data/test/fixtures/categorizations.yml +23 -0
- data/test/fixtures/clubs.yml +8 -0
- data/test/fixtures/collections.yml +3 -0
- data/test/fixtures/colleges.yml +3 -0
- data/test/fixtures/comments.yml +65 -0
- data/test/fixtures/companies.yml +67 -0
- data/test/fixtures/computers.yml +10 -0
- data/test/fixtures/courses.yml +8 -0
- data/test/fixtures/customers.yml +26 -0
- data/test/fixtures/dashboards.yml +6 -0
- data/test/fixtures/developers.yml +22 -0
- data/test/fixtures/developers_projects.yml +17 -0
- data/test/fixtures/dog_lovers.yml +7 -0
- data/test/fixtures/dogs.yml +4 -0
- data/test/fixtures/doubloons.yml +3 -0
- data/test/fixtures/edges.yml +5 -0
- data/test/fixtures/entrants.yml +14 -0
- data/test/fixtures/essays.yml +6 -0
- data/test/fixtures/faces.yml +11 -0
- data/test/fixtures/fk_test_has_fk.yml +3 -0
- data/test/fixtures/fk_test_has_pk.yml +2 -0
- data/test/fixtures/friendships.yml +4 -0
- data/test/fixtures/funny_jokes.yml +10 -0
- data/test/fixtures/interests.yml +33 -0
- data/test/fixtures/items.yml +3 -0
- data/test/fixtures/jobs.yml +7 -0
- data/test/fixtures/legacy_things.yml +3 -0
- data/test/fixtures/mateys.yml +4 -0
- data/test/fixtures/member_details.yml +8 -0
- data/test/fixtures/member_types.yml +6 -0
- data/test/fixtures/members.yml +11 -0
- data/test/fixtures/memberships.yml +34 -0
- data/test/fixtures/men.yml +5 -0
- data/test/fixtures/minimalistics.yml +2 -0
- data/test/fixtures/minivans.yml +5 -0
- data/test/fixtures/mixed_case_monkeys.yml +6 -0
- data/test/fixtures/mixins.yml +29 -0
- data/test/fixtures/movies.yml +7 -0
- data/test/fixtures/naked/csv/accounts.csv +1 -0
- data/test/fixtures/naked/yml/accounts.yml +1 -0
- data/test/fixtures/naked/yml/companies.yml +1 -0
- data/test/fixtures/naked/yml/courses.yml +1 -0
- data/test/fixtures/organizations.yml +5 -0
- data/test/fixtures/other_topics.yml +42 -0
- data/test/fixtures/owners.yml +9 -0
- data/test/fixtures/parrots.yml +27 -0
- data/test/fixtures/parrots_pirates.yml +7 -0
- data/test/fixtures/people.yml +24 -0
- data/test/fixtures/peoples_treasures.yml +3 -0
- data/test/fixtures/pets.yml +19 -0
- data/test/fixtures/pirates.yml +12 -0
- data/test/fixtures/posts.yml +80 -0
- data/test/fixtures/price_estimates.yml +7 -0
- data/test/fixtures/products.yml +4 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/randomly_named_a9.yml +7 -0
- data/test/fixtures/ratings.yml +14 -0
- data/test/fixtures/readers.yml +11 -0
- data/test/fixtures/references.yml +17 -0
- data/test/fixtures/reserved_words/distinct.yml +5 -0
- data/test/fixtures/reserved_words/distinct_select.yml +11 -0
- data/test/fixtures/reserved_words/group.yml +14 -0
- data/test/fixtures/reserved_words/select.yml +8 -0
- data/test/fixtures/reserved_words/values.yml +7 -0
- data/test/fixtures/ships.yml +6 -0
- data/test/fixtures/speedometers.yml +8 -0
- data/test/fixtures/sponsors.yml +12 -0
- data/test/fixtures/string_key_objects.yml +7 -0
- data/test/fixtures/subscribers.yml +11 -0
- data/test/fixtures/subscriptions.yml +12 -0
- data/test/fixtures/taggings.yml +78 -0
- data/test/fixtures/tags.yml +11 -0
- data/test/fixtures/tasks.yml +7 -0
- data/test/fixtures/teapots.yml +3 -0
- data/test/fixtures/to_be_linked/accounts.yml +2 -0
- data/test/fixtures/to_be_linked/users.yml +10 -0
- data/test/fixtures/topics.yml +49 -0
- data/test/fixtures/toys.yml +14 -0
- data/test/fixtures/traffic_lights.yml +10 -0
- data/test/fixtures/treasures.yml +10 -0
- data/test/fixtures/uuid_children.yml +3 -0
- data/test/fixtures/uuid_parents.yml +2 -0
- data/test/fixtures/variants.yml +4 -0
- data/test/fixtures/vegetables.yml +20 -0
- data/test/fixtures/vertices.yml +4 -0
- data/test/fixtures/warehouse_things.yml +3 -0
- data/test/fixtures/zines.yml +5 -0
- data/test/ibm_db_test.rb +24 -24
- data/test/migrations/10_urban/9_add_expressions.rb +11 -0
- data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -0
- data/test/migrations/magic/1_currencies_have_symbols.rb +12 -0
- data/test/migrations/missing/1000_people_have_middle_names.rb +9 -0
- data/test/migrations/missing/1_people_have_last_names.rb +9 -0
- data/test/migrations/missing/3_we_need_reminders.rb +12 -0
- data/test/migrations/missing/4_innocent_jointable.rb +12 -0
- data/test/migrations/rename/1_we_need_things.rb +11 -0
- data/test/migrations/rename/2_rename_things.rb +9 -0
- data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -0
- data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -0
- data/test/migrations/to_copy2/1_create_articles.rb +7 -0
- data/test/migrations/to_copy2/2_create_comments.rb +7 -0
- data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -0
- data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -0
- data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -0
- data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -0
- data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -0
- data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -0
- data/test/migrations/valid/2_we_need_reminders.rb +12 -0
- data/test/migrations/valid/3_innocent_jointable.rb +12 -0
- data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -0
- data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -0
- data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -0
- data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -0
- data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -0
- data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -0
- data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -0
- data/test/models/admin.rb +5 -0
- data/test/models/admin/account.rb +3 -0
- data/test/models/admin/randomly_named_c1.rb +3 -0
- data/test/models/admin/user.rb +40 -0
- data/test/models/aircraft.rb +4 -0
- data/test/models/arunit2_model.rb +3 -0
- data/test/models/author.rb +212 -0
- data/test/models/auto_id.rb +4 -0
- data/test/models/autoloadable/extra_firm.rb +2 -0
- data/test/models/binary.rb +2 -0
- data/test/models/bird.rb +12 -0
- data/test/models/book.rb +18 -0
- data/test/models/boolean.rb +2 -0
- data/test/models/bulb.rb +51 -0
- data/test/models/cake_designer.rb +3 -0
- data/test/models/car.rb +26 -0
- data/test/models/carrier.rb +2 -0
- data/test/models/categorization.rb +19 -0
- data/test/models/category.rb +35 -0
- data/test/models/chef.rb +3 -0
- data/test/models/citation.rb +3 -0
- data/test/models/club.rb +23 -0
- data/test/models/college.rb +10 -0
- data/test/models/column.rb +3 -0
- data/test/models/column_name.rb +3 -0
- data/test/models/comment.rb +64 -0
- data/test/models/company.rb +225 -0
- data/test/models/company_in_module.rb +98 -0
- data/test/models/computer.rb +3 -0
- data/test/models/contact.rb +41 -0
- data/test/models/contract.rb +20 -0
- data/test/models/country.rb +7 -0
- data/test/models/course.rb +6 -0
- data/test/models/customer.rb +77 -0
- data/test/models/customer_carrier.rb +14 -0
- data/test/models/dashboard.rb +3 -0
- data/test/models/default.rb +2 -0
- data/test/models/department.rb +4 -0
- data/test/models/developer.rb +252 -0
- data/test/models/dog.rb +5 -0
- data/test/models/dog_lover.rb +5 -0
- data/test/models/doubloon.rb +12 -0
- data/test/models/drink_designer.rb +3 -0
- data/test/models/edge.rb +5 -0
- data/test/models/electron.rb +5 -0
- data/test/models/engine.rb +4 -0
- data/test/models/entrant.rb +3 -0
- data/test/models/essay.rb +5 -0
- data/test/models/event.rb +3 -0
- data/test/models/eye.rb +37 -0
- data/test/models/face.rb +9 -0
- data/test/models/friendship.rb +6 -0
- data/test/models/guid.rb +2 -0
- data/test/models/hotel.rb +6 -0
- data/test/models/image.rb +3 -0
- data/test/models/interest.rb +5 -0
- data/test/models/invoice.rb +4 -0
- data/test/models/item.rb +7 -0
- data/test/models/job.rb +7 -0
- data/test/models/joke.rb +7 -0
- data/test/models/keyboard.rb +3 -0
- data/test/models/legacy_thing.rb +3 -0
- data/test/models/lesson.rb +11 -0
- data/test/models/line_item.rb +3 -0
- data/test/models/liquid.rb +4 -0
- data/test/models/man.rb +11 -0
- data/test/models/matey.rb +4 -0
- data/test/models/member.rb +41 -0
- data/test/models/member_detail.rb +7 -0
- data/test/models/member_type.rb +3 -0
- data/test/models/membership.rb +35 -0
- data/test/models/minimalistic.rb +2 -0
- data/test/models/minivan.rb +9 -0
- data/test/models/mixed_case_monkey.rb +3 -0
- data/test/models/molecule.rb +6 -0
- data/test/models/movie.rb +5 -0
- data/test/models/order.rb +4 -0
- data/test/models/organization.rb +14 -0
- data/test/models/owner.rb +34 -0
- data/test/models/parrot.rb +29 -0
- data/test/models/person.rb +143 -0
- data/test/models/personal_legacy_thing.rb +4 -0
- data/test/models/pet.rb +15 -0
- data/test/models/pirate.rb +92 -0
- data/test/models/possession.rb +3 -0
- data/test/models/post.rb +264 -0
- data/test/models/price_estimate.rb +4 -0
- data/test/models/professor.rb +5 -0
- data/test/models/project.rb +29 -0
- data/test/models/publisher.rb +2 -0
- data/test/models/publisher/article.rb +4 -0
- data/test/models/publisher/magazine.rb +3 -0
- data/test/models/randomly_named_c1.rb +3 -0
- data/test/models/rating.rb +4 -0
- data/test/models/reader.rb +23 -0
- data/test/models/record.rb +2 -0
- data/test/models/reference.rb +22 -0
- data/test/models/reply.rb +61 -0
- data/test/models/ship.rb +33 -0
- data/test/models/ship_part.rb +8 -0
- data/test/models/shop.rb +17 -0
- data/test/models/shop_account.rb +6 -0
- data/test/models/speedometer.rb +6 -0
- data/test/models/sponsor.rb +7 -0
- data/test/models/string_key_object.rb +3 -0
- data/test/models/student.rb +4 -0
- data/test/models/subject.rb +16 -0
- data/test/models/subscriber.rb +8 -0
- data/test/models/subscription.rb +4 -0
- data/test/models/tag.rb +7 -0
- data/test/models/tagging.rb +13 -0
- data/test/models/task.rb +5 -0
- data/test/models/topic.rb +124 -0
- data/test/models/toy.rb +6 -0
- data/test/models/traffic_light.rb +4 -0
- data/test/models/treasure.rb +14 -0
- data/test/models/treaty.rb +7 -0
- data/test/models/tyre.rb +11 -0
- data/test/models/uuid_child.rb +3 -0
- data/test/models/uuid_parent.rb +3 -0
- data/test/models/vegetables.rb +24 -0
- data/test/models/vehicle.rb +7 -0
- data/test/models/vertex.rb +9 -0
- data/test/models/warehouse_thing.rb +5 -5
- data/test/models/wheel.rb +3 -0
- data/test/models/without_table.rb +3 -0
- data/test/models/zine.rb +3 -0
- data/test/schema/mysql2_specific_schema.rb +58 -0
- data/test/schema/mysql_specific_schema.rb +70 -0
- data/test/schema/oracle_specific_schema.rb +43 -0
- data/test/schema/postgresql_specific_schema.rb +202 -0
- data/test/schema/schema.rb +938 -751
- data/test/schema/sqlite_specific_schema.rb +22 -0
- data/test/support/config.rb +43 -0
- data/test/support/connection.rb +22 -0
- data/test/support/connection_helper.rb +14 -0
- data/test/support/ddl_helper.rb +8 -0
- data/test/support/schema_dumping_helper.rb +20 -0
- metadata +444 -18
@@ -0,0 +1,65 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
|
3
|
+
if current_adapter?(:MysqlAdapter, :Mysql2Adapter)
|
4
|
+
module ActiveRecord
|
5
|
+
module ConnectionAdapters
|
6
|
+
class MysqlTypeLookupTest < ActiveRecord::TestCase
|
7
|
+
setup do
|
8
|
+
@connection = ActiveRecord::Base.connection
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_boolean_types
|
12
|
+
emulate_booleans(true) do
|
13
|
+
assert_lookup_type :boolean, 'tinyint(1)'
|
14
|
+
assert_lookup_type :boolean, 'TINYINT(1)'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_string_types
|
19
|
+
assert_lookup_type :string, "enum('one', 'two', 'three')"
|
20
|
+
assert_lookup_type :string, "ENUM('one', 'two', 'three')"
|
21
|
+
assert_lookup_type :string, "set('one', 'two', 'three')"
|
22
|
+
assert_lookup_type :string, "SET('one', 'two', 'three')"
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_enum_type_with_value_matching_other_type
|
26
|
+
assert_lookup_type :string, "ENUM('unicode', '8bit', 'none')"
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_binary_types
|
30
|
+
assert_lookup_type :binary, 'bit'
|
31
|
+
assert_lookup_type :binary, 'BIT'
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_integer_types
|
35
|
+
emulate_booleans(false) do
|
36
|
+
assert_lookup_type :integer, 'tinyint(1)'
|
37
|
+
assert_lookup_type :integer, 'TINYINT(1)'
|
38
|
+
assert_lookup_type :integer, 'year'
|
39
|
+
assert_lookup_type :integer, 'YEAR'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def assert_lookup_type(type, lookup)
|
46
|
+
cast_type = @connection.type_map.lookup(lookup)
|
47
|
+
assert_equal type, cast_type.type
|
48
|
+
end
|
49
|
+
|
50
|
+
def emulate_booleans(value)
|
51
|
+
old_emulate_booleans = @connection.emulate_booleans
|
52
|
+
change_emulate_booleans(value)
|
53
|
+
yield
|
54
|
+
ensure
|
55
|
+
change_emulate_booleans(old_emulate_booleans)
|
56
|
+
end
|
57
|
+
|
58
|
+
def change_emulate_booleans(value)
|
59
|
+
@connection.emulate_booleans = value
|
60
|
+
@connection.clear_cache!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module Quoting
|
6
|
+
class QuotingTest < ActiveRecord::TestCase
|
7
|
+
def test_quoting_classes
|
8
|
+
assert_equal "'Object'", AbstractAdapter.new(nil).quote(Object)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
class SchemaCacheTest < ActiveRecord::TestCase
|
6
|
+
def setup
|
7
|
+
connection = ActiveRecord::Base.connection
|
8
|
+
@cache = SchemaCache.new connection
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_primary_key
|
12
|
+
assert_equal 'id', @cache.primary_keys('posts')
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_primary_key_for_non_existent_table
|
16
|
+
assert_nil @cache.primary_keys('omgponies')
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_caches_columns
|
20
|
+
columns = @cache.columns('posts')
|
21
|
+
assert_equal columns, @cache.columns('posts')
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_caches_columns_hash
|
25
|
+
columns_hash = @cache.columns_hash('posts')
|
26
|
+
assert_equal columns_hash, @cache.columns_hash('posts')
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_clearing
|
30
|
+
@cache.columns('posts')
|
31
|
+
@cache.columns_hash('posts')
|
32
|
+
@cache.tables('posts')
|
33
|
+
@cache.primary_keys('posts')
|
34
|
+
|
35
|
+
@cache.clear!
|
36
|
+
|
37
|
+
assert_equal 0, @cache.size
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_dump_and_load
|
41
|
+
@cache.columns('posts')
|
42
|
+
@cache.columns_hash('posts')
|
43
|
+
@cache.tables('posts')
|
44
|
+
@cache.primary_keys('posts')
|
45
|
+
|
46
|
+
@cache = Marshal.load(Marshal.dump(@cache))
|
47
|
+
|
48
|
+
assert_equal 11, @cache.columns('posts').size
|
49
|
+
assert_equal 11, @cache.columns_hash('posts').size
|
50
|
+
assert @cache.tables('posts')
|
51
|
+
assert_equal 'id', @cache.primary_keys('posts')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
|
3
|
+
unless current_adapter?(:PostgreSQLAdapter) # PostgreSQL does not use type strigns for lookup
|
4
|
+
module ActiveRecord
|
5
|
+
module ConnectionAdapters
|
6
|
+
class TypeLookupTest < ActiveRecord::TestCase
|
7
|
+
setup do
|
8
|
+
@connection = ActiveRecord::Base.connection
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_boolean_types
|
12
|
+
assert_lookup_type :boolean, 'boolean'
|
13
|
+
assert_lookup_type :boolean, 'BOOLEAN'
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_string_types
|
17
|
+
assert_lookup_type :string, 'char'
|
18
|
+
assert_lookup_type :string, 'varchar'
|
19
|
+
assert_lookup_type :string, 'VARCHAR'
|
20
|
+
assert_lookup_type :string, 'varchar(255)'
|
21
|
+
assert_lookup_type :string, 'character varying'
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_binary_types
|
25
|
+
assert_lookup_type :binary, 'binary'
|
26
|
+
assert_lookup_type :binary, 'BINARY'
|
27
|
+
assert_lookup_type :binary, 'blob'
|
28
|
+
assert_lookup_type :binary, 'BLOB'
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_text_types
|
32
|
+
assert_lookup_type :text, 'text'
|
33
|
+
assert_lookup_type :text, 'TEXT'
|
34
|
+
assert_lookup_type :text, 'clob'
|
35
|
+
assert_lookup_type :text, 'CLOB'
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_date_types
|
39
|
+
assert_lookup_type :date, 'date'
|
40
|
+
assert_lookup_type :date, 'DATE'
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_time_types
|
44
|
+
assert_lookup_type :time, 'time'
|
45
|
+
assert_lookup_type :time, 'TIME'
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_datetime_types
|
49
|
+
assert_lookup_type :datetime, 'datetime'
|
50
|
+
assert_lookup_type :datetime, 'DATETIME'
|
51
|
+
assert_lookup_type :datetime, 'timestamp'
|
52
|
+
assert_lookup_type :datetime, 'TIMESTAMP'
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_decimal_types
|
56
|
+
assert_lookup_type :decimal, 'decimal'
|
57
|
+
assert_lookup_type :decimal, 'decimal(2,8)'
|
58
|
+
assert_lookup_type :decimal, 'DECIMAL'
|
59
|
+
assert_lookup_type :decimal, 'numeric'
|
60
|
+
assert_lookup_type :decimal, 'numeric(2,8)'
|
61
|
+
assert_lookup_type :decimal, 'NUMERIC'
|
62
|
+
assert_lookup_type :decimal, 'number'
|
63
|
+
assert_lookup_type :decimal, 'number(2,8)'
|
64
|
+
assert_lookup_type :decimal, 'NUMBER'
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_float_types
|
68
|
+
assert_lookup_type :float, 'float'
|
69
|
+
assert_lookup_type :float, 'FLOAT'
|
70
|
+
assert_lookup_type :float, 'double'
|
71
|
+
assert_lookup_type :float, 'DOUBLE'
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_integer_types
|
75
|
+
assert_lookup_type :integer, 'integer'
|
76
|
+
assert_lookup_type :integer, 'INTEGER'
|
77
|
+
assert_lookup_type :integer, 'tinyint'
|
78
|
+
assert_lookup_type :integer, 'smallint'
|
79
|
+
assert_lookup_type :integer, 'bigint'
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_bigint_limit
|
83
|
+
cast_type = @connection.type_map.lookup("bigint")
|
84
|
+
if current_adapter?(:OracleAdapter)
|
85
|
+
assert_equal 19, cast_type.limit
|
86
|
+
else
|
87
|
+
assert_equal 8, cast_type.limit
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_decimal_without_scale
|
92
|
+
types = %w{decimal(2) decimal(2,0) numeric(2) numeric(2,0) number(2) number(2,0)}
|
93
|
+
types.each do |type|
|
94
|
+
cast_type = @connection.type_map.lookup(type)
|
95
|
+
|
96
|
+
assert_equal :decimal, cast_type.type
|
97
|
+
assert_equal 2, cast_type.type_cast_from_user(2.1)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def assert_lookup_type(type, lookup)
|
104
|
+
cast_type = @connection.type_map.lookup(lookup)
|
105
|
+
assert_equal type, cast_type.type
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
require "rack"
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
module ConnectionAdapters
|
6
|
+
class ConnectionManagementTest < ActiveRecord::TestCase
|
7
|
+
class App
|
8
|
+
attr_reader :calls
|
9
|
+
def initialize
|
10
|
+
@calls = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
@calls << env
|
15
|
+
[200, {}, ['hi mom']]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@env = {}
|
21
|
+
@app = App.new
|
22
|
+
@management = ConnectionManagement.new(@app)
|
23
|
+
|
24
|
+
# make sure we have an active connection
|
25
|
+
assert ActiveRecord::Base.connection
|
26
|
+
assert ActiveRecord::Base.connection_handler.active_connections?
|
27
|
+
end
|
28
|
+
|
29
|
+
if Process.respond_to?(:fork)
|
30
|
+
def test_connection_pool_per_pid
|
31
|
+
object_id = ActiveRecord::Base.connection.object_id
|
32
|
+
|
33
|
+
rd, wr = IO.pipe
|
34
|
+
rd.binmode
|
35
|
+
wr.binmode
|
36
|
+
|
37
|
+
pid = fork {
|
38
|
+
rd.close
|
39
|
+
wr.write Marshal.dump ActiveRecord::Base.connection.object_id
|
40
|
+
wr.close
|
41
|
+
exit!
|
42
|
+
}
|
43
|
+
|
44
|
+
wr.close
|
45
|
+
|
46
|
+
Process.waitpid pid
|
47
|
+
assert_not_equal object_id, Marshal.load(rd.read)
|
48
|
+
rd.close
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_app_delegation
|
53
|
+
manager = ConnectionManagement.new(@app)
|
54
|
+
|
55
|
+
manager.call @env
|
56
|
+
assert_equal [@env], @app.calls
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_connections_are_active_after_call
|
60
|
+
@management.call(@env)
|
61
|
+
assert ActiveRecord::Base.connection_handler.active_connections?
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_body_responds_to_each
|
65
|
+
_, _, body = @management.call(@env)
|
66
|
+
bits = []
|
67
|
+
body.each { |bit| bits << bit }
|
68
|
+
assert_equal ['hi mom'], bits
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_connections_are_cleared_after_body_close
|
72
|
+
_, _, body = @management.call(@env)
|
73
|
+
body.close
|
74
|
+
assert !ActiveRecord::Base.connection_handler.active_connections?
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_active_connections_are_not_cleared_on_body_close_during_test
|
78
|
+
@env['rack.test'] = true
|
79
|
+
_, _, body = @management.call(@env)
|
80
|
+
body.close
|
81
|
+
assert ActiveRecord::Base.connection_handler.active_connections?
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_connections_closed_if_exception
|
85
|
+
app = Class.new(App) { def call(env); raise NotImplementedError; end }.new
|
86
|
+
explosive = ConnectionManagement.new(app)
|
87
|
+
assert_raises(NotImplementedError) { explosive.call(@env) }
|
88
|
+
assert !ActiveRecord::Base.connection_handler.active_connections?
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_connections_not_closed_if_exception_and_test
|
92
|
+
@env['rack.test'] = true
|
93
|
+
app = Class.new(App) { def call(env); raise; end }.new
|
94
|
+
explosive = ConnectionManagement.new(app)
|
95
|
+
assert_raises(RuntimeError) { explosive.call(@env) }
|
96
|
+
assert ActiveRecord::Base.connection_handler.active_connections?
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_connections_closed_if_exception_and_explicitly_not_test
|
100
|
+
@env['rack.test'] = false
|
101
|
+
app = Class.new(App) { def call(env); raise NotImplementedError; end }.new
|
102
|
+
explosive = ConnectionManagement.new(app)
|
103
|
+
assert_raises(NotImplementedError) { explosive.call(@env) }
|
104
|
+
assert !ActiveRecord::Base.connection_handler.active_connections?
|
105
|
+
end
|
106
|
+
|
107
|
+
test "doesn't clear active connections when running in a test case" do
|
108
|
+
@env['rack.test'] = true
|
109
|
+
@management.call(@env)
|
110
|
+
assert ActiveRecord::Base.connection_handler.active_connections?
|
111
|
+
end
|
112
|
+
|
113
|
+
test "proxy is polite to it's body and responds to it" do
|
114
|
+
body = Class.new(String) { def to_path; "/path"; end }.new
|
115
|
+
app = lambda { |_| [200, {}, body] }
|
116
|
+
response_body = ConnectionManagement.new(app).call(@env)[2]
|
117
|
+
assert response_body.respond_to?(:to_path)
|
118
|
+
assert_equal response_body.to_path, "/path"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,346 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
require 'active_support/concurrency/latch'
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
module ConnectionAdapters
|
6
|
+
class ConnectionPoolTest < ActiveRecord::TestCase
|
7
|
+
attr_reader :pool
|
8
|
+
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
|
12
|
+
# Keep a duplicate pool so we do not bother others
|
13
|
+
@pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
|
14
|
+
|
15
|
+
if in_memory_db?
|
16
|
+
# Separate connections to an in-memory database create an entirely new database,
|
17
|
+
# with an empty schema etc, so we just stub out this schema on the fly.
|
18
|
+
@pool.with_connection do |connection|
|
19
|
+
connection.create_table :posts do |t|
|
20
|
+
t.integer :cololumn
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
teardown do
|
27
|
+
@pool.disconnect!
|
28
|
+
end
|
29
|
+
|
30
|
+
def active_connections(pool)
|
31
|
+
pool.connections.find_all(&:in_use?)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_checkout_after_close
|
35
|
+
connection = pool.connection
|
36
|
+
assert connection.in_use?
|
37
|
+
|
38
|
+
connection.close
|
39
|
+
assert !connection.in_use?
|
40
|
+
|
41
|
+
assert pool.connection.in_use?
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_released_connection_moves_between_threads
|
45
|
+
thread_conn = nil
|
46
|
+
|
47
|
+
Thread.new {
|
48
|
+
pool.with_connection do |conn|
|
49
|
+
thread_conn = conn
|
50
|
+
end
|
51
|
+
}.join
|
52
|
+
|
53
|
+
assert thread_conn
|
54
|
+
|
55
|
+
Thread.new {
|
56
|
+
pool.with_connection do |conn|
|
57
|
+
assert_equal thread_conn, conn
|
58
|
+
end
|
59
|
+
}.join
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_with_connection
|
63
|
+
assert_equal 0, active_connections(pool).size
|
64
|
+
|
65
|
+
main_thread = pool.connection
|
66
|
+
assert_equal 1, active_connections(pool).size
|
67
|
+
|
68
|
+
Thread.new {
|
69
|
+
pool.with_connection do |conn|
|
70
|
+
assert conn
|
71
|
+
assert_equal 2, active_connections(pool).size
|
72
|
+
end
|
73
|
+
assert_equal 1, active_connections(pool).size
|
74
|
+
}.join
|
75
|
+
|
76
|
+
main_thread.close
|
77
|
+
assert_equal 0, active_connections(pool).size
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_active_connection_in_use
|
81
|
+
assert !pool.active_connection?
|
82
|
+
main_thread = pool.connection
|
83
|
+
|
84
|
+
assert pool.active_connection?
|
85
|
+
|
86
|
+
main_thread.close
|
87
|
+
|
88
|
+
assert !pool.active_connection?
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_full_pool_exception
|
92
|
+
@pool.size.times { @pool.checkout }
|
93
|
+
assert_raises(ConnectionTimeoutError) do
|
94
|
+
@pool.checkout
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_full_pool_blocks
|
99
|
+
cs = @pool.size.times.map { @pool.checkout }
|
100
|
+
t = Thread.new { @pool.checkout }
|
101
|
+
|
102
|
+
# make sure our thread is in the timeout section
|
103
|
+
Thread.pass until t.status == "sleep"
|
104
|
+
|
105
|
+
connection = cs.first
|
106
|
+
connection.close
|
107
|
+
assert_equal connection, t.join.value
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_removing_releases_latch
|
111
|
+
cs = @pool.size.times.map { @pool.checkout }
|
112
|
+
t = Thread.new { @pool.checkout }
|
113
|
+
|
114
|
+
# make sure our thread is in the timeout section
|
115
|
+
Thread.pass until t.status == "sleep"
|
116
|
+
|
117
|
+
connection = cs.first
|
118
|
+
@pool.remove connection
|
119
|
+
assert_respond_to t.join.value, :execute
|
120
|
+
connection.close
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_reap_and_active
|
124
|
+
@pool.checkout
|
125
|
+
@pool.checkout
|
126
|
+
@pool.checkout
|
127
|
+
|
128
|
+
connections = @pool.connections.dup
|
129
|
+
|
130
|
+
@pool.reap
|
131
|
+
|
132
|
+
assert_equal connections.length, @pool.connections.length
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_reap_inactive
|
136
|
+
ready = ActiveSupport::Concurrency::Latch.new
|
137
|
+
@pool.checkout
|
138
|
+
child = Thread.new do
|
139
|
+
@pool.checkout
|
140
|
+
@pool.checkout
|
141
|
+
ready.release
|
142
|
+
Thread.stop
|
143
|
+
end
|
144
|
+
ready.await
|
145
|
+
|
146
|
+
assert_equal 3, active_connections(@pool).size
|
147
|
+
|
148
|
+
child.terminate
|
149
|
+
child.join
|
150
|
+
@pool.reap
|
151
|
+
|
152
|
+
assert_equal 1, active_connections(@pool).size
|
153
|
+
ensure
|
154
|
+
@pool.connections.each(&:close)
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_remove_connection
|
158
|
+
conn = @pool.checkout
|
159
|
+
assert conn.in_use?
|
160
|
+
|
161
|
+
length = @pool.connections.length
|
162
|
+
@pool.remove conn
|
163
|
+
assert conn.in_use?
|
164
|
+
assert_equal(length - 1, @pool.connections.length)
|
165
|
+
ensure
|
166
|
+
conn.close
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_remove_connection_for_thread
|
170
|
+
conn = @pool.connection
|
171
|
+
@pool.remove conn
|
172
|
+
assert_not_equal(conn, @pool.connection)
|
173
|
+
ensure
|
174
|
+
conn.close if conn
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_active_connection?
|
178
|
+
assert !@pool.active_connection?
|
179
|
+
assert @pool.connection
|
180
|
+
assert @pool.active_connection?
|
181
|
+
@pool.release_connection
|
182
|
+
assert !@pool.active_connection?
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_checkout_behaviour
|
186
|
+
pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
|
187
|
+
connection = pool.connection
|
188
|
+
assert_not_nil connection
|
189
|
+
threads = []
|
190
|
+
4.times do |i|
|
191
|
+
threads << Thread.new(i) do
|
192
|
+
connection = pool.connection
|
193
|
+
assert_not_nil connection
|
194
|
+
connection.close
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
threads.each(&:join)
|
199
|
+
|
200
|
+
Thread.new do
|
201
|
+
assert pool.connection
|
202
|
+
pool.connection.close
|
203
|
+
end.join
|
204
|
+
end
|
205
|
+
|
206
|
+
# The connection pool is "fair" if threads waiting for
|
207
|
+
# connections receive them the order in which they began
|
208
|
+
# waiting. This ensures that we don't timeout one HTTP request
|
209
|
+
# even while well under capacity in a multi-threaded environment
|
210
|
+
# such as a Java servlet container.
|
211
|
+
#
|
212
|
+
# We don't need strict fairness: if two connections become
|
213
|
+
# available at the same time, it's fine of two threads that were
|
214
|
+
# waiting acquire the connections out of order.
|
215
|
+
#
|
216
|
+
# Thus this test prepares waiting threads and then trickles in
|
217
|
+
# available connections slowly, ensuring the wakeup order is
|
218
|
+
# correct in this case.
|
219
|
+
def test_checkout_fairness
|
220
|
+
@pool.instance_variable_set(:@size, 10)
|
221
|
+
expected = (1..@pool.size).to_a.freeze
|
222
|
+
# check out all connections so our threads start out waiting
|
223
|
+
conns = expected.map { @pool.checkout }
|
224
|
+
mutex = Mutex.new
|
225
|
+
order = []
|
226
|
+
errors = []
|
227
|
+
|
228
|
+
threads = expected.map do |i|
|
229
|
+
t = Thread.new {
|
230
|
+
begin
|
231
|
+
@pool.checkout # never checked back in
|
232
|
+
mutex.synchronize { order << i }
|
233
|
+
rescue => e
|
234
|
+
mutex.synchronize { errors << e }
|
235
|
+
end
|
236
|
+
}
|
237
|
+
Thread.pass until t.status == "sleep"
|
238
|
+
t
|
239
|
+
end
|
240
|
+
|
241
|
+
# this should wake up the waiting threads one by one in order
|
242
|
+
conns.each { |conn| @pool.checkin(conn); sleep 0.1 }
|
243
|
+
|
244
|
+
threads.each(&:join)
|
245
|
+
|
246
|
+
raise errors.first if errors.any?
|
247
|
+
|
248
|
+
assert_equal(expected, order)
|
249
|
+
end
|
250
|
+
|
251
|
+
# As mentioned in #test_checkout_fairness, we don't care about
|
252
|
+
# strict fairness. This test creates two groups of threads:
|
253
|
+
# group1 whose members all start waiting before any thread in
|
254
|
+
# group2. Enough connections are checked in to wakeup all
|
255
|
+
# group1 threads, and the fact that only group1 and no group2
|
256
|
+
# threads acquired a connection is enforced.
|
257
|
+
def test_checkout_fairness_by_group
|
258
|
+
@pool.instance_variable_set(:@size, 10)
|
259
|
+
# take all the connections
|
260
|
+
conns = (1..10).map { @pool.checkout }
|
261
|
+
mutex = Mutex.new
|
262
|
+
successes = [] # threads that successfully got a connection
|
263
|
+
errors = []
|
264
|
+
|
265
|
+
make_thread = proc do |i|
|
266
|
+
t = Thread.new {
|
267
|
+
begin
|
268
|
+
@pool.checkout # never checked back in
|
269
|
+
mutex.synchronize { successes << i }
|
270
|
+
rescue => e
|
271
|
+
mutex.synchronize { errors << e }
|
272
|
+
end
|
273
|
+
}
|
274
|
+
Thread.pass until t.status == "sleep"
|
275
|
+
t
|
276
|
+
end
|
277
|
+
|
278
|
+
# all group1 threads start waiting before any in group2
|
279
|
+
group1 = (1..5).map(&make_thread)
|
280
|
+
group2 = (6..10).map(&make_thread)
|
281
|
+
|
282
|
+
# checkin n connections back to the pool
|
283
|
+
checkin = proc do |n|
|
284
|
+
n.times do
|
285
|
+
c = conns.pop
|
286
|
+
@pool.checkin(c)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
checkin.call(group1.size) # should wake up all group1
|
291
|
+
|
292
|
+
loop do
|
293
|
+
sleep 0.1
|
294
|
+
break if mutex.synchronize { (successes.size + errors.size) == group1.size }
|
295
|
+
end
|
296
|
+
|
297
|
+
winners = mutex.synchronize { successes.dup }
|
298
|
+
checkin.call(group2.size) # should wake up everyone remaining
|
299
|
+
|
300
|
+
group1.each(&:join)
|
301
|
+
group2.each(&:join)
|
302
|
+
|
303
|
+
assert_equal((1..group1.size).to_a, winners.sort)
|
304
|
+
|
305
|
+
if errors.any?
|
306
|
+
raise errors.first
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_automatic_reconnect=
|
311
|
+
pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
|
312
|
+
assert pool.automatic_reconnect
|
313
|
+
assert pool.connection
|
314
|
+
|
315
|
+
pool.disconnect!
|
316
|
+
assert pool.connection
|
317
|
+
|
318
|
+
pool.disconnect!
|
319
|
+
pool.automatic_reconnect = false
|
320
|
+
|
321
|
+
assert_raises(ConnectionNotEstablished) do
|
322
|
+
pool.connection
|
323
|
+
end
|
324
|
+
|
325
|
+
assert_raises(ConnectionNotEstablished) do
|
326
|
+
pool.with_connection
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_pool_sets_connection_visitor
|
331
|
+
assert @pool.connection.visitor.is_a?(Arel::Visitors::ToSql)
|
332
|
+
end
|
333
|
+
|
334
|
+
# make sure exceptions are thrown when establish_connection
|
335
|
+
# is called with an anonymous class
|
336
|
+
def test_anonymous_class_exception
|
337
|
+
anonymous = Class.new(ActiveRecord::Base)
|
338
|
+
handler = ActiveRecord::Base.connection_handler
|
339
|
+
|
340
|
+
assert_raises(RuntimeError) {
|
341
|
+
handler.establish_connection anonymous, nil
|
342
|
+
}
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|