rom-sql 3.6.4 → 4.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -48
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/lib/rom/plugins/relation/sql/auto_restrictions.rb +11 -10
- data/lib/rom/plugins/relation/sql/default_views.rb +75 -0
- data/lib/rom/plugins/relation/sql/instrumentation.rb +8 -13
- data/lib/rom/plugins/relation/sql/postgres/explain.rb +4 -4
- data/lib/rom/plugins/relation/sql/postgres/full_text_search.rb +18 -16
- data/lib/rom/plugins/relation/sql/postgres/streaming.rb +12 -9
- data/lib/rom/sql/associations/many_to_many.rb +7 -7
- data/lib/rom/sql/associations/many_to_one.rb +3 -3
- data/lib/rom/sql/associations/one_to_many.rb +3 -3
- data/lib/rom/sql/associations/one_to_one.rb +1 -1
- data/lib/rom/sql/associations/one_to_one_through.rb +1 -1
- data/lib/rom/sql/associations/self_ref.rb +1 -1
- data/lib/rom/sql/associations.rb +5 -5
- data/lib/rom/sql/attribute.rb +9 -9
- data/lib/rom/sql/attribute_aliasing.rb +2 -3
- data/lib/rom/sql/commands/create.rb +5 -4
- data/lib/rom/sql/commands/delete.rb +2 -2
- data/lib/rom/sql/commands/update.rb +5 -4
- data/lib/rom/sql/commands.rb +4 -4
- data/lib/rom/sql/dsl.rb +3 -3
- data/lib/rom/sql/errors.rb +3 -3
- data/lib/rom/sql/extensions/active_support_notifications.rb +4 -4
- data/lib/rom/sql/extensions/mysql/type_builder.rb +5 -5
- data/lib/rom/sql/extensions/mysql.rb +1 -1
- data/lib/rom/sql/extensions/postgres/commands.rb +13 -31
- data/lib/rom/sql/extensions/postgres/type_builder.rb +28 -31
- data/lib/rom/sql/extensions/postgres/type_serializer.rb +24 -25
- data/lib/rom/sql/extensions/postgres/types/array.rb +4 -4
- data/lib/rom/sql/extensions/postgres/types/array_types.rb +1 -1
- data/lib/rom/sql/extensions/postgres/types/geometric.rb +27 -27
- data/lib/rom/sql/extensions/postgres/types/json.rb +9 -9
- data/lib/rom/sql/extensions/postgres/types/ltree.rb +61 -34
- data/lib/rom/sql/extensions/postgres/types/network.rb +4 -17
- data/lib/rom/sql/extensions/postgres/types/range.rb +25 -25
- data/lib/rom/sql/extensions/postgres/types.rb +14 -14
- data/lib/rom/sql/extensions/postgres.rb +6 -6
- data/lib/rom/sql/extensions/rails_log_subscriber.rb +6 -21
- data/lib/rom/sql/extensions/sqlite/types.rb +1 -1
- data/lib/rom/sql/extensions/sqlite.rb +2 -2
- data/lib/rom/sql/extensions.rb +6 -6
- data/lib/rom/sql/foreign_key.rb +3 -1
- data/lib/rom/sql/function.rb +18 -22
- data/lib/rom/sql/gateway.rb +44 -17
- data/lib/rom/sql/group_dsl.rb +1 -1
- data/lib/rom/sql/index.rb +2 -0
- data/lib/rom/sql/join_dsl.rb +1 -1
- data/lib/rom/sql/mapper_compiler.rb +2 -2
- data/lib/rom/sql/migration/migrator.rb +11 -11
- data/lib/rom/sql/migration/runner.rb +3 -3
- data/lib/rom/sql/migration/schema_diff.rb +7 -8
- data/lib/rom/sql/migration/writer.rb +12 -12
- data/lib/rom/sql/migration.rb +4 -8
- data/lib/rom/sql/order_dsl.rb +1 -1
- data/lib/rom/sql/plugin/associates.rb +49 -11
- data/lib/rom/sql/plugin/pagination.rb +5 -3
- data/lib/rom/sql/plugin/schema_indexes.rb +35 -0
- data/lib/rom/sql/plugins.rb +9 -6
- data/lib/rom/sql/projection_dsl.rb +4 -4
- data/lib/rom/sql/rake_task.rb +2 -2
- data/lib/rom/sql/relation/reading.rb +34 -27
- data/lib/rom/sql/relation/writing.rb +11 -10
- data/lib/rom/sql/relation.rb +57 -89
- data/lib/rom/sql/restriction_dsl.rb +2 -2
- data/lib/rom/sql/schema/attributes_inferrer.rb +3 -3
- data/lib/rom/sql/schema/dsl.rb +4 -2
- data/lib/rom/sql/schema/index_dsl.rb +3 -5
- data/lib/rom/sql/schema/inferrer.rb +25 -23
- data/lib/rom/sql/schema/type_builder.rb +2 -2
- data/lib/rom/sql/schema.rb +9 -21
- data/lib/rom/sql/spec/support.rb +5 -5
- data/lib/rom/sql/tasks/migration_tasks.rake +13 -21
- data/lib/rom/sql/transaction.rb +4 -2
- data/lib/rom/sql/type_extensions.rb +3 -1
- data/lib/rom/sql/type_serializer.rb +10 -10
- data/lib/rom/sql/types.rb +4 -4
- data/lib/rom/sql/version.rb +1 -1
- data/lib/rom/sql/wrap.rb +1 -1
- data/lib/rom/sql.rb +13 -12
- data/lib/rom/types/values.rb +2 -2
- data/lib/rom-sql.rb +1 -1
- metadata +13 -17
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "rom/sql/commands/error_wrapper"
|
4
4
|
|
5
5
|
module ROM
|
6
6
|
module SQL
|
@@ -9,7 +9,7 @@ module ROM
|
|
9
9
|
#
|
10
10
|
# @api public
|
11
11
|
class Update < ROM::Commands::Update
|
12
|
-
adapter :sql
|
12
|
+
config.component.adapter = :sql
|
13
13
|
|
14
14
|
include ErrorWrapper
|
15
15
|
|
@@ -52,10 +52,11 @@ module ROM
|
|
52
52
|
# Yields tuples for insertion or return an enumerator
|
53
53
|
#
|
54
54
|
# @api private
|
55
|
-
def with_input_tuples(tuples)
|
55
|
+
def with_input_tuples(tuples, &block)
|
56
56
|
input_tuples = Array([tuples]).flatten(1).map
|
57
57
|
return input_tuples unless block_given?
|
58
|
-
|
58
|
+
|
59
|
+
input_tuples.each(&block)
|
59
60
|
end
|
60
61
|
end
|
61
62
|
end
|
data/lib/rom/sql/commands.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "rom/commands"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
5
|
+
require "rom/sql/commands/create"
|
6
|
+
require "rom/sql/commands/update"
|
7
|
+
require "rom/sql/commands/delete"
|
data/lib/rom/sql/dsl.rb
CHANGED
data/lib/rom/sql/errors.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "sequel/database/logging"
|
4
|
+
require "active_support/notifications"
|
5
5
|
|
6
6
|
module ROM
|
7
7
|
module SQL
|
8
8
|
module ActiveSupportInstrumentation
|
9
9
|
def log_connection_yield(sql, _conn, args = nil)
|
10
10
|
ActiveSupport::Notifications.instrument(
|
11
|
-
|
11
|
+
"sql.rom",
|
12
12
|
sql: sql,
|
13
13
|
name: instrumentation_name,
|
14
14
|
binds: args
|
@@ -24,4 +24,4 @@ module ROM
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
Sequel::Database.
|
27
|
+
Sequel::Database.prepend ROM::SQL::ActiveSupportInstrumentation
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "rom/sql/schema/attributes_inferrer"
|
4
4
|
|
5
5
|
module ROM
|
6
6
|
module SQL
|
@@ -9,10 +9,10 @@ module ROM
|
|
9
9
|
defines :db_type_mapping
|
10
10
|
|
11
11
|
db_type_mapping(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
"tinytext" => Types::String,
|
13
|
+
"text" => Types::String,
|
14
|
+
"mediumtext" => Types::String,
|
15
|
+
"longtext" => Types::String
|
16
16
|
).freeze
|
17
17
|
|
18
18
|
def map_type(ruby_type, db_type, **_)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "rom/sql/commands/create"
|
4
|
+
require "rom/sql/commands/update"
|
5
5
|
|
6
6
|
module ROM
|
7
7
|
module SQL
|
@@ -83,29 +83,33 @@ module ROM
|
|
83
83
|
#
|
84
84
|
# @api public
|
85
85
|
class Upsert < SQL::Commands::Create
|
86
|
-
adapter :sql
|
86
|
+
config.component.adapter = :sql
|
87
87
|
|
88
|
-
|
88
|
+
setting :constraint
|
89
|
+
setting :conflict_target
|
90
|
+
setting :conflict_where
|
91
|
+
setting :update_statement
|
92
|
+
setting :update_where
|
89
93
|
|
90
94
|
# @!attribute [r] constraint
|
91
95
|
# @return [Symbol] the name of the constraint expected to be violated
|
92
|
-
option :constraint, default: -> {
|
96
|
+
option :constraint, default: -> { config.constraint }
|
93
97
|
|
94
98
|
# @!attribute [r] conflict_target
|
95
99
|
# @return [Object] the column or expression to handle a violation on
|
96
|
-
option :conflict_target, default: -> {
|
100
|
+
option :conflict_target, default: -> { config.conflict_target }
|
97
101
|
|
98
102
|
# @!attribute [r] conflict_where
|
99
103
|
# @return [Object] the index filter, when using a partial index to determine uniqueness
|
100
|
-
option :conflict_where, default: -> {
|
104
|
+
option :conflict_where, default: -> { config.conflict_where }
|
101
105
|
|
102
106
|
# @!attribute [r] update_statement
|
103
107
|
# @return [Object] the update statement which will be executed in case of a violation
|
104
|
-
option :update_statement, default: -> {
|
108
|
+
option :update_statement, default: -> { config.update_statement }
|
105
109
|
|
106
110
|
# @!attribute [r] update_where
|
107
111
|
# @return [Object] the WHERE clause to be added to the update
|
108
|
-
option :update_where, default: -> {
|
112
|
+
option :update_where, default: -> { config.update_where }
|
109
113
|
|
110
114
|
# Tries to insert provided tuples and do an update (or nothing)
|
111
115
|
# when the inserted record violates a unique constraint and hence
|
@@ -137,27 +141,5 @@ module ROM
|
|
137
141
|
end
|
138
142
|
|
139
143
|
Commands::Postgres = Postgres::Commands
|
140
|
-
|
141
|
-
Gateway.subscribe('configuration.commands.class.before_build') do |event|
|
142
|
-
klass = event[:command]
|
143
|
-
|
144
|
-
# TODO: remove this conditional in favor of `adapter: :sql` in subscribe
|
145
|
-
# this is here for backward compatibilty with rom-core 4.x
|
146
|
-
if klass.adapter == :sql
|
147
|
-
dataset = event[:dataset]
|
148
|
-
type = dataset.db.database_type
|
149
|
-
|
150
|
-
if type == :postgres
|
151
|
-
ext =
|
152
|
-
if klass < Commands::Create
|
153
|
-
Postgres::Commands::Create
|
154
|
-
elsif klass < Commands::Update
|
155
|
-
Postgres::Commands::Update
|
156
|
-
end
|
157
|
-
|
158
|
-
klass.include(ext) if ext
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
144
|
end
|
163
145
|
end
|
@@ -6,40 +6,37 @@ module ROM
|
|
6
6
|
class TypeBuilder < Schema::TypeBuilder
|
7
7
|
defines :db_numeric_types, :db_type_mapping, :db_array_type_matcher
|
8
8
|
|
9
|
-
db_numeric_types
|
10
|
-
|
11
|
-
decimal numeric real
|
12
|
-
double\ precision serial bigserial
|
13
|
-
].to_set.freeze
|
9
|
+
db_numeric_types ["smallint", "integer", "bigint", "decimal", "numeric", "real",
|
10
|
+
"double precision", "serial", "bigserial"].to_set.freeze
|
14
11
|
|
15
12
|
db_type_mapping(
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
13
|
+
"uuid" => Types::UUID,
|
14
|
+
"money" => Types::Money,
|
15
|
+
"bytea" => Types::Bytea,
|
16
|
+
"json" => Types::JSON,
|
17
|
+
"jsonb" => Types::JSONB,
|
18
|
+
"xml" => Types::XML,
|
19
|
+
"inet" => Types::IPAddress,
|
20
|
+
"cidr" => Types::IPAddress,
|
21
|
+
"macaddr" => SQL::Types::String,
|
22
|
+
"point" => Types::Point,
|
23
|
+
"hstore" => Types::HStore,
|
24
|
+
"line" => Types::Line,
|
25
|
+
"circle" => Types::Circle,
|
26
|
+
"box" => Types::Box,
|
27
|
+
"lseg" => Types::LineSegment,
|
28
|
+
"polygon" => Types::Polygon,
|
29
|
+
"path" => Types::Path,
|
30
|
+
"int4range" => Types::Int4Range,
|
31
|
+
"int8range" => Types::Int8Range,
|
32
|
+
"numrange" => Types::NumRange,
|
33
|
+
"tsrange" => Types::TsRange,
|
34
|
+
"tstzrange" => Types::TsTzRange,
|
35
|
+
"daterange" => Types::DateRange,
|
36
|
+
"ltree" => Types::LTree
|
40
37
|
).freeze
|
41
38
|
|
42
|
-
db_array_type_matcher
|
39
|
+
db_array_type_matcher "[]"
|
43
40
|
|
44
41
|
def map_pk_type(type, db_type, **options)
|
45
42
|
if numeric?(type, db_type)
|
@@ -66,7 +63,7 @@ module ROM
|
|
66
63
|
|
67
64
|
def map_db_type(db_type)
|
68
65
|
self.class.db_type_mapping[db_type] ||
|
69
|
-
(db_type.start_with?(
|
66
|
+
(db_type.start_with?("timestamp") ? SQL::Types::Time : nil)
|
70
67
|
end
|
71
68
|
|
72
69
|
def numeric?(ruby_type, db_type)
|
@@ -7,37 +7,36 @@ module ROM
|
|
7
7
|
class TypeSerializer < ROM::SQL::TypeSerializer
|
8
8
|
mapping(
|
9
9
|
mapping.merge(
|
10
|
-
SQL::Types::String =>
|
11
|
-
Types::UUID =>
|
12
|
-
Types::XML =>
|
13
|
-
Types::Money =>
|
14
|
-
Types::Bytea =>
|
15
|
-
Types::JSON =>
|
16
|
-
Types::JSONB =>
|
17
|
-
Types::HStore =>
|
18
|
-
Types::IPAddress =>
|
19
|
-
Types::
|
20
|
-
Types::
|
21
|
-
Types::
|
22
|
-
Types::
|
23
|
-
Types::
|
24
|
-
Types::
|
25
|
-
Types::
|
26
|
-
Types::
|
27
|
-
Types::
|
28
|
-
Types::
|
29
|
-
Types::
|
30
|
-
Types::
|
31
|
-
Types::
|
32
|
-
Types::
|
33
|
-
Types::LTree => 'ltree'
|
10
|
+
SQL::Types::String => "text",
|
11
|
+
Types::UUID => "uuid",
|
12
|
+
Types::XML => "xml",
|
13
|
+
Types::Money => "money",
|
14
|
+
Types::Bytea => "bytea",
|
15
|
+
Types::JSON => "json",
|
16
|
+
Types::JSONB => "jsonb",
|
17
|
+
Types::HStore => "hstore",
|
18
|
+
Types::IPAddress => "inet",
|
19
|
+
Types::Point => "point",
|
20
|
+
Types::Line => "line",
|
21
|
+
Types::Circle => "circle",
|
22
|
+
Types::Box => "box",
|
23
|
+
Types::LineSegment => "lseg",
|
24
|
+
Types::Polygon => "polygon",
|
25
|
+
Types::Path => "path",
|
26
|
+
Types::Int4Range => "int4range",
|
27
|
+
Types::Int8Range => "int8range",
|
28
|
+
Types::NumRange => "numrange",
|
29
|
+
Types::TsRange => "tsrange",
|
30
|
+
Types::TsTzRange => "tstzrange",
|
31
|
+
Types::DateRange => "daterange",
|
32
|
+
Types::LTree => "ltree"
|
34
33
|
)
|
35
34
|
)
|
36
35
|
|
37
36
|
def call(type)
|
38
37
|
super do
|
39
38
|
if type.respond_to?(:primitive) && type.primitive.equal?(Array)
|
40
|
-
"#{
|
39
|
+
"#{type.meta[:type]}[]"
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "sequel/core"
|
4
4
|
|
5
5
|
Sequel.extension(:pg_array, :pg_array_ops)
|
6
6
|
|
7
|
-
require
|
7
|
+
require "rom/sql/extensions/postgres/types/array_types"
|
8
8
|
|
9
9
|
module ROM
|
10
10
|
module SQL
|
@@ -123,7 +123,7 @@ module ROM
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def any(_type, expr, value)
|
126
|
-
Attribute[SQL::Types::Bool].meta(sql_expr: {
|
126
|
+
Attribute[SQL::Types::Bool].meta(sql_expr: {value => expr.pg_array.any})
|
127
127
|
end
|
128
128
|
|
129
129
|
def contained_by(type, expr, other)
|
@@ -142,7 +142,7 @@ module ROM
|
|
142
142
|
Attribute[type].meta(sql_expr: expr.pg_array.remove(cast(type, value)))
|
143
143
|
end
|
144
144
|
|
145
|
-
def join(_type, expr, delimiter =
|
145
|
+
def join(_type, expr, delimiter = "", null = nil)
|
146
146
|
Attribute[SQL::Types::String].meta(sql_expr: expr.pg_array.join(delimiter, null))
|
147
147
|
end
|
148
148
|
|
@@ -34,55 +34,55 @@ module ROM
|
|
34
34
|
# The list of geometric data types supported by PostgreSQL
|
35
35
|
# @see https://www.postgresql.org/docs/current/static/datatype-geometric.html
|
36
36
|
|
37
|
-
Point = Type(
|
37
|
+
Point = Type("point") do
|
38
38
|
SQL::Types.define(Values::Point) do
|
39
39
|
input do |point|
|
40
|
-
"(#{
|
40
|
+
"(#{point.x},#{point.y})"
|
41
41
|
end
|
42
42
|
|
43
43
|
output do |point|
|
44
|
-
x, y = point.to_s[1...-1].split(
|
44
|
+
x, y = point.to_s[1...-1].split(",", 2)
|
45
45
|
Values::Point.new(Float(x), Float(y))
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
Line = Type(
|
50
|
+
Line = Type("line") do
|
51
51
|
SQL::Types.define(Values::Line) do
|
52
52
|
input do |line|
|
53
|
-
"{#{
|
53
|
+
"{#{line.a},#{line.b},#{line.c}}"
|
54
54
|
end
|
55
55
|
|
56
56
|
output do |line|
|
57
|
-
a, b, c = line.to_s[1..-2].split(
|
57
|
+
a, b, c = line.to_s[1..-2].split(",", 3)
|
58
58
|
Values::Line.new(Float(a), Float(b), Float(c))
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
Circle = Type(
|
63
|
+
Circle = Type("circle") do
|
64
64
|
SQL::Types.define(Values::Circle) do
|
65
65
|
input do |circle|
|
66
|
-
"<(#{
|
66
|
+
"<(#{circle.center.x},#{circle.center.y}),#{circle.radius}>"
|
67
67
|
end
|
68
68
|
|
69
69
|
output do |circle|
|
70
|
-
x, y, r = circle.to_s.tr(
|
70
|
+
x, y, r = circle.to_s.tr("()<>", "").split(",", 3)
|
71
71
|
center = Values::Point.new(Float(x), Float(y))
|
72
72
|
Values::Circle.new(center, Float(r))
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
Box = Type(
|
77
|
+
Box = Type("box") do
|
78
78
|
SQL::Types.define(Values::Box) do
|
79
79
|
input do |box|
|
80
|
-
"((#{
|
81
|
-
|
80
|
+
"((#{box.upper_right.x},#{box.upper_right.y}),"\
|
81
|
+
"(#{box.lower_left.x},#{box.lower_left.y}))"
|
82
82
|
end
|
83
83
|
|
84
84
|
output do |box|
|
85
|
-
x_right, y_right, x_left, y_left = box.to_s.tr(
|
85
|
+
x_right, y_right, x_left, y_left = box.to_s.tr("()", "").split(",", 4)
|
86
86
|
upper_right = Values::Point.new(Float(x_right), Float(y_right))
|
87
87
|
lower_left = Values::Point.new(Float(x_left), Float(y_left))
|
88
88
|
Values::Box.new(upper_right, lower_left)
|
@@ -90,15 +90,15 @@ module ROM
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
LineSegment = Type(
|
93
|
+
LineSegment = Type("lseg") do
|
94
94
|
SQL::Types.define(Values::LineSegment) do
|
95
95
|
input do |segment|
|
96
|
-
"[(#{
|
97
|
-
|
96
|
+
"[(#{segment.begin.x},#{segment.begin.y}),"\
|
97
|
+
"(#{segment.end.x},#{segment.end.y})]"
|
98
98
|
end
|
99
99
|
|
100
100
|
output do |segment|
|
101
|
-
x_begin, y_begin, x_end, y_end = segment.to_s.tr(
|
101
|
+
x_begin, y_begin, x_end, y_end = segment.to_s.tr("()[]", "").split(",", 4)
|
102
102
|
point_begin = Values::Point.new(Float(x_begin), Float(y_begin))
|
103
103
|
point_end = Values::Point.new(Float(x_end), Float(y_end))
|
104
104
|
Values::LineSegment.new(point_begin, point_end)
|
@@ -106,35 +106,35 @@ module ROM
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
-
Polygon = Type(
|
109
|
+
Polygon = Type("polygon") do
|
110
110
|
SQL::Types.define(::Array) do
|
111
111
|
input do |points|
|
112
|
-
points_joined = points.map { |p| "(#{
|
113
|
-
"(#{
|
112
|
+
points_joined = points.map { |p| "(#{p.x},#{p.y})" }.join(",")
|
113
|
+
"(#{points_joined})"
|
114
114
|
end
|
115
115
|
|
116
116
|
output do |polygon|
|
117
|
-
coordinates = polygon.to_s.tr(
|
117
|
+
coordinates = polygon.to_s.tr("()", "").split(",").each_slice(2)
|
118
118
|
coordinates.map { |x, y| Values::Point.new(Float(x), Float(y)) }
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
Path = Type(
|
123
|
+
Path = Type("path") do
|
124
124
|
SQL::Types.define(Values::Path) do
|
125
125
|
input do |path|
|
126
|
-
points_joined = path.to_a.map { |p| "(#{
|
126
|
+
points_joined = path.to_a.map { |p| "(#{p.x},#{p.y})" }.join(",")
|
127
127
|
|
128
128
|
if path.open?
|
129
|
-
"[#{
|
129
|
+
"[#{points_joined}]"
|
130
130
|
else
|
131
|
-
"(#{
|
131
|
+
"(#{points_joined})"
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
135
|
output do |path|
|
136
|
-
open = path.to_s.start_with?(
|
137
|
-
coordinates = path.to_s.tr(
|
136
|
+
open = path.to_s.start_with?("[") && path.to_s.end_with?("]")
|
137
|
+
coordinates = path.to_s.tr("()[]", "").split(",").each_slice(2)
|
138
138
|
points = coordinates.map { |x, y| Values::Point.new(Float(x), Float(y)) }
|
139
139
|
|
140
140
|
if open
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "sequel/core"
|
4
|
+
require "singleton"
|
5
5
|
|
6
6
|
Sequel.extension(:pg_json, :pg_json_ops)
|
7
7
|
|
@@ -23,11 +23,11 @@ module ROM
|
|
23
23
|
include ::Singleton
|
24
24
|
|
25
25
|
def to_s
|
26
|
-
|
26
|
+
"null"
|
27
27
|
end
|
28
28
|
|
29
29
|
def inspect
|
30
|
-
|
30
|
+
"null"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -44,7 +44,7 @@ module ROM
|
|
44
44
|
SQL::Types::False
|
45
45
|
]
|
46
46
|
|
47
|
-
JSON = Type(
|
47
|
+
JSON = Type("json") do
|
48
48
|
casts = ::Hash.new(-> v { ::Sequel.pg_json(v) })
|
49
49
|
json_null = ::Sequel.pg_json_wrap(nil)
|
50
50
|
casts[JSONNullType] = -> _ { json_null }
|
@@ -60,7 +60,7 @@ module ROM
|
|
60
60
|
.meta(read: JSONRead)
|
61
61
|
end
|
62
62
|
|
63
|
-
JSONB = Type(
|
63
|
+
JSONB = Type("jsonb") do
|
64
64
|
casts = ::Hash.new(-> v { ::Sequel.pg_jsonb(v) })
|
65
65
|
jsonb_null = ::Sequel.pg_jsonb_wrap(nil)
|
66
66
|
casts[JSONNullType] = -> _ { jsonb_null }
|
@@ -76,11 +76,11 @@ module ROM
|
|
76
76
|
.meta(read: JSONRead)
|
77
77
|
end
|
78
78
|
else
|
79
|
-
JSON = Type(
|
79
|
+
JSON = Type("json") do
|
80
80
|
(SQL::Types::Array | SQL::Types::Hash).constructor(Sequel.method(:pg_json)).meta(read: JSONRead)
|
81
81
|
end
|
82
82
|
|
83
|
-
JSONB = Type(
|
83
|
+
JSONB = Type("jsonb") do
|
84
84
|
(SQL::Types::Array | SQL::Types::Hash).constructor(Sequel.method(:pg_jsonb)).meta(read: JSONRead)
|
85
85
|
end
|
86
86
|
end
|
@@ -242,7 +242,7 @@ module ROM
|
|
242
242
|
|
243
243
|
def path_args(path)
|
244
244
|
case path.size
|
245
|
-
when 0 then raise ArgumentError,
|
245
|
+
when 0 then raise ArgumentError, "wrong number of arguments (given 0, expected 1+)"
|
246
246
|
when 1 then path[0]
|
247
247
|
else path
|
248
248
|
end
|