activerecord 3.2.22.5 → 5.2.8
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +657 -621
- data/MIT-LICENSE +2 -2
- data/README.rdoc +41 -46
- data/examples/performance.rb +55 -42
- data/examples/simple.rb +6 -5
- data/lib/active_record/aggregations.rb +264 -236
- data/lib/active_record/association_relation.rb +40 -0
- data/lib/active_record/associations/alias_tracker.rb +47 -42
- data/lib/active_record/associations/association.rb +127 -75
- data/lib/active_record/associations/association_scope.rb +126 -92
- data/lib/active_record/associations/belongs_to_association.rb +78 -27
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +9 -4
- data/lib/active_record/associations/builder/association.rb +117 -32
- data/lib/active_record/associations/builder/belongs_to.rb +135 -60
- data/lib/active_record/associations/builder/collection_association.rb +61 -54
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +120 -42
- data/lib/active_record/associations/builder/has_many.rb +10 -64
- data/lib/active_record/associations/builder/has_one.rb +19 -51
- data/lib/active_record/associations/builder/singular_association.rb +28 -18
- data/lib/active_record/associations/collection_association.rb +226 -293
- data/lib/active_record/associations/collection_proxy.rb +1067 -69
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +83 -47
- data/lib/active_record/associations/has_many_through_association.rb +98 -65
- data/lib/active_record/associations/has_one_association.rb +57 -20
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +48 -126
- data/lib/active_record/associations/join_dependency/join_base.rb +11 -12
- data/lib/active_record/associations/join_dependency/join_part.rb +35 -42
- data/lib/active_record/associations/join_dependency.rb +212 -164
- data/lib/active_record/associations/preloader/association.rb +95 -89
- data/lib/active_record/associations/preloader/through_association.rb +84 -44
- data/lib/active_record/associations/preloader.rb +123 -111
- data/lib/active_record/associations/singular_association.rb +33 -24
- data/lib/active_record/associations/through_association.rb +60 -26
- data/lib/active_record/associations.rb +1759 -1506
- data/lib/active_record/attribute_assignment.rb +60 -193
- data/lib/active_record/attribute_decorators.rb +90 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +55 -8
- data/lib/active_record/attribute_methods/dirty.rb +113 -74
- data/lib/active_record/attribute_methods/primary_key.rb +106 -77
- data/lib/active_record/attribute_methods/query.rb +8 -5
- data/lib/active_record/attribute_methods/read.rb +63 -114
- data/lib/active_record/attribute_methods/serialization.rb +60 -90
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +69 -43
- data/lib/active_record/attribute_methods/write.rb +43 -45
- data/lib/active_record/attribute_methods.rb +366 -149
- data/lib/active_record/attributes.rb +266 -0
- data/lib/active_record/autosave_association.rb +312 -225
- data/lib/active_record/base.rb +114 -505
- data/lib/active_record/callbacks.rb +145 -67
- data/lib/active_record/coders/json.rb +15 -0
- data/lib/active_record/coders/yaml_column.rb +32 -23
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +883 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +16 -2
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +350 -200
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +150 -65
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +146 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +477 -284
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +95 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1100 -310
- data/lib/active_record/connection_adapters/abstract/transaction.rb +283 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +450 -118
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +657 -446
- data/lib/active_record/connection_adapters/column.rb +50 -255
- data/lib/active_record/connection_adapters/connection_specification.rb +287 -0
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -210
- data/lib/active_record/connection_adapters/postgresql/column.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +163 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +56 -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 +50 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +111 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -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 +34 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +168 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +206 -0
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +774 -0
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +620 -1080
- data/lib/active_record/connection_adapters/schema_cache.rb +85 -36
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +106 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +545 -27
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +145 -0
- data/lib/active_record/core.rb +559 -0
- data/lib/active_record/counter_cache.rb +200 -105
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +107 -69
- data/lib/active_record/enum.rb +244 -0
- data/lib/active_record/errors.rb +245 -60
- data/lib/active_record/explain.rb +35 -71
- data/lib/active_record/explain_registry.rb +32 -0
- data/lib/active_record/explain_subscriber.rb +18 -9
- data/lib/active_record/fixture_set/file.rb +82 -0
- data/lib/active_record/fixtures.rb +418 -275
- data/lib/active_record/gem_version.rb +17 -0
- data/lib/active_record/inheritance.rb +209 -100
- data/lib/active_record/integration.rb +116 -21
- data/lib/active_record/internal_metadata.rb +45 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +9 -1
- data/lib/active_record/locking/optimistic.rb +107 -94
- data/lib/active_record/locking/pessimistic.rb +20 -8
- data/lib/active_record/log_subscriber.rb +99 -34
- data/lib/active_record/migration/command_recorder.rb +199 -64
- data/lib/active_record/migration/compatibility.rb +217 -0
- data/lib/active_record/migration/join_table.rb +17 -0
- data/lib/active_record/migration.rb +893 -296
- data/lib/active_record/model_schema.rb +328 -175
- data/lib/active_record/nested_attributes.rb +338 -242
- data/lib/active_record/no_touching.rb +58 -0
- data/lib/active_record/null_relation.rb +68 -0
- data/lib/active_record/persistence.rb +557 -170
- data/lib/active_record/query_cache.rb +14 -43
- data/lib/active_record/querying.rb +36 -24
- data/lib/active_record/railtie.rb +147 -52
- data/lib/active_record/railties/console_sandbox.rb +5 -4
- data/lib/active_record/railties/controller_runtime.rb +13 -6
- data/lib/active_record/railties/databases.rake +206 -488
- data/lib/active_record/readonly_attributes.rb +4 -6
- data/lib/active_record/reflection.rb +734 -228
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +249 -52
- data/lib/active_record/relation/calculations.rb +330 -284
- data/lib/active_record/relation/delegation.rb +135 -37
- data/lib/active_record/relation/finder_methods.rb +450 -287
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +193 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder.rb +132 -43
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +1037 -221
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +48 -151
- data/lib/active_record/relation/where_clause.rb +186 -0
- data/lib/active_record/relation/where_clause_factory.rb +34 -0
- data/lib/active_record/relation.rb +451 -359
- data/lib/active_record/result.rb +129 -20
- data/lib/active_record/runtime_registry.rb +24 -0
- data/lib/active_record/sanitization.rb +164 -136
- data/lib/active_record/schema.rb +31 -19
- data/lib/active_record/schema_dumper.rb +154 -107
- data/lib/active_record/schema_migration.rb +56 -0
- data/lib/active_record/scoping/default.rb +108 -98
- data/lib/active_record/scoping/named.rb +125 -112
- data/lib/active_record/scoping.rb +77 -123
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +10 -6
- data/lib/active_record/statement_cache.rb +121 -0
- data/lib/active_record/store.rb +175 -16
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +82 -0
- data/lib/active_record/tasks/database_tasks.rb +337 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +143 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +83 -0
- data/lib/active_record/timestamp.rb +80 -41
- data/lib/active_record/touch_later.rb +64 -0
- data/lib/active_record/transactions.rb +240 -119
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +136 -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 +25 -0
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +71 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +21 -0
- data/lib/active_record/type/type_map.rb +62 -0
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +79 -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 +35 -18
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +68 -0
- data/lib/active_record/validations/uniqueness.rb +133 -75
- data/lib/active_record/validations.rb +53 -43
- data/lib/active_record/version.rb +7 -7
- data/lib/active_record.rb +89 -57
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -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 +61 -8
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +46 -0
- data/lib/rails/generators/active_record/migration.rb +28 -8
- data/lib/rails/generators/active_record/model/model_generator.rb +23 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +13 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +1 -1
- data/lib/rails/generators/active_record.rb +10 -16
- metadata +141 -62
- data/examples/associations.png +0 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
- data/lib/active_record/associations/join_helper.rb +0 -55
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -15
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -441
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
- data/lib/active_record/dynamic_finder_match.rb +0 -68
- data/lib/active_record/dynamic_scope_match.rb +0 -23
- data/lib/active_record/fixtures/file.rb +0 -65
- data/lib/active_record/identity_map.rb +0 -162
- data/lib/active_record/observer.rb +0 -121
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -203
- data/lib/active_record/session_store.rb +0 -360
- data/lib/active_record/test_case.rb +0 -73
- data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -34
- data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -12
- data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
- data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,120 +1,221 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/connection_adapters/determine_if_preparable_visitor"
|
4
|
+
require "active_record/connection_adapters/schema_cache"
|
5
|
+
require "active_record/connection_adapters/sql_type_metadata"
|
6
|
+
require "active_record/connection_adapters/abstract/schema_dumper"
|
7
|
+
require "active_record/connection_adapters/abstract/schema_creation"
|
8
|
+
require "active_support/concurrency/load_interlock_aware_monitor"
|
9
|
+
require "arel/collectors/bind"
|
10
|
+
require "arel/collectors/composite"
|
11
|
+
require "arel/collectors/sql_string"
|
12
|
+
require "arel/collectors/substitute_binds"
|
8
13
|
|
9
14
|
module ActiveRecord
|
10
15
|
module ConnectionAdapters # :nodoc:
|
11
16
|
extend ActiveSupport::Autoload
|
12
17
|
|
13
18
|
autoload :Column
|
19
|
+
autoload :ConnectionSpecification
|
20
|
+
|
21
|
+
autoload_at "active_record/connection_adapters/abstract/schema_definitions" do
|
22
|
+
autoload :IndexDefinition
|
23
|
+
autoload :ColumnDefinition
|
24
|
+
autoload :ChangeColumnDefinition
|
25
|
+
autoload :ForeignKeyDefinition
|
26
|
+
autoload :TableDefinition
|
27
|
+
autoload :Table
|
28
|
+
autoload :AlterTable
|
29
|
+
autoload :ReferenceDefinition
|
30
|
+
end
|
14
31
|
|
15
|
-
|
16
|
-
autoload :
|
17
|
-
|
18
|
-
autoload :TableDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
|
19
|
-
autoload :Table, 'active_record/connection_adapters/abstract/schema_definitions'
|
32
|
+
autoload_at "active_record/connection_adapters/abstract/connection_pool" do
|
33
|
+
autoload :ConnectionHandler
|
34
|
+
end
|
20
35
|
|
36
|
+
autoload_under "abstract" do
|
21
37
|
autoload :SchemaStatements
|
22
38
|
autoload :DatabaseStatements
|
23
39
|
autoload :DatabaseLimits
|
24
40
|
autoload :Quoting
|
25
|
-
|
26
41
|
autoload :ConnectionPool
|
27
|
-
autoload :ConnectionHandler, 'active_record/connection_adapters/abstract/connection_pool'
|
28
|
-
autoload :ConnectionManagement, 'active_record/connection_adapters/abstract/connection_pool'
|
29
|
-
autoload :ConnectionSpecification
|
30
|
-
|
31
42
|
autoload :QueryCache
|
43
|
+
autoload :Savepoints
|
44
|
+
end
|
45
|
+
|
46
|
+
autoload_at "active_record/connection_adapters/abstract/transaction" do
|
47
|
+
autoload :TransactionManager
|
48
|
+
autoload :NullTransaction
|
49
|
+
autoload :RealTransaction
|
50
|
+
autoload :SavepointTransaction
|
51
|
+
autoload :TransactionState
|
32
52
|
end
|
33
53
|
|
34
54
|
# Active Record supports multiple database systems. AbstractAdapter and
|
35
55
|
# related classes form the abstraction layer which makes this possible.
|
36
56
|
# An AbstractAdapter represents a connection to a database, and provides an
|
37
57
|
# abstract interface for database-specific functionality such as establishing
|
38
|
-
# a connection, escaping values, building the right SQL fragments for
|
39
|
-
# and
|
58
|
+
# a connection, escaping values, building the right SQL fragments for +:offset+
|
59
|
+
# and +:limit+ options, etc.
|
40
60
|
#
|
41
61
|
# All the concrete database adapters follow the interface laid down in this class.
|
42
|
-
# ActiveRecord::Base.connection returns an AbstractAdapter object, which
|
62
|
+
# {ActiveRecord::Base.connection}[rdoc-ref:ConnectionHandling#connection] returns an AbstractAdapter object, which
|
43
63
|
# you can use.
|
44
64
|
#
|
45
65
|
# Most of the methods in the adapter are useful during migrations. Most
|
46
|
-
# notably, the instance methods provided by
|
66
|
+
# notably, the instance methods provided by SchemaStatements are very useful.
|
47
67
|
class AbstractAdapter
|
68
|
+
ADAPTER_NAME = "Abstract".freeze
|
69
|
+
include ActiveSupport::Callbacks
|
70
|
+
define_callbacks :checkout, :checkin
|
71
|
+
|
48
72
|
include Quoting, DatabaseStatements, SchemaStatements
|
49
73
|
include DatabaseLimits
|
50
74
|
include QueryCache
|
51
|
-
include
|
52
|
-
include MonitorMixin
|
75
|
+
include Savepoints
|
53
76
|
|
54
|
-
|
77
|
+
SIMPLE_INT = /\A\d+\z/
|
55
78
|
|
56
79
|
attr_accessor :visitor, :pool
|
57
|
-
attr_reader :schema_cache, :
|
58
|
-
alias :in_use? :
|
80
|
+
attr_reader :schema_cache, :owner, :logger, :prepared_statements, :lock
|
81
|
+
alias :in_use? :owner
|
82
|
+
|
83
|
+
def self.type_cast_config_to_integer(config)
|
84
|
+
if config.is_a?(Integer)
|
85
|
+
config
|
86
|
+
elsif config =~ SIMPLE_INT
|
87
|
+
config.to_i
|
88
|
+
else
|
89
|
+
config
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.type_cast_config_to_boolean(config)
|
94
|
+
if config == "false"
|
95
|
+
false
|
96
|
+
else
|
97
|
+
config
|
98
|
+
end
|
99
|
+
end
|
59
100
|
|
60
|
-
def initialize(connection, logger = nil,
|
101
|
+
def initialize(connection, logger = nil, config = {}) # :nodoc:
|
61
102
|
super()
|
62
103
|
|
63
|
-
@active = nil
|
64
104
|
@connection = connection
|
65
|
-
@
|
105
|
+
@owner = nil
|
66
106
|
@instrumenter = ActiveSupport::Notifications.instrumenter
|
67
|
-
@last_use = false
|
68
107
|
@logger = logger
|
69
|
-
@
|
70
|
-
@pool =
|
71
|
-
@
|
72
|
-
@query_cache_enabled = false
|
108
|
+
@config = config
|
109
|
+
@pool = nil
|
110
|
+
@idle_since = Concurrent.monotonic_time
|
73
111
|
@schema_cache = SchemaCache.new self
|
74
|
-
@
|
112
|
+
@quoted_column_names, @quoted_table_names = {}, {}
|
113
|
+
@visitor = arel_visitor
|
114
|
+
@lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
115
|
+
|
116
|
+
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
|
117
|
+
@prepared_statements = true
|
118
|
+
@visitor.extend(DetermineIfPreparableVisitor)
|
119
|
+
else
|
120
|
+
@prepared_statements = false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def migrations_paths # :nodoc:
|
125
|
+
@config[:migrations_paths] || Migrator.migrations_paths
|
126
|
+
end
|
127
|
+
|
128
|
+
def migration_context # :nodoc:
|
129
|
+
MigrationContext.new(migrations_paths)
|
130
|
+
end
|
131
|
+
|
132
|
+
class Version
|
133
|
+
include Comparable
|
134
|
+
|
135
|
+
def initialize(version_string)
|
136
|
+
@version = version_string.split(".").map(&:to_i)
|
137
|
+
end
|
138
|
+
|
139
|
+
def <=>(version_string)
|
140
|
+
@version <=> version_string.split(".").map(&:to_i)
|
141
|
+
end
|
75
142
|
end
|
76
143
|
|
144
|
+
def valid_type?(type) # :nodoc:
|
145
|
+
!native_database_types[type].nil?
|
146
|
+
end
|
147
|
+
|
148
|
+
# this method must only be called while holding connection pool's mutex
|
77
149
|
def lease
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
150
|
+
if in_use?
|
151
|
+
msg = "Cannot lease connection, ".dup
|
152
|
+
if @owner == Thread.current
|
153
|
+
msg << "it is already leased by the current thread."
|
154
|
+
else
|
155
|
+
msg << "it is already in use by a different thread: #{@owner}. " \
|
156
|
+
"Current thread: #{Thread.current}."
|
82
157
|
end
|
158
|
+
raise ActiveRecordError, msg
|
83
159
|
end
|
160
|
+
|
161
|
+
@owner = Thread.current
|
84
162
|
end
|
85
163
|
|
164
|
+
def schema_cache=(cache)
|
165
|
+
cache.connection = self
|
166
|
+
@schema_cache = cache
|
167
|
+
end
|
168
|
+
|
169
|
+
# this method must only be called while holding connection pool's mutex
|
86
170
|
def expire
|
87
|
-
|
171
|
+
if in_use?
|
172
|
+
if @owner != Thread.current
|
173
|
+
raise ActiveRecordError, "Cannot expire connection, " \
|
174
|
+
"it is owned by a different thread: #{@owner}. " \
|
175
|
+
"Current thread: #{Thread.current}."
|
176
|
+
end
|
177
|
+
|
178
|
+
@idle_since = Concurrent.monotonic_time
|
179
|
+
@owner = nil
|
180
|
+
else
|
181
|
+
raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
|
182
|
+
end
|
88
183
|
end
|
89
184
|
|
90
|
-
#
|
91
|
-
|
92
|
-
|
93
|
-
|
185
|
+
# this method must only be called while holding connection pool's mutex (and a desire for segfaults)
|
186
|
+
def steal! # :nodoc:
|
187
|
+
if in_use?
|
188
|
+
if @owner != Thread.current
|
189
|
+
pool.send :remove_connection_from_thread_cache, self, @owner
|
190
|
+
|
191
|
+
@owner = Thread.current
|
192
|
+
end
|
193
|
+
else
|
194
|
+
raise ActiveRecordError, "Cannot steal connection, it is not currently leased."
|
195
|
+
end
|
94
196
|
end
|
95
197
|
|
96
|
-
#
|
97
|
-
|
98
|
-
|
99
|
-
|
198
|
+
# Seconds since this connection was returned to the pool
|
199
|
+
def seconds_idle # :nodoc:
|
200
|
+
return 0 if in_use?
|
201
|
+
Concurrent.monotonic_time - @idle_since
|
100
202
|
end
|
101
203
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
204
|
+
def unprepared_statement
|
205
|
+
old_prepared_statements, @prepared_statements = @prepared_statements, false
|
206
|
+
yield
|
207
|
+
ensure
|
208
|
+
@prepared_statements = old_prepared_statements
|
107
209
|
end
|
108
210
|
|
109
|
-
#
|
110
|
-
#
|
111
|
-
def
|
112
|
-
|
211
|
+
# Returns the human-readable name of the adapter. Use mixed case - one
|
212
|
+
# can always use downcase if needed.
|
213
|
+
def adapter_name
|
214
|
+
self.class::ADAPTER_NAME
|
113
215
|
end
|
114
216
|
|
115
217
|
# Does this adapter support DDL rollbacks in transactions? That is, would
|
116
|
-
# CREATE TABLE or ALTER TABLE get rolled back by a transaction?
|
117
|
-
# SQL Server, and others support this. MySQL and others do not.
|
218
|
+
# CREATE TABLE or ALTER TABLE get rolled back by a transaction?
|
118
219
|
def supports_ddl_transactions?
|
119
220
|
false
|
120
221
|
end
|
@@ -123,16 +224,19 @@ module ActiveRecord
|
|
123
224
|
false
|
124
225
|
end
|
125
226
|
|
126
|
-
# Does this adapter support savepoints?
|
127
|
-
# SQLite < 3.6.8 does not.
|
227
|
+
# Does this adapter support savepoints?
|
128
228
|
def supports_savepoints?
|
129
229
|
false
|
130
230
|
end
|
131
231
|
|
232
|
+
# Does this adapter support application-enforced advisory locking?
|
233
|
+
def supports_advisory_locks?
|
234
|
+
false
|
235
|
+
end
|
236
|
+
|
132
237
|
# Should primary key values be selected from their corresponding
|
133
238
|
# sequence before the insert statement? If true, next_sequence_value
|
134
239
|
# is called before each insert to set the record's primary key.
|
135
|
-
# This is false for all adapters but Firebird.
|
136
240
|
def prefetch_primary_key?(table_name = nil)
|
137
241
|
false
|
138
242
|
end
|
@@ -142,23 +246,123 @@ module ActiveRecord
|
|
142
246
|
false
|
143
247
|
end
|
144
248
|
|
145
|
-
# Does this adapter support
|
146
|
-
|
249
|
+
# Does this adapter support partial indices?
|
250
|
+
def supports_partial_index?
|
251
|
+
false
|
252
|
+
end
|
253
|
+
|
254
|
+
# Does this adapter support expression indices?
|
255
|
+
def supports_expression_index?
|
256
|
+
false
|
257
|
+
end
|
258
|
+
|
259
|
+
# Does this adapter support explain?
|
147
260
|
def supports_explain?
|
148
261
|
false
|
149
262
|
end
|
150
263
|
|
151
|
-
#
|
264
|
+
# Does this adapter support setting the isolation level for a transaction?
|
265
|
+
def supports_transaction_isolation?
|
266
|
+
false
|
267
|
+
end
|
152
268
|
|
153
|
-
#
|
154
|
-
def
|
155
|
-
|
269
|
+
# Does this adapter support database extensions?
|
270
|
+
def supports_extensions?
|
271
|
+
false
|
156
272
|
end
|
157
273
|
|
158
|
-
#
|
159
|
-
#
|
160
|
-
def
|
161
|
-
|
274
|
+
# Does this adapter support creating indexes in the same statement as
|
275
|
+
# creating the table?
|
276
|
+
def supports_indexes_in_create?
|
277
|
+
false
|
278
|
+
end
|
279
|
+
|
280
|
+
# Does this adapter support creating foreign key constraints?
|
281
|
+
def supports_foreign_keys?
|
282
|
+
false
|
283
|
+
end
|
284
|
+
|
285
|
+
# Does this adapter support creating invalid constraints?
|
286
|
+
def supports_validate_constraints?
|
287
|
+
false
|
288
|
+
end
|
289
|
+
|
290
|
+
# Does this adapter support creating foreign key constraints
|
291
|
+
# in the same statement as creating the table?
|
292
|
+
def supports_foreign_keys_in_create?
|
293
|
+
supports_foreign_keys?
|
294
|
+
end
|
295
|
+
|
296
|
+
# Does this adapter support views?
|
297
|
+
def supports_views?
|
298
|
+
false
|
299
|
+
end
|
300
|
+
|
301
|
+
# Does this adapter support datetime with precision?
|
302
|
+
def supports_datetime_with_precision?
|
303
|
+
false
|
304
|
+
end
|
305
|
+
|
306
|
+
# Does this adapter support json data type?
|
307
|
+
def supports_json?
|
308
|
+
false
|
309
|
+
end
|
310
|
+
|
311
|
+
# Does this adapter support metadata comments on database objects (tables, columns, indexes)?
|
312
|
+
def supports_comments?
|
313
|
+
false
|
314
|
+
end
|
315
|
+
|
316
|
+
# Can comments for tables, columns, and indexes be specified in create/alter table statements?
|
317
|
+
def supports_comments_in_create?
|
318
|
+
false
|
319
|
+
end
|
320
|
+
|
321
|
+
# Does this adapter support multi-value insert?
|
322
|
+
def supports_multi_insert?
|
323
|
+
true
|
324
|
+
end
|
325
|
+
|
326
|
+
# Does this adapter support virtual columns?
|
327
|
+
def supports_virtual_columns?
|
328
|
+
false
|
329
|
+
end
|
330
|
+
|
331
|
+
# Does this adapter support foreign/external tables?
|
332
|
+
def supports_foreign_tables?
|
333
|
+
false
|
334
|
+
end
|
335
|
+
|
336
|
+
# This is meant to be implemented by the adapters that support extensions
|
337
|
+
def disable_extension(name)
|
338
|
+
end
|
339
|
+
|
340
|
+
# This is meant to be implemented by the adapters that support extensions
|
341
|
+
def enable_extension(name)
|
342
|
+
end
|
343
|
+
|
344
|
+
# This is meant to be implemented by the adapters that support advisory
|
345
|
+
# locks
|
346
|
+
#
|
347
|
+
# Return true if we got the lock, otherwise false
|
348
|
+
def get_advisory_lock(lock_id) # :nodoc:
|
349
|
+
end
|
350
|
+
|
351
|
+
# This is meant to be implemented by the adapters that support advisory
|
352
|
+
# locks.
|
353
|
+
#
|
354
|
+
# Return true if we released the lock, otherwise false
|
355
|
+
def release_advisory_lock(lock_id) # :nodoc:
|
356
|
+
end
|
357
|
+
|
358
|
+
# A list of extensions, to be filled in by adapters that support them.
|
359
|
+
def extensions
|
360
|
+
[]
|
361
|
+
end
|
362
|
+
|
363
|
+
# A list of index algorithms, to be filled by adapters that support them.
|
364
|
+
def index_algorithms
|
365
|
+
{}
|
162
366
|
end
|
163
367
|
|
164
368
|
# REFERENTIAL INTEGRITY ====================================
|
@@ -174,19 +378,34 @@ module ActiveRecord
|
|
174
378
|
# checking whether the database is actually capable of responding, i.e. whether
|
175
379
|
# the connection isn't stale.
|
176
380
|
def active?
|
177
|
-
@active != false
|
178
381
|
end
|
179
382
|
|
180
383
|
# Disconnects from the database if already connected, and establishes a
|
181
|
-
# new connection with the database.
|
384
|
+
# new connection with the database. Implementors should call super if they
|
385
|
+
# override the default implementation.
|
182
386
|
def reconnect!
|
183
|
-
|
387
|
+
clear_cache!
|
388
|
+
reset_transaction
|
184
389
|
end
|
185
390
|
|
186
391
|
# Disconnects from the database if already connected. Otherwise, this
|
187
392
|
# method does nothing.
|
188
393
|
def disconnect!
|
189
|
-
|
394
|
+
clear_cache!
|
395
|
+
reset_transaction
|
396
|
+
end
|
397
|
+
|
398
|
+
# Immediately forget this connection ever existed. Unlike disconnect!,
|
399
|
+
# this will not communicate with the server.
|
400
|
+
#
|
401
|
+
# After calling this method, the behavior of all other methods becomes
|
402
|
+
# undefined. This is called internally just before a forked process gets
|
403
|
+
# rid of a connection that belonged to its parent.
|
404
|
+
def discard!
|
405
|
+
# This should be overridden by concrete adapters.
|
406
|
+
#
|
407
|
+
# Prevent @connection's finalizer from touching the socket, or
|
408
|
+
# otherwise communicating with its server, when it is collected.
|
190
409
|
end
|
191
410
|
|
192
411
|
# Reset the state of this connection, directing the DBMS to clear
|
@@ -207,21 +426,20 @@ module ActiveRecord
|
|
207
426
|
end
|
208
427
|
|
209
428
|
# Returns true if its required to reload the connection between requests for development mode.
|
210
|
-
# This is not the case for Ruby/MySQL and it's not necessary for any adapters except SQLite.
|
211
429
|
def requires_reloading?
|
212
430
|
false
|
213
431
|
end
|
214
432
|
|
215
433
|
# Checks whether the connection to the database is still active (i.e. not stale).
|
216
|
-
# This is done under the hood by calling
|
434
|
+
# This is done under the hood by calling #active?. If the connection
|
217
435
|
# is no longer active, then this method will reconnect to the database.
|
218
|
-
def verify!
|
436
|
+
def verify!
|
219
437
|
reconnect! unless active?
|
220
438
|
end
|
221
439
|
|
222
440
|
# Provides access to the underlying database driver for this adapter. For
|
223
|
-
# example, this method returns a
|
224
|
-
# and a
|
441
|
+
# example, this method returns a Mysql2::Client object in case of Mysql2Adapter,
|
442
|
+
# and a PG::Connection object in case of PostgreSQLAdapter.
|
225
443
|
#
|
226
444
|
# This is useful for when you need to call a proprietary method such as
|
227
445
|
# PostgreSQL's lo_* methods.
|
@@ -229,68 +447,182 @@ module ActiveRecord
|
|
229
447
|
@connection
|
230
448
|
end
|
231
449
|
|
232
|
-
|
233
|
-
|
234
|
-
def increment_open_transactions
|
235
|
-
@open_transactions += 1
|
450
|
+
def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
|
451
|
+
table[attribute].eq(value)
|
236
452
|
end
|
237
453
|
|
238
|
-
def
|
239
|
-
|
454
|
+
def case_insensitive_comparison(table, attribute, column, value) # :nodoc:
|
455
|
+
if can_perform_case_insensitive_comparison_for?(column)
|
456
|
+
table[attribute].lower.eq(table.lower(value))
|
457
|
+
else
|
458
|
+
table[attribute].eq(value)
|
459
|
+
end
|
240
460
|
end
|
241
461
|
|
242
|
-
def
|
243
|
-
|
462
|
+
def can_perform_case_insensitive_comparison_for?(column)
|
463
|
+
true
|
244
464
|
end
|
465
|
+
private :can_perform_case_insensitive_comparison_for?
|
245
466
|
|
246
|
-
|
467
|
+
# Check the connection back in to the connection pool
|
468
|
+
def close
|
469
|
+
pool.checkin self
|
247
470
|
end
|
248
471
|
|
249
|
-
def
|
472
|
+
def column_name_for_operation(operation, node) # :nodoc:
|
473
|
+
column_name_from_arel_node(node)
|
250
474
|
end
|
251
475
|
|
252
|
-
def
|
476
|
+
def column_name_from_arel_node(node) # :nodoc:
|
477
|
+
visitor.accept(node, Arel::Collectors::SQLString.new).value
|
253
478
|
end
|
254
479
|
|
255
|
-
def
|
256
|
-
|
480
|
+
def default_index_type?(index) # :nodoc:
|
481
|
+
index.using.nil?
|
257
482
|
end
|
258
483
|
|
259
|
-
|
260
|
-
|
261
|
-
|
484
|
+
private
|
485
|
+
def type_map
|
486
|
+
@type_map ||= Type::TypeMap.new.tap do |mapping|
|
487
|
+
initialize_type_map(mapping)
|
488
|
+
end
|
489
|
+
end
|
262
490
|
|
263
|
-
|
264
|
-
|
265
|
-
|
491
|
+
def initialize_type_map(m = type_map)
|
492
|
+
register_class_with_limit m, %r(boolean)i, Type::Boolean
|
493
|
+
register_class_with_limit m, %r(char)i, Type::String
|
494
|
+
register_class_with_limit m, %r(binary)i, Type::Binary
|
495
|
+
register_class_with_limit m, %r(text)i, Type::Text
|
496
|
+
register_class_with_precision m, %r(date)i, Type::Date
|
497
|
+
register_class_with_precision m, %r(time)i, Type::Time
|
498
|
+
register_class_with_precision m, %r(datetime)i, Type::DateTime
|
499
|
+
register_class_with_limit m, %r(float)i, Type::Float
|
500
|
+
register_class_with_limit m, %r(int)i, Type::Integer
|
501
|
+
|
502
|
+
m.alias_type %r(blob)i, "binary"
|
503
|
+
m.alias_type %r(clob)i, "text"
|
504
|
+
m.alias_type %r(timestamp)i, "datetime"
|
505
|
+
m.alias_type %r(numeric)i, "decimal"
|
506
|
+
m.alias_type %r(number)i, "decimal"
|
507
|
+
m.alias_type %r(double)i, "float"
|
508
|
+
|
509
|
+
m.register_type %r(^json)i, Type::Json.new
|
510
|
+
|
511
|
+
m.register_type(%r(decimal)i) do |sql_type|
|
512
|
+
scale = extract_scale(sql_type)
|
513
|
+
precision = extract_precision(sql_type)
|
514
|
+
|
515
|
+
if scale == 0
|
516
|
+
# FIXME: Remove this class as well
|
517
|
+
Type::DecimalWithoutScale.new(precision: precision)
|
518
|
+
else
|
519
|
+
Type::Decimal.new(precision: precision, scale: scale)
|
520
|
+
end
|
521
|
+
end
|
522
|
+
end
|
266
523
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
524
|
+
def reload_type_map
|
525
|
+
type_map.clear
|
526
|
+
initialize_type_map
|
527
|
+
end
|
528
|
+
|
529
|
+
def register_class_with_limit(mapping, key, klass)
|
530
|
+
mapping.register_type(key) do |*args|
|
531
|
+
limit = extract_limit(args.last)
|
532
|
+
klass.new(limit: limit)
|
533
|
+
end
|
534
|
+
end
|
271
535
|
|
272
|
-
|
536
|
+
def register_class_with_precision(mapping, key, klass)
|
537
|
+
mapping.register_type(key) do |*args|
|
538
|
+
precision = extract_precision(args.last)
|
539
|
+
klass.new(precision: precision)
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
def extract_scale(sql_type)
|
544
|
+
case sql_type
|
545
|
+
when /\((\d+)\)/ then 0
|
546
|
+
when /\((\d+)(,(\d+))\)/ then $3.to_i
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
def extract_precision(sql_type)
|
551
|
+
$1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
|
552
|
+
end
|
553
|
+
|
554
|
+
def extract_limit(sql_type)
|
555
|
+
$1.to_i if sql_type =~ /\((.*)\)/
|
556
|
+
end
|
557
|
+
|
558
|
+
def translate_exception_class(e, sql)
|
559
|
+
begin
|
560
|
+
message = "#{e.class.name}: #{e.message}: #{sql}"
|
561
|
+
rescue Encoding::CompatibilityError
|
562
|
+
message = "#{e.class.name}: #{e.message.force_encoding sql.encoding}: #{sql}"
|
563
|
+
end
|
273
564
|
|
274
|
-
def log(sql, name = "SQL", binds = [])
|
275
|
-
@instrumenter.instrument(
|
276
|
-
"sql.active_record",
|
277
|
-
:sql => sql,
|
278
|
-
:name => name,
|
279
|
-
:connection_id => object_id,
|
280
|
-
:binds => binds) { yield }
|
281
|
-
rescue Exception => e
|
282
|
-
message = "#{e.class.name}: #{e.message}: #{sql}"
|
283
|
-
@logger.debug message if @logger
|
284
565
|
exception = translate_exception(e, message)
|
285
566
|
exception.set_backtrace e.backtrace
|
286
|
-
|
567
|
+
exception
|
568
|
+
end
|
569
|
+
|
570
|
+
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc:
|
571
|
+
@instrumenter.instrument(
|
572
|
+
"sql.active_record",
|
573
|
+
sql: sql,
|
574
|
+
name: name,
|
575
|
+
binds: binds,
|
576
|
+
type_casted_binds: type_casted_binds,
|
577
|
+
statement_name: statement_name,
|
578
|
+
connection_id: object_id) do
|
579
|
+
begin
|
580
|
+
@lock.synchronize do
|
581
|
+
yield
|
582
|
+
end
|
583
|
+
rescue => e
|
584
|
+
raise translate_exception_class(e, sql)
|
585
|
+
end
|
586
|
+
end
|
287
587
|
end
|
288
588
|
|
289
|
-
def translate_exception(
|
589
|
+
def translate_exception(exception, message)
|
290
590
|
# override in derived class
|
291
|
-
|
591
|
+
case exception
|
592
|
+
when RuntimeError
|
593
|
+
exception
|
594
|
+
else
|
595
|
+
ActiveRecord::StatementInvalid.new(message)
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
def without_prepared_statement?(binds)
|
600
|
+
!prepared_statements || binds.empty?
|
601
|
+
end
|
602
|
+
|
603
|
+
def column_for(table_name, column_name)
|
604
|
+
column_name = column_name.to_s
|
605
|
+
columns(table_name).detect { |c| c.name == column_name } ||
|
606
|
+
raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
|
292
607
|
end
|
293
608
|
|
609
|
+
def collector
|
610
|
+
if prepared_statements
|
611
|
+
Arel::Collectors::Composite.new(
|
612
|
+
Arel::Collectors::SQLString.new,
|
613
|
+
Arel::Collectors::Bind.new,
|
614
|
+
)
|
615
|
+
else
|
616
|
+
Arel::Collectors::SubstituteBinds.new(
|
617
|
+
self,
|
618
|
+
Arel::Collectors::SQLString.new,
|
619
|
+
)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
def arel_visitor
|
624
|
+
Arel::Visitors::ToSql.new(self)
|
625
|
+
end
|
294
626
|
end
|
295
627
|
end
|
296
628
|
end
|