activerecord 5.2.8.1 → 6.0.6
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 +919 -573
- data/MIT-LICENSE +3 -1
- data/README.rdoc +5 -3
- data/examples/performance.rb +1 -1
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +4 -3
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +55 -19
- data/lib/active_record/associations/association_scope.rb +11 -7
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +19 -23
- data/lib/active_record/associations/collection_proxy.rb +14 -17
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -11
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +16 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +4 -4
- data/lib/active_record/associations/join_dependency.rb +47 -30
- data/lib/active_record/associations/preloader/association.rb +61 -41
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/preloader.rb +44 -33
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +21 -16
- data/lib/active_record/attribute_assignment.rb +7 -11
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -24
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -54
- data/lib/active_record/attribute_methods/serialization.rb +1 -2
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
- data/lib/active_record/attribute_methods/write.rb +17 -25
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attributes.rb +13 -1
- data/lib/active_record/autosave_association.rb +12 -14
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +6 -21
- data/lib/active_record/coders/yaml_column.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -18
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +105 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
- data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -217
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +137 -147
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +139 -26
- data/lib/active_record/core.rb +108 -67
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +78 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +44 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +144 -474
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +13 -6
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +11 -3
- data/lib/active_record/locking/optimistic.rb +14 -7
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +8 -27
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/migration/command_recorder.rb +54 -22
- data/lib/active_record/migration/compatibility.rb +79 -52
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +104 -85
- data/lib/active_record/model_schema.rb +62 -11
- data/lib/active_record/nested_attributes.rb +2 -4
- data/lib/active_record/no_touching.rb +9 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +232 -29
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +33 -21
- data/lib/active_record/railtie.rb +80 -61
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +199 -46
- data/lib/active_record/reflection.rb +51 -51
- data/lib/active_record/relation/batches.rb +13 -11
- data/lib/active_record/relation/calculations.rb +55 -49
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +23 -28
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +12 -17
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder.rb +5 -11
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +232 -69
- data/lib/active_record/relation/spawn_methods.rb +1 -2
- data/lib/active_record/relation/where_clause.rb +14 -11
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/relation.rb +326 -81
- data/lib/active_record/result.rb +30 -12
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +6 -2
- data/lib/active_record/scoping/default.rb +4 -6
- data/lib/active_record/scoping/named.rb +25 -16
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +23 -15
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +243 -0
- data/lib/active_record/timestamp.rb +39 -26
- data/lib/active_record/touch_later.rb +5 -4
- data/lib/active_record/transactions.rb +64 -73
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +0 -1
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +3 -5
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations/associated.rb +0 -1
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record.rb +10 -2
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +256 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +62 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/migration.rb +14 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +112 -25
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -5,7 +5,7 @@ module ActiveRecord
|
|
5
5
|
module ConnectionAdapters
|
6
6
|
# An abstract definition of a column in a table.
|
7
7
|
class Column
|
8
|
-
attr_reader :name, :default, :sql_type_metadata, :null, :
|
8
|
+
attr_reader :name, :default, :sql_type_metadata, :null, :default_function, :collation, :comment
|
9
9
|
|
10
10
|
delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
|
11
11
|
|
@@ -15,9 +15,8 @@ module ActiveRecord
|
|
15
15
|
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
|
16
16
|
# +sql_type_metadata+ is various information about the type of the column
|
17
17
|
# +null+ determines if this column allows +NULL+ values.
|
18
|
-
def initialize(name, default, sql_type_metadata = nil, null = true,
|
18
|
+
def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil, **)
|
19
19
|
@name = name.freeze
|
20
|
-
@table_name = table_name
|
21
20
|
@sql_type_metadata = sql_type_metadata
|
22
21
|
@null = null
|
23
22
|
@default = default
|
@@ -44,7 +43,6 @@ module ActiveRecord
|
|
44
43
|
|
45
44
|
def init_with(coder)
|
46
45
|
@name = coder["name"]
|
47
|
-
@table_name = coder["table_name"]
|
48
46
|
@sql_type_metadata = coder["sql_type_metadata"]
|
49
47
|
@null = coder["null"]
|
50
48
|
@default = coder["default"]
|
@@ -55,7 +53,6 @@ module ActiveRecord
|
|
55
53
|
|
56
54
|
def encode_with(coder)
|
57
55
|
coder["name"] = @name
|
58
|
-
coder["table_name"] = @table_name
|
59
56
|
coder["sql_type_metadata"] = @sql_type_metadata
|
60
57
|
coder["null"] = @null
|
61
58
|
coder["default"] = @default
|
@@ -66,19 +63,26 @@ module ActiveRecord
|
|
66
63
|
|
67
64
|
def ==(other)
|
68
65
|
other.is_a?(Column) &&
|
69
|
-
|
66
|
+
name == other.name &&
|
67
|
+
default == other.default &&
|
68
|
+
sql_type_metadata == other.sql_type_metadata &&
|
69
|
+
null == other.null &&
|
70
|
+
default_function == other.default_function &&
|
71
|
+
collation == other.collation &&
|
72
|
+
comment == other.comment
|
70
73
|
end
|
71
74
|
alias :eql? :==
|
72
75
|
|
73
76
|
def hash
|
74
|
-
|
77
|
+
Column.hash ^
|
78
|
+
name.hash ^
|
79
|
+
default.hash ^
|
80
|
+
sql_type_metadata.hash ^
|
81
|
+
null.hash ^
|
82
|
+
default_function.hash ^
|
83
|
+
collation.hash ^
|
84
|
+
comment.hash
|
75
85
|
end
|
76
|
-
|
77
|
-
protected
|
78
|
-
|
79
|
-
def attributes_for_hash
|
80
|
-
[self.class, name, default, sql_type_metadata, null, table_name, default_function, collation]
|
81
|
-
end
|
82
86
|
end
|
83
87
|
|
84
88
|
class NullColumn < Column
|
@@ -56,10 +56,7 @@ module ActiveRecord
|
|
56
56
|
end
|
57
57
|
|
58
58
|
private
|
59
|
-
|
60
|
-
def uri
|
61
|
-
@uri
|
62
|
-
end
|
59
|
+
attr_reader :uri
|
63
60
|
|
64
61
|
def uri_parser
|
65
62
|
@uri_parser ||= URI::Parser.new
|
@@ -75,7 +72,7 @@ module ActiveRecord
|
|
75
72
|
# "localhost"
|
76
73
|
# # => {}
|
77
74
|
def query_hash
|
78
|
-
Hash[(@query || "").split("&").map { |pair| pair.split("=") }]
|
75
|
+
Hash[(@query || "").split("&").map { |pair| pair.split("=", 2) }]
|
79
76
|
end
|
80
77
|
|
81
78
|
def raw_config
|
@@ -116,8 +113,7 @@ module ActiveRecord
|
|
116
113
|
class Resolver # :nodoc:
|
117
114
|
attr_reader :configurations
|
118
115
|
|
119
|
-
# Accepts a
|
120
|
-
# environments such as "production". Keys must be strings.
|
116
|
+
# Accepts a list of db config objects.
|
121
117
|
def initialize(configurations)
|
122
118
|
@configurations = configurations
|
123
119
|
end
|
@@ -138,34 +134,14 @@ module ActiveRecord
|
|
138
134
|
# Resolver.new(configurations).resolve(:production)
|
139
135
|
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
|
140
136
|
#
|
141
|
-
def resolve(
|
142
|
-
if
|
143
|
-
resolve_connection
|
144
|
-
elsif env = ActiveRecord::ConnectionHandling::RAILS_ENV.call
|
145
|
-
resolve_symbol_connection env.to_sym
|
137
|
+
def resolve(config_or_env, pool_name = nil)
|
138
|
+
if config_or_env
|
139
|
+
resolve_connection config_or_env, pool_name
|
146
140
|
else
|
147
141
|
raise AdapterNotSpecified
|
148
142
|
end
|
149
143
|
end
|
150
144
|
|
151
|
-
# Expands each key in @configurations hash into fully resolved hash
|
152
|
-
def resolve_all
|
153
|
-
config = configurations.dup
|
154
|
-
|
155
|
-
if env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
|
156
|
-
env_config = config[env] if config[env].is_a?(Hash) && !(config[env].key?("adapter") || config[env].key?("url"))
|
157
|
-
end
|
158
|
-
|
159
|
-
config.reject! { |k, v| v.is_a?(Hash) && !(v.key?("adapter") || v.key?("url")) }
|
160
|
-
config.merge! env_config if env_config
|
161
|
-
|
162
|
-
config.each do |key, value|
|
163
|
-
config[key] = resolve(value) if value
|
164
|
-
end
|
165
|
-
|
166
|
-
config
|
167
|
-
end
|
168
|
-
|
169
145
|
# Returns an instance of ConnectionSpecification for a given adapter.
|
170
146
|
# Accepts a hash one layer deep that contains all connection information.
|
171
147
|
#
|
@@ -179,7 +155,9 @@ module ActiveRecord
|
|
179
155
|
# # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" }
|
180
156
|
#
|
181
157
|
def spec(config)
|
182
|
-
|
158
|
+
pool_name = config if config.is_a?(Symbol)
|
159
|
+
|
160
|
+
spec = resolve(config, pool_name).symbolize_keys
|
183
161
|
|
184
162
|
raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
|
185
163
|
|
@@ -207,14 +185,13 @@ module ActiveRecord
|
|
207
185
|
adapter_method = "#{spec[:adapter]}_connection"
|
208
186
|
|
209
187
|
unless ActiveRecord::Base.respond_to?(adapter_method)
|
210
|
-
raise AdapterNotFound, "database configuration specifies nonexistent #{spec
|
188
|
+
raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter"
|
211
189
|
end
|
212
190
|
|
213
191
|
ConnectionSpecification.new(spec.delete(:name) || "primary", spec, adapter_method)
|
214
192
|
end
|
215
193
|
|
216
194
|
private
|
217
|
-
|
218
195
|
# Returns fully resolved connection, accepts hash, string or symbol.
|
219
196
|
# Always returns a hash.
|
220
197
|
#
|
@@ -235,32 +212,64 @@ module ActiveRecord
|
|
235
212
|
# Resolver.new({}).resolve_connection("postgresql://localhost/foo")
|
236
213
|
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
|
237
214
|
#
|
238
|
-
def resolve_connection(
|
239
|
-
case
|
215
|
+
def resolve_connection(config_or_env, pool_name = nil)
|
216
|
+
case config_or_env
|
240
217
|
when Symbol
|
241
|
-
resolve_symbol_connection
|
218
|
+
resolve_symbol_connection config_or_env, pool_name
|
242
219
|
when String
|
243
|
-
resolve_url_connection
|
220
|
+
resolve_url_connection config_or_env
|
244
221
|
when Hash
|
245
|
-
resolve_hash_connection
|
222
|
+
resolve_hash_connection config_or_env
|
223
|
+
else
|
224
|
+
raise TypeError, "Invalid type for configuration. Expected Symbol, String, or Hash. Got #{config_or_env.inspect}"
|
246
225
|
end
|
247
226
|
end
|
248
227
|
|
249
|
-
# Takes the environment such as +:production+ or +:development
|
228
|
+
# Takes the environment such as +:production+ or +:development+ and a
|
229
|
+
# pool name the corresponds to the name given by the connection pool
|
230
|
+
# to the connection. That pool name is merged into the hash with the
|
231
|
+
# name key.
|
232
|
+
#
|
250
233
|
# This requires that the @configurations was initialized with a key that
|
251
234
|
# matches.
|
252
235
|
#
|
253
|
-
#
|
254
|
-
#
|
236
|
+
# configurations = #<ActiveRecord::DatabaseConfigurations:0x00007fd9fdace3e0
|
237
|
+
# @configurations=[
|
238
|
+
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd9fdace250
|
239
|
+
# @env_name="production", @spec_name="primary", @config={"database"=>"my_db"}>
|
240
|
+
# ]>
|
255
241
|
#
|
256
|
-
|
257
|
-
|
258
|
-
|
242
|
+
# Resolver.new(configurations).resolve_symbol_connection(:production, "primary")
|
243
|
+
# # => { "database" => "my_db" }
|
244
|
+
def resolve_symbol_connection(env_name, pool_name)
|
245
|
+
db_config = configurations.find_db_config(env_name)
|
246
|
+
|
247
|
+
if db_config
|
248
|
+
resolve_connection(db_config.config).merge("name" => pool_name.to_s)
|
259
249
|
else
|
260
|
-
raise
|
250
|
+
raise AdapterNotSpecified, <<~MSG
|
251
|
+
The `#{env_name}` database is not configured for the `#{ActiveRecord::ConnectionHandling::DEFAULT_ENV.call}` environment.
|
252
|
+
|
253
|
+
Available databases configurations are:
|
254
|
+
|
255
|
+
#{build_configuration_sentence}
|
256
|
+
MSG
|
261
257
|
end
|
262
258
|
end
|
263
259
|
|
260
|
+
def build_configuration_sentence # :nodoc:
|
261
|
+
configs = configurations.configs_for(include_replicas: true)
|
262
|
+
|
263
|
+
configs.group_by(&:env_name).map do |env, config|
|
264
|
+
namespaces = config.map(&:spec_name)
|
265
|
+
if namespaces.size > 1
|
266
|
+
"#{env}: #{namespaces.join(", ")}"
|
267
|
+
else
|
268
|
+
env
|
269
|
+
end
|
270
|
+
end.join("\n")
|
271
|
+
end
|
272
|
+
|
264
273
|
# Accepts a hash. Expands the "url" key that contains a
|
265
274
|
# URL database connection to a full connection
|
266
275
|
# hash and merges with the rest of the hash.
|
@@ -5,26 +5,22 @@ module ActiveRecord
|
|
5
5
|
module DetermineIfPreparableVisitor
|
6
6
|
attr_accessor :preparable
|
7
7
|
|
8
|
-
def accept(
|
8
|
+
def accept(object, collector)
|
9
9
|
@preparable = true
|
10
10
|
super
|
11
11
|
end
|
12
12
|
|
13
13
|
def visit_Arel_Nodes_In(o, collector)
|
14
14
|
@preparable = false
|
15
|
+
super
|
16
|
+
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
if Arel::Nodes::BindParam === bind && Relation::QueryAttribute === bind.value
|
19
|
-
!bind.value.boundable?
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
18
|
+
def visit_Arel_Nodes_NotIn(o, collector)
|
19
|
+
@preparable = false
|
24
20
|
super
|
25
21
|
end
|
26
22
|
|
27
|
-
def visit_Arel_Nodes_SqlLiteral(
|
23
|
+
def visit_Arel_Nodes_SqlLiteral(o, collector)
|
28
24
|
@preparable = false
|
29
25
|
super
|
30
26
|
end
|
@@ -5,13 +5,13 @@ module ActiveRecord
|
|
5
5
|
module MySQL
|
6
6
|
module DatabaseStatements
|
7
7
|
# Returns an ActiveRecord::Result instance.
|
8
|
-
def select_all(
|
8
|
+
def select_all(*, **) # :nodoc:
|
9
9
|
result = if ExplainRegistry.collect? && prepared_statements
|
10
10
|
unprepared_statement { super }
|
11
11
|
else
|
12
12
|
super
|
13
13
|
end
|
14
|
-
|
14
|
+
@connection.abandon_results!
|
15
15
|
result
|
16
16
|
end
|
17
17
|
|
@@ -19,8 +19,21 @@ module ActiveRecord
|
|
19
19
|
execute(sql, name).to_a
|
20
20
|
end
|
21
21
|
|
22
|
+
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
|
23
|
+
:desc, :describe, :set, :show, :use
|
24
|
+
) # :nodoc:
|
25
|
+
private_constant :READ_QUERY
|
26
|
+
|
27
|
+
def write_query?(sql) # :nodoc:
|
28
|
+
!READ_QUERY.match?(sql)
|
29
|
+
end
|
30
|
+
|
22
31
|
# Executes the SQL statement in the context of this connection.
|
23
32
|
def execute(sql, name = nil)
|
33
|
+
if preventing_writes? && write_query?(sql)
|
34
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
35
|
+
end
|
36
|
+
|
24
37
|
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
|
25
38
|
# made since we established the connection
|
26
39
|
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
@@ -31,18 +44,28 @@ module ActiveRecord
|
|
31
44
|
def exec_query(sql, name = "SQL", binds = [], prepare: false)
|
32
45
|
if without_prepared_statement?(binds)
|
33
46
|
execute_and_free(sql, name) do |result|
|
34
|
-
|
47
|
+
if result
|
48
|
+
ActiveRecord::Result.new(result.fields, result.to_a)
|
49
|
+
else
|
50
|
+
ActiveRecord::Result.new([], [])
|
51
|
+
end
|
35
52
|
end
|
36
53
|
else
|
37
54
|
exec_stmt_and_free(sql, name, binds, cache_stmt: prepare) do |_, result|
|
38
|
-
|
55
|
+
if result
|
56
|
+
ActiveRecord::Result.new(result.fields, result.to_a)
|
57
|
+
else
|
58
|
+
ActiveRecord::Result.new([], [])
|
59
|
+
end
|
39
60
|
end
|
40
61
|
end
|
41
62
|
end
|
42
63
|
|
43
64
|
def exec_delete(sql, name = nil, binds = [])
|
44
65
|
if without_prepared_statement?(binds)
|
45
|
-
|
66
|
+
@lock.synchronize do
|
67
|
+
execute_and_free(sql, name) { @connection.affected_rows }
|
68
|
+
end
|
46
69
|
else
|
47
70
|
exec_stmt_and_free(sql, name, binds) { |stmt| stmt.affected_rows }
|
48
71
|
end
|
@@ -50,18 +73,21 @@ module ActiveRecord
|
|
50
73
|
alias :exec_update :exec_delete
|
51
74
|
|
52
75
|
private
|
76
|
+
def execute_batch(statements, name = nil)
|
77
|
+
combine_multi_statements(statements).each do |statement|
|
78
|
+
execute(statement, name)
|
79
|
+
end
|
80
|
+
@connection.abandon_results!
|
81
|
+
end
|
82
|
+
|
53
83
|
def default_insert_value(column)
|
54
|
-
|
84
|
+
super unless column.auto_increment?
|
55
85
|
end
|
56
86
|
|
57
87
|
def last_inserted_id(result)
|
58
88
|
@connection.last_id
|
59
89
|
end
|
60
90
|
|
61
|
-
def discard_remaining_results
|
62
|
-
@connection.next_result while @connection.more_results?
|
63
|
-
end
|
64
|
-
|
65
91
|
def supports_set_server_option?
|
66
92
|
@connection.respond_to?(:set_server_option)
|
67
93
|
end
|
@@ -98,7 +124,40 @@ module ActiveRecord
|
|
98
124
|
end
|
99
125
|
end
|
100
126
|
|
127
|
+
def combine_multi_statements(total_sql)
|
128
|
+
total_sql.each_with_object([]) do |sql, total_sql_chunks|
|
129
|
+
previous_packet = total_sql_chunks.last
|
130
|
+
if max_allowed_packet_reached?(sql, previous_packet)
|
131
|
+
total_sql_chunks << +sql
|
132
|
+
else
|
133
|
+
previous_packet << ";\n"
|
134
|
+
previous_packet << sql
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def max_allowed_packet_reached?(current_packet, previous_packet)
|
140
|
+
if current_packet.bytesize > max_allowed_packet
|
141
|
+
raise ActiveRecordError,
|
142
|
+
"Fixtures set is too large #{current_packet.bytesize}. Consider increasing the max_allowed_packet variable."
|
143
|
+
elsif previous_packet.nil?
|
144
|
+
true
|
145
|
+
else
|
146
|
+
(current_packet.bytesize + previous_packet.bytesize + 2) > max_allowed_packet
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def max_allowed_packet
|
151
|
+
@max_allowed_packet ||= show_variable("max_allowed_packet")
|
152
|
+
end
|
153
|
+
|
101
154
|
def exec_stmt_and_free(sql, name, binds, cache_stmt: false)
|
155
|
+
if preventing_writes? && write_query?(sql)
|
156
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
157
|
+
end
|
158
|
+
|
159
|
+
materialize_transactions
|
160
|
+
|
102
161
|
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
|
103
162
|
# made since we established the connection
|
104
163
|
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
@@ -107,10 +166,7 @@ module ActiveRecord
|
|
107
166
|
|
108
167
|
log(sql, name, binds, type_casted_binds) do
|
109
168
|
if cache_stmt
|
110
|
-
|
111
|
-
stmt: @connection.prepare(sql)
|
112
|
-
}
|
113
|
-
stmt = cache[:stmt]
|
169
|
+
stmt = @statements[sql] ||= @connection.prepare(sql)
|
114
170
|
else
|
115
171
|
stmt = @connection.prepare(sql)
|
116
172
|
end
|
@@ -5,11 +5,11 @@ module ActiveRecord
|
|
5
5
|
module MySQL
|
6
6
|
module Quoting # :nodoc:
|
7
7
|
def quote_column_name(name)
|
8
|
-
|
8
|
+
self.class.quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
|
9
9
|
end
|
10
10
|
|
11
11
|
def quote_table_name(name)
|
12
|
-
|
12
|
+
self.class.quoted_table_names[name] ||= super.gsub(".", "`.`").freeze
|
13
13
|
end
|
14
14
|
|
15
15
|
def unquoted_true
|
@@ -32,12 +32,49 @@ module ActiveRecord
|
|
32
32
|
"x'#{value.hex}'"
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
def column_name_matcher
|
36
|
+
COLUMN_NAME
|
37
|
+
end
|
38
|
+
|
39
|
+
def column_name_with_order_matcher
|
40
|
+
COLUMN_NAME_WITH_ORDER
|
40
41
|
end
|
42
|
+
|
43
|
+
COLUMN_NAME = /
|
44
|
+
\A
|
45
|
+
(
|
46
|
+
(?:
|
47
|
+
# `table_name`.`column_name` | function(one or no argument)
|
48
|
+
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
|
49
|
+
)
|
50
|
+
(?:\s+AS\s+(?:\w+|`\w+`))?
|
51
|
+
)
|
52
|
+
(?:\s*,\s*\g<1>)*
|
53
|
+
\z
|
54
|
+
/ix
|
55
|
+
|
56
|
+
COLUMN_NAME_WITH_ORDER = /
|
57
|
+
\A
|
58
|
+
(
|
59
|
+
(?:
|
60
|
+
# `table_name`.`column_name` | function(one or no argument)
|
61
|
+
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
|
62
|
+
)
|
63
|
+
(?:\s+ASC|\s+DESC)?
|
64
|
+
)
|
65
|
+
(?:\s*,\s*\g<1>)*
|
66
|
+
\z
|
67
|
+
/ix
|
68
|
+
|
69
|
+
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
70
|
+
|
71
|
+
private
|
72
|
+
def _type_cast(value)
|
73
|
+
case value
|
74
|
+
when Date, Time then value
|
75
|
+
else super
|
76
|
+
end
|
77
|
+
end
|
41
78
|
end
|
42
79
|
end
|
43
80
|
end
|
@@ -4,11 +4,9 @@ module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
module MySQL
|
6
6
|
class SchemaCreation < AbstractAdapter::SchemaCreation # :nodoc:
|
7
|
-
delegate :add_sql_comment!, :mariadb?, to: :@conn
|
8
|
-
private :add_sql_comment!, :mariadb?
|
7
|
+
delegate :add_sql_comment!, :mariadb?, to: :@conn, private: true
|
9
8
|
|
10
9
|
private
|
11
|
-
|
12
10
|
def visit_DropForeignKey(name)
|
13
11
|
"DROP FOREIGN KEY #{name}"
|
14
12
|
end
|
@@ -18,7 +16,7 @@ module ActiveRecord
|
|
18
16
|
end
|
19
17
|
|
20
18
|
def visit_ChangeColumnDefinition(o)
|
21
|
-
change_column_sql = "CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
|
19
|
+
change_column_sql = +"CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
|
22
20
|
add_column_position!(change_column_sql, column_options(o.column))
|
23
21
|
end
|
24
22
|
|
@@ -64,8 +62,8 @@ module ActiveRecord
|
|
64
62
|
end
|
65
63
|
|
66
64
|
def index_in_create(table_name, column_name, options)
|
67
|
-
index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, options)
|
68
|
-
add_sql_comment!("#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})"
|
65
|
+
index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, **options)
|
66
|
+
add_sql_comment!((+"#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})"), comment)
|
69
67
|
end
|
70
68
|
end
|
71
69
|
end
|
@@ -4,48 +4,56 @@ module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
module MySQL
|
6
6
|
module ColumnMethods
|
7
|
-
|
8
|
-
args.each { |name| column(name, :blob, options) }
|
9
|
-
end
|
7
|
+
extend ActiveSupport::Concern
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
##
|
10
|
+
# :method: blob
|
11
|
+
# :call-seq: blob(*names, **options)
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
##
|
14
|
+
# :method: tinyblob
|
15
|
+
# :call-seq: tinyblob(*names, **options)
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
##
|
18
|
+
# :method: mediumblob
|
19
|
+
# :call-seq: mediumblob(*names, **options)
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
##
|
22
|
+
# :method: longblob
|
23
|
+
# :call-seq: longblob(*names, **options)
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
##
|
26
|
+
# :method: tinytext
|
27
|
+
# :call-seq: tinytext(*names, **options)
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
##
|
30
|
+
# :method: mediumtext
|
31
|
+
# :call-seq: mediumtext(*names, **options)
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
##
|
34
|
+
# :method: longtext
|
35
|
+
# :call-seq: longtext(*names, **options)
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
##
|
38
|
+
# :method: unsigned_integer
|
39
|
+
# :call-seq: unsigned_integer(*names, **options)
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
##
|
42
|
+
# :method: unsigned_bigint
|
43
|
+
# :call-seq: unsigned_bigint(*names, **options)
|
44
|
+
|
45
|
+
##
|
46
|
+
# :method: unsigned_float
|
47
|
+
# :call-seq: unsigned_float(*names, **options)
|
48
|
+
|
49
|
+
##
|
50
|
+
# :method: unsigned_decimal
|
51
|
+
# :call-seq: unsigned_decimal(*names, **options)
|
46
52
|
|
47
|
-
|
48
|
-
|
53
|
+
included do
|
54
|
+
define_column_methods :blob, :tinyblob, :mediumblob, :longblob,
|
55
|
+
:tinytext, :mediumtext, :longtext, :unsigned_integer, :unsigned_bigint,
|
56
|
+
:unsigned_float, :unsigned_decimal
|
49
57
|
end
|
50
58
|
end
|
51
59
|
|