Skip to content

Commit

Permalink
Merge 38799bc into 5ca6a8d
Browse files Browse the repository at this point in the history
  • Loading branch information
nickfarina authored Aug 16, 2016
2 parents 5ca6a8d + 38799bc commit bf8e5a7
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 14 deletions.
5 changes: 3 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in activerecord-hierarchical_query.gemspec
gemspec

gem 'pg', '~> 0.17.1'
gem 'pg', '~> 0.18.3'
gem 'activerecord', '~> 4.2.0'

group :local do
gem 'yard'
Expand All @@ -14,4 +15,4 @@ end

group :travis do
gem 'coveralls'
end
end
2 changes: 1 addition & 1 deletion lib/active_record/hierarchical_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ class << base
end

ActiveRecord::Relation.send :include, ActiveRecord::HierarchicalQuery
end
end
6 changes: 4 additions & 2 deletions lib/active_record/hierarchical_query/cte/query_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ module CTE
class QueryBuilder
attr_reader :query,
:columns,
:cycle_detector
:cycle_detector,
:options

delegate :klass, :table, :recursive_table, to: :query

# @param [ActiveRecord::HierarchicalQuery::Query] query
def initialize(query)
def initialize(query, options: {})
@query = query
@columns = Columns.new(@query)
@cycle_detector = CycleDetector.new(@query)
@options = options
end

def bind_values
Expand Down
2 changes: 1 addition & 1 deletion lib/active_record/hierarchical_query/cte/recursive_term.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ def ordering
end
end
end
end
end
11 changes: 9 additions & 2 deletions lib/active_record/hierarchical_query/cte/union_term.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,17 @@ def bind_values
end

def arel
non_recursive_term.arel.union(:all, recursive_term.arel)
non_recursive_term.arel.union(union_type, recursive_term.arel)
end

private

def union_type
return @builder.options[:union_type] if @builder.options[:union_type].present?

:all
end

def recursive_term
@rt ||= RecursiveTerm.new(@builder)
end
Expand All @@ -29,4 +36,4 @@ def non_recursive_term
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/active_record/hierarchical_query/join_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class JoinBuilder
# @param [#to_s] subquery_alias
def initialize(query, join_to, subquery_alias, options = {})
@query = query
@builder = CTE::QueryBuilder.new(query)
@builder = CTE::QueryBuilder.new(query, options: options)
@relation = join_to
@alias = Arel::Table.new(subquery_alias, ActiveRecord::Base)
@options = options
Expand Down
8 changes: 4 additions & 4 deletions lib/active_record/hierarchical_query/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ def start_with(scope = nil, *arguments, &block)
object = @start_with_value || @klass

@start_with_value = if block.arity == 0
object.instance_eval(&block)
else
block.call(object)
end
object.instance_eval(&block)
else
block.call(object)
end
end

self
Expand Down
10 changes: 9 additions & 1 deletion lib/arel/nodes/postgresql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ def initialize(values)

class ArrayConcat < Binary
end

class UnionDistinct < Binary
end
end

module Visitors
Expand Down Expand Up @@ -43,6 +46,11 @@ def visit_Arel_Nodes_ArrayConcat o, collector
visit o.right, collector
end
end

def visit_Arel_Nodes_UnionDistinct o, collector
collector << "( "
infix_value(o, collector, " UNION DISTINCT ") << " )"
end
end
end
end
end
27 changes: 27 additions & 0 deletions spec/active_record/hierarchical_query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,33 @@
let!(:child_5) { klass.create(parent: child_4) }

describe '#join_recursive' do
describe 'UNION clause' do
let(:options) { {} }
subject { klass.join_recursive(options) { connect_by(id: :parent_id) }.to_sql }

it 'defaults to UNION ALL' do
expect(subject).to include('UNION ALL')
end

context 'specifying DISTINCT union type' do
let(:options) { { union_type: :distinct } }

it 'uses UNION DISTINCT' do
expect(subject).to include('UNION DISTINCT')
expect(subject).to_not include('UNION ALL')
end
end

context 'specifying ALL union type' do
let(:options) { { union_type: :all } }

it 'uses UNION ALL' do
expect(subject).to include('UNION ALL')
expect(subject).to_not include('UNION DISTINCT')
end
end
end

describe 'CONNECT BY clause' do
it 'throws error if CONNECT BY clause not specified' do
expect {
Expand Down

0 comments on commit bf8e5a7

Please sign in to comment.