Class: DagMe::Graph
- Inherits:
-
Object
- Object
- DagMe::Graph
- Defined in:
- lib/dag_me/graph.rb
Overview
Class-level facade for graph-wide operations, reached via Model.dag
(default graph) or Model.dag(:name) (named graph):
Task.dag.between(a, b)
Task.dag.edges_among(relation)
Relay.dag(:power).rebuild!
Task.dag.valid?
Task.dag.validate!
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
Instance Method Summary collapse
- #adapter ⇒ Object
-
#backfill_self_rows! ⇒ Object
Restores missing self-rows for nodes inserted with triggers disabled - Rails fixture loading wraps inserts in disable_referential_integrity, which skips the node_insert trigger.
-
#between(ancestor, descendant) ⇒ Object
Every node lying on some path from
ancestortodescendant, both endpoints included. - #edges ⇒ Object
-
#edges_among(relation) ⇒ Object
Edges whose both endpoints are inside the given node relation - the induced subgraph's edge set (for exports, visualization, Kahn walks in Ruby, ...).
-
#initialize(model, config = nil) ⇒ Graph
constructor
A new instance of Graph.
-
#rebuild! ⇒ Object
Rebuilds the closure table from the edges table.
- #valid? ⇒ Boolean
-
#validate ⇒ Object
Rows where the stored closure disagrees with the recursive-CTE truth.
- #validate! ⇒ Object
Constructor Details
#initialize(model, config = nil) ⇒ Graph
Returns a new instance of Graph.
15 16 17 18 |
# File 'lib/dag_me/graph.rb', line 15 def initialize(model, config = nil) @model = model @config = config || model.dag_config end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
13 14 15 |
# File 'lib/dag_me/graph.rb', line 13 def config @config end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
13 14 15 |
# File 'lib/dag_me/graph.rb', line 13 def model @model end |
Instance Method Details
#adapter ⇒ Object
20 21 22 |
# File 'lib/dag_me/graph.rb', line 20 def adapter config.adapter end |
#backfill_self_rows! ⇒ Object
Restores missing self-rows for nodes inserted with triggers disabled - Rails fixture loading wraps inserts in disable_referential_integrity, which skips the node_insert trigger. Idempotent; meant for test setups.
62 63 64 65 66 67 68 69 |
# File 'lib/dag_me/graph.rb', line 62 def backfill_self_rows! return self unless config.closure? model.connection_pool.with_connection do |conn| conn.execute(DDL.new(config).backfill_self_rows_sql) end self end |
#between(ancestor, descendant) ⇒ Object
Every node lying on some path from ancestor to descendant,
both endpoints included.
26 27 28 |
# File 'lib/dag_me/graph.rb', line 26 def between(ancestor, descendant) adapter.between(ancestor, descendant) end |
#edges ⇒ Object
30 31 32 |
# File 'lib/dag_me/graph.rb', line 30 def edges config.edge_class.all end |
#edges_among(relation) ⇒ Object
Edges whose both endpoints are inside the given node relation - the induced subgraph's edge set (for exports, visualization, Kahn walks in Ruby, ...).
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/dag_me/graph.rb', line 37 def edges_among(relation) edges = config.edge_class sub = relation.select(*config.node_pk_columns).arel.ast endpoint_in = lambda do |columns| tuple = Arel::Nodes::Grouping.new(columns.map { |c| edges.arel_table[c] }) Arel::Nodes::In.new(tuple, sub) end edges.where(endpoint_in.call(config.edge_parent_columns)) .where(endpoint_in.call(config.edge_child_columns)) end |
#rebuild! ⇒ Object
Rebuilds the closure table from the edges table. No-op for maintain: :recursive_cte (there is nothing materialized).
50 51 52 53 54 55 56 57 |
# File 'lib/dag_me/graph.rb', line 50 def rebuild! return self unless config.closure? model.connection_pool.with_connection do |conn| conn.execute("SELECT #{conn.quote_table_name(config.function_ref('rebuild_paths'))}();") end self end |
#valid? ⇒ Boolean
81 82 83 |
# File 'lib/dag_me/graph.rb', line 81 def valid? validate.empty? end |
#validate ⇒ Object
Rows where the stored closure disagrees with the recursive-CTE truth. Empty means healthy.
73 74 75 76 77 78 79 |
# File 'lib/dag_me/graph.rb', line 73 def validate return [] unless config.closure? model.connection_pool.with_connection do |conn| conn.select_all("SELECT * FROM #{conn.quote_table_name(config.function_ref('validate_paths'))}();").to_a end end |
#validate! ⇒ Object
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/dag_me/graph.rb', line 85 def validate! rows = validate if rows.any? raise CorruptionError.new( "dag_me: closure for #{model.name} diverged from edge truth (#{rows.length} rows)", rows ) end self end |