activerecord 5.1.7 → 5.2.0.beta1
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 +221 -900
- data/README.rdoc +3 -3
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +10 -3
- data/lib/active_record/aggregations.rb +2 -0
- data/lib/active_record/association_relation.rb +2 -0
- data/lib/active_record/associations.rb +13 -42
- data/lib/active_record/associations/alias_tracker.rb +17 -17
- data/lib/active_record/associations/association.rb +11 -22
- data/lib/active_record/associations/association_scope.rb +32 -44
- data/lib/active_record/associations/belongs_to_association.rb +6 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
- data/lib/active_record/associations/builder/association.rb +2 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -12
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +41 -33
- data/lib/active_record/associations/collection_proxy.rb +11 -14
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +4 -2
- data/lib/active_record/associations/has_many_through_association.rb +4 -2
- data/lib/active_record/associations/has_one_association.rb +3 -1
- data/lib/active_record/associations/has_one_through_association.rb +3 -1
- data/lib/active_record/associations/join_dependency.rb +22 -40
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +42 -58
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +2 -0
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +47 -7
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +21 -9
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +5 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +6 -8
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +120 -28
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +3 -1
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -6
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +47 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +19 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -89
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +27 -57
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +15 -13
- data/lib/active_record/errors.rb +54 -21
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +40 -24
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +6 -5
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +31 -20
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +2 -0
- data/lib/active_record/migration.rb +47 -21
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +20 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +29 -38
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +184 -40
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +54 -1
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +41 -28
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +100 -182
- data/lib/active_record/relation.rb +61 -193
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +40 -23
- data/lib/active_record/relation/delegation.rb +10 -27
- data/lib/active_record/relation/finder_methods.rb +53 -49
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +22 -19
- data/lib/active_record/relation/predicate_builder.rb +42 -79
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +9 -2
- data/lib/active_record/relation/query_methods.rb +80 -69
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -0
- data/lib/active_record/relation/where_clause.rb +50 -67
- data/lib/active_record/relation/where_clause_factory.rb +4 -46
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +15 -9
- data/lib/active_record/schema.rb +3 -1
- data/lib/active_record/schema_dumper.rb +24 -23
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +15 -7
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +2 -0
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +3 -1
- data/lib/active_record/tasks/database_tasks.rb +23 -12
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +2 -4
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +2 -0
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +36 -6
- data/lib/active_record/version.rb +2 -0
- data/lib/rails/generators/active_record.rb +3 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +25 -38
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/attribute_set/builder.rb +0 -126
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_record/connection_adapters/postgresql/oid/array"
|
2
4
|
require "active_record/connection_adapters/postgresql/oid/bit"
|
3
5
|
require "active_record/connection_adapters/postgresql/oid/bit_varying"
|
@@ -8,7 +10,6 @@ require "active_record/connection_adapters/postgresql/oid/decimal"
|
|
8
10
|
require "active_record/connection_adapters/postgresql/oid/enum"
|
9
11
|
require "active_record/connection_adapters/postgresql/oid/hstore"
|
10
12
|
require "active_record/connection_adapters/postgresql/oid/inet"
|
11
|
-
require "active_record/connection_adapters/postgresql/oid/json"
|
12
13
|
require "active_record/connection_adapters/postgresql/oid/jsonb"
|
13
14
|
require "active_record/connection_adapters/postgresql/oid/money"
|
14
15
|
require "active_record/connection_adapters/postgresql/oid/oid"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
@@ -31,13 +33,7 @@ module ActiveRecord
|
|
31
33
|
|
32
34
|
def cast(value)
|
33
35
|
if value.is_a?(::String)
|
34
|
-
value =
|
35
|
-
@pg_decoder.decode(value)
|
36
|
-
rescue TypeError
|
37
|
-
# malformed array string is treated as [], will raise in PG 2.0 gem
|
38
|
-
# this keeps a consistent implementation
|
39
|
-
[]
|
40
|
-
end
|
36
|
+
value = @pg_decoder.decode(value)
|
41
37
|
end
|
42
38
|
type_cast_array(value, :cast)
|
43
39
|
end
|
@@ -70,10 +66,6 @@ module ActiveRecord
|
|
70
66
|
deserialize(raw_old_value) != new_value
|
71
67
|
end
|
72
68
|
|
73
|
-
def force_equality?(value)
|
74
|
-
value.is_a?(::Array)
|
75
|
-
end
|
76
|
-
|
77
69
|
private
|
78
70
|
|
79
71
|
def type_cast_array(value, method)
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
4
6
|
module OID # :nodoc:
|
5
7
|
class Decimal < Type::Decimal # :nodoc:
|
6
8
|
def infinity(options = {})
|
7
|
-
BigDecimal("Infinity") * (options[:negative] ? -1 : 1)
|
9
|
+
BigDecimal.new("Infinity") * (options[:negative] ? -1 : 1)
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
@@ -22,7 +24,7 @@ module ActiveRecord
|
|
22
24
|
# (3) -$2.55
|
23
25
|
# (4) ($2.55)
|
24
26
|
|
25
|
-
value.sub
|
27
|
+
value = value.sub(/^\((.+)\)$/, '-\1') # (4)
|
26
28
|
case value
|
27
29
|
when /^-?\D+[\d,]+\.\d{2}$/ # (1)
|
28
30
|
value.gsub!(/[^-\d.]/, "")
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
@@ -33,7 +35,7 @@ module ActiveRecord
|
|
33
35
|
if value.is_a?(::Range)
|
34
36
|
from = type_cast_single_for_database(value.begin)
|
35
37
|
to = type_cast_single_for_database(value.end)
|
36
|
-
|
38
|
+
::Range.new(from, to, value.exclude_end?)
|
37
39
|
else
|
38
40
|
super
|
39
41
|
end
|
@@ -51,10 +53,6 @@ module ActiveRecord
|
|
51
53
|
::Range.new(new_begin, new_end, value.exclude_end?)
|
52
54
|
end
|
53
55
|
|
54
|
-
def force_equality?(value)
|
55
|
-
value.is_a?(::Range)
|
56
|
-
end
|
57
|
-
|
58
56
|
private
|
59
57
|
|
60
58
|
def type_cast_single(value)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
@@ -29,8 +31,8 @@ module ActiveRecord
|
|
29
31
|
composites.each { |row| register_composite_type(row) }
|
30
32
|
end
|
31
33
|
|
32
|
-
def query_conditions_for_initial_load
|
33
|
-
known_type_names =
|
34
|
+
def query_conditions_for_initial_load
|
35
|
+
known_type_names = @store.keys.map { |n| "'#{n}'" }
|
34
36
|
known_type_types = %w('r' 'e' 'd')
|
35
37
|
<<-SQL % [known_type_names.join(", "), known_type_types.join(", ")]
|
36
38
|
WHERE
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
4
6
|
module OID # :nodoc:
|
5
7
|
class Uuid < Type::Value # :nodoc:
|
6
|
-
ACCEPTABLE_UUID = %r{\A\{?([a-fA-F0-9]{4}-?){8}\}
|
8
|
+
ACCEPTABLE_UUID = %r{\A(\{)?([a-fA-F0-9]{4}-?){8}(?(1)\}|)\z}
|
7
9
|
|
8
10
|
alias_method :serialize, :deserialize
|
9
11
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
@@ -99,6 +101,8 @@ module ActiveRecord
|
|
99
101
|
end
|
100
102
|
when OID::Array::Data
|
101
103
|
_quote(encode_array(value))
|
104
|
+
when Range
|
105
|
+
_quote(encode_range(value))
|
102
106
|
else
|
103
107
|
super
|
104
108
|
end
|
@@ -115,6 +119,8 @@ module ActiveRecord
|
|
115
119
|
value.to_s
|
116
120
|
when OID::Array::Data
|
117
121
|
encode_array(value)
|
122
|
+
when Range
|
123
|
+
encode_range(value)
|
118
124
|
else
|
119
125
|
super
|
120
126
|
end
|
@@ -131,6 +137,10 @@ module ActiveRecord
|
|
131
137
|
result
|
132
138
|
end
|
133
139
|
|
140
|
+
def encode_range(range)
|
141
|
+
"[#{type_cast(range.first)},#{type_cast(range.last)}#{range.exclude_end? ? ')' : ']'}"
|
142
|
+
end
|
143
|
+
|
134
144
|
def determine_encoding_of_strings_in_array(value)
|
135
145
|
case value
|
136
146
|
when ::Array then determine_encoding_of_strings_in_array(value.first)
|
@@ -1,27 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
4
6
|
module ReferentialIntegrity # :nodoc:
|
5
|
-
def supports_disable_referential_integrity? # :nodoc:
|
6
|
-
true
|
7
|
-
end
|
8
|
-
|
9
7
|
def disable_referential_integrity # :nodoc:
|
10
|
-
|
11
|
-
original_exception = nil
|
8
|
+
original_exception = nil
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
rescue ActiveRecord::ActiveRecordError => e
|
18
|
-
original_exception = e
|
10
|
+
begin
|
11
|
+
transaction(requires_new: true) do
|
12
|
+
execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
|
19
13
|
end
|
14
|
+
rescue ActiveRecord::ActiveRecordError => e
|
15
|
+
original_exception = e
|
16
|
+
end
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
begin
|
19
|
+
yield
|
20
|
+
rescue ActiveRecord::InvalidForeignKey => e
|
21
|
+
warn <<-WARNING
|
25
22
|
WARNING: Rails was not able to disable referential integrity.
|
26
23
|
|
27
24
|
This is most likely caused due to missing permissions.
|
@@ -30,17 +27,14 @@ Rails needs superuser privileges to disable referential integrity.
|
|
30
27
|
cause: #{original_exception.try(:message)}
|
31
28
|
|
32
29
|
WARNING
|
33
|
-
|
34
|
-
|
30
|
+
raise e
|
31
|
+
end
|
35
32
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
rescue ActiveRecord::ActiveRecordError
|
33
|
+
begin
|
34
|
+
transaction(requires_new: true) do
|
35
|
+
execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
|
41
36
|
end
|
42
|
-
|
43
|
-
yield
|
37
|
+
rescue ActiveRecord::ActiveRecordError
|
44
38
|
end
|
45
39
|
end
|
46
40
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
@@ -42,15 +44,8 @@ module ActiveRecord
|
|
42
44
|
# a record (as primary keys cannot be +nil+). This might be done via the
|
43
45
|
# +SecureRandom.uuid+ method and a +before_save+ callback, for instance.
|
44
46
|
def primary_key(name, type = :primary_key, **options)
|
45
|
-
options[:auto_increment] = true if [:integer, :bigint].include?(type) && !options.key?(:default)
|
46
47
|
if type == :uuid
|
47
48
|
options[:default] = options.fetch(:default, "gen_random_uuid()")
|
48
|
-
elsif options.delete(:auto_increment) == true && %i(integer bigint).include?(type)
|
49
|
-
type = if type == :bigint || options[:limit] == 8
|
50
|
-
:bigserial
|
51
|
-
else
|
52
|
-
:serial
|
53
|
-
end
|
54
49
|
end
|
55
50
|
|
56
51
|
super
|
@@ -183,6 +178,15 @@ module ActiveRecord
|
|
183
178
|
|
184
179
|
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
|
185
180
|
include ColumnMethods
|
181
|
+
|
182
|
+
private
|
183
|
+
def integer_like_primary_key_type(type, options)
|
184
|
+
if type == :bigint || options[:limit] == 8
|
185
|
+
:bigserial
|
186
|
+
else
|
187
|
+
:serial
|
188
|
+
end
|
189
|
+
end
|
186
190
|
end
|
187
191
|
|
188
192
|
class Table < ActiveRecord::ConnectionAdapters::Table
|
@@ -1,21 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module PostgreSQL
|
4
|
-
|
5
|
-
# Adds +:array+ option to the default set
|
6
|
-
def prepare_column_options(column)
|
7
|
-
spec = super
|
8
|
-
spec[:array] = "true" if column.array?
|
9
|
-
spec
|
10
|
-
end
|
11
|
-
|
12
|
-
# Adds +:array+ as a valid migration key
|
13
|
-
def migration_keys
|
14
|
-
super + [:array]
|
15
|
-
end
|
16
|
-
|
6
|
+
class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
|
17
7
|
private
|
18
8
|
|
9
|
+
def extensions(stream)
|
10
|
+
extensions = @connection.extensions
|
11
|
+
if extensions.any?
|
12
|
+
stream.puts " # These are extensions that must be enabled in order to support this database"
|
13
|
+
extensions.sort.each do |extension|
|
14
|
+
stream.puts " enable_extension #{extension.inspect}"
|
15
|
+
end
|
16
|
+
stream.puts
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def prepare_column_options(column)
|
21
|
+
spec = super
|
22
|
+
spec[:array] = "true" if column.array?
|
23
|
+
spec
|
24
|
+
end
|
25
|
+
|
19
26
|
def default_primary_key?(column)
|
20
27
|
schema_type(column) == :bigserial
|
21
28
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters
|
@@ -64,12 +64,7 @@ module ActiveRecord
|
|
64
64
|
end
|
65
65
|
|
66
66
|
# Verifies existence of an index with a given name.
|
67
|
-
def index_name_exists?(table_name, index_name
|
68
|
-
unless default.nil?
|
69
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
70
|
-
Passing default to #index_name_exists? is deprecated without replacement.
|
71
|
-
MSG
|
72
|
-
end
|
67
|
+
def index_name_exists?(table_name, index_name)
|
73
68
|
table = quoted_scope(table_name)
|
74
69
|
index = quoted_scope(index_name)
|
75
70
|
|
@@ -87,13 +82,7 @@ module ActiveRecord
|
|
87
82
|
end
|
88
83
|
|
89
84
|
# Returns an array of indexes for the given table.
|
90
|
-
def indexes(table_name
|
91
|
-
if name
|
92
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
93
|
-
Passing name to #indexes is deprecated without replacement.
|
94
|
-
MSG
|
95
|
-
end
|
96
|
-
|
85
|
+
def indexes(table_name) # :nodoc:
|
97
86
|
scope = quoted_scope(table_name)
|
98
87
|
|
99
88
|
result = query(<<-SQL, "SCHEMA")
|
@@ -122,7 +111,7 @@ module ActiveRecord
|
|
122
111
|
comment = row[5]
|
123
112
|
opclass = row[6]
|
124
113
|
|
125
|
-
using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/
|
114
|
+
using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/).flatten
|
126
115
|
|
127
116
|
if indkey.include?(0) || opclass > 0
|
128
117
|
columns = expressions
|
@@ -140,28 +129,17 @@ module ActiveRecord
|
|
140
129
|
]
|
141
130
|
end
|
142
131
|
|
143
|
-
IndexDefinition.new(
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
PostgreSQLColumn.new(
|
155
|
-
column_name,
|
156
|
-
default_value,
|
157
|
-
type_metadata,
|
158
|
-
!notnull,
|
159
|
-
table_name,
|
160
|
-
default_function,
|
161
|
-
collation,
|
162
|
-
comment: comment.presence,
|
163
|
-
max_identifier_length: max_identifier_length
|
164
|
-
)
|
132
|
+
IndexDefinition.new(
|
133
|
+
table_name,
|
134
|
+
index_name,
|
135
|
+
unique,
|
136
|
+
columns,
|
137
|
+
orders: orders,
|
138
|
+
where: where,
|
139
|
+
using: using.to_sym,
|
140
|
+
comment: comment.presence
|
141
|
+
)
|
142
|
+
end
|
165
143
|
end
|
166
144
|
|
167
145
|
def table_options(table_name) # :nodoc:
|
@@ -233,7 +211,7 @@ module ActiveRecord
|
|
233
211
|
|
234
212
|
# Sets the schema search path to a string of comma-separated schema names.
|
235
213
|
# Names beginning with $ have to be quoted (e.g. $user => '$user').
|
236
|
-
# See:
|
214
|
+
# See: https://www.postgresql.org/docs/current/static/ddl-schemas.html
|
237
215
|
#
|
238
216
|
# This should be not be called manually but set in database.yml.
|
239
217
|
def schema_search_path=(schema_csv)
|
@@ -334,7 +312,7 @@ module ActiveRecord
|
|
334
312
|
AND seq.relnamespace = nsp.oid
|
335
313
|
AND cons.contype = 'p'
|
336
314
|
AND dep.classid = 'pg_class'::regclass
|
337
|
-
AND dep.refobjid =
|
315
|
+
AND dep.refobjid = #{quote(quote_table_name(table))}::regclass
|
338
316
|
end_sql
|
339
317
|
|
340
318
|
if result.nil? || result.empty?
|
@@ -352,7 +330,7 @@ module ActiveRecord
|
|
352
330
|
JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
|
353
331
|
JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
|
354
332
|
JOIN pg_namespace nsp ON (t.relnamespace = nsp.oid)
|
355
|
-
WHERE t.oid =
|
333
|
+
WHERE t.oid = #{quote(quote_table_name(table))}::regclass
|
356
334
|
AND cons.contype = 'p'
|
357
335
|
AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate'
|
358
336
|
end_sql
|
@@ -394,14 +372,15 @@ module ActiveRecord
|
|
394
372
|
clear_cache!
|
395
373
|
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
|
396
374
|
pk, seq = pk_and_sequence_for(new_name)
|
397
|
-
if
|
398
|
-
new_seq = "#{new_name}_#{pk}_seq"
|
375
|
+
if pk
|
399
376
|
idx = "#{table_name}_pkey"
|
400
377
|
new_idx = "#{new_name}_pkey"
|
401
|
-
execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
|
402
378
|
execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}"
|
379
|
+
if seq && seq.identifier == "#{table_name}_#{pk}_seq"
|
380
|
+
new_seq = "#{new_name}_#{pk}_seq"
|
381
|
+
execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
|
382
|
+
end
|
403
383
|
end
|
404
|
-
|
405
384
|
rename_table_indexes(table_name, new_name)
|
406
385
|
end
|
407
386
|
|
@@ -416,7 +395,7 @@ module ActiveRecord
|
|
416
395
|
quoted_table_name = quote_table_name(table_name)
|
417
396
|
quoted_column_name = quote_column_name(column_name)
|
418
397
|
sql_type = type_to_sql(type, options)
|
419
|
-
sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}"
|
398
|
+
sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}".dup
|
420
399
|
if options[:collation]
|
421
400
|
sql << " COLLATE \"#{options[:collation]}\""
|
422
401
|
end
|
@@ -547,14 +526,6 @@ module ActiveRecord
|
|
547
526
|
end
|
548
527
|
end
|
549
528
|
|
550
|
-
def extract_foreign_key_action(specifier) # :nodoc:
|
551
|
-
case specifier
|
552
|
-
when "c"; :cascade
|
553
|
-
when "n"; :nullify
|
554
|
-
when "r"; :restrict
|
555
|
-
end
|
556
|
-
end
|
557
|
-
|
558
529
|
# Maps logical Rails types to PostgreSQL-specific data types.
|
559
530
|
def type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil, **) # :nodoc:
|
560
531
|
sql = \
|
@@ -584,7 +555,7 @@ module ActiveRecord
|
|
584
555
|
super
|
585
556
|
end
|
586
557
|
|
587
|
-
sql
|
558
|
+
sql = "#{sql}[]" if array && type != :primary_key
|
588
559
|
sql
|
589
560
|
end
|
590
561
|
|
@@ -602,24 +573,67 @@ module ActiveRecord
|
|
602
573
|
[super, *order_columns].join(", ")
|
603
574
|
end
|
604
575
|
|
605
|
-
def
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
precision: cast_type.precision,
|
612
|
-
scale: cast_type.scale,
|
613
|
-
)
|
614
|
-
PostgreSQLTypeMetadata.new(simple_type, oid: oid, fmod: fmod)
|
576
|
+
def update_table_definition(table_name, base) # :nodoc:
|
577
|
+
PostgreSQL::Table.new(table_name, base)
|
578
|
+
end
|
579
|
+
|
580
|
+
def create_schema_dumper(options) # :nodoc:
|
581
|
+
PostgreSQL::SchemaDumper.create(self, options)
|
615
582
|
end
|
616
583
|
|
617
584
|
private
|
585
|
+
def schema_creation
|
586
|
+
PostgreSQL::SchemaCreation.new(self)
|
587
|
+
end
|
588
|
+
|
589
|
+
def create_table_definition(*args)
|
590
|
+
PostgreSQL::TableDefinition.new(*args)
|
591
|
+
end
|
592
|
+
|
593
|
+
def new_column_from_field(table_name, field)
|
594
|
+
column_name, type, default, notnull, oid, fmod, collation, comment = field
|
595
|
+
type_metadata = fetch_type_metadata(column_name, type, oid.to_i, fmod.to_i)
|
596
|
+
default_value = extract_value_from_default(default)
|
597
|
+
default_function = extract_default_function(default_value, default)
|
598
|
+
|
599
|
+
PostgreSQLColumn.new(
|
600
|
+
column_name,
|
601
|
+
default_value,
|
602
|
+
type_metadata,
|
603
|
+
!notnull,
|
604
|
+
table_name,
|
605
|
+
default_function,
|
606
|
+
collation,
|
607
|
+
comment: comment.presence,
|
608
|
+
max_identifier_length: max_identifier_length
|
609
|
+
)
|
610
|
+
end
|
611
|
+
|
612
|
+
def fetch_type_metadata(column_name, sql_type, oid, fmod)
|
613
|
+
cast_type = get_oid_type(oid, fmod, column_name, sql_type)
|
614
|
+
simple_type = SqlTypeMetadata.new(
|
615
|
+
sql_type: sql_type,
|
616
|
+
type: cast_type.type,
|
617
|
+
limit: cast_type.limit,
|
618
|
+
precision: cast_type.precision,
|
619
|
+
scale: cast_type.scale,
|
620
|
+
)
|
621
|
+
PostgreSQLTypeMetadata.new(simple_type, oid: oid, fmod: fmod)
|
622
|
+
end
|
623
|
+
|
624
|
+
def extract_foreign_key_action(specifier)
|
625
|
+
case specifier
|
626
|
+
when "c"; :cascade
|
627
|
+
when "n"; :nullify
|
628
|
+
when "r"; :restrict
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
618
632
|
def data_source_sql(name = nil, type: nil)
|
619
633
|
scope = quoted_scope(name, type: type)
|
620
634
|
scope[:type] ||= "'r','v','m'" # (r)elation/table, (v)iew, (m)aterialized view
|
621
635
|
|
622
|
-
sql = "SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace"
|
636
|
+
sql = "SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace".dup
|
623
637
|
sql << " WHERE n.nspname = #{scope[:schema]}"
|
624
638
|
sql << " AND c.relname = #{scope[:name]}" if scope[:name]
|
625
639
|
sql << " AND c.relkind IN (#{scope[:type]})"
|