rom-sql 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d964bf81ba3e921c992aff816f2c09bc1c91c3a
4
- data.tar.gz: 1f8516a4f8420e4a009d41b98d9d1f1dd9bcb608
3
+ metadata.gz: 8a59a75e6eb28bd684acbd721bf2718637ec3463
4
+ data.tar.gz: eb2281b8bb5f156d73056e1b56f8a58fa7fa174a
5
5
  SHA512:
6
- metadata.gz: 21ac8dc3534190ed1a72d6b0a798cdc60c0ff9207995a304a9edfc44356e41c53a0123fa49718b91b7c093cd53060d1c1adb15a2fd02694e85ceaf310b7647aa
7
- data.tar.gz: 63dcf1fcc5c3bc2e5f4dc09335eb2da9138abf83790934daf725651df004c5333e4f15669a7a64c2c78160ffd9326a25fe4feec0d75d1dbbee19b7b41f88ba2d
6
+ metadata.gz: 3385bfffcc897f83b3d7c0a77d93d4a7bb9ff3416be241fe9df53e5b8a4c38371a196461d8f7b7c90dcf99f2083cfe876fcfe109b86d3fe3910913c8537fc95a
7
+ data.tar.gz: 6c4cf20e4be86dc15f49162657ced6df27818c8d3c4a12bf966ce327541a585ce8d94ad7c2ad003ee318e442ae5611b4f4979114e099947b5627ba82264e9bf4
data/CHANGELOG.md CHANGED
@@ -1,9 +1,26 @@
1
+ ## v2.2.0 2017-11-02
2
+
3
+ ### Added
4
+
5
+ * Relation registry is passed as an argument to DSL blocks (in `select`, `where`, `order` etc.), which enables syntax like `select { |r| [id, r.tasks[:title]] }` (solnic)
6
+ * Support for self-referenced many-to-many associations (solnic)
7
+ * PG's geometric types include meta data about db types (GustavoCaso)
8
+
9
+ ### Fixed
10
+
11
+ * Custom schema is used correctly in command results (solnic)
12
+ * Schemas no longer finalize PKs (this is done in core schema already) (solnic)
13
+
14
+ [Compare v2.1.0...v2.2.0](https://github.com/rom-rb/rom-sql/compare/v2.1.0...v2.2.0)
15
+
1
16
  ## v2.1.0 2017-10-23
2
17
 
3
18
  ### Added
4
19
 
5
20
  * Support for PG's range types (v-kolesnikov)
6
21
  * Support for PG's `ltree` (GustavoCaso + solnic)
22
+ * Support for the `FILTER` clause (flash-gordon)
23
+ * PG's array types will use custom types for processing members ie `ltree[]` will use `LTree` type (solnic)
7
24
 
8
25
  ### Fixed
9
26
 
@@ -1,11 +1,13 @@
1
1
  require 'rom/associations/many_to_many'
2
2
  require 'rom/sql/associations/core'
3
+ require 'rom/sql/associations/self_ref'
3
4
 
4
5
  module ROM
5
6
  module SQL
6
7
  module Associations
7
8
  class ManyToMany < ROM::Associations::ManyToMany
8
9
  include Associations::Core
10
+ include Associations::SelfRef
9
11
 
10
12
  # @api public
11
13
  def call(target: self.target)
@@ -22,7 +24,7 @@ module ROM
22
24
  target_schema
23
25
  end.qualified
24
26
 
25
- relation = left.join(source.name.dataset, join_keys)
27
+ relation = left.join(source_table, join_keys)
26
28
 
27
29
  if view
28
30
  apply_view(schema, relation)
@@ -43,11 +45,6 @@ module ROM
43
45
  { source_attr => target_attr }
44
46
  end
45
47
 
46
- # @api public
47
- def source_attr
48
- source[source_key].qualified
49
- end
50
-
51
48
  # @api public
52
49
  def target_attr
53
50
  join_relation[target_key].qualified
data/lib/rom/sql/dsl.rb CHANGED
@@ -1,18 +1,26 @@
1
+ require 'rom/constants'
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  # @api private
4
6
  class DSL < BasicObject
5
- # @api private
7
+ # @!attribute [r] schema
8
+ # @return [SQL::Schema]
6
9
  attr_reader :schema
7
10
 
11
+ # @!attribute [r] relations
12
+ # @return [Hash, RelationRegistry]
13
+ attr_reader :relations
14
+
8
15
  # @api private
9
16
  def initialize(schema)
10
17
  @schema = schema
18
+ @relations = schema.respond_to?(:relations) ? schema.relations : EMPTY_HASH
11
19
  end
12
20
 
13
21
  # @api private
14
22
  def call(&block)
15
- result = instance_exec(&block)
23
+ result = instance_exec(relations, &block)
16
24
 
17
25
  if result.is_a?(::Array)
18
26
  result
@@ -5,13 +5,29 @@ module ROM
5
5
  module SQL
6
6
  module Postgres
7
7
  module Commands
8
+ # @api private
9
+ module Core
10
+ private
11
+
12
+ # Common dataset used by create/update commands
13
+ #
14
+ # @return [Sequel::Dataset]
15
+ #
16
+ # @api private
17
+ def returning_dataset
18
+ relation.dataset.returning(*relation.columns)
19
+ end
20
+ end
21
+
8
22
  module Create
23
+ include Core
24
+
9
25
  # Executes insert statement and returns inserted tuples
10
26
  #
11
27
  # @api private
12
28
  def insert(tuples)
13
29
  dataset = tuples.flat_map do |tuple|
14
- relation.dataset.returning.insert(tuple)
30
+ returning_dataset.insert(tuple)
15
31
  end
16
32
 
17
33
  wrap_dataset(dataset)
@@ -21,7 +37,7 @@ module ROM
21
37
  #
22
38
  # @api private
23
39
  def multi_insert(tuples)
24
- relation.dataset.returning.multi_insert(tuples)
40
+ returning_dataset.multi_insert(tuples)
25
41
  end
26
42
 
27
43
  # Executes upsert statement (INSERT with ON CONFLICT clause)
@@ -29,17 +45,18 @@ module ROM
29
45
  #
30
46
  # @api private
31
47
  def upsert(tuple, opts = EMPTY_HASH)
32
- relation.dataset.returning.insert_conflict(opts).insert(tuple)
48
+ returning_dataset.insert_conflict(opts).insert(tuple)
33
49
  end
34
50
  end
35
51
 
36
52
  module Update
53
+ include Core
54
+
37
55
  # Executes update statement and returns updated tuples
38
56
  #
39
57
  # @api private
40
58
  def update(tuple)
41
- dataset = relation.dataset.returning.update(tuple)
42
- wrap_dataset(dataset)
59
+ wrap_dataset(returning_dataset.update(tuple))
43
60
  end
44
61
  end
45
62
 
@@ -32,100 +32,114 @@ module ROM
32
32
  # The list of geometric data types supported by PostgreSQL
33
33
  # @see https://www.postgresql.org/docs/current/static/datatype-geometric.html
34
34
 
35
- Point = SQL::Types.define(Values::Point) do
36
- input do |point|
37
- "(#{ point.x },#{ point.y })"
38
- end
35
+ Point = Type('point') do
36
+ SQL::Types.define(Values::Point) do
37
+ input do |point|
38
+ "(#{ point.x },#{ point.y })"
39
+ end
39
40
 
40
- output do |point|
41
- x, y = point.to_s[1...-1].split(',', 2)
42
- Values::Point.new(Float(x), Float(y))
41
+ output do |point|
42
+ x, y = point.to_s[1...-1].split(',', 2)
43
+ Values::Point.new(Float(x), Float(y))
44
+ end
43
45
  end
44
46
  end
45
47
 
46
- Line = SQL::Types.define(Values::Line) do
47
- input do |line|
48
- "{#{ line.a },#{ line.b },#{line.c}}"
49
- end
48
+ Line = Type('line') do
49
+ SQL::Types.define(Values::Line) do
50
+ input do |line|
51
+ "{#{ line.a },#{ line.b },#{line.c}}"
52
+ end
50
53
 
51
- output do |line|
52
- a, b, c = line.to_s[1..-2].split(',', 3)
53
- Values::Line.new(Float(a), Float(b), Float(c))
54
+ output do |line|
55
+ a, b, c = line.to_s[1..-2].split(',', 3)
56
+ Values::Line.new(Float(a), Float(b), Float(c))
57
+ end
54
58
  end
55
59
  end
56
60
 
57
- Circle = SQL::Types.define(Values::Circle) do
58
- input do |circle|
59
- "<(#{ circle.center.x },#{ circle.center.y }),#{ circle.radius }>"
60
- end
61
+ Circle = Type('circle') do
62
+ SQL::Types.define(Values::Circle) do
63
+ input do |circle|
64
+ "<(#{ circle.center.x },#{ circle.center.y }),#{ circle.radius }>"
65
+ end
61
66
 
62
- output do |circle|
63
- x, y, r = circle.to_s.tr('()<>', '').split(',', 3)
64
- center = Values::Point.new(Float(x), Float(y))
65
- Values::Circle.new(center, Float(r))
67
+ output do |circle|
68
+ x, y, r = circle.to_s.tr('()<>', '').split(',', 3)
69
+ center = Values::Point.new(Float(x), Float(y))
70
+ Values::Circle.new(center, Float(r))
71
+ end
66
72
  end
67
73
  end
68
74
 
69
- Box = SQL::Types.define(Values::Box) do
70
- input do |box|
71
- "((#{ box.upper_right.x },#{ box.upper_right.y }),"\
72
- "(#{ box.lower_left.x },#{ box.lower_left.y }))"
73
- end
75
+ Box = Type('box') do
76
+ SQL::Types.define(Values::Box) do
77
+ input do |box|
78
+ "((#{ box.upper_right.x },#{ box.upper_right.y }),"\
79
+ "(#{ box.lower_left.x },#{ box.lower_left.y }))"
80
+ end
74
81
 
75
- output do |box|
76
- x_right, y_right, x_left, y_left = box.to_s.tr('()', '').split(',', 4)
77
- upper_right = Values::Point.new(Float(x_right), Float(y_right))
78
- lower_left = Values::Point.new(Float(x_left), Float(y_left))
79
- Values::Box.new(upper_right, lower_left)
82
+ output do |box|
83
+ x_right, y_right, x_left, y_left = box.to_s.tr('()', '').split(',', 4)
84
+ upper_right = Values::Point.new(Float(x_right), Float(y_right))
85
+ lower_left = Values::Point.new(Float(x_left), Float(y_left))
86
+ Values::Box.new(upper_right, lower_left)
87
+ end
80
88
  end
81
89
  end
82
90
 
83
- LineSegment = SQL::Types.define(Values::LineSegment) do
84
- input do |segment|
85
- "[(#{ segment.begin.x },#{ segment.begin.y }),"\
86
- "(#{ segment.end.x },#{ segment.end.y })]"
87
- end
91
+ LineSegment = Type('lseg') do
92
+ SQL::Types.define(Values::LineSegment) do
93
+ input do |segment|
94
+ "[(#{ segment.begin.x },#{ segment.begin.y }),"\
95
+ "(#{ segment.end.x },#{ segment.end.y })]"
96
+ end
88
97
 
89
- output do |segment|
90
- x_begin, y_begin, x_end, y_end = segment.to_s.tr('()[]', '').split(',', 4)
91
- point_begin = Values::Point.new(Float(x_begin), Float(y_begin))
92
- point_end = Values::Point.new(Float(x_end), Float(y_end))
93
- Values::LineSegment.new(point_begin, point_end)
98
+ output do |segment|
99
+ x_begin, y_begin, x_end, y_end = segment.to_s.tr('()[]', '').split(',', 4)
100
+ point_begin = Values::Point.new(Float(x_begin), Float(y_begin))
101
+ point_end = Values::Point.new(Float(x_end), Float(y_end))
102
+ Values::LineSegment.new(point_begin, point_end)
103
+ end
94
104
  end
95
105
  end
96
106
 
97
- Polygon = SQL::Types.define(::Array) do
98
- input do |points|
99
- points_joined = points.map { |p| "(#{ p.x },#{ p.y })" }.join(',')
100
- "(#{ points_joined })"
101
- end
107
+ Polygon = Type('polygon') do
108
+ SQL::Types.define(::Array) do
109
+ input do |points|
110
+ points_joined = points.map { |p| "(#{ p.x },#{ p.y })" }.join(',')
111
+ "(#{ points_joined })"
112
+ end
102
113
 
103
- output do |polygon|
104
- coordinates = polygon.to_s.tr('()', '').split(',').each_slice(2)
105
- coordinates.map { |x, y| Values::Point.new(Float(x), Float(y)) }
114
+ output do |polygon|
115
+ coordinates = polygon.to_s.tr('()', '').split(',').each_slice(2)
116
+ coordinates.map { |x, y| Values::Point.new(Float(x), Float(y)) }
117
+ end
106
118
  end
107
119
  end
108
120
 
109
- Path = SQL::Types.define(Values::Path) do
110
- input do |path|
111
- points_joined = path.to_a.map { |p| "(#{ p.x },#{ p.y })" }.join(',')
121
+ Path = Type('path') do
122
+ SQL::Types.define(Values::Path) do
123
+ input do |path|
124
+ points_joined = path.to_a.map { |p| "(#{ p.x },#{ p.y })" }.join(',')
112
125
 
113
- if path.open?
114
- "[#{ points_joined }]"
115
- else
116
- "(#{ points_joined })"
126
+ if path.open?
127
+ "[#{ points_joined }]"
128
+ else
129
+ "(#{ points_joined })"
130
+ end
117
131
  end
118
- end
119
132
 
120
- output do |path|
121
- open = path.to_s.start_with?('[') && path.to_s.end_with?(']')
122
- coordinates = path.to_s.tr('()[]', '').split(',').each_slice(2)
123
- points = coordinates.map { |x, y| Values::Point.new(Float(x), Float(y)) }
133
+ output do |path|
134
+ open = path.to_s.start_with?('[') && path.to_s.end_with?(']')
135
+ coordinates = path.to_s.tr('()[]', '').split(',').each_slice(2)
136
+ points = coordinates.map { |x, y| Values::Point.new(Float(x), Float(y)) }
124
137
 
125
- if open
126
- Values::Path.new(points, :open)
127
- else
128
- Values::Path.new(points, :closed)
138
+ if open
139
+ Values::Path.new(points, :open)
140
+ else
141
+ Values::Path.new(points, :closed)
142
+ end
129
143
  end
130
144
  end
131
145
  end
@@ -6,7 +6,7 @@ module ROM
6
6
  class RestrictionDSL < DSL
7
7
  # @api private
8
8
  def call(&block)
9
- instance_exec(&block)
9
+ instance_exec(relations, &block)
10
10
  end
11
11
 
12
12
  # Returns a result of SQL EXISTS clause.
@@ -145,7 +145,6 @@ module ROM
145
145
  def finalize_attributes!(options = EMPTY_HASH)
146
146
  super do
147
147
  @attributes = map(&:qualified)
148
- initialize_primary_key_names
149
148
  end
150
149
  end
151
150
 
@@ -1,5 +1,5 @@
1
1
  module ROM
2
2
  module SQL
3
- VERSION = '2.1.0'.freeze
3
+ VERSION = '2.2.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rom-sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-23 00:00:00.000000000 Z
11
+ date: 2017-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -79,6 +79,9 @@ dependencies:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '4.0'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 4.0.2
82
85
  type: :runtime
83
86
  prerelease: false
84
87
  version_requirements: !ruby/object:Gem::Requirement
@@ -86,6 +89,9 @@ dependencies:
86
89
  - - "~>"
87
90
  - !ruby/object:Gem::Version
88
91
  version: '4.0'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 4.0.2
89
95
  - !ruby/object:Gem::Dependency
90
96
  name: bundler
91
97
  requirement: !ruby/object:Gem::Requirement
@@ -240,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
240
246
  version: '0'
241
247
  requirements: []
242
248
  rubyforge_project:
243
- rubygems_version: 2.6.13
249
+ rubygems_version: 2.6.11
244
250
  signing_key:
245
251
  specification_version: 4
246
252
  summary: SQL databases support for ROM