neo4j-core 8.1.4 → 9.0.0.alpha.1

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.
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