activerecord 4.2.11.1 → 5.2.4
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 +4 -4
- data/CHANGELOG.md +579 -1635
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -11
- data/examples/performance.rb +32 -31
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +263 -249
- data/lib/active_record/association_relation.rb +11 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +77 -43
- data/lib/active_record/associations/association_scope.rb +106 -133
- data/lib/active_record/associations/belongs_to_association.rb +52 -41
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +29 -38
- data/lib/active_record/associations/builder/belongs_to.rb +77 -30
- data/lib/active_record/associations/builder/collection_association.rb +9 -22
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -35
- data/lib/active_record/associations/builder/has_many.rb +6 -4
- data/lib/active_record/associations/builder/has_one.rb +13 -6
- data/lib/active_record/associations/builder/singular_association.rb +15 -11
- data/lib/active_record/associations/collection_association.rb +139 -280
- data/lib/active_record/associations/collection_proxy.rb +231 -133
- data/lib/active_record/associations/foreign_association.rb +3 -1
- data/lib/active_record/associations/has_many_association.rb +34 -89
- data/lib/active_record/associations/has_many_through_association.rb +49 -76
- data/lib/active_record/associations/has_one_association.rb +38 -24
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +40 -87
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +133 -159
- data/lib/active_record/associations/preloader/association.rb +85 -120
- data/lib/active_record/associations/preloader/through_association.rb +85 -74
- data/lib/active_record/associations/preloader.rb +81 -91
- data/lib/active_record/associations/singular_association.rb +27 -34
- data/lib/active_record/associations/through_association.rb +38 -18
- data/lib/active_record/associations.rb +1732 -1597
- data/lib/active_record/attribute_assignment.rb +58 -182
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +10 -8
- data/lib/active_record/attribute_methods/dirty.rb +94 -135
- data/lib/active_record/attribute_methods/primary_key.rb +86 -71
- data/lib/active_record/attribute_methods/query.rb +4 -2
- data/lib/active_record/attribute_methods/read.rb +45 -63
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
- data/lib/active_record/attribute_methods/write.rb +30 -45
- data/lib/active_record/attribute_methods.rb +166 -109
- data/lib/active_record/attributes.rb +201 -82
- data/lib/active_record/autosave_association.rb +94 -36
- data/lib/active_record/base.rb +57 -44
- data/lib/active_record/callbacks.rb +97 -57
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +24 -12
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +712 -290
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +237 -90
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +71 -21
- data/lib/active_record/connection_adapters/abstract/quoting.rb +118 -52
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +67 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +318 -217
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +81 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +570 -228
- data/lib/active_record/connection_adapters/abstract/transaction.rb +138 -70
- data/lib/active_record/connection_adapters/abstract_adapter.rb +325 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +542 -601
- data/lib/active_record/connection_adapters/column.rb +50 -41
- data/lib/active_record/connection_adapters/connection_specification.rb +147 -135
- 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 +41 -180
- data/lib/active_record/connection_adapters/postgresql/column.rb +35 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +45 -114
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -7
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +55 -53
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +107 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +144 -90
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -284
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +432 -323
- data/lib/active_record/connection_adapters/schema_cache.rb +48 -24
- 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 +269 -308
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +40 -27
- data/lib/active_record/core.rb +178 -198
- data/lib/active_record/counter_cache.rb +79 -36
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +135 -88
- data/lib/active_record/errors.rb +179 -52
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixtures.rb +188 -132
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +148 -112
- data/lib/active_record/integration.rb +70 -28
- data/lib/active_record/internal_metadata.rb +45 -0
- data/lib/active_record/legacy_yaml_adapter.rb +21 -3
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +88 -96
- data/lib/active_record/locking/pessimistic.rb +15 -3
- data/lib/active_record/log_subscriber.rb +95 -33
- data/lib/active_record/migration/command_recorder.rb +133 -90
- data/lib/active_record/migration/compatibility.rb +217 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +581 -282
- data/lib/active_record/model_schema.rb +290 -111
- data/lib/active_record/nested_attributes.rb +264 -222
- data/lib/active_record/no_touching.rb +7 -1
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +347 -119
- data/lib/active_record/query_cache.rb +13 -24
- data/lib/active_record/querying.rb +19 -17
- data/lib/active_record/railtie.rb +94 -32
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +9 -3
- data/lib/active_record/railties/databases.rake +149 -156
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +414 -267
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +204 -55
- data/lib/active_record/relation/calculations.rb +256 -248
- data/lib/active_record/relation/delegation.rb +67 -60
- data/lib/active_record/relation/finder_methods.rb +288 -239
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +86 -86
- data/lib/active_record/relation/predicate_builder/array_handler.rb +24 -24
- 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 +7 -1
- data/lib/active_record/relation/predicate_builder.rb +116 -119
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +448 -393
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +11 -13
- 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 +287 -340
- data/lib/active_record/result.rb +54 -36
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +155 -124
- data/lib/active_record/schema.rb +30 -24
- data/lib/active_record/schema_dumper.rb +91 -87
- data/lib/active_record/schema_migration.rb +19 -16
- data/lib/active_record/scoping/default.rb +102 -85
- data/lib/active_record/scoping/named.rb +81 -32
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +45 -35
- data/lib/active_record/store.rb +42 -36
- 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 +134 -96
- data/lib/active_record/tasks/mysql_database_tasks.rb +56 -100
- data/lib/active_record/tasks/postgresql_database_tasks.rb +83 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -16
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +64 -0
- data/lib/active_record/transactions.rb +199 -124
- 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 +4 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- 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 +24 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type.rb +79 -23
- 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 +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +40 -41
- data/lib/active_record/validations.rb +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +34 -22
- 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 +43 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +8 -3
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +8 -1
- data/lib/rails/generators/active_record/migration.rb +18 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +3 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +72 -49
- 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_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- 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.rb +0 -163
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -64
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
@@ -1,14 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
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"
|
12
13
|
|
13
14
|
module ActiveRecord
|
14
15
|
module ConnectionAdapters # :nodoc:
|
@@ -17,22 +18,22 @@ module ActiveRecord
|
|
17
18
|
autoload :Column
|
18
19
|
autoload :ConnectionSpecification
|
19
20
|
|
20
|
-
autoload_at
|
21
|
+
autoload_at "active_record/connection_adapters/abstract/schema_definitions" do
|
21
22
|
autoload :IndexDefinition
|
22
23
|
autoload :ColumnDefinition
|
23
24
|
autoload :ChangeColumnDefinition
|
25
|
+
autoload :ForeignKeyDefinition
|
24
26
|
autoload :TableDefinition
|
25
27
|
autoload :Table
|
26
28
|
autoload :AlterTable
|
27
|
-
autoload :
|
29
|
+
autoload :ReferenceDefinition
|
28
30
|
end
|
29
31
|
|
30
|
-
autoload_at
|
32
|
+
autoload_at "active_record/connection_adapters/abstract/connection_pool" do
|
31
33
|
autoload :ConnectionHandler
|
32
|
-
autoload :ConnectionManagement
|
33
34
|
end
|
34
35
|
|
35
|
-
autoload_under
|
36
|
+
autoload_under "abstract" do
|
36
37
|
autoload :SchemaStatements
|
37
38
|
autoload :DatabaseStatements
|
38
39
|
autoload :DatabaseLimits
|
@@ -42,7 +43,7 @@ module ActiveRecord
|
|
42
43
|
autoload :Savepoints
|
43
44
|
end
|
44
45
|
|
45
|
-
autoload_at
|
46
|
+
autoload_at "active_record/connection_adapters/abstract/transaction" do
|
46
47
|
autoload :TransactionManager
|
47
48
|
autoload :NullTransaction
|
48
49
|
autoload :RealTransaction
|
@@ -54,34 +55,35 @@ module ActiveRecord
|
|
54
55
|
# related classes form the abstraction layer which makes this possible.
|
55
56
|
# An AbstractAdapter represents a connection to a database, and provides an
|
56
57
|
# abstract interface for database-specific functionality such as establishing
|
57
|
-
# a connection, escaping values, building the right SQL fragments for
|
58
|
-
# and
|
58
|
+
# a connection, escaping values, building the right SQL fragments for +:offset+
|
59
|
+
# and +:limit+ options, etc.
|
59
60
|
#
|
60
61
|
# All the concrete database adapters follow the interface laid down in this class.
|
61
|
-
# ActiveRecord::Base.connection returns an AbstractAdapter object, which
|
62
|
+
# {ActiveRecord::Base.connection}[rdoc-ref:ConnectionHandling#connection] returns an AbstractAdapter object, which
|
62
63
|
# you can use.
|
63
64
|
#
|
64
65
|
# Most of the methods in the adapter are useful during migrations. Most
|
65
|
-
# notably, the instance methods provided by
|
66
|
+
# notably, the instance methods provided by SchemaStatements are very useful.
|
66
67
|
class AbstractAdapter
|
67
|
-
ADAPTER_NAME =
|
68
|
+
ADAPTER_NAME = "Abstract".freeze
|
69
|
+
include ActiveSupport::Callbacks
|
70
|
+
define_callbacks :checkout, :checkin
|
71
|
+
|
68
72
|
include Quoting, DatabaseStatements, SchemaStatements
|
69
73
|
include DatabaseLimits
|
70
74
|
include QueryCache
|
71
|
-
include
|
72
|
-
include MonitorMixin
|
73
|
-
include ColumnDumper
|
75
|
+
include Savepoints
|
74
76
|
|
75
77
|
SIMPLE_INT = /\A\d+\z/
|
76
78
|
|
77
|
-
define_callbacks :checkout, :checkin
|
78
|
-
|
79
79
|
attr_accessor :visitor, :pool
|
80
|
-
attr_reader :schema_cache, :owner, :logger
|
80
|
+
attr_reader :schema_cache, :owner, :logger, :prepared_statements, :lock
|
81
81
|
alias :in_use? :owner
|
82
82
|
|
83
83
|
def self.type_cast_config_to_integer(config)
|
84
|
-
if config
|
84
|
+
if config.is_a?(Integer)
|
85
|
+
config
|
86
|
+
elsif config =~ SIMPLE_INT
|
85
87
|
config.to_i
|
86
88
|
else
|
87
89
|
config
|
@@ -96,76 +98,107 @@ module ActiveRecord
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
99
|
-
|
100
|
-
|
101
|
-
def initialize(connection, logger = nil, pool = nil) #:nodoc:
|
101
|
+
def initialize(connection, logger = nil, config = {}) # :nodoc:
|
102
102
|
super()
|
103
103
|
|
104
104
|
@connection = connection
|
105
105
|
@owner = nil
|
106
106
|
@instrumenter = ActiveSupport::Notifications.instrumenter
|
107
107
|
@logger = logger
|
108
|
-
@
|
108
|
+
@config = config
|
109
|
+
@pool = nil
|
110
|
+
@idle_since = Concurrent.monotonic_time
|
109
111
|
@schema_cache = SchemaCache.new self
|
110
|
-
@
|
111
|
-
@
|
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)
|
112
130
|
end
|
113
131
|
|
114
132
|
class Version
|
115
133
|
include Comparable
|
116
134
|
|
117
135
|
def initialize(version_string)
|
118
|
-
@version = version_string.split(
|
136
|
+
@version = version_string.split(".").map(&:to_i)
|
119
137
|
end
|
120
138
|
|
121
139
|
def <=>(version_string)
|
122
|
-
@version <=> version_string.split(
|
140
|
+
@version <=> version_string.split(".").map(&:to_i)
|
123
141
|
end
|
124
142
|
end
|
125
143
|
|
126
|
-
|
127
|
-
|
128
|
-
super(bvs.map { |bv| conn.quote(*bv.reverse) })
|
129
|
-
end
|
144
|
+
def valid_type?(type) # :nodoc:
|
145
|
+
!native_database_types[type].nil?
|
130
146
|
end
|
131
147
|
|
132
|
-
|
133
|
-
|
134
|
-
|
148
|
+
# this method must only be called while holding connection pool's mutex
|
149
|
+
def lease
|
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}."
|
157
|
+
end
|
158
|
+
raise ActiveRecordError, msg
|
135
159
|
end
|
136
|
-
end
|
137
160
|
|
138
|
-
|
139
|
-
if prepared_statements
|
140
|
-
SQLString.new
|
141
|
-
else
|
142
|
-
BindCollector.new
|
143
|
-
end
|
161
|
+
@owner = Thread.current
|
144
162
|
end
|
145
163
|
|
146
|
-
def
|
147
|
-
|
164
|
+
def schema_cache=(cache)
|
165
|
+
cache.connection = self
|
166
|
+
@schema_cache = cache
|
148
167
|
end
|
149
168
|
|
150
|
-
|
151
|
-
|
169
|
+
# this method must only be called while holding connection pool's mutex
|
170
|
+
def expire
|
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
|
152
183
|
end
|
153
184
|
|
154
|
-
|
155
|
-
|
156
|
-
|
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
|
+
|
157
191
|
@owner = Thread.current
|
158
192
|
end
|
193
|
+
else
|
194
|
+
raise ActiveRecordError, "Cannot steal connection, it is not currently leased."
|
159
195
|
end
|
160
196
|
end
|
161
197
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
def expire
|
168
|
-
@owner = nil
|
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
|
169
202
|
end
|
170
203
|
|
171
204
|
def unprepared_statement
|
@@ -181,17 +214,6 @@ module ActiveRecord
|
|
181
214
|
self.class::ADAPTER_NAME
|
182
215
|
end
|
183
216
|
|
184
|
-
# Does this adapter support migrations?
|
185
|
-
def supports_migrations?
|
186
|
-
false
|
187
|
-
end
|
188
|
-
|
189
|
-
# Can this adapter determine the primary key for tables not attached
|
190
|
-
# to an Active Record class, such as join tables?
|
191
|
-
def supports_primary_key?
|
192
|
-
false
|
193
|
-
end
|
194
|
-
|
195
217
|
# Does this adapter support DDL rollbacks in transactions? That is, would
|
196
218
|
# CREATE TABLE or ALTER TABLE get rolled back by a transaction?
|
197
219
|
def supports_ddl_transactions?
|
@@ -207,6 +229,11 @@ module ActiveRecord
|
|
207
229
|
false
|
208
230
|
end
|
209
231
|
|
232
|
+
# Does this adapter support application-enforced advisory locking?
|
233
|
+
def supports_advisory_locks?
|
234
|
+
false
|
235
|
+
end
|
236
|
+
|
210
237
|
# Should primary key values be selected from their corresponding
|
211
238
|
# sequence before the insert statement? If true, next_sequence_value
|
212
239
|
# is called before each insert to set the record's primary key.
|
@@ -224,6 +251,11 @@ module ActiveRecord
|
|
224
251
|
false
|
225
252
|
end
|
226
253
|
|
254
|
+
# Does this adapter support expression indices?
|
255
|
+
def supports_expression_index?
|
256
|
+
false
|
257
|
+
end
|
258
|
+
|
227
259
|
# Does this adapter support explain?
|
228
260
|
def supports_explain?
|
229
261
|
false
|
@@ -250,11 +282,57 @@ module ActiveRecord
|
|
250
282
|
false
|
251
283
|
end
|
252
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
|
+
|
253
296
|
# Does this adapter support views?
|
254
297
|
def supports_views?
|
255
298
|
false
|
256
299
|
end
|
257
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
|
+
|
258
336
|
# This is meant to be implemented by the adapters that support extensions
|
259
337
|
def disable_extension(name)
|
260
338
|
end
|
@@ -263,6 +341,20 @@ module ActiveRecord
|
|
263
341
|
def enable_extension(name)
|
264
342
|
end
|
265
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
|
+
|
266
358
|
# A list of extensions, to be filled in by adapters that support them.
|
267
359
|
def extensions
|
268
360
|
[]
|
@@ -273,14 +365,6 @@ module ActiveRecord
|
|
273
365
|
{}
|
274
366
|
end
|
275
367
|
|
276
|
-
# QUOTING ==================================================
|
277
|
-
|
278
|
-
# Returns a bind substitution value given a bind +column+
|
279
|
-
# NOTE: The column param is currently being used by the sqlserver-adapter
|
280
|
-
def substitute_at(column, _unused = 0)
|
281
|
-
Arel::Nodes::BindParam.new
|
282
|
-
end
|
283
|
-
|
284
368
|
# REFERENTIAL INTEGRITY ====================================
|
285
369
|
|
286
370
|
# Override to turn off referential integrity while executing <tt>&block</tt>.
|
@@ -311,6 +395,19 @@ module ActiveRecord
|
|
311
395
|
reset_transaction
|
312
396
|
end
|
313
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.
|
409
|
+
end
|
410
|
+
|
314
411
|
# Reset the state of this connection, directing the DBMS to clear
|
315
412
|
# transactions and other connection-related server-side state. Usually a
|
316
413
|
# database-dependent operation.
|
@@ -334,15 +431,15 @@ module ActiveRecord
|
|
334
431
|
end
|
335
432
|
|
336
433
|
# Checks whether the connection to the database is still active (i.e. not stale).
|
337
|
-
# This is done under the hood by calling
|
434
|
+
# This is done under the hood by calling #active?. If the connection
|
338
435
|
# is no longer active, then this method will reconnect to the database.
|
339
|
-
def verify!
|
436
|
+
def verify!
|
340
437
|
reconnect! unless active?
|
341
438
|
end
|
342
439
|
|
343
440
|
# Provides access to the underlying database driver for this adapter. For
|
344
|
-
# example, this method returns a
|
345
|
-
# 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.
|
346
443
|
#
|
347
444
|
# This is useful for when you need to call a proprietary method such as
|
348
445
|
# PostgreSQL's lo_* methods.
|
@@ -350,156 +447,182 @@ module ActiveRecord
|
|
350
447
|
@connection
|
351
448
|
end
|
352
449
|
|
353
|
-
def
|
354
|
-
|
355
|
-
|
356
|
-
def release_savepoint(name = nil)
|
357
|
-
end
|
358
|
-
|
359
|
-
def case_sensitive_modifier(node, table_attribute)
|
360
|
-
node
|
361
|
-
end
|
362
|
-
|
363
|
-
def case_sensitive_comparison(table, attribute, column, value)
|
364
|
-
table_attr = table[attribute]
|
365
|
-
value = case_sensitive_modifier(value, table_attr) unless value.nil?
|
366
|
-
table_attr.eq(value)
|
450
|
+
def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
|
451
|
+
table[attribute].eq(value)
|
367
452
|
end
|
368
453
|
|
369
|
-
def case_insensitive_comparison(table, attribute, column, value)
|
370
|
-
|
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
|
371
460
|
end
|
372
461
|
|
373
|
-
def
|
374
|
-
|
462
|
+
def can_perform_case_insensitive_comparison_for?(column)
|
463
|
+
true
|
375
464
|
end
|
465
|
+
private :can_perform_case_insensitive_comparison_for?
|
376
466
|
|
377
467
|
# Check the connection back in to the connection pool
|
378
468
|
def close
|
379
469
|
pool.checkin self
|
380
470
|
end
|
381
471
|
|
382
|
-
def
|
383
|
-
|
384
|
-
initialize_type_map(mapping)
|
385
|
-
end
|
472
|
+
def column_name_for_operation(operation, node) # :nodoc:
|
473
|
+
column_name_from_arel_node(node)
|
386
474
|
end
|
387
475
|
|
388
|
-
def
|
389
|
-
|
476
|
+
def column_name_from_arel_node(node) # :nodoc:
|
477
|
+
visitor.accept(node, Arel::Collectors::SQLString.new).value
|
390
478
|
end
|
391
479
|
|
392
|
-
def
|
393
|
-
|
480
|
+
def default_index_type?(index) # :nodoc:
|
481
|
+
index.using.nil?
|
394
482
|
end
|
395
483
|
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
protected
|
401
|
-
|
402
|
-
def initialize_type_map(m) # :nodoc:
|
403
|
-
register_class_with_limit m, %r(boolean)i, Type::Boolean
|
404
|
-
register_class_with_limit m, %r(char)i, Type::String
|
405
|
-
register_class_with_limit m, %r(binary)i, Type::Binary
|
406
|
-
register_class_with_limit m, %r(text)i, Type::Text
|
407
|
-
register_class_with_limit m, %r(date)i, Type::Date
|
408
|
-
register_class_with_limit m, %r(time)i, Type::Time
|
409
|
-
register_class_with_limit m, %r(datetime)i, Type::DateTime
|
410
|
-
register_class_with_limit m, %r(float)i, Type::Float
|
411
|
-
register_class_with_limit m, %r(int)i, Type::Integer
|
412
|
-
|
413
|
-
m.alias_type %r(blob)i, 'binary'
|
414
|
-
m.alias_type %r(clob)i, 'text'
|
415
|
-
m.alias_type %r(timestamp)i, 'datetime'
|
416
|
-
m.alias_type %r(numeric)i, 'decimal'
|
417
|
-
m.alias_type %r(number)i, 'decimal'
|
418
|
-
m.alias_type %r(double)i, 'float'
|
419
|
-
|
420
|
-
m.register_type(%r(decimal)i) do |sql_type|
|
421
|
-
scale = extract_scale(sql_type)
|
422
|
-
precision = extract_precision(sql_type)
|
423
|
-
|
424
|
-
if scale == 0
|
425
|
-
# FIXME: Remove this class as well
|
426
|
-
Type::DecimalWithoutScale.new(precision: precision)
|
427
|
-
else
|
428
|
-
Type::Decimal.new(precision: precision, scale: scale)
|
484
|
+
private
|
485
|
+
def type_map
|
486
|
+
@type_map ||= Type::TypeMap.new.tap do |mapping|
|
487
|
+
initialize_type_map(mapping)
|
429
488
|
end
|
430
489
|
end
|
431
|
-
end
|
432
490
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
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
|
437
523
|
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
klass.new(limit: limit)
|
524
|
+
def reload_type_map
|
525
|
+
type_map.clear
|
526
|
+
initialize_type_map
|
442
527
|
end
|
443
|
-
end
|
444
528
|
|
445
|
-
|
446
|
-
|
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
|
535
|
+
|
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
|
447
545
|
when /\((\d+)\)/ then 0
|
448
546
|
when /\((\d+)(,(\d+))\)/ then $3.to_i
|
547
|
+
end
|
449
548
|
end
|
450
|
-
end
|
451
549
|
|
452
|
-
|
453
|
-
|
454
|
-
|
550
|
+
def extract_precision(sql_type)
|
551
|
+
$1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
|
552
|
+
end
|
455
553
|
|
456
|
-
|
457
|
-
|
458
|
-
when /^bigint/i
|
459
|
-
8
|
460
|
-
when /\((.*)\)/
|
461
|
-
$1.to_i
|
554
|
+
def extract_limit(sql_type)
|
555
|
+
$1.to_i if sql_type =~ /\((.*)\)/
|
462
556
|
end
|
463
|
-
end
|
464
557
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
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
|
564
|
+
|
565
|
+
exception = translate_exception(e, message)
|
566
|
+
exception.set_backtrace e.backtrace
|
567
|
+
exception
|
470
568
|
end
|
471
569
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
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
|
587
|
+
end
|
476
588
|
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
raise translate_exception_class(e, sql)
|
487
|
-
end
|
589
|
+
def translate_exception(exception, message)
|
590
|
+
# override in derived class
|
591
|
+
case exception
|
592
|
+
when RuntimeError
|
593
|
+
exception
|
594
|
+
else
|
595
|
+
ActiveRecord::StatementInvalid.new(message)
|
596
|
+
end
|
597
|
+
end
|
488
598
|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
end
|
599
|
+
def without_prepared_statement?(binds)
|
600
|
+
!prepared_statements || binds.empty?
|
601
|
+
end
|
493
602
|
|
494
|
-
|
495
|
-
|
496
|
-
|
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}")
|
607
|
+
end
|
497
608
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
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
|
503
626
|
end
|
504
627
|
end
|
505
628
|
end
|