class Rasti::DB::Relations::Graph

Attributes

collection_class[R]
environment[R]
graph[R]

Public Class Methods

new(environment, collection_class, relations=[], selected_attributes={}, excluded_attributes={}) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 6
def initialize(environment, collection_class, relations=[], selected_attributes={}, excluded_attributes={})
  @environment = environment
  @collection_class = collection_class
  @graph = build_graph relations,
                       Hash::Indifferent.new(selected_attributes),
                       Hash::Indifferent.new(excluded_attributes)
end

Public Instance Methods

add_joins(dataset, prefix=nil) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 47
def add_joins(dataset, prefix=nil)
  graph.roots.inject(dataset) do |ds, node|
    relation = relation_of node
    dataset_with_relation = relation.add_join environment, ds, prefix
    subgraph_of(node).add_joins dataset_with_relation, relation.join_relation_name(prefix)
  end
end
apply_to(query) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 29
def apply_to(query)
  query.graph(*flat_relations)
       .select_graph_attributes(flat_selected_attributes)
       .exclude_graph_attributes(flat_excluded_attributes)
end
fetch_graph(rows) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 35
def fetch_graph(rows)
  return if rows.empty?

  graph.roots.each do |node|
    relation_of(node).fetch_graph environment,
                                  rows,
                                  node[:selected_attributes],
                                  node[:excluded_attributes] ,
                                  subgraph_of(node)
  end
end
merge(relations:[], selected_attributes:{}, excluded_attributes:{}) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 14
def merge(relations:[], selected_attributes:{}, excluded_attributes:{})
  Graph.new environment,
            collection_class,
            (flat_relations | relations),
            flat_selected_attributes.merge(selected_attributes),
            flat_excluded_attributes.merge(excluded_attributes)
end
with_all_attributes_for(relations) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 22
def with_all_attributes_for(relations)
  relations_with_all_attributes = relations.map { |r| [r, nil] }.to_h

  merge selected_attributes: relations_with_all_attributes,
        excluded_attributes: relations_with_all_attributes
end

Private Instance Methods

build_graph(relations, selected_attributes, excluded_attributes) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 98
def build_graph(relations, selected_attributes, excluded_attributes)
  HierarchicalGraph.new.tap do |graph|
    flatten(relations).each do |relation|
      sections = relation.split('.')

      graph.add_node relation, name: sections.last.to_sym,
                               selected_attributes: selected_attributes[relation],
                               excluded_attributes: excluded_attributes[relation]

      if sections.count > 1
        parent_id = sections[0..-2].join('.')
        graph.add_relation parent_id: parent_id,
                           child_id: relation
      end
    end
  end
end
flat_excluded_attributes() click to toggle source
# File lib/rasti/db/relations/graph.rb, line 73
def flat_excluded_attributes
  graph.each_with_object(Hash::Indifferent.new) do |node, hash|
    hash[node.id] = node[:excluded_attributes]
  end
end
flat_relations() click to toggle source
# File lib/rasti/db/relations/graph.rb, line 63
def flat_relations
  graph.map(&:id)
end
flat_selected_attributes() click to toggle source
# File lib/rasti/db/relations/graph.rb, line 67
def flat_selected_attributes
  graph.each_with_object(Hash::Indifferent.new) do |node, hash|
    hash[node.id] = node[:selected_attributes]
  end
end
flatten(relations) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 116
def flatten(relations)
  relations.flat_map do |relation|
    parents = []
    relation.to_s.split('.').map do |section|
      parents << section
      parents.compact.join('.')
    end
  end.uniq.sort
end
relation_of(node) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 59
def relation_of(node)
  collection_class.relations.fetch(node[:name])
end
subgraph_of(node) click to toggle source
# File lib/rasti/db/relations/graph.rb, line 79
def subgraph_of(node)
  relations = []
  selected = Hash::Indifferent.new
  excluded = Hash::Indifferent.new

  node.descendants.each do |descendant|
    id = descendant.id[node[:name].length+1..-1]
    relations << id
    selected[id] = descendant[:selected_attributes]
    excluded[id] = descendant[:excluded_attributes]
  end

  Graph.new environment,
            relation_of(node).target_collection_class,
            relations,
            selected,
            excluded
end