activerecord 4.2.11.3 → 5.0.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 +1029 -1349
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -7
- data/examples/performance.rb +2 -2
- data/lib/active_record.rb +7 -3
- data/lib/active_record/aggregations.rb +35 -25
- data/lib/active_record/association_relation.rb +2 -2
- data/lib/active_record/associations.rb +305 -204
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +10 -8
- data/lib/active_record/associations/association_scope.rb +73 -102
- data/lib/active_record/associations/belongs_to_association.rb +20 -32
- data/lib/active_record/associations/builder/association.rb +28 -34
- data/lib/active_record/associations/builder/belongs_to.rb +41 -18
- data/lib/active_record/associations/builder/collection_association.rb +8 -24
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +11 -11
- data/lib/active_record/associations/builder/has_many.rb +4 -4
- data/lib/active_record/associations/builder/has_one.rb +10 -5
- data/lib/active_record/associations/builder/singular_association.rb +2 -9
- data/lib/active_record/associations/collection_association.rb +40 -43
- data/lib/active_record/associations/collection_proxy.rb +55 -29
- data/lib/active_record/associations/foreign_association.rb +1 -1
- data/lib/active_record/associations/has_many_association.rb +20 -71
- data/lib/active_record/associations/has_many_through_association.rb +8 -52
- data/lib/active_record/associations/has_one_association.rb +12 -5
- data/lib/active_record/associations/join_dependency.rb +28 -18
- data/lib/active_record/associations/join_dependency/join_association.rb +13 -12
- data/lib/active_record/associations/preloader.rb +13 -4
- data/lib/active_record/associations/preloader/association.rb +45 -51
- data/lib/active_record/associations/preloader/collection_association.rb +0 -6
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/has_one.rb +0 -8
- data/lib/active_record/associations/preloader/through_association.rb +5 -4
- data/lib/active_record/associations/singular_association.rb +6 -0
- data/lib/active_record/associations/through_association.rb +11 -3
- data/lib/active_record/attribute.rb +61 -17
- data/lib/active_record/attribute/user_provided_default.rb +23 -0
- data/lib/active_record/attribute_assignment.rb +27 -140
- data/lib/active_record/attribute_decorators.rb +6 -5
- data/lib/active_record/attribute_methods.rb +79 -26
- data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
- data/lib/active_record/attribute_methods/dirty.rb +46 -86
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +26 -42
- data/lib/active_record/attribute_methods/serialization.rb +13 -16
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +42 -9
- data/lib/active_record/attribute_methods/write.rb +13 -24
- data/lib/active_record/attribute_mutation_tracker.rb +70 -0
- data/lib/active_record/attribute_set.rb +30 -3
- data/lib/active_record/attribute_set/builder.rb +6 -4
- data/lib/active_record/attributes.rb +194 -81
- data/lib/active_record/autosave_association.rb +33 -15
- data/lib/active_record/base.rb +30 -18
- data/lib/active_record/callbacks.rb +36 -40
- data/lib/active_record/coders/yaml_column.rb +20 -8
- data/lib/active_record/collection_cache_key.rb +31 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +431 -122
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +40 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -8
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +46 -38
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +229 -185
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +52 -13
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +275 -115
- data/lib/active_record/connection_adapters/abstract/transaction.rb +32 -33
- data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -32
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +384 -221
- data/lib/active_record/connection_adapters/column.rb +27 -41
- data/lib/active_record/connection_adapters/connection_specification.rb +2 -21
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +57 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +69 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +59 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +22 -101
- data/lib/active_record/connection_adapters/postgresql/column.rb +6 -10
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +23 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
- 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 +23 -16
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -11
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +54 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +174 -128
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +184 -112
- data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +15 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +134 -110
- data/lib/active_record/connection_adapters/statement_pool.rb +28 -11
- data/lib/active_record/connection_handling.rb +5 -5
- data/lib/active_record/core.rb +72 -104
- data/lib/active_record/counter_cache.rb +9 -20
- data/lib/active_record/dynamic_matchers.rb +1 -20
- data/lib/active_record/enum.rb +110 -76
- data/lib/active_record/errors.rb +72 -47
- data/lib/active_record/explain_registry.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +19 -4
- data/lib/active_record/fixtures.rb +76 -40
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +27 -40
- data/lib/active_record/integration.rb +4 -4
- data/lib/active_record/legacy_yaml_adapter.rb +18 -2
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +10 -14
- data/lib/active_record/locking/pessimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +40 -22
- data/lib/active_record/migration.rb +304 -133
- data/lib/active_record/migration/command_recorder.rb +59 -18
- data/lib/active_record/migration/compatibility.rb +90 -0
- data/lib/active_record/model_schema.rb +92 -40
- data/lib/active_record/nested_attributes.rb +45 -34
- data/lib/active_record/null_relation.rb +15 -7
- data/lib/active_record/persistence.rb +112 -72
- data/lib/active_record/querying.rb +6 -5
- data/lib/active_record/railtie.rb +20 -13
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +47 -38
- data/lib/active_record/readonly_attributes.rb +1 -1
- data/lib/active_record/reflection.rb +182 -57
- data/lib/active_record/relation.rb +152 -100
- data/lib/active_record/relation/batches.rb +133 -33
- data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
- data/lib/active_record/relation/calculations.rb +80 -101
- data/lib/active_record/relation/delegation.rb +6 -19
- data/lib/active_record/relation/finder_methods.rb +58 -46
- data/lib/active_record/relation/from_clause.rb +32 -0
- data/lib/active_record/relation/merger.rb +13 -42
- data/lib/active_record/relation/predicate_builder.rb +99 -105
- data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +78 -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/range_handler.rb +17 -0
- data/lib/active_record/relation/query_attribute.rb +19 -0
- data/lib/active_record/relation/query_methods.rb +274 -238
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -6
- data/lib/active_record/relation/where_clause.rb +173 -0
- data/lib/active_record/relation/where_clause_factory.rb +37 -0
- data/lib/active_record/result.rb +4 -3
- data/lib/active_record/runtime_registry.rb +1 -1
- data/lib/active_record/sanitization.rb +94 -65
- data/lib/active_record/schema.rb +23 -22
- data/lib/active_record/schema_dumper.rb +33 -22
- data/lib/active_record/schema_migration.rb +10 -4
- data/lib/active_record/scoping.rb +17 -6
- data/lib/active_record/scoping/default.rb +19 -6
- data/lib/active_record/scoping/named.rb +39 -28
- data/lib/active_record/secure_token.rb +38 -0
- data/lib/active_record/serialization.rb +2 -4
- data/lib/active_record/statement_cache.rb +15 -13
- data/lib/active_record/store.rb +8 -3
- data/lib/active_record/suppressor.rb +54 -0
- data/lib/active_record/table_metadata.rb +64 -0
- data/lib/active_record/tasks/database_tasks.rb +30 -40
- data/lib/active_record/tasks/mysql_database_tasks.rb +7 -15
- data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
- data/lib/active_record/timestamp.rb +16 -9
- data/lib/active_record/touch_later.rb +58 -0
- data/lib/active_record/transactions.rb +138 -56
- data/lib/active_record/type.rb +66 -17
- data/lib/active_record/type/adapter_specific_registry.rb +130 -0
- data/lib/active_record/type/date.rb +2 -45
- data/lib/active_record/type/date_time.rb +2 -49
- data/lib/active_record/type/internal/abstract_json.rb +33 -0
- data/lib/active_record/type/internal/timezone.rb +15 -0
- data/lib/active_record/type/serialized.rb +9 -14
- data/lib/active_record/type/time.rb +3 -21
- data/lib/active_record/type/type_map.rb +4 -4
- data/lib/active_record/type_caster.rb +7 -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/validations.rb +33 -32
- data/lib/active_record/validations/absence.rb +24 -0
- data/lib/active_record/validations/associated.rb +10 -3
- data/lib/active_record/validations/length.rb +36 -0
- data/lib/active_record/validations/presence.rb +12 -12
- data/lib/active_record/validations/uniqueness.rb +24 -21
- data/lib/rails/generators/active_record/migration.rb +7 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
- data/lib/rails/generators/active_record/migration/templates/migration.rb +4 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +21 -15
- data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
- metadata +50 -35
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -64
- data/lib/active_record/type/decimal_without_scale.rb +0 -11
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/text.rb +0 -11
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/unsigned_integer.rb +0 -15
- data/lib/active_record/type/value.rb +0 -110
@@ -2,18 +2,14 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters
|
3
3
|
# PostgreSQL-specific extensions to column definitions in a table.
|
4
4
|
class PostgreSQLColumn < Column #:nodoc:
|
5
|
-
|
5
|
+
delegate :array, :oid, :fmod, to: :sql_type_metadata
|
6
|
+
alias :array? :array
|
6
7
|
|
7
|
-
def
|
8
|
-
|
9
|
-
@array = true
|
10
|
-
super(name, default, cast_type, sql_type[0..sql_type.length - 3], null)
|
11
|
-
else
|
12
|
-
@array = false
|
13
|
-
super(name, default, cast_type, sql_type, null)
|
14
|
-
end
|
8
|
+
def serial?
|
9
|
+
return unless default_function
|
15
10
|
|
16
|
-
|
11
|
+
table_name = @table_name || '(?<table_name>.+)'
|
12
|
+
%r{\Anextval\('"?#{table_name}_#{name}_seq"?'::regclass\)\z} === default_function
|
17
13
|
end
|
18
14
|
end
|
19
15
|
end
|
@@ -8,7 +8,7 @@ module ActiveRecord
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class ExplainPrettyPrinter # :nodoc:
|
11
|
-
# Pretty prints the result of
|
11
|
+
# Pretty prints the result of an EXPLAIN in a way that resembles the output of the
|
12
12
|
# PostgreSQL shell:
|
13
13
|
#
|
14
14
|
# QUERY PLAN
|
@@ -156,8 +156,8 @@ module ActiveRecord
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
-
def exec_query(sql, name = 'SQL', binds = [])
|
160
|
-
execute_and_clear(sql, name, binds) do |result|
|
159
|
+
def exec_query(sql, name = 'SQL', binds = [], prepare: false)
|
160
|
+
execute_and_clear(sql, name, binds, prepare: prepare) do |result|
|
161
161
|
types = {}
|
162
162
|
fields = result.fields
|
163
163
|
fields.each_with_index do |fname, i|
|
@@ -1,25 +1,20 @@
|
|
1
|
-
require 'active_record/connection_adapters/postgresql/oid/infinity'
|
2
|
-
|
3
1
|
require 'active_record/connection_adapters/postgresql/oid/array'
|
4
2
|
require 'active_record/connection_adapters/postgresql/oid/bit'
|
5
3
|
require 'active_record/connection_adapters/postgresql/oid/bit_varying'
|
6
4
|
require 'active_record/connection_adapters/postgresql/oid/bytea'
|
7
5
|
require 'active_record/connection_adapters/postgresql/oid/cidr'
|
8
|
-
require 'active_record/connection_adapters/postgresql/oid/date'
|
9
6
|
require 'active_record/connection_adapters/postgresql/oid/date_time'
|
10
7
|
require 'active_record/connection_adapters/postgresql/oid/decimal'
|
11
8
|
require 'active_record/connection_adapters/postgresql/oid/enum'
|
12
|
-
require 'active_record/connection_adapters/postgresql/oid/float'
|
13
9
|
require 'active_record/connection_adapters/postgresql/oid/hstore'
|
14
10
|
require 'active_record/connection_adapters/postgresql/oid/inet'
|
15
|
-
require 'active_record/connection_adapters/postgresql/oid/integer'
|
16
11
|
require 'active_record/connection_adapters/postgresql/oid/json'
|
17
12
|
require 'active_record/connection_adapters/postgresql/oid/jsonb'
|
18
13
|
require 'active_record/connection_adapters/postgresql/oid/money'
|
19
14
|
require 'active_record/connection_adapters/postgresql/oid/point'
|
15
|
+
require 'active_record/connection_adapters/postgresql/oid/rails_5_1_point'
|
20
16
|
require 'active_record/connection_adapters/postgresql/oid/range'
|
21
17
|
require 'active_record/connection_adapters/postgresql/oid/specialized_string'
|
22
|
-
require 'active_record/connection_adapters/postgresql/oid/time'
|
23
18
|
require 'active_record/connection_adapters/postgresql/oid/uuid'
|
24
19
|
require 'active_record/connection_adapters/postgresql/oid/vector'
|
25
20
|
require 'active_record/connection_adapters/postgresql/oid/xml'
|
@@ -3,51 +3,53 @@ module ActiveRecord
|
|
3
3
|
module PostgreSQL
|
4
4
|
module OID # :nodoc:
|
5
5
|
class Array < Type::Value # :nodoc:
|
6
|
-
include Type::Mutable
|
7
|
-
|
8
|
-
# Loads pg_array_parser if available. String parsing can be
|
9
|
-
# performed quicker by a native extension, which will not create
|
10
|
-
# a large amount of Ruby objects that will need to be garbage
|
11
|
-
# collected. pg_array_parser has a C and Java extension
|
12
|
-
begin
|
13
|
-
require 'pg_array_parser'
|
14
|
-
include PgArrayParser
|
15
|
-
rescue LoadError
|
16
|
-
require 'active_record/connection_adapters/postgresql/array_parser'
|
17
|
-
include PostgreSQL::ArrayParser
|
18
|
-
end
|
6
|
+
include Type::Helpers::Mutable
|
19
7
|
|
20
8
|
attr_reader :subtype, :delimiter
|
21
|
-
delegate :type, :limit, to: :subtype
|
9
|
+
delegate :type, :user_input_in_time_zone, :limit, to: :subtype
|
22
10
|
|
23
11
|
def initialize(subtype, delimiter = ',')
|
24
12
|
@subtype = subtype
|
25
13
|
@delimiter = delimiter
|
14
|
+
|
15
|
+
@pg_encoder = PG::TextEncoder::Array.new name: "#{type}[]", delimiter: delimiter
|
16
|
+
@pg_decoder = PG::TextDecoder::Array.new name: "#{type}[]", delimiter: delimiter
|
26
17
|
end
|
27
18
|
|
28
|
-
def
|
19
|
+
def deserialize(value)
|
29
20
|
if value.is_a?(::String)
|
30
|
-
type_cast_array(
|
21
|
+
type_cast_array(@pg_decoder.decode(value), :deserialize)
|
31
22
|
else
|
32
23
|
super
|
33
24
|
end
|
34
25
|
end
|
35
26
|
|
36
|
-
def
|
27
|
+
def cast(value)
|
37
28
|
if value.is_a?(::String)
|
38
|
-
value =
|
29
|
+
value = @pg_decoder.decode(value)
|
39
30
|
end
|
40
|
-
type_cast_array(value, :
|
31
|
+
type_cast_array(value, :cast)
|
41
32
|
end
|
42
33
|
|
43
|
-
def
|
34
|
+
def serialize(value)
|
44
35
|
if value.is_a?(::Array)
|
45
|
-
|
36
|
+
@pg_encoder.encode(type_cast_array(value, :serialize))
|
46
37
|
else
|
47
38
|
super
|
48
39
|
end
|
49
40
|
end
|
50
41
|
|
42
|
+
def ==(other)
|
43
|
+
other.is_a?(Array) &&
|
44
|
+
subtype == other.subtype &&
|
45
|
+
delimiter == other.delimiter
|
46
|
+
end
|
47
|
+
|
48
|
+
def type_cast_for_schema(value)
|
49
|
+
return super unless value.is_a?(::Array)
|
50
|
+
"[" + value.map { |v| subtype.type_cast_for_schema(v) }.join(", ") + "]"
|
51
|
+
end
|
52
|
+
|
51
53
|
private
|
52
54
|
|
53
55
|
def type_cast_array(value, method)
|
@@ -57,42 +59,6 @@ module ActiveRecord
|
|
57
59
|
@subtype.public_send(method, value)
|
58
60
|
end
|
59
61
|
end
|
60
|
-
|
61
|
-
def cast_value_for_database(value)
|
62
|
-
if value.is_a?(::Array)
|
63
|
-
casted_values = value.map { |item| cast_value_for_database(item) }
|
64
|
-
"{#{casted_values.join(delimiter)}}"
|
65
|
-
else
|
66
|
-
quote_and_escape(subtype.type_cast_for_database(value))
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays
|
71
|
-
|
72
|
-
def quote_and_escape(value)
|
73
|
-
case value
|
74
|
-
when ::String
|
75
|
-
if string_requires_quoting?(value)
|
76
|
-
value = value.gsub(/\\/, ARRAY_ESCAPE)
|
77
|
-
value.gsub!(/"/,"\\\"")
|
78
|
-
%("#{value}")
|
79
|
-
else
|
80
|
-
value
|
81
|
-
end
|
82
|
-
when nil then "NULL"
|
83
|
-
when ::Date, ::DateTime, ::Time then subtype.type_cast_for_schema(value)
|
84
|
-
else value
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# See http://www.postgresql.org/docs/9.2/static/arrays.html#ARRAYS-IO
|
89
|
-
# for a list of all cases in which strings will be quoted.
|
90
|
-
def string_requires_quoting?(string)
|
91
|
-
string.empty? ||
|
92
|
-
string == "NULL" ||
|
93
|
-
string =~ /[\{\}"\\\s]/ ||
|
94
|
-
string.include?(delimiter)
|
95
|
-
end
|
96
62
|
end
|
97
63
|
end
|
98
64
|
end
|
@@ -7,7 +7,7 @@ module ActiveRecord
|
|
7
7
|
:bit
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def cast(value)
|
11
11
|
if ::String === value
|
12
12
|
case value
|
13
13
|
when /^0x/i
|
@@ -20,7 +20,7 @@ module ActiveRecord
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def serialize(value)
|
24
24
|
Data.new(super) if value
|
25
25
|
end
|
26
26
|
|
@@ -3,7 +3,7 @@ module ActiveRecord
|
|
3
3
|
module PostgreSQL
|
4
4
|
module OID # :nodoc:
|
5
5
|
class Bytea < Type::Binary # :nodoc:
|
6
|
-
def
|
6
|
+
def deserialize(value)
|
7
7
|
return if value.nil?
|
8
8
|
return value.to_s if value.is_a?(Type::Binary::Data)
|
9
9
|
PGconn.unescape_bytea(super)
|
@@ -3,30 +3,15 @@ module ActiveRecord
|
|
3
3
|
module PostgreSQL
|
4
4
|
module OID # :nodoc:
|
5
5
|
class DateTime < Type::DateTime # :nodoc:
|
6
|
-
include Infinity
|
7
|
-
|
8
|
-
def type_cast_for_database(value)
|
9
|
-
if has_precision? && value.acts_like?(:time) && value.year <= 0
|
10
|
-
bce_year = format("%04d", -value.year + 1)
|
11
|
-
super.sub(/^-?\d+/, bce_year) + " BC"
|
12
|
-
else
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
6
|
def cast_value(value)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
|
25
|
-
else
|
26
|
-
super
|
27
|
-
end
|
7
|
+
case value
|
8
|
+
when 'infinity' then ::Float::INFINITY
|
9
|
+
when '-infinity' then -::Float::INFINITY
|
10
|
+
when / BC$/
|
11
|
+
astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
|
12
|
+
super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
|
28
13
|
else
|
29
|
-
|
14
|
+
super
|
30
15
|
end
|
31
16
|
end
|
32
17
|
end
|
@@ -3,13 +3,13 @@ module ActiveRecord
|
|
3
3
|
module PostgreSQL
|
4
4
|
module OID # :nodoc:
|
5
5
|
class Hstore < Type::Value # :nodoc:
|
6
|
-
include Type::Mutable
|
6
|
+
include Type::Helpers::Mutable
|
7
7
|
|
8
8
|
def type
|
9
9
|
:hstore
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def deserialize(value)
|
13
13
|
if value.is_a?(::String)
|
14
14
|
::Hash[value.scan(HstorePair).map { |k, v|
|
15
15
|
v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
|
@@ -21,7 +21,7 @@ module ActiveRecord
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def serialize(value)
|
25
25
|
if value.is_a?(::Hash)
|
26
26
|
value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(', ')
|
27
27
|
else
|
@@ -2,32 +2,7 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters
|
3
3
|
module PostgreSQL
|
4
4
|
module OID # :nodoc:
|
5
|
-
class Json < Type::
|
6
|
-
include Type::Mutable
|
7
|
-
|
8
|
-
def type
|
9
|
-
:json
|
10
|
-
end
|
11
|
-
|
12
|
-
def type_cast_from_database(value)
|
13
|
-
if value.is_a?(::String)
|
14
|
-
::ActiveSupport::JSON.decode(value) rescue nil
|
15
|
-
else
|
16
|
-
super
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def type_cast_for_database(value)
|
21
|
-
if value.is_a?(::Array) || value.is_a?(::Hash)
|
22
|
-
::ActiveSupport::JSON.encode(value)
|
23
|
-
else
|
24
|
-
super
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def accessor
|
29
|
-
ActiveRecord::Store::StringKeyedHashAccessor
|
30
|
-
end
|
5
|
+
class Json < Type::Internal::AbstractJson
|
31
6
|
end
|
32
7
|
end
|
33
8
|
end
|
@@ -9,11 +9,11 @@ module ActiveRecord
|
|
9
9
|
|
10
10
|
def changed_in_place?(raw_old_value, new_value)
|
11
11
|
# Postgres does not preserve insignificant whitespaces when
|
12
|
-
#
|
12
|
+
# round-tripping jsonb columns. This causes some false positives for
|
13
13
|
# the comparison here. Therefore, we need to parse and re-dump the
|
14
14
|
# raw value here to ensure the insignificant whitespaces are
|
15
15
|
# consistent with our encoder's output.
|
16
|
-
raw_old_value =
|
16
|
+
raw_old_value = serialize(deserialize(raw_old_value))
|
17
17
|
super(raw_old_value, new_value)
|
18
18
|
end
|
19
19
|
end
|
@@ -3,19 +3,19 @@ module ActiveRecord
|
|
3
3
|
module PostgreSQL
|
4
4
|
module OID # :nodoc:
|
5
5
|
class Point < Type::Value # :nodoc:
|
6
|
-
include Type::Mutable
|
6
|
+
include Type::Helpers::Mutable
|
7
7
|
|
8
8
|
def type
|
9
9
|
:point
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def cast(value)
|
13
13
|
case value
|
14
14
|
when ::String
|
15
15
|
if value[0] == '(' && value[-1] == ')'
|
16
16
|
value = value[1...-1]
|
17
17
|
end
|
18
|
-
|
18
|
+
cast(value.split(','))
|
19
19
|
when ::Array
|
20
20
|
value.map { |v| Float(v) }
|
21
21
|
else
|
@@ -23,7 +23,7 @@ module ActiveRecord
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def serialize(value)
|
27
27
|
if value.is_a?(::Array)
|
28
28
|
"(#{number_for_point(value[0])},#{number_for_point(value[1])})"
|
29
29
|
else
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
Point = Struct.new(:x, :y)
|
3
|
+
|
4
|
+
module ConnectionAdapters
|
5
|
+
module PostgreSQL
|
6
|
+
module OID # :nodoc:
|
7
|
+
class Rails51Point < Type::Value # :nodoc:
|
8
|
+
include Type::Helpers::Mutable
|
9
|
+
|
10
|
+
def type
|
11
|
+
:point
|
12
|
+
end
|
13
|
+
|
14
|
+
def cast(value)
|
15
|
+
case value
|
16
|
+
when ::String
|
17
|
+
if value[0] == '(' && value[-1] == ')'
|
18
|
+
value = value[1...-1]
|
19
|
+
end
|
20
|
+
x, y = value.split(",")
|
21
|
+
build_point(x, y)
|
22
|
+
when ::Array
|
23
|
+
build_point(*value)
|
24
|
+
else
|
25
|
+
value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def serialize(value)
|
30
|
+
if value.is_a?(ActiveRecord::Point)
|
31
|
+
"(#{number_for_point(value.x)},#{number_for_point(value.y)})"
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def number_for_point(number)
|
40
|
+
number.to_s.gsub(/\.0$/, '')
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_point(x, y)
|
44
|
+
ActiveRecord::Point.new(Float(x), Float(y))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -7,7 +7,7 @@ module ActiveRecord
|
|
7
7
|
class Range < Type::Value # :nodoc:
|
8
8
|
attr_reader :subtype, :type
|
9
9
|
|
10
|
-
def initialize(subtype, type)
|
10
|
+
def initialize(subtype, type = :range)
|
11
11
|
@subtype = subtype
|
12
12
|
@type = type
|
13
13
|
end
|
@@ -25,21 +25,12 @@ module ActiveRecord
|
|
25
25
|
to = type_cast_single extracted[:to]
|
26
26
|
|
27
27
|
if !infinity?(from) && extracted[:exclude_start]
|
28
|
-
|
29
|
-
from = from.succ
|
30
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
31
|
-
Excluding the beginning of a Range is only partialy supported
|
32
|
-
through `#succ`. This is not reliable and will be removed in
|
33
|
-
the future.
|
34
|
-
MSG
|
35
|
-
else
|
36
|
-
raise ArgumentError, "The Ruby Range object does not support excluding the beginning of a Range. (unsupported value: '#{value}')"
|
37
|
-
end
|
28
|
+
raise ArgumentError, "The Ruby Range object does not support excluding the beginning of a Range. (unsupported value: '#{value}')"
|
38
29
|
end
|
39
30
|
::Range.new(from, to, extracted[:exclude_end])
|
40
31
|
end
|
41
32
|
|
42
|
-
def
|
33
|
+
def serialize(value)
|
43
34
|
if value.is_a?(::Range)
|
44
35
|
from = type_cast_single_for_database(value.begin)
|
45
36
|
to = type_cast_single_for_database(value.end)
|
@@ -49,26 +40,42 @@ module ActiveRecord
|
|
49
40
|
end
|
50
41
|
end
|
51
42
|
|
43
|
+
def ==(other)
|
44
|
+
other.is_a?(Range) &&
|
45
|
+
other.subtype == subtype &&
|
46
|
+
other.type == type
|
47
|
+
end
|
48
|
+
|
52
49
|
private
|
53
50
|
|
54
51
|
def type_cast_single(value)
|
55
|
-
infinity?(value) ? value : @subtype.
|
52
|
+
infinity?(value) ? value : @subtype.deserialize(value)
|
56
53
|
end
|
57
54
|
|
58
55
|
def type_cast_single_for_database(value)
|
59
|
-
infinity?(value) ? '' : @subtype.
|
56
|
+
infinity?(value) ? '' : @subtype.serialize(value)
|
60
57
|
end
|
61
58
|
|
62
59
|
def extract_bounds(value)
|
63
60
|
from, to = value[1..-2].split(',')
|
64
61
|
{
|
65
|
-
from: (value[1] == ',' || from == '-infinity') ?
|
66
|
-
to: (value[-2] == ',' || to == 'infinity') ?
|
62
|
+
from: (value[1] == ',' || from == '-infinity') ? infinity(negative: true) : from,
|
63
|
+
to: (value[-2] == ',' || to == 'infinity') ? infinity : to,
|
67
64
|
exclude_start: (value[0] == '('),
|
68
65
|
exclude_end: (value[-1] == ')')
|
69
66
|
}
|
70
67
|
end
|
71
68
|
|
69
|
+
def infinity(negative: false)
|
70
|
+
if subtype.respond_to?(:infinity)
|
71
|
+
subtype.infinity(negative: negative)
|
72
|
+
elsif negative
|
73
|
+
-::Float::INFINITY
|
74
|
+
else
|
75
|
+
::Float::INFINITY
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
72
79
|
def infinity?(value)
|
73
80
|
value.respond_to?(:infinite?) && value.infinite?
|
74
81
|
end
|