activerecord 4.2.0 → 5.2.8.1
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 +640 -928
- 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 +264 -247
- data/lib/active_record/association_relation.rb +24 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +87 -41
- data/lib/active_record/associations/association_scope.rb +106 -132
- data/lib/active_record/associations/belongs_to_association.rb +55 -36
- 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 +14 -23
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -39
- 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 +145 -266
- data/lib/active_record/associations/collection_proxy.rb +242 -138
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +35 -75
- data/lib/active_record/associations/has_many_through_association.rb +51 -69
- data/lib/active_record/associations/has_one_association.rb +39 -24
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +40 -81
- 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 +134 -154
- data/lib/active_record/associations/preloader/association.rb +85 -116
- data/lib/active_record/associations/preloader/through_association.rb +85 -74
- data/lib/active_record/associations/preloader.rb +83 -93
- data/lib/active_record/associations/singular_association.rb +27 -40
- data/lib/active_record/associations/through_association.rb +48 -23
- data/lib/active_record/associations.rb +1732 -1596
- 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 +12 -5
- data/lib/active_record/attribute_methods/dirty.rb +94 -125
- 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 +62 -36
- data/lib/active_record/attribute_methods/write.rb +31 -46
- data/lib/active_record/attribute_methods.rb +170 -117
- data/lib/active_record/attributes.rb +201 -74
- data/lib/active_record/autosave_association.rb +118 -45
- data/lib/active_record/base.rb +60 -48
- 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 +37 -13
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +712 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +254 -87
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +72 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -52
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +67 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -217
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +81 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +617 -212
- data/lib/active_record/connection_adapters/abstract/transaction.rb +139 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +332 -191
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +567 -563
- 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 +42 -195
- data/lib/active_record/connection_adapters/postgresql/column.rb +35 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -115
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
- 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 +5 -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 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -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 +7 -9
- 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 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +65 -51
- 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 +466 -280
- 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 +439 -330
- 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 -324
- 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 +205 -202
- data/lib/active_record/counter_cache.rb +80 -37
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +136 -90
- data/lib/active_record/errors.rb +180 -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 +11 -6
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixtures.rb +193 -135
- 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 +48 -0
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +92 -98
- 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 +594 -267
- data/lib/active_record/model_schema.rb +292 -111
- data/lib/active_record/nested_attributes.rb +266 -214
- data/lib/active_record/no_touching.rb +8 -2
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +350 -119
- data/lib/active_record/query_cache.rb +13 -24
- data/lib/active_record/querying.rb +19 -17
- data/lib/active_record/railtie.rb +117 -35
- 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 +160 -174
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +447 -288
- 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 +259 -244
- data/lib/active_record/relation/delegation.rb +67 -60
- data/lib/active_record/relation/finder_methods.rb +290 -253
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +91 -68
- data/lib/active_record/relation/predicate_builder/array_handler.rb +24 -23
- 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 +118 -92
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +446 -389
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -16
- 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 -339
- 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 -19
- data/lib/active_record/scoping/default.rb +102 -84
- 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 +136 -95
- data/lib/active_record/tasks/mysql_database_tasks.rb +59 -89
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -31
- 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 +208 -123
- 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 -41
- data/lib/active_record/type/date_time.rb +4 -38
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
- 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 +30 -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 +41 -32
- data/lib/active_record/validations.rb +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -21
- 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 -6
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +8 -7
- 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.rb +7 -5
- metadata +77 -53
- 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 -149
- data/lib/active_record/attribute_set/builder.rb +0 -86
- data/lib/active_record/attribute_set.rb +0 -77
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- 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 -30
- data/lib/active_record/type/decimal.rb +0 -40
- 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 -55
- 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 -36
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -101
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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,55 +98,67 @@ 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
|
-
|
112
|
+
@quoted_column_names, @quoted_table_names = {}, {}
|
113
|
+
@visitor = arel_visitor
|
114
|
+
@lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
113
115
|
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
117
121
|
end
|
118
122
|
end
|
119
123
|
|
120
|
-
|
121
|
-
|
122
|
-
super(bvs)
|
123
|
-
end
|
124
|
+
def migrations_paths # :nodoc:
|
125
|
+
@config[:migrations_paths] || Migrator.migrations_paths
|
124
126
|
end
|
125
127
|
|
126
|
-
def
|
127
|
-
|
128
|
-
SQLString.new
|
129
|
-
else
|
130
|
-
BindCollector.new
|
131
|
-
end
|
128
|
+
def migration_context # :nodoc:
|
129
|
+
MigrationContext.new(migrations_paths)
|
132
130
|
end
|
133
131
|
|
134
|
-
|
135
|
-
|
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
|
136
142
|
end
|
137
143
|
|
138
|
-
def
|
139
|
-
|
144
|
+
def valid_type?(type) # :nodoc:
|
145
|
+
!native_database_types[type].nil?
|
140
146
|
end
|
141
147
|
|
148
|
+
# this method must only be called while holding connection pool's mutex
|
142
149
|
def lease
|
143
|
-
|
144
|
-
|
145
|
-
|
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}."
|
146
157
|
end
|
158
|
+
raise ActiveRecordError, msg
|
147
159
|
end
|
160
|
+
|
161
|
+
@owner = Thread.current
|
148
162
|
end
|
149
163
|
|
150
164
|
def schema_cache=(cache)
|
@@ -152,8 +166,39 @@ module ActiveRecord
|
|
152
166
|
@schema_cache = cache
|
153
167
|
end
|
154
168
|
|
169
|
+
# this method must only be called while holding connection pool's mutex
|
155
170
|
def expire
|
156
|
-
|
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
|
183
|
+
end
|
184
|
+
|
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
|
196
|
+
end
|
197
|
+
|
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
|
157
202
|
end
|
158
203
|
|
159
204
|
def unprepared_statement
|
@@ -169,17 +214,6 @@ module ActiveRecord
|
|
169
214
|
self.class::ADAPTER_NAME
|
170
215
|
end
|
171
216
|
|
172
|
-
# Does this adapter support migrations?
|
173
|
-
def supports_migrations?
|
174
|
-
false
|
175
|
-
end
|
176
|
-
|
177
|
-
# Can this adapter determine the primary key for tables not attached
|
178
|
-
# to an Active Record class, such as join tables?
|
179
|
-
def supports_primary_key?
|
180
|
-
false
|
181
|
-
end
|
182
|
-
|
183
217
|
# Does this adapter support DDL rollbacks in transactions? That is, would
|
184
218
|
# CREATE TABLE or ALTER TABLE get rolled back by a transaction?
|
185
219
|
def supports_ddl_transactions?
|
@@ -195,6 +229,11 @@ module ActiveRecord
|
|
195
229
|
false
|
196
230
|
end
|
197
231
|
|
232
|
+
# Does this adapter support application-enforced advisory locking?
|
233
|
+
def supports_advisory_locks?
|
234
|
+
false
|
235
|
+
end
|
236
|
+
|
198
237
|
# Should primary key values be selected from their corresponding
|
199
238
|
# sequence before the insert statement? If true, next_sequence_value
|
200
239
|
# is called before each insert to set the record's primary key.
|
@@ -212,6 +251,11 @@ module ActiveRecord
|
|
212
251
|
false
|
213
252
|
end
|
214
253
|
|
254
|
+
# Does this adapter support expression indices?
|
255
|
+
def supports_expression_index?
|
256
|
+
false
|
257
|
+
end
|
258
|
+
|
215
259
|
# Does this adapter support explain?
|
216
260
|
def supports_explain?
|
217
261
|
false
|
@@ -238,11 +282,57 @@ module ActiveRecord
|
|
238
282
|
false
|
239
283
|
end
|
240
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
|
+
|
241
296
|
# Does this adapter support views?
|
242
297
|
def supports_views?
|
243
298
|
false
|
244
299
|
end
|
245
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
|
+
|
246
336
|
# This is meant to be implemented by the adapters that support extensions
|
247
337
|
def disable_extension(name)
|
248
338
|
end
|
@@ -251,6 +341,20 @@ module ActiveRecord
|
|
251
341
|
def enable_extension(name)
|
252
342
|
end
|
253
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
|
+
|
254
358
|
# A list of extensions, to be filled in by adapters that support them.
|
255
359
|
def extensions
|
256
360
|
[]
|
@@ -261,14 +365,6 @@ module ActiveRecord
|
|
261
365
|
{}
|
262
366
|
end
|
263
367
|
|
264
|
-
# QUOTING ==================================================
|
265
|
-
|
266
|
-
# Returns a bind substitution value given a bind +column+
|
267
|
-
# NOTE: The column param is currently being used by the sqlserver-adapter
|
268
|
-
def substitute_at(column, _unused = 0)
|
269
|
-
Arel::Nodes::BindParam.new
|
270
|
-
end
|
271
|
-
|
272
368
|
# REFERENTIAL INTEGRITY ====================================
|
273
369
|
|
274
370
|
# Override to turn off referential integrity while executing <tt>&block</tt>.
|
@@ -299,6 +395,19 @@ module ActiveRecord
|
|
299
395
|
reset_transaction
|
300
396
|
end
|
301
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
|
+
|
302
411
|
# Reset the state of this connection, directing the DBMS to clear
|
303
412
|
# transactions and other connection-related server-side state. Usually a
|
304
413
|
# database-dependent operation.
|
@@ -322,15 +431,15 @@ module ActiveRecord
|
|
322
431
|
end
|
323
432
|
|
324
433
|
# Checks whether the connection to the database is still active (i.e. not stale).
|
325
|
-
# This is done under the hood by calling
|
434
|
+
# This is done under the hood by calling #active?. If the connection
|
326
435
|
# is no longer active, then this method will reconnect to the database.
|
327
|
-
def verify!
|
436
|
+
def verify!
|
328
437
|
reconnect! unless active?
|
329
438
|
end
|
330
439
|
|
331
440
|
# Provides access to the underlying database driver for this adapter. For
|
332
|
-
# example, this method returns a
|
333
|
-
# 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.
|
334
443
|
#
|
335
444
|
# This is useful for when you need to call a proprietary method such as
|
336
445
|
# PostgreSQL's lo_* methods.
|
@@ -338,150 +447,182 @@ module ActiveRecord
|
|
338
447
|
@connection
|
339
448
|
end
|
340
449
|
|
341
|
-
def
|
342
|
-
|
343
|
-
|
344
|
-
def rollback_to_savepoint(name = nil)
|
450
|
+
def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
|
451
|
+
table[attribute].eq(value)
|
345
452
|
end
|
346
453
|
|
347
|
-
def
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
def case_sensitive_comparison(table, attribute, column, value)
|
355
|
-
table_attr = table[attribute]
|
356
|
-
value = case_sensitive_modifier(value, table_attr) unless value.nil?
|
357
|
-
table_attr.eq(value)
|
358
|
-
end
|
359
|
-
|
360
|
-
def case_insensitive_comparison(table, attribute, column, value)
|
361
|
-
table[attribute].lower.eq(table.lower(value))
|
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
|
362
460
|
end
|
363
461
|
|
364
|
-
def
|
365
|
-
|
462
|
+
def can_perform_case_insensitive_comparison_for?(column)
|
463
|
+
true
|
366
464
|
end
|
465
|
+
private :can_perform_case_insensitive_comparison_for?
|
367
466
|
|
368
467
|
# Check the connection back in to the connection pool
|
369
468
|
def close
|
370
469
|
pool.checkin self
|
371
470
|
end
|
372
471
|
|
373
|
-
def
|
374
|
-
|
375
|
-
initialize_type_map(mapping)
|
376
|
-
end
|
472
|
+
def column_name_for_operation(operation, node) # :nodoc:
|
473
|
+
column_name_from_arel_node(node)
|
377
474
|
end
|
378
475
|
|
379
|
-
def
|
380
|
-
|
476
|
+
def column_name_from_arel_node(node) # :nodoc:
|
477
|
+
visitor.accept(node, Arel::Collectors::SQLString.new).value
|
381
478
|
end
|
382
479
|
|
383
|
-
def
|
384
|
-
|
480
|
+
def default_index_type?(index) # :nodoc:
|
481
|
+
index.using.nil?
|
385
482
|
end
|
386
483
|
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
protected
|
392
|
-
|
393
|
-
def initialize_type_map(m) # :nodoc:
|
394
|
-
register_class_with_limit m, %r(boolean)i, Type::Boolean
|
395
|
-
register_class_with_limit m, %r(char)i, Type::String
|
396
|
-
register_class_with_limit m, %r(binary)i, Type::Binary
|
397
|
-
register_class_with_limit m, %r(text)i, Type::Text
|
398
|
-
register_class_with_limit m, %r(date)i, Type::Date
|
399
|
-
register_class_with_limit m, %r(time)i, Type::Time
|
400
|
-
register_class_with_limit m, %r(datetime)i, Type::DateTime
|
401
|
-
register_class_with_limit m, %r(float)i, Type::Float
|
402
|
-
register_class_with_limit m, %r(int)i, Type::Integer
|
403
|
-
|
404
|
-
m.alias_type %r(blob)i, 'binary'
|
405
|
-
m.alias_type %r(clob)i, 'text'
|
406
|
-
m.alias_type %r(timestamp)i, 'datetime'
|
407
|
-
m.alias_type %r(numeric)i, 'decimal'
|
408
|
-
m.alias_type %r(number)i, 'decimal'
|
409
|
-
m.alias_type %r(double)i, 'float'
|
410
|
-
|
411
|
-
m.register_type(%r(decimal)i) do |sql_type|
|
412
|
-
scale = extract_scale(sql_type)
|
413
|
-
precision = extract_precision(sql_type)
|
414
|
-
|
415
|
-
if scale == 0
|
416
|
-
# FIXME: Remove this class as well
|
417
|
-
Type::DecimalWithoutScale.new(precision: precision)
|
418
|
-
else
|
419
|
-
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)
|
420
488
|
end
|
421
489
|
end
|
422
|
-
end
|
423
490
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
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
|
428
523
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
klass.new(limit: limit)
|
524
|
+
def reload_type_map
|
525
|
+
type_map.clear
|
526
|
+
initialize_type_map
|
433
527
|
end
|
434
|
-
end
|
435
528
|
|
436
|
-
|
437
|
-
|
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
|
438
545
|
when /\((\d+)\)/ then 0
|
439
546
|
when /\((\d+)(,(\d+))\)/ then $3.to_i
|
547
|
+
end
|
440
548
|
end
|
441
|
-
end
|
442
549
|
|
443
|
-
|
444
|
-
|
445
|
-
|
550
|
+
def extract_precision(sql_type)
|
551
|
+
$1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
|
552
|
+
end
|
446
553
|
|
447
|
-
|
448
|
-
|
449
|
-
|
554
|
+
def extract_limit(sql_type)
|
555
|
+
$1.to_i if sql_type =~ /\((.*)\)/
|
556
|
+
end
|
450
557
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
end
|
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
|
458
564
|
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
:name => name,
|
464
|
-
:connection_id => object_id,
|
465
|
-
:statement_name => statement_name,
|
466
|
-
:binds => binds) { yield }
|
467
|
-
rescue => e
|
468
|
-
raise translate_exception_class(e, sql)
|
469
|
-
end
|
565
|
+
exception = translate_exception(e, message)
|
566
|
+
exception.set_backtrace e.backtrace
|
567
|
+
exception
|
568
|
+
end
|
470
569
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
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
|
475
588
|
|
476
|
-
|
477
|
-
|
478
|
-
|
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
|
479
598
|
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
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}")
|
607
|
+
end
|
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
|
485
626
|
end
|
486
627
|
end
|
487
628
|
end
|