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.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +71 -8
  3. data/lib/neo4j-core.rb +3 -49
  4. data/lib/neo4j/core.rb +4 -0
  5. data/lib/neo4j/core/config.rb +13 -0
  6. data/lib/neo4j/core/cypher_session/adaptors.rb +15 -15
  7. data/lib/neo4j/core/cypher_session/adaptors/bolt.rb +39 -48
  8. data/lib/neo4j/core/cypher_session/adaptors/bolt/chunk_writer_io.rb +0 -4
  9. data/lib/neo4j/core/cypher_session/adaptors/bolt/pack_stream.rb +7 -3
  10. data/lib/neo4j/core/cypher_session/adaptors/embedded.rb +1 -2
  11. data/lib/neo4j/core/cypher_session/adaptors/has_uri.rb +4 -0
  12. data/lib/neo4j/core/cypher_session/adaptors/http.rb +1 -3
  13. data/lib/neo4j/core/cypher_session/responses.rb +1 -1
  14. data/lib/neo4j/core/cypher_session/responses/bolt.rb +0 -17
  15. data/lib/neo4j/core/cypher_session/responses/embedded.rb +9 -7
  16. data/lib/neo4j/core/cypher_session/responses/http.rb +3 -4
  17. data/lib/neo4j/core/cypher_session/transactions.rb +2 -0
  18. data/lib/{neo4j-core → neo4j/core}/helpers.rb +1 -14
  19. data/lib/neo4j/core/logging.rb +44 -0
  20. data/lib/{neo4j-core → neo4j/core}/query.rb +7 -6
  21. data/lib/{neo4j-core → neo4j/core}/query_clauses.rb +9 -16
  22. data/lib/{neo4j-core → neo4j/core}/query_find_in_batches.rb +3 -5
  23. data/lib/{neo4j-core → neo4j/core}/version.rb +1 -1
  24. data/lib/neo4j/transaction.rb +6 -8
  25. data/neo4j-core.gemspec +13 -11
  26. metadata +46 -50
  27. data/lib/ext/kernel.rb +0 -9
  28. data/lib/neo4j-core/active_entity.rb +0 -11
  29. data/lib/neo4j-core/label.rb +0 -9
  30. data/lib/neo4j-embedded.rb +0 -16
  31. data/lib/neo4j-embedded/cypher_response.rb +0 -71
  32. data/lib/neo4j-embedded/embedded_database.rb +0 -26
  33. data/lib/neo4j-embedded/embedded_ha_session.rb +0 -30
  34. data/lib/neo4j-embedded/embedded_impermanent_session.rb +0 -17
  35. data/lib/neo4j-embedded/embedded_label.rb +0 -88
  36. data/lib/neo4j-embedded/embedded_node.rb +0 -206
  37. data/lib/neo4j-embedded/embedded_relationship.rb +0 -77
  38. data/lib/neo4j-embedded/embedded_session.rb +0 -203
  39. data/lib/neo4j-embedded/embedded_transaction.rb +0 -30
  40. data/lib/neo4j-embedded/label.rb +0 -66
  41. data/lib/neo4j-embedded/property.rb +0 -106
  42. data/lib/neo4j-embedded/to_java.rb +0 -44
  43. data/lib/neo4j-server.rb +0 -12
  44. data/lib/neo4j-server/cypher_label.rb +0 -35
  45. data/lib/neo4j-server/cypher_node.rb +0 -221
  46. data/lib/neo4j-server/cypher_relationship.rb +0 -142
  47. data/lib/neo4j-server/cypher_response.rb +0 -248
  48. data/lib/neo4j-server/cypher_session.rb +0 -263
  49. data/lib/neo4j-server/cypher_transaction.rb +0 -100
  50. data/lib/neo4j-server/label.rb +0 -40
  51. data/lib/neo4j-server/resource.rb +0 -57
  52. data/lib/neo4j/entity_equality.rb +0 -8
  53. data/lib/neo4j/entity_marshal.rb +0 -20
  54. data/lib/neo4j/label.rb +0 -90
  55. data/lib/neo4j/node.rb +0 -216
  56. data/lib/neo4j/property_container.rb +0 -17
  57. data/lib/neo4j/property_validator.rb +0 -22
  58. data/lib/neo4j/relationship.rb +0 -161
  59. data/lib/neo4j/session.rb +0 -222
@@ -1,30 +0,0 @@
1
- module Neo4j
2
- module Embedded
3
- class EmbeddedTransaction < Neo4j::Transaction::Base
4
- attr_reader :root_tx
5
-
6
- def initialize(session)
7
- super
8
- @root_tx = @session.begin_tx
9
- end
10
-
11
- def acquire_read_lock(entity)
12
- @root_tx.acquire_read_lock(entity)
13
- end
14
-
15
- def acquire_write_lock(entity)
16
- @root_tx.acquire_write_lock(entity)
17
- end
18
-
19
- def delete
20
- @root_tx.failure
21
- @root_tx.close
22
- end
23
-
24
- def commit
25
- @root_tx.success
26
- @root_tx.close
27
- end
28
- end
29
- end
30
- end
@@ -1,66 +0,0 @@
1
- module Neo4j
2
- class Label
3
- class << self
4
- def indexes
5
- schema_query(:get_indexes)
6
- end
7
-
8
- def constraints
9
- schema_query(:get_constraints)
10
- end
11
-
12
- def index?(label, property)
13
- schema_index_operation(label, property, :indexes)
14
- end
15
-
16
- def constraint?(label, property)
17
- schema_index_operation(label, property, :constraints)
18
- end
19
-
20
- def drop_all_indexes
21
- Neo4j::Transaction.run do
22
- schema.get_indexes.to_a.each do |i|
23
- begin
24
- i.drop
25
- rescue Java::JavaLang::IllegalStateException
26
- end
27
- end
28
- end
29
- end
30
-
31
- def drop_all_constraints
32
- Neo4j::Transaction.run do
33
- schema.get_constraints.to_a.each(&:drop)
34
- end
35
- end
36
-
37
- private
38
-
39
- def schema_query(query_method)
40
- [].tap do |index_array|
41
- Neo4j::Transaction.run do
42
- schema.send(query_method).to_a.each { |i| index_array << index_hash(i) }
43
- end
44
- end
45
- end
46
-
47
- def schema_index_operation(label, property, schema_method)
48
- label = label.to_s
49
- property = property.to_s
50
- !send(schema_method).select { |i| matched_index(i, label, property) }.empty?
51
- end
52
-
53
- def index_hash(java_index)
54
- {property_keys: java_index.get_property_keys.to_a, label: java_index.get_label.name}
55
- end
56
-
57
- def matched_index(java_index, label, property)
58
- java_index[:property_keys].first == property && java_index[:label] == label
59
- end
60
-
61
- def schema
62
- Neo4j::Session.current.graph_db.schema
63
- end
64
- end
65
- end
66
- end
@@ -1,106 +0,0 @@
1
-
2
- # TODO: code duplication with the Neo4j::PropertyContainer,
3
- # This module should extend that module by adding transaction around methods
4
- module Neo4j
5
- module Embedded
6
- module Property
7
- include Neo4j::PropertyValidator
8
- include Neo4j::PropertyContainer
9
- extend Neo4j::Core::TxMethods
10
-
11
- # inherit the []= method but add auto transaction around it
12
- tx_methods :[]=
13
-
14
- def [](key)
15
- return nil unless has_property?(key.to_s)
16
-
17
- to_ruby_property(key.to_s)
18
- end
19
- tx_methods :[]
20
-
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>Integer</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,Integer,Float,true,false, Array] v to set
32
- def []=(k, v)
33
- to_java_property(k, v)
34
- end
35
- tx_methods :[]=
36
-
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
43
-
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=
52
-
53
- def _update_props(hash)
54
- hash.each { |k, v| to_java_property(k, v) }
55
- end
56
-
57
- def update_props(hash)
58
- _update_props(hash)
59
- end
60
- tx_methods :update_props
61
-
62
- def neo_id
63
- get_id
64
- end
65
-
66
- def refresh
67
- # nothing is needed in the embedded db since we always asks the database
68
- end
69
-
70
- private
71
-
72
- def to_ruby_property(key)
73
- val = get_property(key)
74
- val.class.superclass == ArrayJavaProxy ? val.to_a : val
75
- end
76
-
77
- def to_java_property(k, v)
78
- validate_property!(v)
79
-
80
- k = k.to_s
81
- case v
82
- when nil then remove_property(k)
83
- when Array
84
- set_property(k, v.to_java(java_type_from_value(v[0])))
85
- else
86
- set_property(k, v)
87
- end
88
- end
89
-
90
- def java_type_from_value(value)
91
- case value
92
- when String
93
- :string
94
- when Float
95
- :double
96
- when FalseClass, TrueClass
97
- :boolean
98
- when Integer
99
- :long
100
- else
101
- fail "Not allowed to store array with value #{value.inspect} type #{value.class}"
102
- end
103
- end
104
- end
105
- end
106
- end
@@ -1,44 +0,0 @@
1
- module Neo4j
2
- module Embedded
3
- # A Utility class for translating Ruby object to Neo4j Java types
4
- # @private
5
- module ToJava
6
- def type_to_java(type)
7
- type && Java::OrgNeo4jGraphdb::DynamicRelationshipType.withName(type.to_s)
8
- end
9
-
10
- module_function :type_to_java
11
-
12
- def types_to_java(types)
13
- types.inject([]) { |result, type| result << type_to_java(type) }.to_java(Java::OrgNeo4jGraphdb::RelationshipType)
14
- end
15
-
16
- module_function :types_to_java
17
-
18
-
19
- def dir_from_java(dir)
20
- case dir
21
- when Java::OrgNeo4jGraphdb::Direction::OUTGOING then :outgoing
22
- when Java::OrgNeo4jGraphdb::Direction::BOTH then :both
23
- when Java::OrgNeo4jGraphdb::Direction::INCOMING then :incoming
24
- else
25
- fail "unknown direction '#{dir} / #{dir.class}'"
26
- end
27
- end
28
-
29
- module_function :dir_from_java
30
-
31
- def dir_to_java(dir)
32
- case dir
33
- when :outgoing then Java::OrgNeo4jGraphdb::Direction::OUTGOING
34
- when :both then Java::OrgNeo4jGraphdb::Direction::BOTH
35
- when :incoming then Java::OrgNeo4jGraphdb::Direction::INCOMING
36
- else
37
- fail "unknown direction '#{dir}', expects argument: outgoing, :incoming or :both"
38
- end
39
- end
40
-
41
- module_function :dir_to_java
42
- end
43
- end
44
- end
@@ -1,12 +0,0 @@
1
- require 'json'
2
- require 'faraday'
3
- require 'faraday_middleware'
4
- require 'faraday_middleware/multi_json'
5
- require 'neo4j-server/resource'
6
- require 'neo4j-server/cypher_node'
7
- require 'neo4j-server/cypher_label'
8
- require 'neo4j-server/label'
9
- require 'neo4j-server/cypher_session'
10
- require 'neo4j-server/cypher_relationship'
11
- require 'neo4j-server/cypher_response'
12
- require 'neo4j-server/cypher_transaction'
@@ -1,35 +0,0 @@
1
- module Neo4j
2
- module Server
3
- class CypherLabel < Neo4j::Label
4
- extend Forwardable
5
- def_delegator :@session, :query_cypher_for
6
- attr_reader :name
7
-
8
- def initialize(session, name)
9
- @name = name
10
- @session = session
11
- end
12
-
13
- def create_index(property, options = {}, session = Neo4j::Session.current)
14
- validate_index_options!(options)
15
- properties = property.is_a?(Array) ? property.join(',') : property
16
- response = session._query("CREATE INDEX ON :`#{@name}`(#{properties})")
17
- response.raise_error if response.error?
18
- end
19
-
20
- def drop_index(property, options = {}, session = Neo4j::Session.current)
21
- validate_index_options!(options)
22
- response = session._query("DROP INDEX ON :`#{@name}`(#{property})")
23
- response.raise_error if response.error? && !response.error_msg.match(/No such INDEX ON/)
24
- end
25
-
26
- def indexes
27
- @session.indexes(@name)
28
- end
29
-
30
- def uniqueness_constraints
31
- @session.uniqueness_constraints(@name)
32
- end
33
- end
34
- end
35
- end
@@ -1,221 +0,0 @@
1
- module Neo4j
2
- module Server
3
- class CypherNode < Neo4j::Node
4
- include Neo4j::Server::Resource
5
- include Neo4j::Core::ActiveEntity
6
-
7
- MARSHAL_INSTANCE_VARIABLES = %i[@props @labels @neo_id]
8
-
9
- def initialize(session, value)
10
- @session = session
11
-
12
- @neo_id = if value.is_a?(Hash)
13
- @props = value[:data]
14
- @labels = value[:metadata][:labels].map!(&:to_sym) if value[:metadata]
15
- value[:id]
16
- else
17
- value
18
- end
19
- end
20
-
21
- attr_reader :neo_id
22
-
23
- def inspect
24
- "CypherNode #{neo_id} (#{object_id})"
25
- end
26
-
27
- # TODO, needed by neo4j-cypher
28
- def _java_node
29
- self
30
- end
31
-
32
- # (see Neo4j::Node#create_rel)
33
- def create_rel(type, other_node, props = nil)
34
- q = @session.query.match(:a, :b).where(a: {neo_id: neo_id}, b: {neo_id: other_node.neo_id})
35
- .create("(a)-[r:`#{type}`]->(b)").break.set(r: props).return(r: :neo_id)
36
-
37
- id = @session._query_or_fail(q, true)
38
-
39
- CypherRelationship.new(@session, type: type, data: props, start: neo_id, end: other_node.neo_id, id: id)
40
- end
41
-
42
- # (see Neo4j::Node#props)
43
- def props
44
- if @props
45
- @props
46
- else
47
- hash = @session._query_entity_data(match_start_query.return(:n), nil)
48
- @props = Hash[hash[:data].to_a]
49
- end
50
- end
51
-
52
- def refresh
53
- @props = nil
54
- end
55
-
56
- # (see Neo4j::Node#remove_property)
57
- def remove_property(key)
58
- refresh
59
- @session._query_or_fail(match_start_query.remove(n: key), false)
60
- end
61
-
62
- # (see Neo4j::Node#set_property)
63
- def set_property(key, value)
64
- refresh
65
- @session._query_or_fail(match_start_query.set(n: {key => value}), false)
66
- end
67
-
68
- # (see Neo4j::Node#props=)
69
- def props=(properties)
70
- refresh
71
- @session._query_or_fail(match_start_query.set_props(n: properties), false)
72
- properties
73
- end
74
-
75
- def remove_properties(properties)
76
- return if properties.empty?
77
-
78
- refresh
79
- @session._query_or_fail(match_start_query.remove(n: properties), false, neo_id: neo_id)
80
- end
81
-
82
- # (see Neo4j::Node#update_props)
83
- def update_props(properties)
84
- refresh
85
- return if properties.empty?
86
-
87
- @session._query_or_fail(match_start_query.set(n: properties), false)
88
-
89
- properties
90
- end
91
-
92
- # (see Neo4j::Node#get_property)
93
- def get_property(key)
94
- @props ? @props[key.to_sym] : @session._query_or_fail(match_start_query.return(n: key), true)
95
- end
96
-
97
- # (see Neo4j::Node#labels)
98
- def labels
99
- @labels ||= @session._query_or_fail(match_start_query.return('labels(n) AS labels'), true).map(&:to_sym)
100
- end
101
-
102
- def _cypher_label_list(labels_list)
103
- ':' + labels_list.map { |label| "`#{label}`" }.join(':')
104
- end
105
-
106
- def add_label(*new_labels)
107
- @session._query_or_fail(match_start_query.set(n: new_labels), false)
108
- new_labels.each { |label| labels << label }
109
- end
110
-
111
- def remove_label(*target_labels)
112
- @session._query_or_fail(match_start_query.remove(n: target_labels), false)
113
- target_labels.each { |label| labels.delete(label) } unless labels.nil?
114
- end
115
-
116
- def set_label(*label_names)
117
- labels_to_add = label_names.map(&:to_sym).uniq
118
- labels_to_remove = labels - label_names
119
-
120
- common_labels = labels & labels_to_add
121
- labels_to_add -= common_labels
122
- labels_to_remove -= common_labels
123
-
124
- query = _set_label_query(labels_to_add, labels_to_remove)
125
- @session._query_or_fail(query, false) unless (labels_to_add + labels_to_remove).empty?
126
- end
127
-
128
- def _set_label_query(labels_to_add, labels_to_remove)
129
- query = match_start_query
130
- query = query.remove(n: labels_to_remove) unless labels_to_remove.empty?
131
- query = query.set(n: labels_to_add) unless labels_to_add.empty?
132
- query
133
- end
134
-
135
- # (see Neo4j::Node#del)
136
- def del
137
- query = match_start_query.optional_match('(n)-[r]-()').delete(:n, :r)
138
- @session._query_or_fail(query, false)
139
- end
140
-
141
- alias delete del
142
- alias destroy del
143
-
144
- # (see Neo4j::Node#exist?)
145
- def exist?
146
- !@session._query(match_start_query.return(n: :neo_id)).data.empty?
147
- end
148
-
149
- # (see Neo4j::Node#node)
150
- def node(match = {})
151
- ensure_single_relationship { match(CypherNode, 'p as result LIMIT 2', match) }
152
- end
153
-
154
- # (see Neo4j::Node#rel)
155
- def rel(match = {})
156
- ensure_single_relationship { match(CypherRelationship, 'r as result LIMIT 2', match) }
157
- end
158
-
159
- # (see Neo4j::Node#rel?)
160
- def rel?(match = {})
161
- result = match(CypherRelationship, 'r as result', match)
162
- !!result.first
163
- end
164
-
165
- # (see Neo4j::Node#nodes)
166
- def nodes(match = {})
167
- match(CypherNode, 'p as result', match)
168
- end
169
-
170
- # (see Neo4j::Node#rels)
171
- def rels(match = {dir: :both})
172
- match(CypherRelationship, 'r as result', match)
173
- end
174
-
175
- # @private
176
- def match(clazz, returns, match = {})
177
- ::Neo4j::Node.validate_match!(match)
178
-
179
- query = self.query
180
-
181
- query = query.match(:p).where(p: {neo_id: match[:between].neo_id}) if match[:between]
182
-
183
- r = query.match("(n)#{relationship_arrow(match)}(p)").return(returns).response
184
-
185
- r.raise_error if r.error?
186
-
187
- r.to_node_enumeration.map(&:result)
188
- end
189
-
190
- def query(identifier = :n)
191
- @session.query.match(identifier).where(identifier => {neo_id: neo_id})
192
- end
193
-
194
- private
195
-
196
- DEFAULT_RELATIONSHIP_ARROW_DIRECTION = :both
197
- def relationship_arrow(match)
198
- rel_spec = match[:type] ? "[r:`#{match[:type]}`]" : '[r]'
199
-
200
- case match[:dir] || DEFAULT_RELATIONSHIP_ARROW_DIRECTION
201
- when :outgoing then "-#{rel_spec}->"
202
- when :incoming then "<-#{rel_spec}-"
203
- when :both then "-#{rel_spec}-"
204
- else
205
- fail "Invalid value for relationship_arrow direction: #{match[:dir].inspect}"
206
- end
207
- end
208
-
209
- def ensure_single_relationship
210
- fail 'Expected a block' unless block_given?
211
- result = yield
212
- fail "Expected to only find one relationship from node #{neo_id} matching #{match.inspect} but found #{result.count}" if result.count > 1
213
- result.first
214
- end
215
-
216
- def match_start_query(identifier = :n)
217
- @session.query.match(identifier).where(identifier => {neo_id: neo_id}).with(identifier)
218
- end
219
- end
220
- end
221
- end