Class: DagMe::Adapters::RecursiveCte

Inherits:
Base
  • Object
show all
Defined in:
lib/dag_me/adapters/recursive_cte.rb

Overview

Answers reachability by walking the edges table with WITH RECURSIVE. No materialized state; suited to small graphs, high mutation rates, and as the truth oracle when validating the closure adapter.

Instance Attribute Summary

Attributes inherited from Base

#config

Instance Method Summary collapse

Methods inherited from Base

#between, #initialize, #model

Constructor Details

This class inherits a constructor from DagMe::Adapters::Base

Instance Method Details

#ancestors(node) ⇒ Object



9
10
11
# File 'lib/dag_me/adapters/recursive_cte.rb', line 9

def ancestors(node)
  walk(node, from: config.edge_child_columns, to: config.edge_parent_columns)
end

#apply_topological_order(relation) ⇒ Object



31
32
33
34
35
36
37
38
39
40
# File 'lib/dag_me/adapters/recursive_cte.rb', line 31

def apply_topological_order(relation)
  cte, definition = reach_cte('up',
                              from: config.edge_child_columns,
                              to: config.edge_parent_columns) do |edge|
    config.edge_child_columns.zip(pk_columns)
          .map { |c, pk| edge[c].eq(model.arel_table[pk]) }.inject(:and)
  end
  count = cte.project(Arel.star.count).with(:recursive, definition)
  ordered_by(relation, count)
end

#descendants(node) ⇒ Object



13
14
15
# File 'lib/dag_me/adapters/recursive_cte.rb', line 13

def descendants(node)
  walk(node, from: config.edge_parent_columns, to: config.edge_child_columns)
end

#reachable?(ancestor, descendant) ⇒ Boolean

Returns:

  • (Boolean)


25
26
27
28
29
# File 'lib/dag_me/adapters/recursive_cte.rb', line 25

def reachable?(ancestor, descendant)
  return false if same_node?(ancestor, descendant)

  descendants(ancestor).where(node_key(descendant)).exists?
end

#self_and_ancestors(node) ⇒ Object



17
18
19
# File 'lib/dag_me/adapters/recursive_cte.rb', line 17

def self_and_ancestors(node)
  ancestors(node).or(model.where(node_key(node)))
end

#self_and_descendants(node) ⇒ Object



21
22
23
# File 'lib/dag_me/adapters/recursive_cte.rb', line 21

def self_and_descendants(node)
  descendants(node).or(model.where(node_key(node)))
end