neo4j-core 3.1.1 → 4.0.0
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.
- checksums.yaml +4 -4
- data/Gemfile +7 -12
- data/README.md +7 -7
- data/lib/neo4j-core.rb +3 -2
- data/lib/neo4j-core/active_entity.rb +8 -10
- data/lib/neo4j-core/cypher_translator.rb +61 -59
- data/lib/neo4j-core/hash_with_indifferent_access.rb +31 -22
- data/lib/neo4j-core/helpers.rb +15 -17
- data/lib/neo4j-core/label.rb +7 -6
- data/lib/neo4j-core/query.rb +271 -268
- data/lib/neo4j-core/query_clauses.rb +371 -355
- data/lib/neo4j-core/query_find_in_batches.rb +26 -26
- data/lib/neo4j-core/version.rb +1 -1
- data/lib/neo4j-embedded.rb +2 -2
- data/lib/neo4j-embedded/cypher_response.rb +40 -41
- data/lib/neo4j-embedded/embedded_database.rb +21 -22
- data/lib/neo4j-embedded/embedded_ha_session.rb +13 -11
- data/lib/neo4j-embedded/embedded_impermanent_session.rb +9 -8
- data/lib/neo4j-embedded/embedded_label.rb +64 -70
- data/lib/neo4j-embedded/embedded_node.rb +68 -73
- data/lib/neo4j-embedded/embedded_relationship.rb +6 -13
- data/lib/neo4j-embedded/embedded_session.rb +128 -132
- data/lib/neo4j-embedded/embedded_transaction.rb +34 -33
- data/lib/neo4j-embedded/property.rb +84 -77
- data/lib/neo4j-embedded/to_java.rb +24 -23
- data/lib/neo4j-server.rb +1 -1
- data/lib/neo4j-server/cypher_authentication.rb +105 -103
- data/lib/neo4j-server/cypher_label.rb +25 -23
- data/lib/neo4j-server/cypher_node.rb +180 -177
- data/lib/neo4j-server/cypher_node_uncommited.rb +11 -9
- data/lib/neo4j-server/cypher_relationship.rb +101 -102
- data/lib/neo4j-server/cypher_response.rb +171 -170
- data/lib/neo4j-server/cypher_session.rb +209 -205
- data/lib/neo4j-server/cypher_transaction.rb +66 -48
- data/lib/neo4j-server/resource.rb +17 -22
- data/lib/neo4j/entity_equality.rb +3 -4
- data/lib/neo4j/label.rb +13 -16
- data/lib/neo4j/node.rb +30 -34
- data/lib/neo4j/property_container.rb +3 -3
- data/lib/neo4j/property_validator.rb +4 -5
- data/lib/neo4j/relationship.rb +17 -22
- data/lib/neo4j/session.rb +19 -21
- data/lib/neo4j/tasks/config_server.rb +2 -3
- data/lib/neo4j/tasks/neo4j_server.rake +82 -74
- data/lib/neo4j/transaction.rb +23 -22
- data/neo4j-core.gemspec +21 -16
- metadata +72 -2
@@ -1,9 +1,8 @@
|
|
1
|
-
module Neo4j
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
java_clazz.class_eval do
|
1
|
+
module Neo4j
|
2
|
+
module Embedded
|
3
|
+
class EmbeddedRelationship
|
4
|
+
class << self
|
5
|
+
Java::OrgNeo4jKernelImplCore::RelationshipProxy.class_eval do
|
7
6
|
include Neo4j::Embedded::Property
|
8
7
|
include Neo4j::EntityEquality
|
9
8
|
include Neo4j::Relationship::Wrapper
|
@@ -39,7 +38,7 @@ module Neo4j::Embedded
|
|
39
38
|
end
|
40
39
|
|
41
40
|
def _rel_type
|
42
|
-
getType
|
41
|
+
getType.name.to_sym
|
43
42
|
end
|
44
43
|
tx_methods :rel_type
|
45
44
|
|
@@ -67,14 +66,8 @@ module Neo4j::Embedded
|
|
67
66
|
def _end_node
|
68
67
|
getEndNode
|
69
68
|
end
|
70
|
-
|
71
69
|
end
|
72
70
|
end
|
73
71
|
end
|
74
|
-
|
75
|
-
extend_java_class(Java::OrgNeo4jKernelImplCore::RelationshipProxy)
|
76
|
-
|
77
72
|
end
|
78
|
-
|
79
|
-
|
80
73
|
end
|
@@ -5,166 +5,162 @@ Neo4j::Session.register_db(:embedded_db) do |*args|
|
|
5
5
|
end
|
6
6
|
|
7
7
|
|
8
|
-
module Neo4j
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
module Neo4j
|
9
|
+
module Embedded
|
10
|
+
class EmbeddedSession < Neo4j::Session
|
11
|
+
class Error < StandardError
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
attr_reader :graph_db, :db_location, :properties_file
|
15
|
+
extend Forwardable
|
16
|
+
extend Neo4j::Core::TxMethods
|
17
|
+
def_delegator :@graph_db, :begin_tx
|
18
18
|
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
def initialize(db_location, config = {})
|
21
|
+
@db_location = db_location
|
22
|
+
@auto_commit = !!config[:auto_commit]
|
23
|
+
@properties_file = config[:properties_file]
|
24
|
+
Neo4j::Session.register(self)
|
25
|
+
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
def db_type
|
28
|
+
:embedded_db
|
29
|
+
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
def inspect
|
32
|
+
"#{self.class} db_location: '#{@db_location}', running: #{running?}"
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
def version
|
36
|
+
# Wow
|
37
|
+
version_string = graph_db.to_java(Java::OrgNeo4jKernel::GraphDatabaseAPI).getDependencyResolver.resolveDependency(Java::OrgNeo4jKernel::KernelData.java_class).version.to_s
|
38
|
+
version_string.split(' ')[-1]
|
39
|
+
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
41
|
+
def start
|
42
|
+
fail Error, 'Embedded Neo4j db is already running' if running?
|
43
|
+
puts "Start embedded Neo4j db at #{db_location}"
|
44
|
+
factory = Java::OrgNeo4jGraphdbFactory::GraphDatabaseFactory.new
|
45
|
+
db_service = factory.newEmbeddedDatabaseBuilder(db_location)
|
46
|
+
db_service.loadPropertiesFromFile(properties_file) if properties_file
|
47
|
+
@graph_db = db_service.newGraphDatabase
|
48
|
+
Neo4j::Session._notify_listeners(:session_available, self)
|
49
|
+
@engine = Java::OrgNeo4jCypherJavacompat::ExecutionEngine.new(@graph_db)
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
52
|
+
def factory_class
|
53
|
+
Java::OrgNeo4jTest::ImpermanentGraphDatabase
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
56
|
+
def begin_tx
|
57
|
+
if Neo4j::Transaction.current
|
58
|
+
# Handle nested transaction "placebo transaction"
|
59
|
+
Neo4j::Transaction.current.push_nested!
|
60
|
+
else
|
61
|
+
Neo4j::Embedded::EmbeddedTransaction.new(@graph_db.begin_tx)
|
62
|
+
end
|
63
|
+
Neo4j::Transaction.current
|
63
64
|
end
|
64
|
-
Neo4j::Transaction.current
|
65
|
-
end
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
def close
|
67
|
+
super
|
68
|
+
shutdown
|
69
|
+
end
|
71
70
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
def shutdown
|
72
|
+
graph_db && graph_db.shutdown
|
73
|
+
@graph_db = nil
|
74
|
+
end
|
76
75
|
|
77
|
-
|
78
|
-
|
79
|
-
|
76
|
+
def running?
|
77
|
+
!!graph_db
|
78
|
+
end
|
80
79
|
|
81
|
-
|
82
|
-
|
83
|
-
|
80
|
+
def create_label(name)
|
81
|
+
EmbeddedLabel.new(self, name)
|
82
|
+
end
|
84
83
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
84
|
+
def load_node(neo_id)
|
85
|
+
_load_node(neo_id)
|
86
|
+
end
|
87
|
+
tx_methods :load_node
|
88
|
+
|
89
|
+
# Same as load but does not return the node as a wrapped Ruby object.
|
90
|
+
#
|
91
|
+
def _load_node(neo_id)
|
92
|
+
return nil if neo_id.nil?
|
93
|
+
@graph_db.get_node_by_id(neo_id.to_i)
|
94
|
+
rescue Java::OrgNeo4jGraphdb.NotFoundException
|
95
|
+
nil
|
96
|
+
end
|
98
97
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
def load_relationship(neo_id)
|
99
|
+
_load_relationship(neo_id)
|
100
|
+
end
|
101
|
+
tx_methods :load_relationship
|
103
102
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
103
|
+
def _load_relationship(neo_id)
|
104
|
+
return nil if neo_id.nil?
|
105
|
+
@graph_db.get_relationship_by_id(neo_id.to_i)
|
106
|
+
rescue Java::OrgNeo4jGraphdb.NotFoundException
|
107
|
+
nil
|
108
|
+
end
|
110
109
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
110
|
+
def query(*args)
|
111
|
+
if [[String], [String, String]].include?(args.map(&:class))
|
112
|
+
query, params = args[0, 2]
|
113
|
+
Neo4j::Embedded::ResultWrapper.new(_query(query, params), query)
|
114
|
+
else
|
115
|
+
options = args[0] || {}
|
116
|
+
Neo4j::Core::Query.new(options.merge(session: self))
|
117
|
+
end
|
118
118
|
end
|
119
|
-
end
|
120
119
|
|
121
120
|
|
122
|
-
|
123
|
-
|
124
|
-
|
121
|
+
def find_all_nodes(label)
|
122
|
+
EmbeddedLabel.new(self, label).find_nodes
|
123
|
+
end
|
125
124
|
|
126
|
-
|
127
|
-
|
128
|
-
|
125
|
+
def find_nodes(label, key, value)
|
126
|
+
EmbeddedLabel.new(self, label).find_nodes(key, value)
|
127
|
+
end
|
129
128
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
129
|
+
# Performs a cypher query with given string.
|
130
|
+
# Remember that you should close the resource iterator.
|
131
|
+
# @param [String] q the cypher query as a String
|
132
|
+
# @return (see #query)
|
133
|
+
def _query(q, params = {})
|
134
|
+
@engine ||= Java::OrgNeo4jCypherJavacompat::ExecutionEngine.new(@graph_db)
|
135
|
+
@engine.execute(q, Neo4j::Core::HashWithIndifferentAccess.new(params))
|
136
|
+
rescue StandardError => e
|
137
|
+
raise Neo4j::Session::CypherError.new(e.message, e.class, 'cypher error')
|
138
|
+
end
|
140
139
|
|
141
|
-
|
142
|
-
|
143
|
-
|
140
|
+
def query_default_return(as)
|
141
|
+
" RETURN #{as}"
|
142
|
+
end
|
144
143
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
144
|
+
def _query_or_fail(q)
|
145
|
+
@engine ||= Java::OrgNeo4jCypherJavacompat::ExecutionEngine.new(@graph_db)
|
146
|
+
@engine.execute(q)
|
147
|
+
end
|
149
148
|
|
150
|
-
|
151
|
-
|
152
|
-
|
149
|
+
def search_result_to_enumerable(result)
|
150
|
+
result.map { |column| column['n'].wrapper }
|
151
|
+
end
|
153
152
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
153
|
+
def create_node(properties = nil, labels = [])
|
154
|
+
if labels.empty?
|
155
|
+
graph_db.create_node
|
156
|
+
else
|
157
|
+
labels = EmbeddedLabel.as_java(labels)
|
158
|
+
graph_db.create_node(labels)
|
159
|
+
end.tap do |java_node|
|
160
|
+
properties.each_pair { |k, v| java_node[k] = v } if properties
|
161
|
+
end
|
160
162
|
end
|
161
|
-
|
162
|
-
_java_node
|
163
|
+
tx_methods :create_node
|
163
164
|
end
|
164
|
-
tx_methods :create_node
|
165
|
-
|
166
165
|
end
|
167
|
-
|
168
|
-
|
169
|
-
|
170
166
|
end
|
@@ -1,35 +1,36 @@
|
|
1
|
-
module Neo4j
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module Neo4j
|
2
|
+
module Embedded
|
3
|
+
class EmbeddedTransaction
|
4
|
+
attr_reader :root_tx
|
5
|
+
include Neo4j::Transaction::Instance
|
6
|
+
|
7
|
+
def initialize(root_tx)
|
8
|
+
@root_tx = root_tx
|
9
|
+
register_instance
|
10
|
+
end
|
11
|
+
|
12
|
+
def acquire_read_lock(entity)
|
13
|
+
@root_tx.acquire_read_lock(entity)
|
14
|
+
end
|
15
|
+
|
16
|
+
def acquire_write_lock(entity)
|
17
|
+
@root_tx.acquire_write_lock(entity)
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
"EmbeddedTransaction [nested: #{@pushed_nested} failed?: #{failure?} active: #{Neo4j::Transaction.current == self}]"
|
23
|
+
end
|
24
|
+
|
25
|
+
def _delete_tx
|
26
|
+
@root_tx.failure
|
27
|
+
@root_tx.close
|
28
|
+
end
|
29
|
+
|
30
|
+
def _commit_tx
|
31
|
+
@root_tx.success
|
32
|
+
@root_tx.close
|
33
|
+
end
|
13
34
|
end
|
14
|
-
|
15
|
-
def acquire_write_lock(entity)
|
16
|
-
@root_tx.acquire_write_lock(entity)
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
|
-
def inspect
|
21
|
-
"EmbeddedTransaction [nested: #{@pushed_nested} failed?: #{failure?} active: #{Neo4j::Transaction.current == self}]"
|
22
|
-
end
|
23
|
-
|
24
|
-
def _delete_tx
|
25
|
-
@root_tx.failure
|
26
|
-
@root_tx.close
|
27
|
-
end
|
28
|
-
|
29
|
-
def _commit_tx
|
30
|
-
@root_tx.success
|
31
|
-
@root_tx.close
|
32
|
-
end
|
33
|
-
|
34
35
|
end
|
35
|
-
end
|
36
|
+
end
|
@@ -1,99 +1,106 @@
|
|
1
1
|
|
2
|
-
# TODO code duplication with the Neo4j::PropertyContainer,
|
2
|
+
# TODO: code duplication with the Neo4j::PropertyContainer,
|
3
3
|
# This module should extend that module by adding transaction around methods
|
4
|
-
module Neo4j
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module Neo4j
|
5
|
+
module Embedded
|
6
|
+
module Property
|
7
|
+
include Neo4j::PropertyValidator
|
8
|
+
include Neo4j::PropertyContainer
|
9
|
+
extend Neo4j::Core::TxMethods
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
# inherit the []= method but add auto transaction around it
|
12
|
+
tx_methods :[]=
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
val = to_ruby_property(key.to_s)
|
15
|
-
end
|
16
|
-
tx_methods :[]
|
17
|
-
|
18
|
-
# Sets the property of this node.
|
19
|
-
# Property keys are always strings. Valid property value types are the primitives(<tt>String</tt>, <tt>Fixnum</tt>, <tt>Float</tt>, <tt>FalseClass</tt>, <tt>TrueClass</tt>) or array of those primitives.
|
20
|
-
#
|
21
|
-
# ==== Gotchas
|
22
|
-
# * Values in the array must be of the same type.
|
23
|
-
# * You can *not* delete or add one item in the array (e.g. person.phones.delete('123')) but instead you must create a new array instead.
|
24
|
-
#
|
25
|
-
# @param [String, Symbol] k of the property to set
|
26
|
-
# @param [String,Fixnum,Float,true,false, Array] v to set
|
27
|
-
def []=(k, v)
|
28
|
-
to_java_property(k, v)
|
29
|
-
end
|
30
|
-
tx_methods :[]=
|
14
|
+
def [](key)
|
15
|
+
return nil unless has_property?(key.to_s)
|
31
16
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
ret[key.to_sym] = val
|
36
|
-
ret
|
37
|
-
end
|
38
|
-
end
|
39
|
-
tx_methods :props
|
17
|
+
to_ruby_property(key.to_s)
|
18
|
+
end
|
19
|
+
tx_methods :[]
|
40
20
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
21
|
+
# Sets the property of this node.
|
22
|
+
# Property keys are always strings. Valid property value types are the primitives:
|
23
|
+
# (<tt>String</tt>, <tt>Fixnum</tt>, <tt>Float</tt>, <tt>FalseClass</tt>, <tt>TrueClass</tt>)
|
24
|
+
# or an array of those primitives.
|
25
|
+
#
|
26
|
+
# ==== Gotchas
|
27
|
+
# * Values in the array must be of the same type.
|
28
|
+
# * You can *not* delete or add one item in the array (e.g. person.phones.delete('123')) but instead you must create a new array instead.
|
29
|
+
#
|
30
|
+
# @param [String, Symbol] k of the property to set
|
31
|
+
# @param [String,Fixnum,Float,true,false, Array] v to set
|
32
|
+
def []=(k, v)
|
33
|
+
to_java_property(k, v)
|
34
|
+
end
|
35
|
+
tx_methods :[]=
|
49
36
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
37
|
+
def props
|
38
|
+
property_keys.each_with_object({}) do |key, ret|
|
39
|
+
ret[key.to_sym] = to_ruby_property(key)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
tx_methods :props
|
54
43
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
44
|
+
def props=(hash)
|
45
|
+
property_keys.each do |key|
|
46
|
+
remove_property(key)
|
47
|
+
end
|
48
|
+
_update_props(hash)
|
49
|
+
hash
|
50
|
+
end
|
51
|
+
tx_methods :props=
|
59
52
|
|
60
|
-
|
61
|
-
|
62
|
-
|
53
|
+
def _update_props(hash)
|
54
|
+
hash.each { |k, v| to_java_property(k, v) }
|
55
|
+
end
|
63
56
|
|
64
|
-
|
65
|
-
|
66
|
-
|
57
|
+
def update_props(hash)
|
58
|
+
_update_props(hash)
|
59
|
+
end
|
60
|
+
tx_methods :update_props
|
67
61
|
|
68
|
-
|
62
|
+
def neo_id
|
63
|
+
get_id
|
64
|
+
end
|
69
65
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
66
|
+
def refresh
|
67
|
+
# nothing is needed in the embedded db since we always asks the database
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
74
71
|
|
75
|
-
|
76
|
-
|
72
|
+
def to_ruby_property(key)
|
73
|
+
val = get_property(key)
|
74
|
+
val.class.superclass == ArrayJavaProxy ? val.to_a : val
|
75
|
+
end
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
def to_java_property(k, v)
|
78
|
+
validate_property(v)
|
79
|
+
|
80
|
+
k = k.to_s
|
81
|
+
case v
|
82
|
+
when nil
|
83
|
+
remove_property(k)
|
84
|
+
when Array
|
85
|
+
type = java_type_from_value(v[0]) || fail("Not allowed to store array with value #{v[0]} type #{v[0].class}")
|
86
|
+
set_property(k, v.to_java(type))
|
87
|
+
else
|
88
|
+
set_property(k, v)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def java_type_from_value(value)
|
93
|
+
case value
|
83
94
|
when String
|
84
|
-
|
95
|
+
:string
|
85
96
|
when Float
|
86
|
-
|
97
|
+
:double
|
87
98
|
when FalseClass, TrueClass
|
88
|
-
|
99
|
+
:boolean
|
89
100
|
when Fixnum
|
90
|
-
|
91
|
-
|
92
|
-
raise "Not allowed to store array with value #{v[0]} type #{v[0].class}"
|
101
|
+
:long
|
102
|
+
end
|
93
103
|
end
|
94
|
-
else
|
95
|
-
set_property(k, v)
|
96
104
|
end
|
97
105
|
end
|
98
|
-
|
99
106
|
end
|