rom-sql 3.6.4 → 4.0.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|