neo4j-core 8.1.4 → 9.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +71 -8
- data/lib/neo4j-core.rb +3 -49
- data/lib/neo4j/core.rb +4 -0
- data/lib/neo4j/core/config.rb +13 -0
- data/lib/neo4j/core/cypher_session/adaptors.rb +15 -15
- data/lib/neo4j/core/cypher_session/adaptors/bolt.rb +39 -48
- data/lib/neo4j/core/cypher_session/adaptors/bolt/chunk_writer_io.rb +0 -4
- data/lib/neo4j/core/cypher_session/adaptors/bolt/pack_stream.rb +7 -3
- data/lib/neo4j/core/cypher_session/adaptors/embedded.rb +1 -2
- data/lib/neo4j/core/cypher_session/adaptors/has_uri.rb +4 -0
- data/lib/neo4j/core/cypher_session/adaptors/http.rb +1 -3
- data/lib/neo4j/core/cypher_session/responses.rb +1 -1
- data/lib/neo4j/core/cypher_session/responses/bolt.rb +0 -17
- data/lib/neo4j/core/cypher_session/responses/embedded.rb +9 -7
- data/lib/neo4j/core/cypher_session/responses/http.rb +3 -4
- data/lib/neo4j/core/cypher_session/transactions.rb +2 -0
- data/lib/{neo4j-core → neo4j/core}/helpers.rb +1 -14
- data/lib/neo4j/core/logging.rb +44 -0
- data/lib/{neo4j-core → neo4j/core}/query.rb +7 -6
- data/lib/{neo4j-core → neo4j/core}/query_clauses.rb +9 -16
- data/lib/{neo4j-core → neo4j/core}/query_find_in_batches.rb +3 -5
- data/lib/{neo4j-core → neo4j/core}/version.rb +1 -1
- data/lib/neo4j/transaction.rb +6 -8
- data/neo4j-core.gemspec +13 -11
- metadata +46 -50
- data/lib/ext/kernel.rb +0 -9
- data/lib/neo4j-core/active_entity.rb +0 -11
- data/lib/neo4j-core/label.rb +0 -9
- data/lib/neo4j-embedded.rb +0 -16
- data/lib/neo4j-embedded/cypher_response.rb +0 -71
- data/lib/neo4j-embedded/embedded_database.rb +0 -26
- data/lib/neo4j-embedded/embedded_ha_session.rb +0 -30
- data/lib/neo4j-embedded/embedded_impermanent_session.rb +0 -17
- data/lib/neo4j-embedded/embedded_label.rb +0 -88
- data/lib/neo4j-embedded/embedded_node.rb +0 -206
- data/lib/neo4j-embedded/embedded_relationship.rb +0 -77
- data/lib/neo4j-embedded/embedded_session.rb +0 -203
- data/lib/neo4j-embedded/embedded_transaction.rb +0 -30
- data/lib/neo4j-embedded/label.rb +0 -66
- data/lib/neo4j-embedded/property.rb +0 -106
- data/lib/neo4j-embedded/to_java.rb +0 -44
- data/lib/neo4j-server.rb +0 -12
- data/lib/neo4j-server/cypher_label.rb +0 -35
- data/lib/neo4j-server/cypher_node.rb +0 -221
- data/lib/neo4j-server/cypher_relationship.rb +0 -142
- data/lib/neo4j-server/cypher_response.rb +0 -248
- data/lib/neo4j-server/cypher_session.rb +0 -263
- data/lib/neo4j-server/cypher_transaction.rb +0 -100
- data/lib/neo4j-server/label.rb +0 -40
- data/lib/neo4j-server/resource.rb +0 -57
- data/lib/neo4j/entity_equality.rb +0 -8
- data/lib/neo4j/entity_marshal.rb +0 -20
- data/lib/neo4j/label.rb +0 -90
- data/lib/neo4j/node.rb +0 -216
- data/lib/neo4j/property_container.rb +0 -17
- data/lib/neo4j/property_validator.rb +0 -22
- data/lib/neo4j/relationship.rb +0 -161
- data/lib/neo4j/session.rb +0 -222
@@ -1,17 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module PropertyContainer
|
3
|
-
include Neo4j::PropertyValidator
|
4
|
-
|
5
|
-
# Returns the Neo4j Property of given key
|
6
|
-
def [](key)
|
7
|
-
get_property(key)
|
8
|
-
end
|
9
|
-
|
10
|
-
# Sets the neo4j property
|
11
|
-
def []=(key, value)
|
12
|
-
validate_property!(value)
|
13
|
-
|
14
|
-
set_property(key, value)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module PropertyValidator
|
3
|
-
require 'set'
|
4
|
-
class InvalidPropertyException < Exception
|
5
|
-
end
|
6
|
-
|
7
|
-
# the valid values on a property, and arrays of those.
|
8
|
-
VALID_PROPERTY_VALUE_CLASSES = Set.new([Array, NilClass, String, Float, TrueClass, FalseClass, Integer])
|
9
|
-
|
10
|
-
# @param [Object] value the value we want to check if it's a valid neo4j property value
|
11
|
-
# @return [True, False] A false means it can't be persisted.
|
12
|
-
def valid_property?(value)
|
13
|
-
VALID_PROPERTY_VALUE_CLASSES.any? { |c| value.is_a?(c) }
|
14
|
-
end
|
15
|
-
|
16
|
-
def validate_property!(value)
|
17
|
-
return if valid_property?(value)
|
18
|
-
|
19
|
-
fail Neo4j::PropertyValidator::InvalidPropertyException, "Not valid Neo4j Property value #{value.class}, valid: #{Neo4j::Node::VALID_PROPERTY_VALUE_CLASSES.to_a.join(', ')}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/lib/neo4j/relationship.rb
DELETED
@@ -1,161 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
# A relationship between two nodes in the graph. A relationship has a start node, an end node and a type.
|
3
|
-
# You can attach properties to relationships like Neo4j::Node.
|
4
|
-
#
|
5
|
-
# The fact that the relationship API gives meaning to start and end nodes implicitly means that all relationships have a direction.
|
6
|
-
# In the example above, rel would be directed from node to otherNode.
|
7
|
-
# A relationship's start node and end node and their relation to outgoing and incoming are defined so that the assertions in the following code are true:
|
8
|
-
#
|
9
|
-
# Furthermore, Neo4j guarantees that a relationship is never "hanging freely,"
|
10
|
-
# i.e. start_node, end_node and other_node are guaranteed to always return valid, non-nil nodes.
|
11
|
-
class Relationship
|
12
|
-
# A module that allows plugins to register wrappers around Neo4j::Node objects
|
13
|
-
module Wrapper
|
14
|
-
# Used by Neo4j::NodeMixin to wrap nodes
|
15
|
-
def wrapper
|
16
|
-
self
|
17
|
-
end
|
18
|
-
|
19
|
-
def neo4j_obj
|
20
|
-
self
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
include PropertyContainer
|
25
|
-
include EntityEquality
|
26
|
-
include Wrapper
|
27
|
-
include EntityMarshal
|
28
|
-
|
29
|
-
# @return [Hash<Symbol,Object>] all properties of the relationship
|
30
|
-
def props
|
31
|
-
fail 'not implemented'
|
32
|
-
end
|
33
|
-
|
34
|
-
# replace all properties with new properties
|
35
|
-
# @param [Hash] properties a hash of properties the relationship should have
|
36
|
-
def props=(properties)
|
37
|
-
fail 'not implemented'
|
38
|
-
end
|
39
|
-
|
40
|
-
# Updates the properties, keeps old properties
|
41
|
-
# @param [Hash<Symbol,Object>] properties hash of properties that should be updated on the relationship
|
42
|
-
def update_props(properties)
|
43
|
-
fail 'not implemented'
|
44
|
-
end
|
45
|
-
|
46
|
-
# Directly remove the property on the relationship (low level method, may need transaction)
|
47
|
-
def remove_property(key)
|
48
|
-
fail 'not implemented'
|
49
|
-
end
|
50
|
-
|
51
|
-
# Directly set the property on the relationship (low level method, may need transaction)
|
52
|
-
# @param [Hash, String] key
|
53
|
-
# @param value see Neo4j::PropertyValidator::VALID_PROPERTY_VALUE_CLASSES for valid values
|
54
|
-
def set_property(key, value)
|
55
|
-
fail 'not implemented'
|
56
|
-
end
|
57
|
-
|
58
|
-
# Directly get the property on the relationship (low level method, may need transaction)
|
59
|
-
# @param [Hash, String] key
|
60
|
-
# @return the value of the key
|
61
|
-
def get_property(key, value)
|
62
|
-
fail 'not implemented'
|
63
|
-
end
|
64
|
-
|
65
|
-
# Returns the start node of this relationship.
|
66
|
-
# @return [Neo4j::Node,Object] the node or wrapped node
|
67
|
-
def start_node
|
68
|
-
_start_node.wrapper
|
69
|
-
end
|
70
|
-
|
71
|
-
# Same as #start_node but does not wrap the node
|
72
|
-
# @return [Neo4j::Node]
|
73
|
-
def _start_node
|
74
|
-
fail 'not implemented'
|
75
|
-
end
|
76
|
-
|
77
|
-
# Returns the end node of this relationship.
|
78
|
-
# @return [Neo4j::Node,Object] the node or wrapped node
|
79
|
-
def end_node
|
80
|
-
_end_node.wrapper
|
81
|
-
end
|
82
|
-
|
83
|
-
# Same as #end_node but does not wrap the node
|
84
|
-
# @return [Neo4j::Node]
|
85
|
-
def _end_node
|
86
|
-
fail 'not implemented'
|
87
|
-
end
|
88
|
-
|
89
|
-
# @abstract
|
90
|
-
def del
|
91
|
-
fail 'not implemented'
|
92
|
-
end
|
93
|
-
|
94
|
-
# The unique neo4j id
|
95
|
-
# @abstract
|
96
|
-
def neo_id
|
97
|
-
fail 'not implemented'
|
98
|
-
end
|
99
|
-
|
100
|
-
# @return [true, false] if the relationship exists
|
101
|
-
# @abstract
|
102
|
-
def exist?
|
103
|
-
fail 'not implemented'
|
104
|
-
end
|
105
|
-
|
106
|
-
# Returns the relationship name
|
107
|
-
#
|
108
|
-
# @example
|
109
|
-
# a = Neo4j::Node.new
|
110
|
-
# a.create_rel(:friends, node_b)
|
111
|
-
# a.rels.first.rel_type # => :friends
|
112
|
-
# @return [Symbol] the type of the relationship
|
113
|
-
def rel_type
|
114
|
-
fail 'not implemented'
|
115
|
-
end
|
116
|
-
|
117
|
-
# A convenience operation that, given a node that is attached to this relationship, returns the other node.
|
118
|
-
# For example if node is a start node, the end node will be returned, and vice versa.
|
119
|
-
# This is a very convenient operation when you're manually traversing the node space by invoking one of the #rels
|
120
|
-
# method on a node. For example, to get the node "at the other end" of a relationship, use the following:
|
121
|
-
#
|
122
|
-
# @example
|
123
|
-
# end_node = node.rels.first.other_node(node)
|
124
|
-
#
|
125
|
-
# @raise This operation will throw a runtime exception if node is neither this relationship's start node nor its end node.
|
126
|
-
#
|
127
|
-
# @param [Neo4j::Node] node the node that we don't want to return
|
128
|
-
# @return [Neo4j::Node] the other node wrapper
|
129
|
-
# @see #_other_node
|
130
|
-
def other_node(node)
|
131
|
-
_other_node(node.neo4j_obj).wrapper
|
132
|
-
end
|
133
|
-
|
134
|
-
# Same as #other_node but can return a none wrapped node
|
135
|
-
def _other_node(node)
|
136
|
-
if node == _start_node
|
137
|
-
_end_node
|
138
|
-
elsif node == _end_node
|
139
|
-
_start_node
|
140
|
-
else
|
141
|
-
fail "Node #{node.inspect} is neither start nor end node"
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
|
146
|
-
class << self
|
147
|
-
def create(rel_type, from_node, other_node, props = {})
|
148
|
-
from_node.neo4j_obj.create_rel(rel_type, other_node, props)
|
149
|
-
end
|
150
|
-
|
151
|
-
def load(neo_id, session = Neo4j::Session.current)
|
152
|
-
rel = _load(neo_id, session)
|
153
|
-
rel && rel.wrapper
|
154
|
-
end
|
155
|
-
|
156
|
-
def _load(neo_id, session = Neo4j::Session.current)
|
157
|
-
session.load_relationship(neo_id)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
data/lib/neo4j/session.rb
DELETED
@@ -1,222 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
class Session
|
3
|
-
@@current_session = nil
|
4
|
-
@@all_sessions = {}
|
5
|
-
@@factories = {}
|
6
|
-
|
7
|
-
# @abstract
|
8
|
-
def close
|
9
|
-
self.class.unregister(self)
|
10
|
-
end
|
11
|
-
|
12
|
-
# Only for embedded database
|
13
|
-
# @abstract
|
14
|
-
def start
|
15
|
-
fail 'not impl.'
|
16
|
-
end
|
17
|
-
|
18
|
-
# Only for embedded database
|
19
|
-
# @abstract
|
20
|
-
def shutdown
|
21
|
-
fail 'not impl.'
|
22
|
-
end
|
23
|
-
|
24
|
-
# Only for embedded database
|
25
|
-
# @abstract
|
26
|
-
def running
|
27
|
-
fail 'not impl.'
|
28
|
-
end
|
29
|
-
|
30
|
-
# @return [:embedded_db | :server_db]
|
31
|
-
def db_type
|
32
|
-
fail 'not impl.'
|
33
|
-
end
|
34
|
-
|
35
|
-
def auto_commit?
|
36
|
-
true # TODO
|
37
|
-
end
|
38
|
-
|
39
|
-
class CypherError < StandardError
|
40
|
-
attr_reader :error_msg, :error_status, :error_code
|
41
|
-
def initialize(error_msg, error_code, error_status)
|
42
|
-
super(error_msg)
|
43
|
-
@error_msg = error_msg
|
44
|
-
@error_status = error_status
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class InitializationError < RuntimeError; end
|
49
|
-
|
50
|
-
# Performs a cypher query. See {Neo4j::Core::Query} for more details, but basic usage looks like:
|
51
|
-
#
|
52
|
-
# @example Using cypher DSL
|
53
|
-
# Neo4j::Session.query.match("(c:person)-[:friends]->(p:person)").where(c: {name: 'andreas'}).pluck(:p).first[:name]
|
54
|
-
#
|
55
|
-
# @example Show the generated Cypher
|
56
|
-
# Neo4j::Session.query..match("(c:person)-[:friends]->(p:person)").where(c: {name: 'andreas'}).return(:p).to_cypher
|
57
|
-
#
|
58
|
-
# @example Use Cypher string instead of the cypher DSL
|
59
|
-
# Neo4j::Session.query("MATCH (c:person)-[:friends]->(p:person) WHERE c.name = \"andreas\" RETURN p").first[:p][:name]
|
60
|
-
#
|
61
|
-
# @return [Neo4j::Core::Query, Enumerable] return a Query object for DSL or a Enumerable if using raw cypher strings
|
62
|
-
# @see http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html The Cypher Query Language Documentation
|
63
|
-
#
|
64
|
-
def query(options = {})
|
65
|
-
fail 'not implemented, abstract'
|
66
|
-
end
|
67
|
-
|
68
|
-
# Same as #query but does not accept an DSL and returns the raw result from the database.
|
69
|
-
# Notice, it might return different values depending on which database is used, embedded or server.
|
70
|
-
# @abstract
|
71
|
-
def _query(*params)
|
72
|
-
fail 'not implemented'
|
73
|
-
end
|
74
|
-
|
75
|
-
def transaction_class
|
76
|
-
self.class.transaction_class
|
77
|
-
end
|
78
|
-
|
79
|
-
class << self
|
80
|
-
# Creates a new session to Neo4j.
|
81
|
-
# This will be the default session to be used unless there is already a session created (see #current and #set_current)
|
82
|
-
#
|
83
|
-
# @example A Neo4j Server session
|
84
|
-
# Neo4j::Session.open(:server_db, 'http://localhost:7474', {basic_auth: {username: 'foo', password: 'bar'}})
|
85
|
-
#
|
86
|
-
# @example Using a user defined Faraday HTTP connection
|
87
|
-
# connection = Faraday.new do |b|
|
88
|
-
# # faraday config
|
89
|
-
# end
|
90
|
-
# Neo4j::Session.open(:server_db, 'http://localhost:7474', connection: connection)
|
91
|
-
#
|
92
|
-
# @example A embedded Neo4j session
|
93
|
-
# Neo4j::Session.open(:embedded_db, 'path/to/db')
|
94
|
-
#
|
95
|
-
# @see also Neo4j::Server::CypherSession#open for :server_db params
|
96
|
-
# @param db_type the type of database, e.g. :embedded_db, or :server_db
|
97
|
-
# @param [String] endpoint_url The path to the server, either a URL or path to embedded DB
|
98
|
-
# @param [Hash] params Additional configuration options
|
99
|
-
def open(db_type = :server_db, endpoint_url = nil, params = {})
|
100
|
-
case db_type
|
101
|
-
when :server_db then require 'neo4j-server'
|
102
|
-
when :embedded_db then require 'neo4j-embedded'
|
103
|
-
end
|
104
|
-
|
105
|
-
validate_session_num!(db_type)
|
106
|
-
name = params[:name]
|
107
|
-
default = params[:default]
|
108
|
-
%i[name default].each { |k| params.delete(k) }
|
109
|
-
register(create_session(db_type, endpoint_url, params), name, default)
|
110
|
-
end
|
111
|
-
|
112
|
-
# @private
|
113
|
-
def validate_session_num!(db_type)
|
114
|
-
return unless current && db_type == :embedded_db
|
115
|
-
fail InitializationError, 'Multiple sessions are not supported by Neo4j Embedded.'
|
116
|
-
end
|
117
|
-
private :validate_session_num!
|
118
|
-
|
119
|
-
# @private
|
120
|
-
def create_session(db_type, endpoint_url, params = {})
|
121
|
-
unless @@factories[db_type]
|
122
|
-
fail InitializationError, "Can't connect to database '#{db_type}', available #{@@factories.keys.join(',')}"
|
123
|
-
end
|
124
|
-
@@factories[db_type].call(endpoint_url, params)
|
125
|
-
end
|
126
|
-
|
127
|
-
# @return [Neo4j::Session] the current session
|
128
|
-
def current
|
129
|
-
@@current_session
|
130
|
-
end
|
131
|
-
|
132
|
-
# Returns the current session or raise an exception if no session is available
|
133
|
-
def current!
|
134
|
-
fail 'No session, please create a session first with Neo4j::Session.open(:server_db) or :embedded_db' unless current
|
135
|
-
current
|
136
|
-
end
|
137
|
-
|
138
|
-
# @see Neo4j::Session#query
|
139
|
-
def query(*args)
|
140
|
-
current!.query(*args)
|
141
|
-
end
|
142
|
-
|
143
|
-
# Returns a session with given name or else raise an exception
|
144
|
-
def named(name)
|
145
|
-
@@all_sessions[name] || fail("No session named #{name}.")
|
146
|
-
end
|
147
|
-
|
148
|
-
# Sets the session to be used as default
|
149
|
-
# @param [Neo4j::Session] session the session to use
|
150
|
-
def set_current(session)
|
151
|
-
@@current_session = session
|
152
|
-
end
|
153
|
-
|
154
|
-
# Registers a callback which will be called immediately if session is already available,
|
155
|
-
# or called when it later becomes available.
|
156
|
-
def on_next_session_available
|
157
|
-
return yield(Neo4j::Session.current) if Neo4j::Session.current
|
158
|
-
|
159
|
-
add_listener do |event, data|
|
160
|
-
yield data if event == :session_available
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def user_agent_string
|
165
|
-
gem, version = if defined?(::Neo4j::ActiveNode)
|
166
|
-
['neo4j', ::Neo4j::VERSION]
|
167
|
-
else
|
168
|
-
['neo4j-core', ::Neo4j::Core::VERSION]
|
169
|
-
end
|
170
|
-
|
171
|
-
|
172
|
-
"#{gem}-gem/#{version} (https://github.com/neo4jrb/#{gem})"
|
173
|
-
end
|
174
|
-
|
175
|
-
def clear_listeners
|
176
|
-
@@listeners = []
|
177
|
-
end
|
178
|
-
|
179
|
-
# @private
|
180
|
-
def add_listener(&listener)
|
181
|
-
_listeners << listener
|
182
|
-
end
|
183
|
-
|
184
|
-
# @private
|
185
|
-
def _listeners
|
186
|
-
@@listeners ||= []
|
187
|
-
@@listeners
|
188
|
-
end
|
189
|
-
|
190
|
-
# @private
|
191
|
-
def _notify_listeners(event, data)
|
192
|
-
_listeners.shift.call(event, data) until _listeners.empty?
|
193
|
-
end
|
194
|
-
|
195
|
-
# @private
|
196
|
-
def register(session, name = nil, default = nil)
|
197
|
-
if default == true
|
198
|
-
set_current(session)
|
199
|
-
elsif default.nil?
|
200
|
-
set_current(session) unless @@current_session
|
201
|
-
end
|
202
|
-
@@all_sessions[name] = session if name
|
203
|
-
session
|
204
|
-
end
|
205
|
-
|
206
|
-
# @private
|
207
|
-
def unregister(session)
|
208
|
-
@@current_session = nil if @@current_session == session
|
209
|
-
end
|
210
|
-
|
211
|
-
def inspect
|
212
|
-
"Neo4j::Session available: #{@@factories && @@factories.keys}"
|
213
|
-
end
|
214
|
-
|
215
|
-
# @private
|
216
|
-
def register_db(db, &session_factory)
|
217
|
-
puts "replace factory for #{db}" if @@factories[db]
|
218
|
-
@@factories[db] = session_factory
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|