Class: Neo4j::Wrapper::Rule::RuleNode
- Inherits:
-
Object
- Object
- Neo4j::Wrapper::Rule::RuleNode
- Includes:
- Core::ToJava
- Defined in:
- lib/neo4j-wrapper/rule/rule_node.rb
Overview
This is the node that has relationships to all nodes of a given class. For example if the PersonNode has a rule then it will also have one RuleNode from where it will create relationships to each created node of type PersonNode. The RuleNode can also be used to hold properties for functions, like sum and count.
Constant Summary collapse
- @@rule_nodes =
{}
Instance Attribute Summary collapse
-
#model_class ⇒ Object
readonly
Returns the value of attribute model_class.
-
#rules ⇒ Object
readonly
Returns the value of attribute rules.
Instance Method Summary collapse
- #add_rule(rule) ⇒ Object
-
#break_connection(rule_name, end_node) ⇒ Object
sever a direct one-to-one relationship if it exists.
- #bulk_update? ⇒ Boolean
- #classes_changed(total) ⇒ Object
- #clear_rule_node ⇒ Object
- #connect(rule_name, end_node) ⇒ Object
-
#connected?(rule_name, end_node) ⇒ Boolean
work out if two nodes are connected by a particular relationship uses the end_node to start with because it’s more likely to have less relationships to go through (just the number of superclasses it has really).
- #create_node(ref) ⇒ Object
- #execute_add_functions(rule, *changes) ⇒ Object
- #execute_delete_functions(rule, *changes) ⇒ Object
- #execute_other_rules(rule, node) ⇒ Object
- #execute_rule(rule, node, *changes) ⇒ Object
- #execute_rules(node, *changes) ⇒ Object
- #execute_update_functions(rule, *changes) ⇒ Object
- #find_function(rule_name, function_name, function_id) ⇒ Object
- #find_functions_for_changes(rule, *changes) ⇒ Object
- #find_node(ref = ref_node) ⇒ Object
- #find_rule(rule_name) ⇒ Object
- #inherit(subclass) ⇒ Object
-
#initialize(clazz) ⇒ RuleNode
constructor
A new instance of RuleNode.
- #key ⇒ Object
- #ref_node ⇒ Object
- #ref_node_changed? ⇒ Boolean
- #remove_rule(rule_name) ⇒ Object
- #rule_names ⇒ Object
- #rule_node ⇒ Object
- #rule_node?(node) ⇒ Boolean
- #to_s ⇒ Object
-
#traversal(rule_name, cypher_query_hash = nil, &cypher_block) ⇒ Object
Return a traversal object with methods for each rule and function.
Constructor Details
#initialize(clazz) ⇒ RuleNode
Returns a new instance of RuleNode.
16 17 18 19 20 21 22 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 16 def initialize(clazz) classname = clazz.to_s @model_class = Neo4j::Wrapper.to_class(classname) @classname = clazz @rules = [] @ref_node_key = ("rule_ref_for_" + clazz.to_s).to_sym end |
Instance Attribute Details
#model_class ⇒ Object (readonly)
Returns the value of attribute model_class.
13 14 15 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 13 def model_class @model_class end |
#rules ⇒ Object (readonly)
Returns the value of attribute rules.
12 13 14 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 12 def rules @rules end |
Instance Method Details
#add_rule(rule) ⇒ Object
89 90 91 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 89 def add_rule(rule) @rules << rule end |
#break_connection(rule_name, end_node) ⇒ Object
sever a direct one-to-one relationship if it exists
187 188 189 190 191 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 187 def break_connection(rule_name, end_node) rel = end_node._rels(:incoming, rule_name).find { |r| r._start_node == rule_node } rel && rel.del !rel.nil? end |
#bulk_update? ⇒ Boolean
193 194 195 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 193 def bulk_update? @rules.size == 1 && @rules.first.bulk_update? end |
#classes_changed(total) ⇒ Object
197 198 199 200 201 202 203 204 205 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 197 def classes_changed(total) @rules.each do |rule| if rule.bulk_update? rule.functions && rule.functions.first.classes_changed(rule.rule_name, rule_node, total) total.added.each { |node| connect(rule.rule_name, node) } total.deleted.each { |node| break_connection(rule.rule_name, node) } end end end |
#clear_rule_node ⇒ Object
77 78 79 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 77 def clear_rule_node @@rule_nodes[key] = nil end |
#connect(rule_name, end_node) ⇒ Object
182 183 184 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 182 def connect(rule_name, end_node) rule_node._java_node.create_relationship_to(end_node._java_node, type_to_java(rule_name)) end |
#connected?(rule_name, end_node) ⇒ Boolean
work out if two nodes are connected by a particular relationship uses the end_node to start with because it’s more likely to have less relationships to go through (just the number of superclasses it has really)
178 179 180 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 178 def connected?(rule_name, end_node) end_node.nodes(:incoming, rule_name).find { |n| n == rule_node } end |
#create_node(ref) ⇒ Object
52 53 54 55 56 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 52 def create_node(ref) node = Neo4j::Node.new ref.create_relationship_to(node, type_to_java(@classname)) node end |
#execute_add_functions(rule, *changes) ⇒ Object
159 160 161 162 163 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 159 def execute_add_functions(rule, *changes) if functions = find_functions_for_changes(rule, *changes) functions && functions.each { |f| f.add(rule.rule_name, rule_node, changes[2]) } end end |
#execute_delete_functions(rule, *changes) ⇒ Object
165 166 167 168 169 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 165 def execute_delete_functions(rule, *changes) if functions = find_functions_for_changes(rule, *changes) functions.each { |f| f.delete(rule.rule_name, rule_node, changes[1]) } end end |
#execute_other_rules(rule, node) ⇒ Object
129 130 131 132 133 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 129 def execute_other_rules(rule, node) rule.triggers && rule.triggers.each do |rel_type| node.incoming(rel_type).each { |n| n.trigger_rules } end end |
#execute_rule(rule, node, *changes) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 135 def execute_rule(rule, node, *changes) if rule.execute_filter(node) if connected?(rule.rule_name, node) # it was already connected - the node is in the same rule group but a property has changed execute_update_functions(rule, *changes) else # the node has changed or is in a new rule group connect(rule.rule_name, node) execute_add_functions(rule, *changes) end else if break_connection(rule.rule_name, node) # the node has been removed from a rule group execute_delete_functions(rule, *changes) end end end |
#execute_rules(node, *changes) ⇒ Object
122 123 124 125 126 127 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 122 def execute_rules(node, *changes) @rules.each do |rule| execute_rule(rule, node, *changes) execute_other_rules(rule, node) end end |
#execute_update_functions(rule, *changes) ⇒ Object
153 154 155 156 157 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 153 def execute_update_functions(rule, *changes) if functions = find_functions_for_changes(rule, *changes) functions && functions.each { |f| f.update(rule.rule_name, rule_node, changes[1], changes[2]) } end end |
#find_function(rule_name, function_name, function_id) ⇒ Object
117 118 119 120 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 117 def find_function(rule_name, function_name, function_id) rule = find_rule(rule_name) rule.find_function(function_name, function_id) end |
#find_functions_for_changes(rule, *changes) ⇒ Object
171 172 173 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 171 def find_functions_for_changes(rule, *changes) !changes.empty? && rule.functions_for(changes[0]) end |
#find_node(ref = ref_node) ⇒ Object
64 65 66 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 64 def find_node(ref = ref_node) ref.rel?(:outgoing, @classname.to_s) && ref_node._node(:outgoing, @classname.to_s) end |
#find_rule(rule_name) ⇒ Object
85 86 87 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 85 def find_rule(rule_name) @rules.find { |rule| rule.rule_name == rule_name } end |
#inherit(subclass) ⇒ Object
58 59 60 61 62 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 58 def inherit(subclass) @rules.each do |rule| subclass.rule rule.rule_name, rule.props, &rule.filter end end |
#key ⇒ Object
40 41 42 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 40 def key "#{ref_node.neo_id}#{@ref_node_key}".to_sym end |
#ref_node ⇒ Object
44 45 46 47 48 49 50 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 44 def ref_node if @model_class.respond_to? :ref_node_for_class @model_class.ref_node_for_class else Neo4j.ref_node end end |
#ref_node_changed? ⇒ Boolean
68 69 70 71 72 73 74 75 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 68 def ref_node_changed? if ref_node != Thread.current[@ref_node_key] Thread.current[@ref_node_key] = ref_node true else false end end |
#remove_rule(rule_name) ⇒ Object
93 94 95 96 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 93 def remove_rule(rule_name) r = find_rule(rule_name) r && @rules.delete(r) end |
#rule_names ⇒ Object
81 82 83 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 81 def rule_names @rules.map { |r| r.rule_name } end |
#rule_node ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 28 def rule_node @@rule_nodes[key] ||= Neo4j::Transaction.run do |tx| java_ref_node = ref_node._java_node tx.acquire_write_lock(java_ref_node) find_node(java_ref_node) || create_node(java_ref_node) end end |
#rule_node?(node) ⇒ Boolean
36 37 38 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 36 def rule_node?(node) @@rule_nodes[key] == node end |
#to_s ⇒ Object
24 25 26 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 24 def to_s "RuleNode #{@classname}, @@rule_nodes #{@@rule_nodes.size} #rules: #{@rules.size}" end |
#traversal(rule_name, cypher_query_hash = nil, &cypher_block) ⇒ Object
Return a traversal object with methods for each rule and function. E.g. Person.all.old or Person.all.sum(:age)
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/neo4j-wrapper/rule/rule_node.rb', line 100 def traversal(rule_name, cypher_query_hash = nil, &cypher_block) traversal = rule_node.outgoing(rule_name) if cypher_query_hash || cypher_block traversal.query(cypher_query_hash, &cypher_block) else @rules.each do |rule| traversal.filter_method(rule.rule_name) do |path| path.end_node.rel?(:incoming, rule.rule_name) end rule.functions && rule.functions.each do |func| traversal.functions_method(func, self, rule_name) end end traversal end end |