activerecord-hierarchical_query 0.1.0 → 0.1.1
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/lib/active_record/hierarchical_query.rb +1 -1
- data/lib/active_record/hierarchical_query/cte/query_builder.rb +4 -2
- data/lib/active_record/hierarchical_query/cte/recursive_term.rb +1 -1
- data/lib/active_record/hierarchical_query/cte/union_term.rb +9 -2
- data/lib/active_record/hierarchical_query/join_builder.rb +1 -1
- data/lib/active_record/hierarchical_query/query.rb +4 -4
- data/lib/active_record/hierarchical_query/version.rb +1 -1
- data/lib/arel/nodes/postgresql.rb +13 -1
- data/spec/active_record/hierarchical_query_spec.rb +27 -0
- data/spec/database.yml +1 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f07d2ec47ffaa6e83ba6fb27cb027773298ad8dc
|
4
|
+
data.tar.gz: cde6840a2e9f1334185a747ac5467850653dfa3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f009457c44deec3eef278505d1e898141fce5e730ddf9245783cfa19efa4245b5c2ed4c4e7b61df45307e476fcbf2138aabc714815d96fc83048e9b35c0c12c
|
7
|
+
data.tar.gz: cbcdb8aa27269c2a6011b1c35a160a280af281c23ce7c2e07bdac044703f26bf06a733f7fafc78e4a9addc4f2493b03690202a880a65d6e15b798e225090c929
|
@@ -11,15 +11,17 @@ module ActiveRecord
|
|
11
11
|
class QueryBuilder
|
12
12
|
attr_reader :query,
|
13
13
|
:columns,
|
14
|
-
:cycle_detector
|
14
|
+
:cycle_detector,
|
15
|
+
:options
|
15
16
|
|
16
17
|
delegate :klass, :table, :recursive_table, to: :query
|
17
18
|
|
18
19
|
# @param [ActiveRecord::HierarchicalQuery::Query] query
|
19
|
-
def initialize(query)
|
20
|
+
def initialize(query, options: {})
|
20
21
|
@query = query
|
21
22
|
@columns = Columns.new(@query)
|
22
23
|
@cycle_detector = CycleDetector.new(@query)
|
24
|
+
@options = options
|
23
25
|
end
|
24
26
|
|
25
27
|
def bind_values
|
@@ -15,10 +15,17 @@ module ActiveRecord
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def arel
|
18
|
-
non_recursive_term.arel.union(
|
18
|
+
non_recursive_term.arel.union(union_type, recursive_term.arel)
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
|
+
|
23
|
+
def union_type
|
24
|
+
return @builder.options[:union_type] if @builder.options[:union_type].present?
|
25
|
+
|
26
|
+
:all
|
27
|
+
end
|
28
|
+
|
22
29
|
def recursive_term
|
23
30
|
@rt ||= RecursiveTerm.new(@builder)
|
24
31
|
end
|
@@ -29,4 +36,4 @@ module ActiveRecord
|
|
29
36
|
end
|
30
37
|
end
|
31
38
|
end
|
32
|
-
end
|
39
|
+
end
|
@@ -8,7 +8,7 @@ module ActiveRecord
|
|
8
8
|
# @param [#to_s] subquery_alias
|
9
9
|
def initialize(query, join_to, subquery_alias, options = {})
|
10
10
|
@query = query
|
11
|
-
@builder = CTE::QueryBuilder.new(query)
|
11
|
+
@builder = CTE::QueryBuilder.new(query, options: options)
|
12
12
|
@relation = join_to
|
13
13
|
@alias = Arel::Table.new(subquery_alias, ActiveRecord::Base)
|
14
14
|
@options = options
|
@@ -99,10 +99,10 @@ module ActiveRecord
|
|
99
99
|
object = @start_with_value || @klass
|
100
100
|
|
101
101
|
@start_with_value = if block.arity == 0
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
102
|
+
object.instance_eval(&block)
|
103
|
+
else
|
104
|
+
block.call(object)
|
105
|
+
end
|
106
106
|
end
|
107
107
|
|
108
108
|
self
|
@@ -13,6 +13,9 @@ module Arel
|
|
13
13
|
|
14
14
|
class ArrayConcat < Binary
|
15
15
|
end
|
16
|
+
|
17
|
+
class UnionDistinct < Binary
|
18
|
+
end
|
16
19
|
end
|
17
20
|
|
18
21
|
module Visitors
|
@@ -30,6 +33,10 @@ module Arel
|
|
30
33
|
def visit_Arel_Nodes_ArrayConcat o, *a
|
31
34
|
"#{visit o.left, *a} #{ARRAY_CONCAT} #{visit o.right, *a}"
|
32
35
|
end
|
36
|
+
|
37
|
+
def visit_Arel_Nodes_UnionDistinct o, *a
|
38
|
+
"( #{visit o.left, *a} UNION DISTINCT #{visit o.right, *a} )"
|
39
|
+
end
|
33
40
|
else
|
34
41
|
def visit_Arel_Nodes_PostgresArray o, collector
|
35
42
|
collector << ARRAY_OPENING
|
@@ -42,7 +49,12 @@ module Arel
|
|
42
49
|
collector << ARRAY_CONCAT
|
43
50
|
visit o.right, collector
|
44
51
|
end
|
52
|
+
|
53
|
+
def visit_Arel_Nodes_UnionDistinct o, collector
|
54
|
+
collector << "( "
|
55
|
+
infix_value(o, collector, " UNION DISTINCT ") << " )"
|
56
|
+
end
|
45
57
|
end
|
46
58
|
end
|
47
59
|
end
|
48
|
-
end
|
60
|
+
end
|
@@ -11,6 +11,33 @@ describe ActiveRecord::HierarchicalQuery do
|
|
11
11
|
let!(:child_5) { klass.create(parent: child_4) }
|
12
12
|
|
13
13
|
describe '#join_recursive' do
|
14
|
+
describe 'UNION clause' do
|
15
|
+
let(:options) { {} }
|
16
|
+
subject { klass.join_recursive(options) { connect_by(id: :parent_id) }.to_sql }
|
17
|
+
|
18
|
+
it 'defaults to UNION ALL' do
|
19
|
+
expect(subject).to include('UNION ALL')
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'specifying DISTINCT union type' do
|
23
|
+
let(:options) { { union_type: :distinct } }
|
24
|
+
|
25
|
+
it 'uses UNION DISTINCT' do
|
26
|
+
expect(subject).to include('UNION DISTINCT')
|
27
|
+
expect(subject).to_not include('UNION ALL')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'specifying ALL union type' do
|
32
|
+
let(:options) { { union_type: :all } }
|
33
|
+
|
34
|
+
it 'uses UNION ALL' do
|
35
|
+
expect(subject).to include('UNION ALL')
|
36
|
+
expect(subject).to_not include('UNION DISTINCT')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
14
41
|
describe 'CONNECT BY clause' do
|
15
42
|
it 'throws error if CONNECT BY clause not specified' do
|
16
43
|
expect {
|
data/spec/database.yml
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-hierarchical_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexei Mikhailov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
version: '0'
|
142
142
|
requirements: []
|
143
143
|
rubyforge_project:
|
144
|
-
rubygems_version: 2.4.
|
144
|
+
rubygems_version: 2.4.8
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Recursively traverse trees using a single SQL query
|