activerecord 6.1.7 → 7.1.5
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/CHANGELOG.md +2030 -1020
- data/MIT-LICENSE +1 -1
- data/README.rdoc +18 -18
- data/lib/active_record/aggregations.rb +17 -14
- data/lib/active_record/association_relation.rb +1 -11
- data/lib/active_record/associations/association.rb +51 -19
- data/lib/active_record/associations/association_scope.rb +17 -12
- data/lib/active_record/associations/belongs_to_association.rb +28 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +11 -5
- data/lib/active_record/associations/builder/belongs_to.rb +40 -14
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +6 -2
- data/lib/active_record/associations/collection_association.rb +39 -35
- data/lib/active_record/associations/collection_proxy.rb +30 -15
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +28 -18
- data/lib/active_record/associations/has_many_through_association.rb +12 -7
- data/lib/active_record/associations/has_one_association.rb +20 -10
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
- data/lib/active_record/associations/join_dependency.rb +28 -20
- data/lib/active_record/associations/preloader/association.rb +210 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +50 -14
- data/lib/active_record/associations/preloader.rb +50 -121
- data/lib/active_record/associations/singular_association.rb +9 -3
- data/lib/active_record/associations/through_association.rb +25 -14
- data/lib/active_record/associations.rb +446 -306
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
- data/lib/active_record/attribute_methods/dirty.rb +73 -22
- data/lib/active_record/attribute_methods/primary_key.rb +78 -26
- data/lib/active_record/attribute_methods/query.rb +31 -19
- data/lib/active_record/attribute_methods/read.rb +27 -12
- data/lib/active_record/attribute_methods/serialization.rb +194 -37
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +8 -3
- data/lib/active_record/attribute_methods/write.rb +12 -15
- data/lib/active_record/attribute_methods.rb +161 -40
- data/lib/active_record/attributes.rb +27 -38
- data/lib/active_record/autosave_association.rb +65 -31
- data/lib/active_record/base.rb +25 -2
- data/lib/active_record/callbacks.rb +18 -34
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -46
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +113 -597
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +172 -50
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +367 -141
- data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
- data/lib/active_record/connection_adapters/abstract_adapter.rb +631 -150
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +317 -164
- data/lib/active_record/connection_adapters/column.rb +13 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
- data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +39 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +112 -55
- data/lib/active_record/connection_adapters/pool_config.rb +20 -11
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +89 -52
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
- 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 +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +397 -75
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +508 -246
- data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +72 -53
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +296 -104
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +258 -0
- data/lib/active_record/connection_adapters.rb +9 -6
- data/lib/active_record/connection_handling.rb +108 -137
- data/lib/active_record/core.rb +242 -233
- data/lib/active_record/counter_cache.rb +52 -27
- data/lib/active_record/database_configurations/connection_url_resolver.rb +3 -2
- data/lib/active_record/database_configurations/database_config.rb +21 -12
- data/lib/active_record/database_configurations/hash_config.rb +88 -16
- data/lib/active_record/database_configurations/url_config.rb +18 -12
- data/lib/active_record/database_configurations.rb +95 -59
- data/lib/active_record/delegated_type.rb +66 -20
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +4 -2
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- 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 +68 -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 +155 -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 +155 -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 +157 -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_serializer.rb +92 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +100 -0
- data/lib/active_record/encryption.rb +58 -0
- data/lib/active_record/enum.rb +154 -63
- data/lib/active_record/errors.rb +172 -15
- data/lib/active_record/explain.rb +23 -3
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +70 -14
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +147 -86
- data/lib/active_record/future_result.rb +174 -0
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +81 -29
- data/lib/active_record/insert_all.rb +135 -22
- data/lib/active_record/integration.rb +11 -10
- data/lib/active_record/internal_metadata.rb +119 -33
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +37 -22
- data/lib/active_record/locking/pessimistic.rb +15 -6
- data/lib/active_record/log_subscriber.rb +52 -19
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
- data/lib/active_record/middleware/database_selector.rb +23 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +112 -14
- data/lib/active_record/migration/compatibility.rb +233 -46
- data/lib/active_record/migration/default_strategy.rb +23 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +361 -173
- data/lib/active_record/model_schema.rb +125 -101
- data/lib/active_record/nested_attributes.rb +50 -20
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/normalization.rb +167 -0
- data/lib/active_record/persistence.rb +409 -88
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +4 -22
- data/lib/active_record/query_logs.rb +174 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +29 -6
- data/lib/active_record/railtie.rb +220 -44
- data/lib/active_record/railties/controller_runtime.rb +15 -10
- data/lib/active_record/railties/databases.rake +188 -252
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +41 -3
- data/lib/active_record/reflection.rb +248 -81
- data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
- data/lib/active_record/relation/batches.rb +192 -63
- data/lib/active_record/relation/calculations.rb +246 -90
- data/lib/active_record/relation/delegation.rb +28 -14
- data/lib/active_record/relation/finder_methods.rb +108 -51
- data/lib/active_record/relation/merger.rb +22 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +27 -20
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +670 -129
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +20 -3
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +287 -120
- data/lib/active_record/result.rb +37 -11
- data/lib/active_record/runtime_registry.rb +32 -13
- data/lib/active_record/sanitization.rb +65 -20
- data/lib/active_record/schema.rb +36 -22
- data/lib/active_record/schema_dumper.rb +73 -24
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +72 -15
- data/lib/active_record/scoping/named.rb +5 -13
- data/lib/active_record/scoping.rb +65 -34
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +10 -8
- data/lib/active_record/store.rb +10 -10
- data/lib/active_record/suppressor.rb +13 -15
- data/lib/active_record/table_metadata.rb +16 -3
- data/lib/active_record/tasks/database_tasks.rb +251 -140
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
- data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +117 -96
- data/lib/active_record/timestamp.rb +32 -19
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +48 -27
- data/lib/active_record/translation.rb +3 -3
- data/lib/active_record/type/adapter_specific_registry.rb +32 -14
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +9 -5
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +4 -4
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +51 -6
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +335 -32
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/and.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -1
- data/lib/arel/nodes/bound_sql_literal.rb +61 -0
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +5 -0
- data/lib/arel/predications.rb +13 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +9 -6
- data/lib/arel/tree_manager.rb +5 -13
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +16 -3
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +141 -20
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +18 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- 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
- metadata +96 -16
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -67
@@ -1,62 +1,80 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_record/connection_adapters/abstract_mysql_adapter"
|
4
|
-
require "active_record/connection_adapters/
|
4
|
+
require "active_record/connection_adapters/mysql2/database_statements"
|
5
5
|
|
6
6
|
gem "mysql2", "~> 0.5"
|
7
7
|
require "mysql2"
|
8
8
|
|
9
9
|
module ActiveRecord
|
10
10
|
module ConnectionHandling # :nodoc:
|
11
|
+
def mysql2_adapter_class
|
12
|
+
ConnectionAdapters::Mysql2Adapter
|
13
|
+
end
|
14
|
+
|
11
15
|
# Establishes a connection to the database that's used by all Active Record objects.
|
12
16
|
def mysql2_connection(config)
|
13
|
-
config
|
14
|
-
config[:flags] ||= 0
|
15
|
-
|
16
|
-
if config[:flags].kind_of? Array
|
17
|
-
config[:flags].push "FOUND_ROWS"
|
18
|
-
else
|
19
|
-
config[:flags] |= Mysql2::Client::FOUND_ROWS
|
20
|
-
end
|
21
|
-
|
22
|
-
ConnectionAdapters::Mysql2Adapter.new(
|
23
|
-
ConnectionAdapters::Mysql2Adapter.new_client(config),
|
24
|
-
logger,
|
25
|
-
nil,
|
26
|
-
config,
|
27
|
-
)
|
17
|
+
mysql2_adapter_class.new(config)
|
28
18
|
end
|
29
19
|
end
|
30
20
|
|
31
21
|
module ConnectionAdapters
|
22
|
+
# = Active Record MySQL2 Adapter
|
32
23
|
class Mysql2Adapter < AbstractMysqlAdapter
|
33
|
-
ER_BAD_DB_ERROR
|
24
|
+
ER_BAD_DB_ERROR = 1049
|
25
|
+
ER_DBACCESS_DENIED_ERROR = 1044
|
26
|
+
ER_ACCESS_DENIED_ERROR = 1045
|
27
|
+
ER_CONN_HOST_ERROR = 2003
|
28
|
+
ER_UNKNOWN_HOST_ERROR = 2005
|
29
|
+
|
34
30
|
ADAPTER_NAME = "Mysql2"
|
35
31
|
|
36
|
-
include
|
32
|
+
include Mysql2::DatabaseStatements
|
37
33
|
|
38
34
|
class << self
|
39
35
|
def new_client(config)
|
40
|
-
Mysql2::Client.new(config)
|
41
|
-
rescue Mysql2::Error => error
|
42
|
-
|
43
|
-
|
36
|
+
::Mysql2::Client.new(config)
|
37
|
+
rescue ::Mysql2::Error => error
|
38
|
+
case error.error_number
|
39
|
+
when ER_BAD_DB_ERROR
|
40
|
+
raise ActiveRecord::NoDatabaseError.db_error(config[:database])
|
41
|
+
when ER_DBACCESS_DENIED_ERROR, ER_ACCESS_DENIED_ERROR
|
42
|
+
raise ActiveRecord::DatabaseConnectionError.username_error(config[:username])
|
43
|
+
when ER_CONN_HOST_ERROR, ER_UNKNOWN_HOST_ERROR
|
44
|
+
raise ActiveRecord::DatabaseConnectionError.hostname_error(config[:host])
|
44
45
|
else
|
45
46
|
raise ActiveRecord::ConnectionNotEstablished, error.message
|
46
47
|
end
|
47
48
|
end
|
48
|
-
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
private
|
51
|
+
def initialize_type_map(m)
|
52
|
+
super
|
53
|
+
|
54
|
+
m.register_type(%r(char)i) do |sql_type|
|
55
|
+
limit = extract_limit(sql_type)
|
56
|
+
Type.lookup(:string, adapter: :mysql2, limit: limit)
|
57
|
+
end
|
58
|
+
|
59
|
+
m.register_type %r(^enum)i, Type.lookup(:string, adapter: :mysql2)
|
60
|
+
m.register_type %r(^set)i, Type.lookup(:string, adapter: :mysql2)
|
61
|
+
end
|
54
62
|
end
|
55
63
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
65
|
+
|
66
|
+
def initialize(...)
|
67
|
+
super
|
68
|
+
|
69
|
+
@config[:flags] ||= 0
|
70
|
+
|
71
|
+
if @config[:flags].kind_of? Array
|
72
|
+
@config[:flags].push "FOUND_ROWS"
|
73
|
+
else
|
74
|
+
@config[:flags] |= ::Mysql2::Client::FOUND_ROWS
|
75
|
+
end
|
76
|
+
|
77
|
+
@connection_parameters ||= @config
|
60
78
|
end
|
61
79
|
|
62
80
|
def supports_json?
|
@@ -75,17 +93,19 @@ module ActiveRecord
|
|
75
93
|
true
|
76
94
|
end
|
77
95
|
|
96
|
+
def savepoint_errors_invalidate_transactions?
|
97
|
+
true
|
98
|
+
end
|
99
|
+
|
78
100
|
def supports_lazy_transactions?
|
79
101
|
true
|
80
102
|
end
|
81
103
|
|
82
104
|
# HELPER METHODS ===========================================
|
83
105
|
|
84
|
-
def each_hash(result) # :nodoc:
|
106
|
+
def each_hash(result, &block) # :nodoc:
|
85
107
|
if block_given?
|
86
|
-
result.each(as: :hash, symbolize_keys: true)
|
87
|
-
yield row
|
88
|
-
end
|
108
|
+
result.each(as: :hash, symbolize_keys: true, &block)
|
89
109
|
else
|
90
110
|
to_enum(:each_hash, result)
|
91
111
|
end
|
@@ -99,10 +119,11 @@ module ActiveRecord
|
|
99
119
|
# QUOTING ==================================================
|
100
120
|
#++
|
101
121
|
|
122
|
+
# Quotes strings for use in SQL input.
|
102
123
|
def quote_string(string)
|
103
|
-
|
104
|
-
|
105
|
-
|
124
|
+
with_raw_connection(allow_retry: true, materialize_transactions: false) do |connection|
|
125
|
+
connection.escape(string)
|
126
|
+
end
|
106
127
|
end
|
107
128
|
|
108
129
|
#--
|
@@ -110,37 +131,51 @@ module ActiveRecord
|
|
110
131
|
#++
|
111
132
|
|
112
133
|
def active?
|
113
|
-
@
|
134
|
+
!(@raw_connection.nil? || @raw_connection.closed?) && @lock.synchronize { @raw_connection&.ping } || false
|
114
135
|
end
|
115
136
|
|
116
|
-
def reconnect!
|
117
|
-
super
|
118
|
-
disconnect!
|
119
|
-
connect
|
120
|
-
end
|
121
137
|
alias :reset! :reconnect!
|
122
138
|
|
123
139
|
# Disconnects from the database if already connected.
|
124
140
|
# Otherwise, this method does nothing.
|
125
141
|
def disconnect!
|
126
|
-
|
127
|
-
|
142
|
+
@lock.synchronize do
|
143
|
+
super
|
144
|
+
@raw_connection&.close
|
145
|
+
@raw_connection = nil
|
146
|
+
end
|
128
147
|
end
|
129
148
|
|
130
149
|
def discard! # :nodoc:
|
131
|
-
|
132
|
-
|
133
|
-
|
150
|
+
@lock.synchronize do
|
151
|
+
super
|
152
|
+
@raw_connection&.automatic_close = false
|
153
|
+
@raw_connection = nil
|
154
|
+
end
|
134
155
|
end
|
135
156
|
|
136
157
|
private
|
158
|
+
def text_type?(type)
|
159
|
+
TYPE_MAP.lookup(type).is_a?(Type::String) || TYPE_MAP.lookup(type).is_a?(Type::Text)
|
160
|
+
end
|
161
|
+
|
137
162
|
def connect
|
138
|
-
@
|
139
|
-
|
163
|
+
@raw_connection = self.class.new_client(@connection_parameters)
|
164
|
+
rescue ConnectionNotEstablished => ex
|
165
|
+
raise ex.set_pool(@pool)
|
166
|
+
end
|
167
|
+
|
168
|
+
def reconnect
|
169
|
+
@lock.synchronize do
|
170
|
+
@raw_connection&.close
|
171
|
+
@raw_connection = nil
|
172
|
+
connect
|
173
|
+
end
|
140
174
|
end
|
141
175
|
|
142
176
|
def configure_connection
|
143
|
-
@
|
177
|
+
@raw_connection.query_options[:as] = :array
|
178
|
+
@raw_connection.query_options[:database_timezone] = default_timezone
|
144
179
|
super
|
145
180
|
end
|
146
181
|
|
@@ -149,16 +184,38 @@ module ActiveRecord
|
|
149
184
|
end
|
150
185
|
|
151
186
|
def get_full_version
|
152
|
-
|
187
|
+
any_raw_connection.server_info[:version]
|
153
188
|
end
|
154
189
|
|
155
190
|
def translate_exception(exception, message:, sql:, binds:)
|
156
|
-
if exception.is_a?(Mysql2::Error::TimeoutError) && !exception.error_number
|
157
|
-
ActiveRecord::AdapterTimeout.new(message, sql: sql, binds: binds)
|
191
|
+
if exception.is_a?(::Mysql2::Error::TimeoutError) && !exception.error_number
|
192
|
+
ActiveRecord::AdapterTimeout.new(message, sql: sql, binds: binds, connection_pool: @pool)
|
193
|
+
elsif exception.is_a?(::Mysql2::Error::ConnectionError)
|
194
|
+
if exception.message.match?(/MySQL client is not connected/i)
|
195
|
+
ActiveRecord::ConnectionNotEstablished.new(exception, connection_pool: @pool)
|
196
|
+
else
|
197
|
+
ActiveRecord::ConnectionFailed.new(message, sql: sql, binds: binds, connection_pool: @pool)
|
198
|
+
end
|
158
199
|
else
|
159
200
|
super
|
160
201
|
end
|
161
202
|
end
|
203
|
+
|
204
|
+
def default_prepared_statements
|
205
|
+
false
|
206
|
+
end
|
207
|
+
|
208
|
+
ActiveRecord::Type.register(:immutable_string, adapter: :mysql2) do |_, **args|
|
209
|
+
Type::ImmutableString.new(true: "1", false: "0", **args)
|
210
|
+
end
|
211
|
+
|
212
|
+
ActiveRecord::Type.register(:string, adapter: :mysql2) do |_, **args|
|
213
|
+
Type::String.new(true: "1", false: "0", **args)
|
214
|
+
end
|
215
|
+
|
216
|
+
ActiveRecord::Type.register(:unsigned_integer, Type::UnsignedInteger, adapter: :mysql2)
|
162
217
|
end
|
218
|
+
|
219
|
+
ActiveSupport.run_load_hooks(:active_record_mysql2adapter, Mysql2Adapter)
|
163
220
|
end
|
164
221
|
end
|
@@ -5,8 +5,13 @@ module ActiveRecord
|
|
5
5
|
class PoolConfig # :nodoc:
|
6
6
|
include Mutex_m
|
7
7
|
|
8
|
-
attr_reader :db_config, :
|
9
|
-
|
8
|
+
attr_reader :db_config, :role, :shard
|
9
|
+
attr_writer :schema_reflection
|
10
|
+
attr_accessor :connection_class
|
11
|
+
|
12
|
+
def schema_reflection
|
13
|
+
@schema_reflection ||= SchemaReflection.new(db_config.lazy_schema_cache_path)
|
14
|
+
end
|
10
15
|
|
11
16
|
INSTANCES = ObjectSpace::WeakMap.new
|
12
17
|
private_constant :INSTANCES
|
@@ -15,27 +20,31 @@ module ActiveRecord
|
|
15
20
|
def discard_pools!
|
16
21
|
INSTANCES.each_key(&:discard_pool!)
|
17
22
|
end
|
23
|
+
|
24
|
+
def disconnect_all!
|
25
|
+
INSTANCES.each_key { |c| c.disconnect!(automatic_reconnect: true) }
|
26
|
+
end
|
18
27
|
end
|
19
28
|
|
20
|
-
def initialize(
|
29
|
+
def initialize(connection_class, db_config, role, shard)
|
21
30
|
super()
|
22
|
-
@
|
31
|
+
@connection_class = connection_class
|
23
32
|
@db_config = db_config
|
33
|
+
@role = role
|
34
|
+
@shard = shard
|
24
35
|
@pool = nil
|
25
36
|
INSTANCES[self] = self
|
26
37
|
end
|
27
38
|
|
28
|
-
def
|
29
|
-
if
|
30
|
-
connection_klass
|
31
|
-
elsif connection_klass.primary_class?
|
39
|
+
def connection_name
|
40
|
+
if connection_class.primary_class?
|
32
41
|
"ActiveRecord::Base"
|
33
42
|
else
|
34
|
-
|
43
|
+
connection_class.name
|
35
44
|
end
|
36
45
|
end
|
37
46
|
|
38
|
-
def disconnect!
|
47
|
+
def disconnect!(automatic_reconnect: false)
|
39
48
|
ActiveSupport::ForkTracker.check!
|
40
49
|
|
41
50
|
return unless @pool
|
@@ -43,7 +52,7 @@ module ActiveRecord
|
|
43
52
|
synchronize do
|
44
53
|
return unless @pool
|
45
54
|
|
46
|
-
@pool.automatic_reconnect =
|
55
|
+
@pool.automatic_reconnect = automatic_reconnect
|
47
56
|
@pool.disconnect!
|
48
57
|
end
|
49
58
|
|
@@ -4,40 +4,50 @@ module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
class PoolManager # :nodoc:
|
6
6
|
def initialize
|
7
|
-
@
|
7
|
+
@role_to_shard_mapping = Hash.new { |h, k| h[k] = {} }
|
8
8
|
end
|
9
9
|
|
10
10
|
def shard_names
|
11
|
-
@
|
11
|
+
@role_to_shard_mapping.values.flat_map { |shard_map| shard_map.keys }.uniq
|
12
12
|
end
|
13
13
|
|
14
14
|
def role_names
|
15
|
-
@
|
15
|
+
@role_to_shard_mapping.keys
|
16
16
|
end
|
17
17
|
|
18
18
|
def pool_configs(role = nil)
|
19
19
|
if role
|
20
|
-
@
|
20
|
+
@role_to_shard_mapping[role].values
|
21
21
|
else
|
22
|
-
@
|
22
|
+
@role_to_shard_mapping.flat_map { |_, shard_map| shard_map.values }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def each_pool_config(role = nil, &block)
|
27
|
+
if role
|
28
|
+
@role_to_shard_mapping[role].each_value(&block)
|
29
|
+
else
|
30
|
+
@role_to_shard_mapping.each_value do |shard_map|
|
31
|
+
shard_map.each_value(&block)
|
32
|
+
end
|
23
33
|
end
|
24
34
|
end
|
25
35
|
|
26
36
|
def remove_role(role)
|
27
|
-
@
|
37
|
+
@role_to_shard_mapping.delete(role)
|
28
38
|
end
|
29
39
|
|
30
40
|
def remove_pool_config(role, shard)
|
31
|
-
@
|
41
|
+
@role_to_shard_mapping[role].delete(shard)
|
32
42
|
end
|
33
43
|
|
34
44
|
def get_pool_config(role, shard)
|
35
|
-
@
|
45
|
+
@role_to_shard_mapping[role][shard]
|
36
46
|
end
|
37
47
|
|
38
48
|
def set_pool_config(role, shard, pool_config)
|
39
49
|
if pool_config
|
40
|
-
@
|
50
|
+
@role_to_shard_mapping[role][shard] = pool_config
|
41
51
|
else
|
42
52
|
raise ArgumentError, "The `pool_config` for the :#{role} role and :#{shard} shard was `nil`. Please check your configuration. If you want your writing role to be something other than `:writing` set `config.active_record.writing_role` in your application configuration. The same setting should be applied for the `reading_role` if applicable."
|
43
53
|
end
|
@@ -6,37 +6,65 @@ module ActiveRecord
|
|
6
6
|
class Column < ConnectionAdapters::Column # :nodoc:
|
7
7
|
delegate :oid, :fmod, to: :sql_type_metadata
|
8
8
|
|
9
|
-
def initialize(*, serial: nil, **)
|
9
|
+
def initialize(*, serial: nil, identity: nil, generated: nil, **)
|
10
10
|
super
|
11
11
|
@serial = serial
|
12
|
+
@identity = identity
|
13
|
+
@generated = generated
|
14
|
+
end
|
15
|
+
|
16
|
+
def identity?
|
17
|
+
@identity
|
12
18
|
end
|
13
19
|
|
14
20
|
def serial?
|
15
21
|
@serial
|
16
22
|
end
|
17
23
|
|
24
|
+
def auto_incremented_by_db?
|
25
|
+
serial? || identity?
|
26
|
+
end
|
27
|
+
|
28
|
+
def virtual?
|
29
|
+
# We assume every generated column is virtual, no matter the concrete type
|
30
|
+
@generated.present?
|
31
|
+
end
|
32
|
+
|
33
|
+
def has_default?
|
34
|
+
super && !virtual?
|
35
|
+
end
|
36
|
+
|
18
37
|
def array
|
19
38
|
sql_type_metadata.sql_type.end_with?("[]")
|
20
39
|
end
|
21
40
|
alias :array? :array
|
22
41
|
|
42
|
+
def enum?
|
43
|
+
type == :enum
|
44
|
+
end
|
45
|
+
|
23
46
|
def sql_type
|
24
47
|
super.delete_suffix("[]")
|
25
48
|
end
|
26
49
|
|
27
50
|
def init_with(coder)
|
28
51
|
@serial = coder["serial"]
|
52
|
+
@identity = coder["identity"]
|
53
|
+
@generated = coder["generated"]
|
29
54
|
super
|
30
55
|
end
|
31
56
|
|
32
57
|
def encode_with(coder)
|
33
58
|
coder["serial"] = @serial
|
59
|
+
coder["identity"] = @identity
|
60
|
+
coder["generated"] = @generated
|
34
61
|
super
|
35
62
|
end
|
36
63
|
|
37
64
|
def ==(other)
|
38
65
|
other.is_a?(Column) &&
|
39
66
|
super &&
|
67
|
+
identity? == other.identity? &&
|
40
68
|
serial? == other.serial?
|
41
69
|
end
|
42
70
|
alias :eql? :==
|
@@ -44,6 +72,7 @@ module ActiveRecord
|
|
44
72
|
def hash
|
45
73
|
Column.hash ^
|
46
74
|
super.hash ^
|
75
|
+
identity?.hash ^
|
47
76
|
serial?.hash
|
48
77
|
end
|
49
78
|
end
|
@@ -4,19 +4,21 @@ module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
module PostgreSQL
|
6
6
|
module DatabaseStatements
|
7
|
-
def explain(arel, binds = [])
|
8
|
-
sql
|
9
|
-
|
7
|
+
def explain(arel, binds = [], options = [])
|
8
|
+
sql = build_explain_clause(options) + " " + to_sql(arel, binds)
|
9
|
+
result = internal_exec_query(sql, "EXPLAIN", binds)
|
10
|
+
PostgreSQL::ExplainPrettyPrinter.new.pp(result)
|
10
11
|
end
|
11
12
|
|
12
13
|
# Queries the database and returns the results in an Array-like object
|
13
|
-
def query(sql, name = nil)
|
14
|
-
materialize_transactions
|
14
|
+
def query(sql, name = nil) # :nodoc:
|
15
15
|
mark_transaction_written_if_write(sql)
|
16
16
|
|
17
17
|
log(sql, name) do
|
18
|
-
|
19
|
-
|
18
|
+
with_raw_connection do |conn|
|
19
|
+
result = conn.async_exec(sql).map_types!(@type_map_for_results).values
|
20
|
+
verified!
|
21
|
+
result
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -34,65 +36,53 @@ module ActiveRecord
|
|
34
36
|
|
35
37
|
# Executes an SQL statement, returning a PG::Result object on success
|
36
38
|
# or raising a PG::Error exception otherwise.
|
39
|
+
#
|
40
|
+
# Setting +allow_retry+ to true causes the db to reconnect and retry
|
41
|
+
# executing the SQL statement in case of a connection-related exception.
|
42
|
+
# This option should only be enabled for known idempotent queries.
|
43
|
+
#
|
37
44
|
# Note: the PG::Result object is manually memory managed; if you don't
|
38
45
|
# need it specifically, you may want consider the <tt>exec_query</tt> wrapper.
|
39
|
-
def execute(
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
materialize_transactions
|
45
|
-
mark_transaction_written_if_write(sql)
|
46
|
+
def execute(...) # :nodoc:
|
47
|
+
super
|
48
|
+
ensure
|
49
|
+
@notice_receiver_sql_warnings = []
|
50
|
+
end
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
|
52
|
+
def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
|
53
|
+
log(sql, name, async: async) do
|
54
|
+
with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
|
55
|
+
result = conn.async_exec(sql)
|
56
|
+
verified!
|
57
|
+
handle_warnings(result)
|
58
|
+
result
|
50
59
|
end
|
51
60
|
end
|
52
61
|
end
|
53
62
|
|
54
|
-
def
|
55
|
-
execute_and_clear(sql, name, binds, prepare: prepare) do |result|
|
63
|
+
def internal_exec_query(sql, name = "SQL", binds = [], prepare: false, async: false, allow_retry: false, materialize_transactions: true) # :nodoc:
|
64
|
+
execute_and_clear(sql, name, binds, prepare: prepare, async: async, allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |result|
|
56
65
|
types = {}
|
57
66
|
fields = result.fields
|
58
67
|
fields.each_with_index do |fname, i|
|
59
68
|
ftype = result.ftype i
|
60
69
|
fmod = result.fmod i
|
61
|
-
|
62
|
-
when Type::Integer, Type::Float, OID::Decimal, Type::String, Type::DateTime, Type::Boolean
|
63
|
-
# skip if a column has already been type casted by pg decoders
|
64
|
-
else types[fname] = type
|
65
|
-
end
|
70
|
+
types[fname] = types[i] = get_oid_type(ftype, fmod, fname)
|
66
71
|
end
|
67
72
|
build_result(columns: fields, rows: result.values, column_types: types)
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
71
|
-
def exec_delete(sql, name = nil, binds = [])
|
76
|
+
def exec_delete(sql, name = nil, binds = []) # :nodoc:
|
72
77
|
execute_and_clear(sql, name, binds) { |result| result.cmd_tuples }
|
73
78
|
end
|
74
79
|
alias :exec_update :exec_delete
|
75
80
|
|
76
|
-
def
|
77
|
-
if pk.nil?
|
78
|
-
# Extract the table from the insert sql. Yuck.
|
79
|
-
table_ref = extract_table_ref_from_insert_sql(sql)
|
80
|
-
pk = primary_key(table_ref) if table_ref
|
81
|
-
end
|
82
|
-
|
83
|
-
if pk = suppress_composite_primary_key(pk)
|
84
|
-
sql = "#{sql} RETURNING #{quote_column_name(pk)}"
|
85
|
-
end
|
86
|
-
|
87
|
-
super
|
88
|
-
end
|
89
|
-
private :sql_for_insert
|
90
|
-
|
91
|
-
def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
|
81
|
+
def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning: nil) # :nodoc:
|
92
82
|
if use_insert_returning? || pk == false
|
93
83
|
super
|
94
84
|
else
|
95
|
-
result =
|
85
|
+
result = internal_exec_query(sql, name, binds)
|
96
86
|
unless sequence_name
|
97
87
|
table_ref = extract_table_ref_from_insert_sql(sql)
|
98
88
|
if table_ref
|
@@ -107,26 +97,56 @@ module ActiveRecord
|
|
107
97
|
end
|
108
98
|
|
109
99
|
# Begins a transaction.
|
110
|
-
def begin_db_transaction
|
111
|
-
|
100
|
+
def begin_db_transaction # :nodoc:
|
101
|
+
internal_execute("BEGIN", "TRANSACTION", allow_retry: true, materialize_transactions: false)
|
112
102
|
end
|
113
103
|
|
114
|
-
def begin_isolated_db_transaction(isolation)
|
115
|
-
|
116
|
-
execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}"
|
104
|
+
def begin_isolated_db_transaction(isolation) # :nodoc:
|
105
|
+
internal_execute("BEGIN ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}", "TRANSACTION", allow_retry: true, materialize_transactions: false)
|
117
106
|
end
|
118
107
|
|
119
108
|
# Commits a transaction.
|
120
|
-
def commit_db_transaction
|
121
|
-
|
109
|
+
def commit_db_transaction # :nodoc:
|
110
|
+
internal_execute("COMMIT", "TRANSACTION", allow_retry: false, materialize_transactions: true)
|
122
111
|
end
|
123
112
|
|
124
113
|
# Aborts a transaction.
|
125
|
-
def exec_rollback_db_transaction
|
126
|
-
|
114
|
+
def exec_rollback_db_transaction # :nodoc:
|
115
|
+
cancel_any_running_query
|
116
|
+
internal_execute("ROLLBACK", "TRANSACTION", allow_retry: false, materialize_transactions: true)
|
117
|
+
end
|
118
|
+
|
119
|
+
def exec_restart_db_transaction # :nodoc:
|
120
|
+
cancel_any_running_query
|
121
|
+
internal_execute("ROLLBACK AND CHAIN", "TRANSACTION", allow_retry: false, materialize_transactions: true)
|
122
|
+
end
|
123
|
+
|
124
|
+
# From https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
|
125
|
+
HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("CURRENT_TIMESTAMP").freeze # :nodoc:
|
126
|
+
private_constant :HIGH_PRECISION_CURRENT_TIMESTAMP
|
127
|
+
|
128
|
+
def high_precision_current_timestamp
|
129
|
+
HIGH_PRECISION_CURRENT_TIMESTAMP
|
130
|
+
end
|
131
|
+
|
132
|
+
def build_explain_clause(options = [])
|
133
|
+
return "EXPLAIN" if options.empty?
|
134
|
+
|
135
|
+
"EXPLAIN (#{options.join(", ").upcase})"
|
127
136
|
end
|
128
137
|
|
129
138
|
private
|
139
|
+
IDLE_TRANSACTION_STATUSES = [PG::PQTRANS_IDLE, PG::PQTRANS_INTRANS, PG::PQTRANS_INERROR]
|
140
|
+
private_constant :IDLE_TRANSACTION_STATUSES
|
141
|
+
|
142
|
+
def cancel_any_running_query
|
143
|
+
return if @raw_connection.nil? || IDLE_TRANSACTION_STATUSES.include?(@raw_connection.transaction_status)
|
144
|
+
|
145
|
+
@raw_connection.cancel
|
146
|
+
@raw_connection.block
|
147
|
+
rescue PG::Error
|
148
|
+
end
|
149
|
+
|
130
150
|
def execute_batch(statements, name = nil)
|
131
151
|
execute(combine_multi_statements(statements))
|
132
152
|
end
|
@@ -137,12 +157,29 @@ module ActiveRecord
|
|
137
157
|
|
138
158
|
# Returns the current ID of a table's sequence.
|
139
159
|
def last_insert_id_result(sequence_name)
|
140
|
-
|
160
|
+
internal_exec_query("SELECT currval(#{quote(sequence_name)})", "SQL")
|
161
|
+
end
|
162
|
+
|
163
|
+
def returning_column_values(result)
|
164
|
+
result.rows.first
|
141
165
|
end
|
142
166
|
|
143
167
|
def suppress_composite_primary_key(pk)
|
144
168
|
pk unless pk.is_a?(Array)
|
145
169
|
end
|
170
|
+
|
171
|
+
def handle_warnings(sql)
|
172
|
+
@notice_receiver_sql_warnings.each do |warning|
|
173
|
+
next if warning_ignored?(warning)
|
174
|
+
|
175
|
+
warning.sql = sql
|
176
|
+
ActiveRecord.db_warnings_action.call(warning)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def warning_ignored?(warning)
|
181
|
+
["WARNING", "ERROR", "FATAL", "PANIC"].exclude?(warning.level) || super
|
182
|
+
end
|
146
183
|
end
|
147
184
|
end
|
148
185
|
end
|