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