Class: Namespace::TraversalHierarchy
- Inherits:
-
Object
- Object
- Namespace::TraversalHierarchy
- Includes:
- Transactions
- Defined in:
- app/models/namespace/traversal_hierarchy.rb
Constant Summary collapse
- LOCK_TIMEOUT =
'1000ms'
Instance Attribute Summary collapse
-
#root ⇒ Object
Returns the value of attribute root.
Class Method Summary collapse
- .for_namespace(namespace) ⇒ Object
-
.recursive_traversal_ids(node) ⇒ Object
Determine traversal_ids for the node and it’s descendants using recursive methods.
-
.sync_traversal_ids!(node) ⇒ Object
Update all traversal_ids for the given namespace and it’s descendants.
Instance Method Summary collapse
-
#incorrect_traversal_ids ⇒ Object
Identify all incorrect traversal_ids in the current namespace hierarchy.
-
#initialize(root) ⇒ TraversalHierarchy
constructor
A new instance of TraversalHierarchy.
-
#sync_traversal_ids! ⇒ Object
Update all traversal_ids in the current namespace hierarchy.
Constructor Details
#initialize(root) ⇒ TraversalHierarchy
Returns a new instance of TraversalHierarchy.
22 23 24 25 26 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 22 def initialize(root) raise StandardError, 'Must specify a root node' if root.parent_id @root = root end |
Instance Attribute Details
#root ⇒ Object
Returns the value of attribute root.
20 21 22 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 20 def root @root end |
Class Method Details
.for_namespace(namespace) ⇒ Object
41 42 43 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 41 def for_namespace(namespace) new(recursive_root_ancestor(namespace)) end |
.recursive_traversal_ids(node) ⇒ Object
Determine traversal_ids for the node and it’s descendants using recursive methods. Generate a collection of [id, traversal_ids] rows.
Note that the traversal_ids represent a calculated traversal path for the namespace and not the value stored within the traversal_ids attribute. rubocop:disable Cop/AvoidBecomes – Normalize STI queries
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 59 def recursive_traversal_ids(node) node_id = Integer(node.id) ancestor_ids = if node.parent_id node .becomes(Namespace) .recursive_self_and_ancestor_ids .reverse .join(',') else node_id end " WITH RECURSIVE cte(id, traversal_ids, cycle) AS (\n VALUES(\#{node_id}::bigint, ARRAY[\#{ancestor_ids}]::bigint[], false)\n UNION ALL\n SELECT n.id, cte.traversal_ids || n.id::bigint, n.id = ANY(cte.traversal_ids)\n FROM namespaces n, cte\n WHERE n.parent_id = cte.id AND NOT cycle\n )\n SELECT id, traversal_ids FROM cte\n SQL\nend\n" |
.sync_traversal_ids!(node) ⇒ Object
Update all traversal_ids for the given namespace and it’s descendants.
46 47 48 49 50 51 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 46 def sync_traversal_ids!(node) Namespace.transaction do acquire_locks(node) sync_traversal_ids_tree!(node) end end |
Instance Method Details
#incorrect_traversal_ids ⇒ Object
Identify all incorrect traversal_ids in the current namespace hierarchy.
34 35 36 37 38 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 34 def incorrect_traversal_ids Namespace .joins("INNER JOIN (#{TraversalHierarchy.recursive_traversal_ids(root)}) as cte ON namespaces.id = cte.id") .where('namespaces.traversal_ids::bigint[] <> cte.traversal_ids') end |
#sync_traversal_ids! ⇒ Object
Update all traversal_ids in the current namespace hierarchy.
29 30 31 |
# File 'app/models/namespace/traversal_hierarchy.rb', line 29 def sync_traversal_ids! TraversalHierarchy.sync_traversal_ids!(root) end |