omg-activerecord 8.0.0.alpha1
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 +7 -0
- data/CHANGELOG.md +355 -0
- data/MIT-LICENSE +22 -0
- data/README.rdoc +219 -0
- data/examples/performance.rb +185 -0
- data/examples/simple.rb +15 -0
- data/lib/active_record/aggregations.rb +287 -0
- data/lib/active_record/association_relation.rb +50 -0
- data/lib/active_record/associations/alias_tracker.rb +90 -0
- data/lib/active_record/associations/association.rb +417 -0
- data/lib/active_record/associations/association_scope.rb +175 -0
- data/lib/active_record/associations/belongs_to_association.rb +163 -0
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
- data/lib/active_record/associations/builder/association.rb +170 -0
- data/lib/active_record/associations/builder/belongs_to.rb +160 -0
- data/lib/active_record/associations/builder/collection_association.rb +80 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +107 -0
- data/lib/active_record/associations/builder/has_many.rb +23 -0
- data/lib/active_record/associations/builder/has_one.rb +61 -0
- data/lib/active_record/associations/builder/singular_association.rb +48 -0
- data/lib/active_record/associations/collection_association.rb +535 -0
- data/lib/active_record/associations/collection_proxy.rb +1163 -0
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +40 -0
- data/lib/active_record/associations/has_many_association.rb +167 -0
- data/lib/active_record/associations/has_many_through_association.rb +232 -0
- data/lib/active_record/associations/has_one_association.rb +142 -0
- data/lib/active_record/associations/has_one_through_association.rb +45 -0
- data/lib/active_record/associations/join_dependency/join_association.rb +106 -0
- data/lib/active_record/associations/join_dependency/join_base.rb +23 -0
- data/lib/active_record/associations/join_dependency/join_part.rb +71 -0
- data/lib/active_record/associations/join_dependency.rb +301 -0
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +316 -0
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +153 -0
- data/lib/active_record/associations/preloader/through_association.rb +150 -0
- data/lib/active_record/associations/preloader.rb +135 -0
- data/lib/active_record/associations/singular_association.rb +76 -0
- data/lib/active_record/associations/through_association.rb +132 -0
- data/lib/active_record/associations.rb +1897 -0
- data/lib/active_record/asynchronous_queries_tracker.rb +64 -0
- data/lib/active_record/attribute_assignment.rb +82 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +106 -0
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +262 -0
- data/lib/active_record/attribute_methods/primary_key.rb +158 -0
- data/lib/active_record/attribute_methods/query.rb +50 -0
- data/lib/active_record/attribute_methods/read.rb +46 -0
- data/lib/active_record/attribute_methods/serialization.rb +232 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +94 -0
- data/lib/active_record/attribute_methods/write.rb +49 -0
- data/lib/active_record/attribute_methods.rb +542 -0
- data/lib/active_record/attributes.rb +307 -0
- data/lib/active_record/autosave_association.rb +586 -0
- data/lib/active_record/base.rb +338 -0
- data/lib/active_record/callbacks.rb +452 -0
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +15 -0
- data/lib/active_record/coders/yaml_column.rb +95 -0
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +290 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +210 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +923 -0
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +31 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +747 -0
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +319 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +239 -0
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +24 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +190 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +961 -0
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +106 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1883 -0
- data/lib/active_record/connection_adapters/abstract/transaction.rb +676 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +1218 -0
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1016 -0
- data/lib/active_record/connection_adapters/column.rb +122 -0
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +28 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +95 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +114 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +106 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +106 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +97 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +300 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +96 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +196 -0
- data/lib/active_record/connection_adapters/pool_config.rb +83 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +82 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +231 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +91 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +54 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +31 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +109 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +42 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +74 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +124 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +125 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +38 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +238 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +71 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +169 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +392 -0
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +127 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +1162 -0
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +79 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1182 -0
- data/lib/active_record/connection_adapters/schema_cache.rb +478 -0
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +145 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +116 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +37 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +39 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +47 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +221 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +843 -0
- data/lib/active_record/connection_adapters/statement_pool.rb +67 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +69 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +212 -0
- data/lib/active_record/connection_adapters.rb +176 -0
- data/lib/active_record/connection_handling.rb +413 -0
- data/lib/active_record/core.rb +836 -0
- data/lib/active_record/counter_cache.rb +230 -0
- data/lib/active_record/database_configurations/connection_url_resolver.rb +105 -0
- data/lib/active_record/database_configurations/database_config.rb +104 -0
- data/lib/active_record/database_configurations/hash_config.rb +172 -0
- data/lib/active_record/database_configurations/url_config.rb +78 -0
- data/lib/active_record/database_configurations.rb +309 -0
- data/lib/active_record/delegated_type.rb +289 -0
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +38 -0
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +121 -0
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +70 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +230 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +184 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +177 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +159 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +96 -0
- data/lib/active_record/encryption/null_encryptor.rb +25 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
- data/lib/active_record/encryption/scheme.rb +107 -0
- data/lib/active_record/encryption.rb +58 -0
- data/lib/active_record/enum.rb +424 -0
- data/lib/active_record/errors.rb +614 -0
- data/lib/active_record/explain.rb +63 -0
- data/lib/active_record/explain_registry.rb +37 -0
- data/lib/active_record/explain_subscriber.rb +34 -0
- data/lib/active_record/fixture_set/file.rb +89 -0
- data/lib/active_record/fixture_set/model_metadata.rb +42 -0
- data/lib/active_record/fixture_set/render_context.rb +19 -0
- data/lib/active_record/fixture_set/table_row.rb +208 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +850 -0
- data/lib/active_record/future_result.rb +182 -0
- data/lib/active_record/gem_version.rb +17 -0
- data/lib/active_record/inheritance.rb +366 -0
- data/lib/active_record/insert_all.rb +328 -0
- data/lib/active_record/integration.rb +209 -0
- data/lib/active_record/internal_metadata.rb +164 -0
- data/lib/active_record/legacy_yaml_adapter.rb +15 -0
- data/lib/active_record/locale/en.yml +48 -0
- data/lib/active_record/locking/optimistic.rb +228 -0
- data/lib/active_record/locking/pessimistic.rb +102 -0
- data/lib/active_record/log_subscriber.rb +149 -0
- data/lib/active_record/marshalling.rb +56 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +87 -0
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +406 -0
- data/lib/active_record/migration/compatibility.rb +490 -0
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +16 -0
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +1626 -0
- data/lib/active_record/model_schema.rb +635 -0
- data/lib/active_record/nested_attributes.rb +633 -0
- data/lib/active_record/no_touching.rb +65 -0
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +968 -0
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +56 -0
- data/lib/active_record/query_logs.rb +247 -0
- data/lib/active_record/query_logs_formatter.rb +30 -0
- data/lib/active_record/querying.rb +122 -0
- data/lib/active_record/railtie.rb +440 -0
- data/lib/active_record/railties/console_sandbox.rb +5 -0
- data/lib/active_record/railties/controller_runtime.rb +65 -0
- data/lib/active_record/railties/databases.rake +641 -0
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +66 -0
- data/lib/active_record/reflection.rb +1287 -0
- data/lib/active_record/relation/batches/batch_enumerator.rb +115 -0
- data/lib/active_record/relation/batches.rb +491 -0
- data/lib/active_record/relation/calculations.rb +679 -0
- data/lib/active_record/relation/delegation.rb +154 -0
- data/lib/active_record/relation/finder_methods.rb +661 -0
- data/lib/active_record/relation/from_clause.rb +30 -0
- data/lib/active_record/relation/merger.rb +192 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +76 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +60 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +24 -0
- data/lib/active_record/relation/predicate_builder.rb +181 -0
- data/lib/active_record/relation/query_attribute.rb +68 -0
- data/lib/active_record/relation/query_methods.rb +2235 -0
- data/lib/active_record/relation/record_fetch_warning.rb +52 -0
- data/lib/active_record/relation/spawn_methods.rb +78 -0
- data/lib/active_record/relation/where_clause.rb +218 -0
- data/lib/active_record/relation.rb +1495 -0
- data/lib/active_record/result.rb +249 -0
- data/lib/active_record/runtime_registry.rb +82 -0
- data/lib/active_record/sanitization.rb +254 -0
- data/lib/active_record/schema.rb +77 -0
- data/lib/active_record/schema_dumper.rb +364 -0
- data/lib/active_record/schema_migration.rb +106 -0
- data/lib/active_record/scoping/default.rb +205 -0
- data/lib/active_record/scoping/named.rb +202 -0
- data/lib/active_record/scoping.rb +136 -0
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +66 -0
- data/lib/active_record/serialization.rb +29 -0
- data/lib/active_record/signed_id.rb +137 -0
- data/lib/active_record/statement_cache.rb +164 -0
- data/lib/active_record/store.rb +299 -0
- data/lib/active_record/suppressor.rb +59 -0
- data/lib/active_record/table_metadata.rb +85 -0
- data/lib/active_record/tasks/database_tasks.rb +681 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +120 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +147 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +89 -0
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +321 -0
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +177 -0
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +70 -0
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +523 -0
- data/lib/active_record/translation.rb +22 -0
- data/lib/active_record/type/adapter_specific_registry.rb +144 -0
- data/lib/active_record/type/date.rb +9 -0
- data/lib/active_record/type/date_time.rb +9 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +57 -0
- data/lib/active_record/type/internal/timezone.rb +22 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +76 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +35 -0
- data/lib/active_record/type/type_map.rb +58 -0
- data/lib/active_record/type/unsigned_integer.rb +16 -0
- data/lib/active_record/type.rb +83 -0
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +65 -0
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/numericality.rb +36 -0
- data/lib/active_record/validations/presence.rb +45 -0
- data/lib/active_record/validations/uniqueness.rb +295 -0
- data/lib/active_record/validations.rb +101 -0
- data/lib/active_record/version.rb +10 -0
- data/lib/active_record.rb +616 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +33 -0
- data/lib/arel/collectors/bind.rb +31 -0
- data/lib/arel/collectors/composite.rb +46 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +48 -0
- data/lib/arel/delete_manager.rb +32 -0
- data/lib/arel/errors.rb +19 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +53 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +48 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +125 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +44 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +45 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +68 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/nary.rb +39 -0
- data/lib/arel/nodes/node.rb +161 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +32 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +35 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +46 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +75 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +260 -0
- data/lib/arel/select_manager.rb +276 -0
- data/lib/arel/table.rb +121 -0
- data/lib/arel/tree_manager.rb +65 -0
- data/lib/arel/update_manager.rb +49 -0
- data/lib/arel/visitors/dot.rb +299 -0
- data/lib/arel/visitors/mysql.rb +111 -0
- data/lib/arel/visitors/postgresql.rb +99 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +1033 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +73 -0
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +76 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +29 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +48 -0
- data/lib/rails/generators/active_record/migration.rb +54 -0
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +94 -0
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +7 -0
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- data/lib/rails/generators/active_record.rb +19 -0
- metadata +505 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
# = Active Record Counter Cache
|
|
5
|
+
module CounterCache
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :_counter_cache_columns, instance_accessor: false, default: []
|
|
10
|
+
class_attribute :counter_cached_association_names, instance_writer: false, default: []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module ClassMethods
|
|
14
|
+
# Resets one or more counter caches to their correct value using an SQL
|
|
15
|
+
# count query. This is useful when adding new counter caches, or if the
|
|
16
|
+
# counter has been corrupted or modified directly by SQL.
|
|
17
|
+
#
|
|
18
|
+
# ==== Parameters
|
|
19
|
+
#
|
|
20
|
+
# * +id+ - The id of the object you wish to reset a counter on.
|
|
21
|
+
# * +counters+ - One or more association counters to reset. Association name or counter name can be given.
|
|
22
|
+
# * <tt>:touch</tt> - Touch timestamp columns when updating.
|
|
23
|
+
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
|
|
24
|
+
# touch that column or an array of symbols to touch just those ones.
|
|
25
|
+
#
|
|
26
|
+
# ==== Examples
|
|
27
|
+
#
|
|
28
|
+
# # For the Post with id #1, reset the comments_count
|
|
29
|
+
# Post.reset_counters(1, :comments)
|
|
30
|
+
#
|
|
31
|
+
# # Like above, but also touch the +updated_at+ and/or +updated_on+
|
|
32
|
+
# # attributes.
|
|
33
|
+
# Post.reset_counters(1, :comments, touch: true)
|
|
34
|
+
def reset_counters(id, *counters, touch: nil)
|
|
35
|
+
object = find(id)
|
|
36
|
+
|
|
37
|
+
updates = {}
|
|
38
|
+
counters.each do |counter_association|
|
|
39
|
+
has_many_association = _reflect_on_association(counter_association)
|
|
40
|
+
unless has_many_association
|
|
41
|
+
has_many = reflect_on_all_associations(:has_many)
|
|
42
|
+
has_many_association = has_many.find { |association| association.counter_cache_column && association.counter_cache_column.to_sym == counter_association.to_sym }
|
|
43
|
+
counter_association = has_many_association.plural_name if has_many_association
|
|
44
|
+
end
|
|
45
|
+
raise ArgumentError, "'#{name}' has no association called '#{counter_association}'" unless has_many_association
|
|
46
|
+
|
|
47
|
+
if has_many_association.is_a? ActiveRecord::Reflection::ThroughReflection
|
|
48
|
+
has_many_association = has_many_association.through_reflection
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
foreign_key = has_many_association.foreign_key.to_s
|
|
52
|
+
child_class = has_many_association.klass
|
|
53
|
+
reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
|
|
54
|
+
counter_name = reflection.counter_cache_column
|
|
55
|
+
|
|
56
|
+
count_was = object.send(counter_name)
|
|
57
|
+
count = object.send(counter_association).count(:all)
|
|
58
|
+
updates[counter_name] = count if count != count_was
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if touch
|
|
62
|
+
names = touch if touch != true
|
|
63
|
+
names = Array.wrap(names)
|
|
64
|
+
options = names.extract_options!
|
|
65
|
+
touch_updates = touch_attributes_with_time(*names, **options)
|
|
66
|
+
updates.merge!(touch_updates)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
unscoped.where(primary_key => [object.id]).update_all(updates) if updates.any?
|
|
70
|
+
|
|
71
|
+
true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# A generic "counter updater" implementation, intended primarily to be
|
|
75
|
+
# used by #increment_counter and #decrement_counter, but which may also
|
|
76
|
+
# be useful on its own. It simply does a direct SQL update for the record
|
|
77
|
+
# with the given ID, altering the given hash of counters by the amount
|
|
78
|
+
# given by the corresponding value:
|
|
79
|
+
#
|
|
80
|
+
# ==== Parameters
|
|
81
|
+
#
|
|
82
|
+
# * +id+ - The id of the object you wish to update a counter on or an array of ids.
|
|
83
|
+
# * +counters+ - A Hash containing the names of the fields
|
|
84
|
+
# to update as keys and the amount to update the field by as values.
|
|
85
|
+
# * <tt>:touch</tt> option - Touch timestamp columns when updating.
|
|
86
|
+
# If attribute names are passed, they are updated along with updated_at/on
|
|
87
|
+
# attributes.
|
|
88
|
+
#
|
|
89
|
+
# ==== Examples
|
|
90
|
+
#
|
|
91
|
+
# # For the Post with id of 5, decrement the comments_count by 1, and
|
|
92
|
+
# # increment the actions_count by 1
|
|
93
|
+
# Post.update_counters 5, comments_count: -1, actions_count: 1
|
|
94
|
+
# # Executes the following SQL:
|
|
95
|
+
# # UPDATE posts
|
|
96
|
+
# # SET comments_count = COALESCE(comments_count, 0) - 1,
|
|
97
|
+
# # actions_count = COALESCE(actions_count, 0) + 1
|
|
98
|
+
# # WHERE id = 5
|
|
99
|
+
#
|
|
100
|
+
# # For the Posts with id of 10 and 15, increment the comments_count by 1
|
|
101
|
+
# Post.update_counters [10, 15], comments_count: 1
|
|
102
|
+
# # Executes the following SQL:
|
|
103
|
+
# # UPDATE posts
|
|
104
|
+
# # SET comments_count = COALESCE(comments_count, 0) + 1
|
|
105
|
+
# # WHERE id IN (10, 15)
|
|
106
|
+
#
|
|
107
|
+
# # For the Posts with id of 10 and 15, increment the comments_count by 1
|
|
108
|
+
# # and update the updated_at value for each counter.
|
|
109
|
+
# Post.update_counters [10, 15], comments_count: 1, touch: true
|
|
110
|
+
# # Executes the following SQL:
|
|
111
|
+
# # UPDATE posts
|
|
112
|
+
# # SET comments_count = COALESCE(comments_count, 0) + 1,
|
|
113
|
+
# # `updated_at` = '2016-10-13T09:59:23-05:00'
|
|
114
|
+
# # WHERE id IN (10, 15)
|
|
115
|
+
def update_counters(id, counters)
|
|
116
|
+
id = [id] if composite_primary_key? && id.is_a?(Array) && !id[0].is_a?(Array)
|
|
117
|
+
unscoped.where!(primary_key => id).update_counters(counters)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Increment a numeric field by one, via a direct SQL update.
|
|
121
|
+
#
|
|
122
|
+
# This method is used primarily for maintaining counter_cache columns that are
|
|
123
|
+
# used to store aggregate values. For example, a +DiscussionBoard+ may cache
|
|
124
|
+
# posts_count and comments_count to avoid running an SQL query to calculate the
|
|
125
|
+
# number of posts and comments there are, each time it is displayed.
|
|
126
|
+
#
|
|
127
|
+
# ==== Parameters
|
|
128
|
+
#
|
|
129
|
+
# * +counter_name+ - The name of the field that should be incremented.
|
|
130
|
+
# * +id+ - The id of the object that should be incremented or an array of ids.
|
|
131
|
+
# * <tt>:by</tt> - The amount by which to increment the value. Defaults to +1+.
|
|
132
|
+
# * <tt>:touch</tt> - Touch timestamp columns when updating.
|
|
133
|
+
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
|
|
134
|
+
# touch that column or an array of symbols to touch just those ones.
|
|
135
|
+
#
|
|
136
|
+
# ==== Examples
|
|
137
|
+
#
|
|
138
|
+
# # Increment the posts_count column for the record with an id of 5
|
|
139
|
+
# DiscussionBoard.increment_counter(:posts_count, 5)
|
|
140
|
+
#
|
|
141
|
+
# # Increment the posts_count column for the record with an id of 5
|
|
142
|
+
# # by a specific amount.
|
|
143
|
+
# DiscussionBoard.increment_counter(:posts_count, 5, by: 3)
|
|
144
|
+
#
|
|
145
|
+
# # Increment the posts_count column for the record with an id of 5
|
|
146
|
+
# # and update the updated_at value.
|
|
147
|
+
# DiscussionBoard.increment_counter(:posts_count, 5, touch: true)
|
|
148
|
+
def increment_counter(counter_name, id, by: 1, touch: nil)
|
|
149
|
+
update_counters(id, counter_name => by, touch: touch)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Decrement a numeric field by one, via a direct SQL update.
|
|
153
|
+
#
|
|
154
|
+
# This works the same as #increment_counter but reduces the column value by
|
|
155
|
+
# 1 instead of increasing it.
|
|
156
|
+
#
|
|
157
|
+
# ==== Parameters
|
|
158
|
+
#
|
|
159
|
+
# * +counter_name+ - The name of the field that should be decremented.
|
|
160
|
+
# * +id+ - The id of the object that should be decremented or an array of ids.
|
|
161
|
+
# * <tt>:by</tt> - The amount by which to decrement the value. Defaults to +1+.
|
|
162
|
+
# * <tt>:touch</tt> - Touch timestamp columns when updating.
|
|
163
|
+
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
|
|
164
|
+
# touch that column or an array of symbols to touch just those ones.
|
|
165
|
+
#
|
|
166
|
+
# ==== Examples
|
|
167
|
+
#
|
|
168
|
+
# # Decrement the posts_count column for the record with an id of 5
|
|
169
|
+
# DiscussionBoard.decrement_counter(:posts_count, 5)
|
|
170
|
+
#
|
|
171
|
+
# # Decrement the posts_count column for the record with an id of 5
|
|
172
|
+
# by a specific amount.
|
|
173
|
+
# DiscussionBoard.decrement_counter(:posts_count, 5, by: 3)
|
|
174
|
+
#
|
|
175
|
+
# # Decrement the posts_count column for the record with an id of 5
|
|
176
|
+
# # and update the updated_at value.
|
|
177
|
+
# DiscussionBoard.decrement_counter(:posts_count, 5, touch: true)
|
|
178
|
+
def decrement_counter(counter_name, id, by: 1, touch: nil)
|
|
179
|
+
update_counters(id, counter_name => -by, touch: touch)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def counter_cache_column?(name) # :nodoc:
|
|
183
|
+
_counter_cache_columns.include?(name)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def load_schema! # :nodoc:
|
|
187
|
+
super
|
|
188
|
+
|
|
189
|
+
association_names = _reflections.filter_map do |name, reflection|
|
|
190
|
+
next unless reflection.belongs_to? && reflection.counter_cache_column
|
|
191
|
+
|
|
192
|
+
name.to_sym
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
self.counter_cached_association_names |= association_names
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
private
|
|
200
|
+
def _create_record(attribute_names = self.attribute_names)
|
|
201
|
+
id = super
|
|
202
|
+
|
|
203
|
+
counter_cached_association_names.each do |association_name|
|
|
204
|
+
association(association_name).increment_counters
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
id
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def destroy_row
|
|
211
|
+
affected_rows = super
|
|
212
|
+
|
|
213
|
+
if affected_rows > 0
|
|
214
|
+
counter_cached_association_names.each do |association_name|
|
|
215
|
+
association = association(association_name)
|
|
216
|
+
|
|
217
|
+
unless destroyed_by_association && _foreign_keys_equal?(destroyed_by_association.foreign_key, association.reflection.foreign_key)
|
|
218
|
+
association.decrement_counters
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
affected_rows
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def _foreign_keys_equal?(fkey1, fkey2)
|
|
227
|
+
fkey1 == fkey2 || Array(fkey1).map(&:to_sym) == Array(fkey2).map(&:to_sym)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
require "active_support/core_ext/enumerable"
|
|
5
|
+
require "active_support/core_ext/hash/reverse_merge"
|
|
6
|
+
|
|
7
|
+
module ActiveRecord
|
|
8
|
+
class DatabaseConfigurations
|
|
9
|
+
# Expands a connection string into a hash.
|
|
10
|
+
class ConnectionUrlResolver # :nodoc:
|
|
11
|
+
# == Example
|
|
12
|
+
#
|
|
13
|
+
# url = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000"
|
|
14
|
+
# ConnectionUrlResolver.new(url).to_hash
|
|
15
|
+
# # => {
|
|
16
|
+
# adapter: "postgresql",
|
|
17
|
+
# host: "localhost",
|
|
18
|
+
# port: 9000,
|
|
19
|
+
# database: "foo_test",
|
|
20
|
+
# username: "foo",
|
|
21
|
+
# password: "bar",
|
|
22
|
+
# pool: "5",
|
|
23
|
+
# timeout: "3000"
|
|
24
|
+
# }
|
|
25
|
+
def initialize(url)
|
|
26
|
+
raise "Database URL cannot be empty" if url.blank?
|
|
27
|
+
@uri = uri_parser.parse(url)
|
|
28
|
+
@adapter = resolved_adapter
|
|
29
|
+
|
|
30
|
+
if @uri.opaque
|
|
31
|
+
@uri.opaque, @query = @uri.opaque.split("?", 2)
|
|
32
|
+
else
|
|
33
|
+
@query = @uri.query
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Converts the given URL to a full connection hash.
|
|
38
|
+
def to_hash
|
|
39
|
+
config = raw_config.compact_blank
|
|
40
|
+
config.map { |key, value| config[key] = uri_parser.unescape(value) if value.is_a? String }
|
|
41
|
+
config
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
attr_reader :uri
|
|
46
|
+
|
|
47
|
+
def uri_parser
|
|
48
|
+
@uri_parser ||= URI::RFC2396_Parser.new
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Converts the query parameters of the URI into a hash.
|
|
52
|
+
#
|
|
53
|
+
# "localhost?pool=5&reaping_frequency=2"
|
|
54
|
+
# # => { pool: "5", reaping_frequency: "2" }
|
|
55
|
+
#
|
|
56
|
+
# returns empty hash if no query present.
|
|
57
|
+
#
|
|
58
|
+
# "localhost"
|
|
59
|
+
# # => {}
|
|
60
|
+
def query_hash
|
|
61
|
+
Hash[(@query || "").split("&").map { |pair| pair.split("=", 2) }].symbolize_keys
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def raw_config
|
|
65
|
+
if uri.opaque
|
|
66
|
+
query_hash.merge(
|
|
67
|
+
adapter: @adapter,
|
|
68
|
+
database: uri.opaque
|
|
69
|
+
)
|
|
70
|
+
else
|
|
71
|
+
query_hash.reverse_merge(
|
|
72
|
+
adapter: @adapter,
|
|
73
|
+
username: uri.user,
|
|
74
|
+
password: uri.password,
|
|
75
|
+
port: uri.port,
|
|
76
|
+
database: database_from_path,
|
|
77
|
+
host: uri.hostname
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def resolved_adapter
|
|
83
|
+
adapter = uri.scheme && @uri.scheme.tr("-", "_")
|
|
84
|
+
adapter = ActiveRecord.protocol_adapters[adapter] || adapter
|
|
85
|
+
adapter
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Returns name of the database.
|
|
89
|
+
def database_from_path
|
|
90
|
+
if @adapter == "sqlite3"
|
|
91
|
+
# 'sqlite3:/foo' is absolute, because that makes sense. The
|
|
92
|
+
# corresponding relative version, 'sqlite3:foo', is handled
|
|
93
|
+
# elsewhere, as an "opaque".
|
|
94
|
+
|
|
95
|
+
uri.path
|
|
96
|
+
else
|
|
97
|
+
# Only SQLite uses a filename as the "database" name; for
|
|
98
|
+
# anything else, a leading slash would be silly.
|
|
99
|
+
|
|
100
|
+
uri.path.delete_prefix("/")
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
class DatabaseConfigurations
|
|
5
|
+
# ActiveRecord::Base.configurations will return either a HashConfig or
|
|
6
|
+
# UrlConfig respectively. It will never return a +DatabaseConfig+ object,
|
|
7
|
+
# as this is the parent class for the types of database configuration objects.
|
|
8
|
+
class DatabaseConfig # :nodoc:
|
|
9
|
+
attr_reader :env_name, :name
|
|
10
|
+
|
|
11
|
+
def initialize(env_name, name)
|
|
12
|
+
@env_name = env_name
|
|
13
|
+
@name = name
|
|
14
|
+
@adapter_class = nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def adapter_class
|
|
18
|
+
@adapter_class ||= ActiveRecord::ConnectionAdapters.resolve(adapter)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def inspect # :nodoc:
|
|
22
|
+
"#<#{self.class.name} env_name=#{@env_name} name=#{@name} adapter_class=#{adapter_class}>"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def new_connection
|
|
26
|
+
adapter_class.new(configuration_hash)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def validate!
|
|
30
|
+
adapter_class if adapter
|
|
31
|
+
|
|
32
|
+
true
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def host
|
|
36
|
+
raise NotImplementedError
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def database
|
|
40
|
+
raise NotImplementedError
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def _database=(database)
|
|
44
|
+
raise NotImplementedError
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def adapter
|
|
48
|
+
raise NotImplementedError
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def pool
|
|
52
|
+
raise NotImplementedError
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def min_threads
|
|
56
|
+
raise NotImplementedError
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def max_threads
|
|
60
|
+
raise NotImplementedError
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def max_queue
|
|
64
|
+
raise NotImplementedError
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def query_cache
|
|
68
|
+
raise NotImplementedError
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def checkout_timeout
|
|
72
|
+
raise NotImplementedError
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def reaping_frequency
|
|
76
|
+
raise NotImplementedError
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def idle_timeout
|
|
80
|
+
raise NotImplementedError
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def replica?
|
|
84
|
+
raise NotImplementedError
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def migrations_paths
|
|
88
|
+
raise NotImplementedError
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def for_current_env?
|
|
92
|
+
env_name == ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def schema_cache_path
|
|
96
|
+
raise NotImplementedError
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def use_metadata_table?
|
|
100
|
+
raise NotImplementedError
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# :markup: markdown
|
|
4
|
+
|
|
5
|
+
module ActiveRecord
|
|
6
|
+
class DatabaseConfigurations
|
|
7
|
+
# # Active Record Database Hash Config
|
|
8
|
+
#
|
|
9
|
+
# A `HashConfig` object is created for each database configuration entry that is
|
|
10
|
+
# created from a hash.
|
|
11
|
+
#
|
|
12
|
+
# A hash config:
|
|
13
|
+
#
|
|
14
|
+
# { "development" => { "database" => "db_name" } }
|
|
15
|
+
#
|
|
16
|
+
# Becomes:
|
|
17
|
+
#
|
|
18
|
+
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
|
|
19
|
+
# @env_name="development", @name="primary", @config={database: "db_name"}>
|
|
20
|
+
#
|
|
21
|
+
# See ActiveRecord::DatabaseConfigurations for more info.
|
|
22
|
+
class HashConfig < DatabaseConfig
|
|
23
|
+
attr_reader :configuration_hash
|
|
24
|
+
|
|
25
|
+
# Initialize a new `HashConfig` object
|
|
26
|
+
#
|
|
27
|
+
# #### Parameters
|
|
28
|
+
#
|
|
29
|
+
# * `env_name` - The Rails environment, i.e. "development".
|
|
30
|
+
# * `name` - The db config name. In a standard two-tier database configuration
|
|
31
|
+
# this will default to "primary". In a multiple database three-tier database
|
|
32
|
+
# configuration this corresponds to the name used in the second tier, for
|
|
33
|
+
# example "primary_readonly".
|
|
34
|
+
# * `configuration_hash` - The config hash. This is the hash that contains the
|
|
35
|
+
# database adapter, name, and other important information for database
|
|
36
|
+
# connections.
|
|
37
|
+
#
|
|
38
|
+
def initialize(env_name, name, configuration_hash)
|
|
39
|
+
super(env_name, name)
|
|
40
|
+
@configuration_hash = configuration_hash.symbolize_keys.freeze
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Determines whether a database configuration is for a replica / readonly
|
|
44
|
+
# connection. If the `replica` key is present in the config, `replica?` will
|
|
45
|
+
# return `true`.
|
|
46
|
+
def replica?
|
|
47
|
+
configuration_hash[:replica]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# The migrations paths for a database configuration. If the `migrations_paths`
|
|
51
|
+
# key is present in the config, `migrations_paths` will return its value.
|
|
52
|
+
def migrations_paths
|
|
53
|
+
configuration_hash[:migrations_paths]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def host
|
|
57
|
+
configuration_hash[:host]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def socket # :nodoc:
|
|
61
|
+
configuration_hash[:socket]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def database
|
|
65
|
+
configuration_hash[:database]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def _database=(database) # :nodoc:
|
|
69
|
+
@configuration_hash = configuration_hash.merge(database: database).freeze
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def pool
|
|
73
|
+
(configuration_hash[:pool] || 5).to_i
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def min_threads
|
|
77
|
+
(configuration_hash[:min_threads] || 0).to_i
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def max_threads
|
|
81
|
+
(configuration_hash[:max_threads] || pool).to_i
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def query_cache
|
|
85
|
+
configuration_hash[:query_cache]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def max_queue
|
|
89
|
+
max_threads * 4
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def checkout_timeout
|
|
93
|
+
(configuration_hash[:checkout_timeout] || 5).to_f
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# `reaping_frequency` is configurable mostly for historical reasons, but it
|
|
97
|
+
# could also be useful if someone wants a very low `idle_timeout`.
|
|
98
|
+
def reaping_frequency
|
|
99
|
+
configuration_hash.fetch(:reaping_frequency, 60)&.to_f
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def idle_timeout
|
|
103
|
+
timeout = configuration_hash.fetch(:idle_timeout, 300).to_f
|
|
104
|
+
timeout if timeout > 0
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def adapter
|
|
108
|
+
configuration_hash[:adapter]&.to_s
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# The path to the schema cache dump file for a database. If omitted, the
|
|
112
|
+
# filename will be read from ENV or a default will be derived.
|
|
113
|
+
def schema_cache_path
|
|
114
|
+
configuration_hash[:schema_cache_path]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def default_schema_cache_path(db_dir = "db")
|
|
118
|
+
if primary?
|
|
119
|
+
File.join(db_dir, "schema_cache.yml")
|
|
120
|
+
else
|
|
121
|
+
File.join(db_dir, "#{name}_schema_cache.yml")
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def lazy_schema_cache_path
|
|
126
|
+
schema_cache_path || default_schema_cache_path
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def primary? # :nodoc:
|
|
130
|
+
Base.configurations.primary?(name)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Determines whether to dump the schema/structure files and the filename that
|
|
134
|
+
# should be used.
|
|
135
|
+
#
|
|
136
|
+
# If `configuration_hash[:schema_dump]` is set to `false` or `nil` the schema
|
|
137
|
+
# will not be dumped.
|
|
138
|
+
#
|
|
139
|
+
# If the config option is set that will be used. Otherwise Rails will generate
|
|
140
|
+
# the filename from the database config name.
|
|
141
|
+
def schema_dump(format = ActiveRecord.schema_format)
|
|
142
|
+
if configuration_hash.key?(:schema_dump)
|
|
143
|
+
if config = configuration_hash[:schema_dump]
|
|
144
|
+
config
|
|
145
|
+
end
|
|
146
|
+
elsif primary?
|
|
147
|
+
schema_file_type(format)
|
|
148
|
+
else
|
|
149
|
+
"#{name}_#{schema_file_type(format)}"
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def database_tasks? # :nodoc:
|
|
154
|
+
!replica? && !!configuration_hash.fetch(:database_tasks, true)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def use_metadata_table? # :nodoc:
|
|
158
|
+
configuration_hash.fetch(:use_metadata_table, true)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
private
|
|
162
|
+
def schema_file_type(format)
|
|
163
|
+
case format
|
|
164
|
+
when :ruby
|
|
165
|
+
"schema.rb"
|
|
166
|
+
when :sql
|
|
167
|
+
"structure.sql"
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
class DatabaseConfigurations
|
|
5
|
+
# = Active Record Database Url Config
|
|
6
|
+
#
|
|
7
|
+
# A +UrlConfig+ object is created for each database configuration
|
|
8
|
+
# entry that is created from a URL. This can either be a URL string
|
|
9
|
+
# or a hash with a URL in place of the config hash.
|
|
10
|
+
#
|
|
11
|
+
# A URL config:
|
|
12
|
+
#
|
|
13
|
+
# postgres://localhost/foo
|
|
14
|
+
#
|
|
15
|
+
# Becomes:
|
|
16
|
+
#
|
|
17
|
+
# #<ActiveRecord::DatabaseConfigurations::UrlConfig:0x00007fdc3238f340
|
|
18
|
+
# @env_name="default_env", @name="primary",
|
|
19
|
+
# @config={adapter: "postgresql", database: "foo", host: "localhost"},
|
|
20
|
+
# @url="postgres://localhost/foo">
|
|
21
|
+
#
|
|
22
|
+
# See ActiveRecord::DatabaseConfigurations for more info.
|
|
23
|
+
#
|
|
24
|
+
class UrlConfig < HashConfig
|
|
25
|
+
attr_reader :url
|
|
26
|
+
|
|
27
|
+
# Initialize a new +UrlConfig+ object
|
|
28
|
+
#
|
|
29
|
+
# ==== Options
|
|
30
|
+
#
|
|
31
|
+
# * <tt>:env_name</tt> - The \Rails environment, i.e. "development".
|
|
32
|
+
# * <tt>:name</tt> - The db config name. In a standard two-tier
|
|
33
|
+
# database configuration this will default to "primary". In a multiple
|
|
34
|
+
# database three-tier database configuration this corresponds to the name
|
|
35
|
+
# used in the second tier, for example "primary_readonly".
|
|
36
|
+
# * <tt>:url</tt> - The database URL.
|
|
37
|
+
# * <tt>:config</tt> - The config hash. This is the hash that contains the
|
|
38
|
+
# database adapter, name, and other important information for database
|
|
39
|
+
# connections.
|
|
40
|
+
def initialize(env_name, name, url, configuration_hash = {})
|
|
41
|
+
super(env_name, name, configuration_hash)
|
|
42
|
+
|
|
43
|
+
@url = url
|
|
44
|
+
@configuration_hash = @configuration_hash.merge(build_url_hash)
|
|
45
|
+
|
|
46
|
+
if @configuration_hash[:schema_dump] == "false"
|
|
47
|
+
@configuration_hash[:schema_dump] = false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if @configuration_hash[:query_cache] == "false"
|
|
51
|
+
@configuration_hash[:query_cache] = false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
to_boolean!(@configuration_hash, :replica)
|
|
55
|
+
to_boolean!(@configuration_hash, :database_tasks)
|
|
56
|
+
|
|
57
|
+
@configuration_hash.freeze
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
def to_boolean!(configuration_hash, key)
|
|
62
|
+
if configuration_hash[key].is_a?(String)
|
|
63
|
+
configuration_hash[key] = configuration_hash[key] != "false"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Return a Hash that can be merged into the main config that represents
|
|
68
|
+
# the passed in url
|
|
69
|
+
def build_url_hash
|
|
70
|
+
if url.nil? || url.start_with?("jdbc:", "http:", "https:")
|
|
71
|
+
{ url: url }
|
|
72
|
+
else
|
|
73
|
+
ConnectionUrlResolver.new(url).to_hash
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|