neo4j 1.0.0.beta.28-java → 1.0.0.beta.29-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CONTRIBUTORS +1 -0
- data/bin/neo4j-shell +4 -106
- data/lib/neo4j.rb +5 -2
- data/lib/neo4j/batch/batch.rb +2 -0
- data/lib/neo4j/batch/inserter.rb +4 -1
- data/lib/neo4j/batch/rule_inserter.rb +24 -0
- data/lib/neo4j/batch/rule_node.rb +72 -0
- data/lib/neo4j/database.rb +13 -0
- data/lib/neo4j/migrations/node_mixin.rb +1 -1
- data/lib/neo4j/neo4j.rb +27 -0
- data/lib/neo4j/node_mixin/node_mixin.rb +1 -1
- data/lib/neo4j/property/property.rb +1 -1
- data/lib/neo4j/rails/attributes.rb +95 -1
- data/lib/neo4j/rails/model.rb +30 -18
- data/lib/neo4j/rule/class_methods.rb +7 -8
- data/lib/neo4j/rule/event_listener.rb +60 -0
- data/lib/neo4j/rule/rule.rb +127 -2
- data/lib/neo4j/type_converters/type_converters.rb +1 -1
- data/lib/neo4j/version.rb +1 -1
- metadata +5 -3
- data/lib/neo4j/rule/rule_event_listener.rb +0 -162
data/CONTRIBUTORS
CHANGED
data/bin/neo4j-shell
CHANGED
@@ -1,107 +1,5 @@
|
|
1
|
-
#!/bin/
|
2
|
-
# ----------------------------------------------------------------------------
|
3
|
-
# Copyright 2001-2006 The Apache Software Foundation.
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
# See the License for the specific language governing permissions and
|
15
|
-
# limitations under the License.
|
16
|
-
# ----------------------------------------------------------------------------
|
1
|
+
#!/usr/bin/env ruby
|
17
2
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
BASEDIR=`dirname $0`/..
|
22
|
-
BASEDIR=`(cd "$BASEDIR"; pwd)`
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# OS specific support. $var _must_ be set to either true or false.
|
27
|
-
cygwin=false;
|
28
|
-
darwin=false;
|
29
|
-
case "`uname`" in
|
30
|
-
CYGWIN*) cygwin=true ;;
|
31
|
-
Darwin*) darwin=true
|
32
|
-
if [ -z "$JAVA_VERSION" ] ; then
|
33
|
-
JAVA_VERSION="CurrentJDK"
|
34
|
-
else
|
35
|
-
echo "Using Java version: $JAVA_VERSION"
|
36
|
-
fi
|
37
|
-
if [ -z "$JAVA_HOME" ] ; then
|
38
|
-
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
|
39
|
-
fi
|
40
|
-
;;
|
41
|
-
esac
|
42
|
-
|
43
|
-
if [ -z "$JAVA_HOME" ] ; then
|
44
|
-
if [ -r /etc/gentoo-release ] ; then
|
45
|
-
JAVA_HOME=`java-config --jre-home`
|
46
|
-
fi
|
47
|
-
fi
|
48
|
-
|
49
|
-
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
50
|
-
if $cygwin ; then
|
51
|
-
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
52
|
-
[ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
53
|
-
fi
|
54
|
-
|
55
|
-
# If a specific java binary isn't specified search for the standard 'java' binary
|
56
|
-
if [ -z "$JAVACMD" ] ; then
|
57
|
-
if [ -n "$JAVA_HOME" ] ; then
|
58
|
-
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
59
|
-
# IBM's JDK on AIX uses strange locations for the executables
|
60
|
-
JAVACMD="$JAVA_HOME/jre/sh/java"
|
61
|
-
else
|
62
|
-
JAVACMD="$JAVA_HOME/bin/java"
|
63
|
-
fi
|
64
|
-
else
|
65
|
-
JAVACMD=`which java`
|
66
|
-
fi
|
67
|
-
fi
|
68
|
-
|
69
|
-
if [ ! -x "$JAVACMD" ] ; then
|
70
|
-
echo "Error: JAVA_HOME is not defined correctly."
|
71
|
-
echo " We cannot execute $JAVACMD"
|
72
|
-
exit 1
|
73
|
-
fi
|
74
|
-
|
75
|
-
if [ -z "$REPO" ]
|
76
|
-
then
|
77
|
-
REPO="$BASEDIR"/lib/neo4j/jars
|
78
|
-
fi
|
79
|
-
|
80
|
-
LIBRARY_JARS=""
|
81
|
-
for jar in $(find $REPO -iname "*.jar")
|
82
|
-
do
|
83
|
-
LIBRARY_JARS=${LIBRARY_JARS}:$jar
|
84
|
-
done
|
85
|
-
|
86
|
-
CLASSPATH=$CLASSPATH_PREFIX${LIBRARY_JARS}
|
87
|
-
|
88
|
-
EXTRA_JVM_ARGUMENTS=""
|
89
|
-
|
90
|
-
# For Cygwin, switch paths to Windows format before running java
|
91
|
-
if $cygwin; then
|
92
|
-
[ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
93
|
-
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
94
|
-
[ -n "$HOME" ] && HOME=`cygpath --path --windows "$HOME"`
|
95
|
-
[ -n "$BASEDIR" ] && BASEDIR=`cygpath --path --windows "$BASEDIR"`
|
96
|
-
[ -n "$REPO" ] && REPO=`cygpath --path --windows "$REPO"`
|
97
|
-
fi
|
98
|
-
|
99
|
-
exec "$JAVACMD" $JAVA_OPTS \
|
100
|
-
$EXTRA_JVM_ARGUMENTS \
|
101
|
-
-classpath "$CLASSPATH" \
|
102
|
-
-Dapp.name="neo4j-shell" \
|
103
|
-
-Dapp.pid="$$" \
|
104
|
-
-Dapp.repo="$REPO" \
|
105
|
-
-Dbasedir="$BASEDIR" \
|
106
|
-
org.neo4j.shell.StartClient \
|
107
|
-
"$@"
|
3
|
+
require 'neo4j'
|
4
|
+
Neo4j.load_shell_jars
|
5
|
+
org.neo4j.shell.StartClient.main(ARGV)
|
data/lib/neo4j.rb
CHANGED
@@ -15,6 +15,7 @@ require 'neo4j/jars/core/geronimo-jta_1.1_spec-1.1.1.jar'
|
|
15
15
|
require 'neo4j/jars/core/lucene-core-3.0.3.jar'
|
16
16
|
require 'neo4j/jars/core/neo4j-lucene-index-0.5-1.3.M01.jar'
|
17
17
|
require 'neo4j/jars/core/neo4j-kernel-1.3-1.3.M01.jar'
|
18
|
+
require 'neo4j/jars/ha/neo4j-management-1.3-1.3.M01.jar'
|
18
19
|
|
19
20
|
module Neo4j
|
20
21
|
|
@@ -24,11 +25,13 @@ module Neo4j
|
|
24
25
|
require 'neo4j/jars/core/neo4j-index-1.3-1.3.M01.jar'
|
25
26
|
end
|
26
27
|
|
28
|
+
def self.load_shell_jars
|
29
|
+
require 'neo4j/jars/ha/neo4j-shell-1.3-1.3.M01.jar'
|
30
|
+
end
|
31
|
+
|
27
32
|
def self.load_ha_jars
|
28
33
|
require 'neo4j/jars/ha/log4j-1.2.16.jar'
|
29
34
|
require 'neo4j/jars/ha/neo4j-ha-0.6-1.3.M01.jar'
|
30
|
-
require 'neo4j/jars/ha/neo4j-management-1.3-1.3.M01.jar'
|
31
|
-
require 'neo4j/jars/ha/neo4j-shell-1.3-1.3.M01.jar'
|
32
35
|
require 'neo4j/jars/ha/netty-3.2.1.Final.jar'
|
33
36
|
require 'neo4j/jars/ha/org.apache.servicemix.bundles.jline-0.9.94_1.jar'
|
34
37
|
require 'neo4j/jars/ha/org.apache.servicemix.bundles.lucene-3.0.1_2.jar'
|
data/lib/neo4j/batch/batch.rb
CHANGED
data/lib/neo4j/batch/inserter.rb
CHANGED
@@ -23,6 +23,7 @@ module Neo4j
|
|
23
23
|
raise "Not allowed to start batch inserter while Neo4j is already running at storage location #{storage_path}" if Neo4j.storage_path == storage_path
|
24
24
|
@batch_inserter = org.neo4j.kernel.impl.batchinsert.BatchInserterImpl.new(storage_path, config)
|
25
25
|
Indexer.index_provider = org.neo4j.index.impl.lucene.LuceneBatchInserterIndexProvider.new(@batch_inserter)
|
26
|
+
@rule_inserter = RuleInserter.new(self)
|
26
27
|
end
|
27
28
|
|
28
29
|
def running?
|
@@ -33,7 +34,8 @@ module Neo4j
|
|
33
34
|
def shutdown
|
34
35
|
@batch_inserter && @batch_inserter.shutdown
|
35
36
|
@batch_inserter = nil
|
36
|
-
|
37
|
+
@rule_inserter = nil
|
38
|
+
|
37
39
|
Indexer.index_provider
|
38
40
|
Indexer.index_provider && Indexer.index_provider.shutdown
|
39
41
|
Indexer.index_provider = nil
|
@@ -48,6 +50,7 @@ module Neo4j
|
|
48
50
|
|
49
51
|
node = @batch_inserter.create_node(props)
|
50
52
|
props && _index(node, props, clazz)
|
53
|
+
@rule_inserter.node_added(node, props)
|
51
54
|
node
|
52
55
|
end
|
53
56
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Batch
|
3
|
+
class RuleInserter #:nodoc:
|
4
|
+
def initialize(inserter)
|
5
|
+
@inserter = inserter
|
6
|
+
end
|
7
|
+
|
8
|
+
def node_added(node, props)
|
9
|
+
classname = props && props['_classname']
|
10
|
+
classname && create_rules(node, props, classname)
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def create_rules(node, props, classname)
|
15
|
+
rule_node = RuleNode.rule_node_for(classname, @inserter)
|
16
|
+
rule_node && rule_node.execute_rules(@inserter, node, props)
|
17
|
+
|
18
|
+
if (clazz = eval("#{classname}.superclass")) && clazz.include?(Neo4j::NodeMixin)
|
19
|
+
create_rules(node, props, clazz.to_s)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Batch
|
3
|
+
class RuleNode #:nodoc:
|
4
|
+
attr_reader :node
|
5
|
+
delegate :rules, :to => :@wrapped_rule_node
|
6
|
+
|
7
|
+
def initialize(wrapped_rule_node, node)
|
8
|
+
@wrapped_rule_node = wrapped_rule_node
|
9
|
+
@node = node
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute_rules(inserter, node, props)
|
13
|
+
rules.each do |rule|
|
14
|
+
if execute_filter(rule, props)
|
15
|
+
inserter.create_rel(rule.rule_name, @node, node)
|
16
|
+
execute_add_functions(inserter, rule, props)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def execute_add_functions(inserter, rule, props)
|
22
|
+
rule_props = nil
|
23
|
+
executed_functions = []
|
24
|
+
props.keys.each do |key|
|
25
|
+
functions = rule.functions_for(key)
|
26
|
+
next unless functions
|
27
|
+
functions -= executed_functions
|
28
|
+
rule_props ||= clone_node_props(inserter) #inserter.node_props(@node)
|
29
|
+
functions.each { |f| executed_functions << f; f.add(rule.rule_name, rule_props, props[key]) }
|
30
|
+
end
|
31
|
+
rule_props && inserter.set_node_props(@node, rule_props)
|
32
|
+
end
|
33
|
+
|
34
|
+
def clone_node_props(inserter)
|
35
|
+
hash = {}
|
36
|
+
props = inserter.node_props(@node) # need to clone this since we can't modify it
|
37
|
+
props.each_pair{|k,v| hash[k]=v}
|
38
|
+
hash
|
39
|
+
end
|
40
|
+
|
41
|
+
def execute_filter(rule, props)
|
42
|
+
if rule.filter.nil?
|
43
|
+
true
|
44
|
+
elsif rule.filter.arity != 1
|
45
|
+
classname = props['_classname'] || 'Neo4j::Node'
|
46
|
+
clazz = Neo4j::Node.to_class(classname)
|
47
|
+
wrapper = clazz.load_wrapper(ActiveSupport::HashWithIndifferentAccess.new(props))
|
48
|
+
wrapper.instance_eval(&rule.filter)
|
49
|
+
else
|
50
|
+
rule.filter.call(ActiveSupport::HashWithIndifferentAccess.new(props))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
def rule_node_for(classname, inserter)
|
56
|
+
return nil unless Neo4j::Rule::Rule.has_rules?(classname)
|
57
|
+
wrapped_rule_node = Neo4j::Rule::Rule.rule_node_for(classname)
|
58
|
+
@rule_nodes ||= {}
|
59
|
+
@rule_nodes[classname] ||= RuleNode.new(wrapped_rule_node, create_node(classname, inserter))
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_node(classname, inserter)
|
63
|
+
rule_node = inserter.create_node
|
64
|
+
inserter.create_rel(classname, inserter.ref_node, rule_node)
|
65
|
+
rule_node
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/neo4j/database.rb
CHANGED
@@ -22,6 +22,12 @@ module Neo4j
|
|
22
22
|
@running = true
|
23
23
|
@storage_path = Config.storage_path
|
24
24
|
|
25
|
+
|
26
|
+
if Config[:enable_remote_shell]
|
27
|
+
Neo4j.logger.info("Enable remote shell at port #{Config[:enable_remote_shell]}")
|
28
|
+
Neo4j.load_shell_jars
|
29
|
+
end
|
30
|
+
|
25
31
|
begin
|
26
32
|
if self.class.locked?
|
27
33
|
start_readonly_graph_db
|
@@ -96,10 +102,17 @@ module Neo4j
|
|
96
102
|
@graph = nil
|
97
103
|
@lucene = nil
|
98
104
|
@running = false
|
105
|
+
@neo4j_manager = nil
|
99
106
|
end
|
100
107
|
|
101
108
|
end
|
102
109
|
|
110
|
+
|
111
|
+
def management(jmx_clazz) #:nodoc:
|
112
|
+
@neo4j_manager ||= org.neo4j.management.Neo4jManager.new(@graph.get_management_bean(org.neo4j.management.Kernel.java_class))
|
113
|
+
@neo4j_manager.getBean(jmx_clazz.java_class)
|
114
|
+
end
|
115
|
+
|
103
116
|
def begin_tx #:nodoc:
|
104
117
|
@graph.begin_tx
|
105
118
|
end
|
@@ -48,7 +48,7 @@ module Neo4j
|
|
48
48
|
|
49
49
|
# The node that holds the db version property
|
50
50
|
def migration_meta_node
|
51
|
-
Neo4j::Rule::
|
51
|
+
Neo4j::Rule::Rule.rule_node_for(self).rule_node
|
52
52
|
end
|
53
53
|
|
54
54
|
# Remote all migration and set migrate_to = nil and set the current version to nil
|
data/lib/neo4j/neo4j.rb
CHANGED
@@ -110,6 +110,33 @@ module Neo4j
|
|
110
110
|
this_db.graph.reference_node
|
111
111
|
end
|
112
112
|
|
113
|
+
# Returns a Management JMX Bean.
|
114
|
+
#
|
115
|
+
# Notice that this information is also provided by the jconsole Java tool, check http://wiki.neo4j.org/content/Monitoring_and_Deployment
|
116
|
+
# and http://docs.neo4j.org/chunked/milestone/operations-monitoring.html
|
117
|
+
#
|
118
|
+
# By default it returns the Primitivies JMX Bean that can be used to find number of nodes in use.
|
119
|
+
#
|
120
|
+
# ==== Example Neo4j Primititives
|
121
|
+
#
|
122
|
+
# Neo4j.management.get_number_of_node_ids_in_use
|
123
|
+
# Neo4j.management.getNumberOfPropertyIdsInUse
|
124
|
+
# Neo4j.management.getNumberOfRelationshipIdsInUse
|
125
|
+
# Neo4j.management.get_number_of_relationship_type_ids_in_use
|
126
|
+
#
|
127
|
+
# ==== Example Neo4j HA Cluster Info
|
128
|
+
#
|
129
|
+
# Neo4j.management(org.neo4j.management.HighAvailability).isMaster
|
130
|
+
#
|
131
|
+
# ==== Arguments
|
132
|
+
#
|
133
|
+
# jmx_clazz :: http://api.neo4j.org/current/org/neo4j/management/package-summary.html
|
134
|
+
# this_db :: default currently runnig instance or a newly started neo4j db instance
|
135
|
+
#
|
136
|
+
def management(jmx_clazz = org.neo4j.management.Primitives, this_db = self.started_db)
|
137
|
+
this_db.management(jmx_clazz)
|
138
|
+
end
|
139
|
+
|
113
140
|
# Returns an Enumerable object for all nodes in the database
|
114
141
|
def all_nodes(this_db = self.started_db)
|
115
142
|
Enumerator.new(this_db, :each_node)
|
@@ -78,7 +78,7 @@ module Neo4j
|
|
78
78
|
|
79
79
|
# Trigger rules.
|
80
80
|
# You don't normally need to call this method (except in Migration) since
|
81
|
-
# it will be triggered automatically by the Neo4j::Rule::
|
81
|
+
# it will be triggered automatically by the Neo4j::Rule::Rule
|
82
82
|
#
|
83
83
|
def trigger_rules
|
84
84
|
self.class.trigger_rules(self)
|
@@ -57,7 +57,101 @@ module Neo4j
|
|
57
57
|
# Mass-assign attributes. Stops any protected attributes from being assigned.
|
58
58
|
def attributes=(attributes, guard_protected_attributes = true)
|
59
59
|
attributes = sanitize_for_mass_assignment(attributes) if guard_protected_attributes
|
60
|
-
|
60
|
+
|
61
|
+
multi_parameter_attributes = []
|
62
|
+
attributes.each do |k, v|
|
63
|
+
if k.to_s.include?("(")
|
64
|
+
multi_parameter_attributes << [ k, v ]
|
65
|
+
else
|
66
|
+
respond_to?("#{k}=") ? send("#{k}=", v) : self[k] = v
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
assign_multiparameter_attributes(multi_parameter_attributes)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
|
74
|
+
# by calling new on the column type or aggregation type (through composed_of) object with these parameters.
|
75
|
+
# So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
|
76
|
+
# written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
|
77
|
+
# parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum,
|
78
|
+
# f for Float, s for String, and a for Array. If all the values for a given attribute are empty, the
|
79
|
+
# attribute will be set to nil.
|
80
|
+
def assign_multiparameter_attributes(pairs)
|
81
|
+
execute_callstack_for_multiparameter_attributes(
|
82
|
+
extract_callstack_for_multiparameter_attributes(pairs)
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
def execute_callstack_for_multiparameter_attributes(callstack)
|
87
|
+
errors = []
|
88
|
+
callstack.each do |name, values_with_empty_parameters|
|
89
|
+
begin
|
90
|
+
# (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
|
91
|
+
klass = self.class._decl_props[name.to_sym][:type]
|
92
|
+
raise "Not a multiparameter attribute, missing :type on property #{name} for #{self.class}" unless klass
|
93
|
+
|
94
|
+
# in order to allow a date to be set without a year, we must keep the empty values.
|
95
|
+
values = values_with_empty_parameters.reject { |v| v.nil? }
|
96
|
+
|
97
|
+
if values.empty?
|
98
|
+
send(name + "=", nil)
|
99
|
+
else
|
100
|
+
|
101
|
+
value = if Time == klass
|
102
|
+
instantiate_time_object(name, values)
|
103
|
+
elsif Date == klass
|
104
|
+
begin
|
105
|
+
values = values_with_empty_parameters.collect do |v| v.nil? ? 1 : v end
|
106
|
+
Date.new(*values)
|
107
|
+
rescue ArgumentError => ex # if Date.new raises an exception on an invalid date
|
108
|
+
instantiate_time_object(name, values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
|
109
|
+
end
|
110
|
+
else
|
111
|
+
klass.new(*values)
|
112
|
+
end
|
113
|
+
|
114
|
+
send(name + "=", value)
|
115
|
+
end
|
116
|
+
rescue Exception => ex
|
117
|
+
raise "error on assignment #{values.inspect} to #{name}, ex: #{ex}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
unless errors.empty?
|
121
|
+
raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def instantiate_time_object(name, values)
|
126
|
+
# if self.class.send(:create_time_zone_conversion_attribute?, name, column_for_attribute(name))
|
127
|
+
# Time.zone.local(*values)
|
128
|
+
# else
|
129
|
+
Time.time_with_datetime_fallback(self.class.default_timezone, *values)
|
130
|
+
# end
|
131
|
+
end
|
132
|
+
|
133
|
+
def extract_callstack_for_multiparameter_attributes(pairs)
|
134
|
+
attributes = { }
|
135
|
+
|
136
|
+
for pair in pairs
|
137
|
+
multiparameter_name, value = pair
|
138
|
+
attribute_name = multiparameter_name.split("(").first
|
139
|
+
attributes[attribute_name] = [] unless attributes.include?(attribute_name)
|
140
|
+
|
141
|
+
parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
|
142
|
+
attributes[attribute_name] << [ find_parameter_position(multiparameter_name), parameter_value ]
|
143
|
+
end
|
144
|
+
|
145
|
+
attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
def type_cast_attribute_value(multiparameter_name, value)
|
150
|
+
multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
|
151
|
+
end
|
152
|
+
|
153
|
+
def find_parameter_position(multiparameter_name)
|
154
|
+
multiparameter_name.scan(/\(([0-9]*).*\)/).first.first
|
61
155
|
end
|
62
156
|
|
63
157
|
# Tracks the current changes and clears the changed attributes hash. Called
|
data/lib/neo4j/rails/model.rb
CHANGED
@@ -2,10 +2,10 @@ module Neo4j
|
|
2
2
|
module Rails
|
3
3
|
class Model
|
4
4
|
include Neo4j::NodeMixin
|
5
|
-
|
5
|
+
|
6
6
|
# Initialize a Node with a set of properties (or empty if nothing is passed)
|
7
7
|
def initialize(attributes = {})
|
8
|
-
|
8
|
+
reset_attributes
|
9
9
|
clear_relationships
|
10
10
|
self.attributes = attributes if attributes.is_a?(Hash)
|
11
11
|
end
|
@@ -39,9 +39,10 @@ module Neo4j
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def ==(other)
|
42
|
-
|
42
|
+
new? ? self.__id__ == other.__id__ : @_java_node == (other)
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
|
+
|
45
46
|
# --------------------------------------
|
46
47
|
# Public Class Methods
|
47
48
|
# --------------------------------------
|
@@ -49,11 +50,22 @@ module Neo4j
|
|
49
50
|
# NodeMixin overwrites the #new class method but it saves it as orig_new
|
50
51
|
# Here, we just get it back to normal
|
51
52
|
alias :new :orig_new
|
52
|
-
|
53
|
+
|
53
54
|
def transaction(&block)
|
54
55
|
Neo4j::Rails::Transaction.run do |tx|
|
55
56
|
block.call(tx)
|
56
|
-
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling
|
62
|
+
# dates and times from the database. This is set to :local by default.
|
63
|
+
def default_timezone
|
64
|
+
@default_timezone || :local
|
65
|
+
end
|
66
|
+
|
67
|
+
def default_timezone=(zone)
|
68
|
+
@default_timezone = zone
|
57
69
|
end
|
58
70
|
|
59
71
|
def accepts_nested_attributes_for(*attr_names)
|
@@ -87,19 +99,19 @@ module Neo4j
|
|
87
99
|
end
|
88
100
|
end
|
89
101
|
end
|
90
|
-
|
102
|
+
|
91
103
|
Model.class_eval do
|
92
|
-
|
93
|
-
|
94
|
-
include Persistence
|
95
|
-
include Attributes
|
96
|
-
include Mapping::Property
|
97
|
-
include Serialization
|
98
|
-
include Timestamps
|
99
|
-
include Validations
|
100
|
-
include Callbacks
|
101
|
-
include Finders
|
102
|
-
include Relationships
|
104
|
+
extend ActiveModel::Translation
|
105
|
+
|
106
|
+
include Persistence # handles how to save, create and update the model
|
107
|
+
include Attributes # handles how to save and retrieve attributes
|
108
|
+
include Mapping::Property # allows some additional options on the #property class method
|
109
|
+
include Serialization # enable to_xml and to_json
|
110
|
+
include Timestamps # handle created_at, updated_at timestamp properties
|
111
|
+
include Validations # enable validations
|
112
|
+
include Callbacks # enable callbacks
|
113
|
+
include Finders # ActiveRecord style find
|
114
|
+
include Relationships # for none persisted relationships
|
103
115
|
end
|
104
116
|
end
|
105
117
|
end
|
@@ -102,7 +102,7 @@ module Neo4j
|
|
102
102
|
|
103
103
|
# define class methods
|
104
104
|
singleton.send(:define_method, rule_name) do
|
105
|
-
rule_node =
|
105
|
+
rule_node = Rule.rule_node_for(self)
|
106
106
|
rule_node.traversal(rule_name)
|
107
107
|
end unless respond_to?(rule_name)
|
108
108
|
|
@@ -111,11 +111,11 @@ module Neo4j
|
|
111
111
|
instance_eval &block
|
112
112
|
end
|
113
113
|
|
114
|
-
rule =
|
114
|
+
rule = Rule.add(self, rule_name, props, &block)
|
115
115
|
|
116
116
|
rule.functions && rule.functions.each do |func|
|
117
117
|
singleton.send(:define_method, func.class.function_name) do |r_name, *args|
|
118
|
-
rule_node =
|
118
|
+
rule_node = Rule.rule_node_for(self)
|
119
119
|
function_id = args.empty? ? "_classname" : args[0]
|
120
120
|
function = rule_node.find_function(r_name, func.class.function_name, function_id)
|
121
121
|
function.value(rule_node.rule_node, r_name)
|
@@ -124,7 +124,7 @@ module Neo4j
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def inherit_rules_from(clazz)
|
127
|
-
|
127
|
+
Rule.inherit(clazz, self)
|
128
128
|
end
|
129
129
|
|
130
130
|
# This is typically used for RSpecs to clean up rule nodes created by the #rule method.
|
@@ -133,7 +133,7 @@ module Neo4j
|
|
133
133
|
singelton = class << self;
|
134
134
|
self;
|
135
135
|
end
|
136
|
-
rule_node =
|
136
|
+
rule_node = Rule.rule_node_for(self)
|
137
137
|
|
138
138
|
rule_node.rule_names.each {|rule_name| singelton.send(:remove_method, rule_name)}
|
139
139
|
rule_node.rules.clear
|
@@ -145,7 +145,7 @@ module Neo4j
|
|
145
145
|
# Can also be called from an migration.
|
146
146
|
#
|
147
147
|
def trigger_rules(node, *changes)
|
148
|
-
|
148
|
+
Rule.trigger_rules(node, *changes)
|
149
149
|
end
|
150
150
|
|
151
151
|
# Returns a proc that will call add method on the given function
|
@@ -167,7 +167,7 @@ module Neo4j
|
|
167
167
|
# Returns a proc that calls the given method on the given function.
|
168
168
|
def function_for(method, rule_name, function_name_or_class, function_id = '_classname')
|
169
169
|
function_name = function_name_or_class.is_a?(Symbol)? function_name_or_class : function_name_or_class.function_name
|
170
|
-
rule_node =
|
170
|
+
rule_node = Rule.rule_node_for(self)
|
171
171
|
rule = rule_node.find_rule(rule_name)
|
172
172
|
rule_node_raw = rule_node.rule_node
|
173
173
|
|
@@ -179,6 +179,5 @@ module Neo4j
|
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
|
-
Neo4j.unstarted_db.event_handler.add(RuleEventListener) unless Neo4j.read_only?
|
183
182
|
end
|
184
183
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Rule
|
3
|
+
class EventListener
|
4
|
+
class << self
|
5
|
+
# ----------------------------------------------------------------------------------------------------------------
|
6
|
+
# Event handling methods
|
7
|
+
# ----------------------------------------------------------------------------------------------------------------
|
8
|
+
|
9
|
+
def on_relationship_created(rel, *)
|
10
|
+
trigger_start_node = Rule.trigger?(rel._start_node)
|
11
|
+
trigger_end_node = Rule.trigger?(rel._end_node)
|
12
|
+
Rule.trigger_rules(rel._start_node) if trigger_start_node
|
13
|
+
Rule.trigger_rules(rel._end_node) if trigger_end_node
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_property_changed(node, *changes)
|
17
|
+
Rule.trigger_rules(node, *changes) if Rule.trigger?(node)
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_node_deleted(node, old_properties, data)
|
21
|
+
# have we deleted a rule node ?
|
22
|
+
del_rule_node = Rule.find_rule_node(node)
|
23
|
+
del_rule_node && del_rule_node.clear_rule_node
|
24
|
+
return if del_rule_node
|
25
|
+
|
26
|
+
# do we have prop_aggregations for this
|
27
|
+
clazz = old_properties['_classname']
|
28
|
+
rule_node = Rule.rule_node_for(clazz)
|
29
|
+
return if rule_node.nil?
|
30
|
+
|
31
|
+
id = node.getId
|
32
|
+
rule_node.rules.each do |rule|
|
33
|
+
next if rule.functions.nil?
|
34
|
+
rule_name = rule.rule_name.to_s
|
35
|
+
|
36
|
+
# is the rule node deleted ?
|
37
|
+
deleted_rule_node = data.deletedNodes.find { |n| n == rule_node.rule_node }
|
38
|
+
next if deleted_rule_node
|
39
|
+
|
40
|
+
rule.functions.each do |function|
|
41
|
+
next unless data.deletedRelationships.find do |r|
|
42
|
+
r.getEndNode().getId() == id && r.rel_type == rule_name
|
43
|
+
end
|
44
|
+
previous_value = old_properties[function.function_id]
|
45
|
+
function.delete(rule_name, rule_node.rule_node, previous_value) if previous_value
|
46
|
+
end if rule.functions
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def on_neo4j_started(*)
|
51
|
+
Rule.on_neo4j_started
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
Neo4j.unstarted_db.event_handler.add(EventListener) unless Neo4j.read_only?
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/lib/neo4j/rule/rule.rb
CHANGED
@@ -1,5 +1,130 @@
|
|
1
|
-
require 'neo4j/rule/
|
1
|
+
require 'neo4j/rule/event_listener'
|
2
2
|
require 'neo4j/rule/class_methods'
|
3
3
|
require 'neo4j/rule/rule_node'
|
4
4
|
|
5
|
-
require 'neo4j/rule/functions/functions'
|
5
|
+
require 'neo4j/rule/functions/functions'
|
6
|
+
|
7
|
+
|
8
|
+
module Neo4j
|
9
|
+
module Rule
|
10
|
+
|
11
|
+
|
12
|
+
# Holds all defined rules added by the Neo4j::Rule::ClassMethods#rule method.
|
13
|
+
#
|
14
|
+
# See Neo4j::Rule::ClassMethods
|
15
|
+
#
|
16
|
+
class Rule
|
17
|
+
|
18
|
+
attr_reader :rule_name, :filter, :triggers, :functions
|
19
|
+
|
20
|
+
def initialize(rule_name, props, &block)
|
21
|
+
@rule_name = rule_name
|
22
|
+
@triggers = props[:triggers]
|
23
|
+
@functions = props[:functions]
|
24
|
+
@triggers = [@triggers] if @triggers && !@triggers.respond_to?(:each)
|
25
|
+
@functions = [@functions] if @functions && !@functions.respond_to?(:each)
|
26
|
+
@filter = block
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"Rule #{rule_name} props=#{props.inspect}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_function(function_name, function_id)
|
34
|
+
function_id = function_id.to_s
|
35
|
+
@functions && @functions.find { |f| f.function_id == function_id && f.class.function_name == function_name }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Reconstruct the properties given when created this rule
|
39
|
+
# Needed when inheriting a rule and we want to duplicate a rule
|
40
|
+
def props
|
41
|
+
props = {}
|
42
|
+
props[:triggers] = @triggers if @triggers
|
43
|
+
props[:functions] = @functions if @functions
|
44
|
+
props
|
45
|
+
end
|
46
|
+
|
47
|
+
def functions_for(property)
|
48
|
+
@functions && @functions.find_all { |f| f.calculate?(property) }
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute_filter(node)
|
52
|
+
if @filter.nil?
|
53
|
+
true
|
54
|
+
elsif @filter.arity != 1
|
55
|
+
node.wrapper.instance_eval(&@filter)
|
56
|
+
else
|
57
|
+
@filter.call(node)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# ------------------------------------------------------------------------------------------------------------------
|
62
|
+
# Class Methods
|
63
|
+
# ------------------------------------------------------------------------------------------------------------------
|
64
|
+
|
65
|
+
class << self
|
66
|
+
def add(clazz, rule_name, props, &block)
|
67
|
+
rule_node = rule_node_for(clazz.to_s)
|
68
|
+
rule_node.remove_rule(rule_name) # remove any previously inherited rules
|
69
|
+
rule = Rule.new(rule_name, props, &block)
|
70
|
+
rule_node.add_rule(rule)
|
71
|
+
rule
|
72
|
+
end
|
73
|
+
|
74
|
+
def has_rules?(clazz)
|
75
|
+
!@rule_nodes[clazz.to_s].nil?
|
76
|
+
end
|
77
|
+
|
78
|
+
def rule_names_for(clazz)
|
79
|
+
rule_node = rule_node_for(clazz)
|
80
|
+
rule_node.rules.map { |rule| rule.rule_name }
|
81
|
+
end
|
82
|
+
|
83
|
+
def rule_node_for(clazz)
|
84
|
+
return nil if clazz.nil?
|
85
|
+
@rule_nodes ||= {}
|
86
|
+
@rule_nodes[clazz.to_s] ||= RuleNode.new(clazz)
|
87
|
+
end
|
88
|
+
|
89
|
+
def find_rule_node(node)
|
90
|
+
@rule_nodes && @rule_nodes.values.find { |rn| rn.rule_node?(node) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def on_neo4j_started
|
94
|
+
@rule_nodes.each_value { |rule_node| rule_node.on_neo4j_started } if @rule_nodes
|
95
|
+
end
|
96
|
+
|
97
|
+
def inherit(parent_class, subclass)
|
98
|
+
# copy all the rules
|
99
|
+
if rule_node = rule_node_for(parent_class)
|
100
|
+
rule_node.inherit(subclass)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def delete(clazz)
|
105
|
+
if rule_node = rule_node_for(clazz)
|
106
|
+
rule_node.delete_node
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def trigger?(node)
|
111
|
+
classname = node[:_classname]
|
112
|
+
@rule_nodes && classname && rule_node_for(classname)
|
113
|
+
end
|
114
|
+
|
115
|
+
def trigger_rules(node, *changes)
|
116
|
+
classname = node[:_classname]
|
117
|
+
return unless classname # there are no rules if there is not a :_classname property
|
118
|
+
rule_node = rule_node_for(classname)
|
119
|
+
rule_node.execute_rules(node, *changes)
|
120
|
+
|
121
|
+
# recursively add relationships for all the parent classes with rules that also pass for this node
|
122
|
+
if (clazz = eval("#{classname}.superclass")) && clazz.include?(Neo4j::NodeMixin)
|
123
|
+
rule_node = rule_node_for(clazz)
|
124
|
+
rule_node && rule_node.execute_rules(node, *changes)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
data/lib/neo4j/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: neo4j
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 1.0.0.beta.
|
5
|
+
version: 1.0.0.beta.29
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- Andreas Ronge
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-02-
|
13
|
+
date: 2011-02-10 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -154,6 +154,8 @@ files:
|
|
154
154
|
- lib/neo4j/index/index.rb
|
155
155
|
- lib/neo4j/batch/inserter.rb
|
156
156
|
- lib/neo4j/batch/indexer.rb
|
157
|
+
- lib/neo4j/batch/rule_inserter.rb
|
158
|
+
- lib/neo4j/batch/rule_node.rb
|
157
159
|
- lib/neo4j/batch/batch.rb
|
158
160
|
- lib/neo4j/has_n/decl_relationship_dsl.rb
|
159
161
|
- lib/neo4j/has_n/has_n.rb
|
@@ -164,7 +166,7 @@ files:
|
|
164
166
|
- lib/neo4j/rule/rule.rb
|
165
167
|
- lib/neo4j/rule/rule_node.rb
|
166
168
|
- lib/neo4j/rule/class_methods.rb
|
167
|
-
- lib/neo4j/rule/
|
169
|
+
- lib/neo4j/rule/event_listener.rb
|
168
170
|
- lib/neo4j/rule/functions/function.rb
|
169
171
|
- lib/neo4j/rule/functions/count.rb
|
170
172
|
- lib/neo4j/rule/functions/sum.rb
|
@@ -1,162 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module Rule
|
3
|
-
|
4
|
-
|
5
|
-
# Holds all defined rules and trigger them when an event is received.
|
6
|
-
#
|
7
|
-
# See Neo4j::Rule::ClassMethods
|
8
|
-
#
|
9
|
-
class RuleEventListener #:nodoc:
|
10
|
-
|
11
|
-
attr_reader :rule_name, :filter, :triggers, :functions
|
12
|
-
|
13
|
-
def initialize(rule_name, props, &block)
|
14
|
-
@rule_name = rule_name
|
15
|
-
@triggers = props[:triggers]
|
16
|
-
@functions = props[:functions]
|
17
|
-
@triggers = [@triggers] if @triggers && !@triggers.respond_to?(:each)
|
18
|
-
@functions = [@functions] if @functions && !@functions.respond_to?(:each)
|
19
|
-
@filter = block
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_s
|
23
|
-
"RuleEventListener #{rule_name} props=#{props.inspect}"
|
24
|
-
end
|
25
|
-
|
26
|
-
def find_function(function_name, function_id)
|
27
|
-
function_id = function_id.to_s
|
28
|
-
@functions && @functions.find { |f| f.function_id == function_id && f.class.function_name == function_name }
|
29
|
-
end
|
30
|
-
|
31
|
-
# Reconstruct the properties given when created this rule
|
32
|
-
# Needed when inheriting a rule and we want to duplicate a rule
|
33
|
-
def props
|
34
|
-
props = {}
|
35
|
-
props[:triggers] = @triggers if @triggers
|
36
|
-
props[:functions] = @functions if @functions
|
37
|
-
props
|
38
|
-
end
|
39
|
-
|
40
|
-
def functions_for(property)
|
41
|
-
@functions && @functions.find_all { |f| f.calculate?(property) }
|
42
|
-
end
|
43
|
-
|
44
|
-
def execute_filter(node)
|
45
|
-
if @filter.nil?
|
46
|
-
true
|
47
|
-
elsif @filter.arity != 1
|
48
|
-
node.wrapper.instance_eval(&@filter)
|
49
|
-
else
|
50
|
-
@filter.call(node)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# ------------------------------------------------------------------------------------------------------------------
|
55
|
-
# Class Methods
|
56
|
-
# ------------------------------------------------------------------------------------------------------------------
|
57
|
-
|
58
|
-
class << self
|
59
|
-
def add(clazz, rule_name, props, &block)
|
60
|
-
rule_node = rule_node_for(clazz.to_s)
|
61
|
-
rule_node.remove_rule(rule_name) # remove any previously inherited rules
|
62
|
-
rule = RuleEventListener.new(rule_name, props, &block)
|
63
|
-
rule_node.add_rule(rule)
|
64
|
-
rule
|
65
|
-
end
|
66
|
-
|
67
|
-
def rule_names_for(clazz)
|
68
|
-
rule_node = rule_node_for(clazz)
|
69
|
-
rule_node.rules.map { |rule| rule.rule_name }
|
70
|
-
end
|
71
|
-
|
72
|
-
def rule_node_for(clazz)
|
73
|
-
return nil if clazz.nil?
|
74
|
-
@rule_nodes ||= {}
|
75
|
-
@rule_nodes[clazz.to_s] ||= RuleNode.new(clazz)
|
76
|
-
end
|
77
|
-
|
78
|
-
def inherit(parent_class, subclass)
|
79
|
-
# copy all the rules
|
80
|
-
if rule_node = rule_node_for(parent_class)
|
81
|
-
rule_node.inherit(subclass)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def delete(clazz)
|
86
|
-
if rule_node = rule_node_for(clazz)
|
87
|
-
rule_node.delete_node
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def trigger?(node)
|
92
|
-
classname = node[:_classname]
|
93
|
-
@rule_nodes && classname && rule_node_for(classname)
|
94
|
-
end
|
95
|
-
|
96
|
-
def trigger_rules(node, *changes)
|
97
|
-
classname = node[:_classname]
|
98
|
-
return unless classname # there are no rules if there is not a :_classname property
|
99
|
-
rule_node = rule_node_for(classname)
|
100
|
-
rule_node.execute_rules(node, *changes)
|
101
|
-
|
102
|
-
# recursively add relationships for all the parent classes with rules that also pass for this node
|
103
|
-
if (clazz = eval("#{classname}.superclass")) && clazz.include?(Neo4j::NodeMixin)
|
104
|
-
rule_node = rule_node_for(clazz)
|
105
|
-
rule_node && rule_node.execute_rules(node, *changes)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
|
110
|
-
# ----------------------------------------------------------------------------------------------------------------
|
111
|
-
# Event handling methods
|
112
|
-
# ----------------------------------------------------------------------------------------------------------------
|
113
|
-
|
114
|
-
def on_relationship_created(rel, *)
|
115
|
-
trigger_start_node = trigger?(rel._start_node)
|
116
|
-
trigger_end_node = trigger?(rel._end_node)
|
117
|
-
trigger_rules(rel._start_node) if trigger_start_node
|
118
|
-
trigger_rules(rel._end_node) if trigger_end_node
|
119
|
-
end
|
120
|
-
|
121
|
-
def on_property_changed(node, *changes)
|
122
|
-
trigger_rules(node, *changes) if trigger?(node)
|
123
|
-
end
|
124
|
-
|
125
|
-
def on_node_deleted(node, old_properties, data)
|
126
|
-
# have we deleted a rule node ?
|
127
|
-
del_rule_node = @rule_nodes && @rule_nodes.values.find { |rn| rn.rule_node?(node) }
|
128
|
-
del_rule_node && del_rule_node.clear_rule_node
|
129
|
-
return if del_rule_node
|
130
|
-
|
131
|
-
# do we have prop_aggregations for this
|
132
|
-
clazz = old_properties['_classname']
|
133
|
-
rule_node = rule_node_for(clazz)
|
134
|
-
return if rule_node.nil?
|
135
|
-
|
136
|
-
id = node.getId
|
137
|
-
rule_node.rules.each do |rule|
|
138
|
-
next if rule.functions.nil?
|
139
|
-
rule_name = rule.rule_name.to_s
|
140
|
-
|
141
|
-
# is the rule node deleted ?
|
142
|
-
deleted_rule_node = data.deletedNodes.find { |n| n == rule_node.rule_node }
|
143
|
-
next if deleted_rule_node
|
144
|
-
|
145
|
-
rule.functions.each do |function|
|
146
|
-
next unless data.deletedRelationships.find do |r|
|
147
|
-
r.getEndNode().getId() == id && r.rel_type == rule_name
|
148
|
-
end
|
149
|
-
previous_value = old_properties[function.function_id]
|
150
|
-
function.delete(rule_name, rule_node.rule_node, previous_value) if previous_value
|
151
|
-
end if rule.functions
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def on_neo4j_started(*)
|
156
|
-
@rule_nodes.each_value { |rule_node| rule_node.on_neo4j_started } if @rule_nodes
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|