neo4j-core 3.0.0.alpha.13 → 3.0.0.alpha.14
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/README.md +60 -49
- data/lib/mydb/active_tx_log +1 -0
- data/lib/mydb/index/lucene-store.db +0 -0
- data/lib/mydb/index/lucene.log.1 +0 -0
- data/lib/mydb/index/lucene.log.active +0 -0
- data/lib/mydb/lock +0 -0
- data/lib/mydb/messages.log +313 -0
- data/lib/mydb/neostore +0 -0
- data/lib/mydb/neostore.id +0 -0
- data/lib/mydb/neostore.labeltokenstore.db +0 -0
- data/lib/mydb/neostore.labeltokenstore.db.id +0 -0
- data/lib/mydb/neostore.labeltokenstore.db.names +0 -0
- data/lib/mydb/neostore.labeltokenstore.db.names.id +0 -0
- data/lib/mydb/neostore.nodestore.db +0 -0
- data/lib/mydb/neostore.nodestore.db.id +0 -0
- data/lib/mydb/neostore.nodestore.db.labels +0 -0
- data/lib/mydb/neostore.nodestore.db.labels.id +0 -0
- data/lib/mydb/neostore.propertystore.db +0 -0
- data/lib/mydb/neostore.propertystore.db.arrays +0 -0
- data/lib/mydb/neostore.propertystore.db.arrays.id +0 -0
- data/lib/mydb/neostore.propertystore.db.id +0 -0
- data/lib/mydb/neostore.propertystore.db.index +0 -0
- data/lib/mydb/neostore.propertystore.db.index.id +0 -0
- data/lib/mydb/neostore.propertystore.db.index.keys +0 -0
- data/lib/mydb/neostore.propertystore.db.index.keys.id +0 -0
- data/lib/mydb/neostore.propertystore.db.strings +0 -0
- data/lib/mydb/neostore.propertystore.db.strings.id +0 -0
- data/lib/mydb/neostore.relationshipstore.db +0 -0
- data/lib/mydb/neostore.relationshipstore.db.id +0 -0
- data/lib/mydb/neostore.relationshiptypestore.db +0 -0
- data/lib/mydb/neostore.relationshiptypestore.db.id +0 -0
- data/lib/mydb/neostore.relationshiptypestore.db.names +0 -0
- data/lib/mydb/neostore.relationshiptypestore.db.names.id +0 -0
- data/lib/mydb/neostore.schemastore.db +0 -0
- data/lib/mydb/neostore.schemastore.db.id +0 -0
- data/lib/mydb/nioneo_logical.log.1 +0 -0
- data/lib/mydb/nioneo_logical.log.active +0 -0
- data/lib/mydb/schema/label/lucene/write.lock +0 -0
- data/lib/mydb/store_lock +0 -0
- data/lib/mydb/tm_tx_log.1 +0 -0
- data/lib/neo4j-core.rb +1 -2
- data/lib/neo4j-core/query_builder.rb +200 -0
- data/lib/neo4j-core/version.rb +1 -1
- data/lib/neo4j-embedded.rb +1 -0
- data/lib/neo4j-embedded/cypher_response.rb +89 -0
- data/lib/neo4j-embedded/cypher_response.rb~ +85 -0
- data/lib/neo4j-embedded/embedded_node.rb +12 -0
- data/lib/neo4j-embedded/embedded_node.rb~ +201 -0
- data/lib/neo4j-embedded/embedded_relationship.rb +8 -0
- data/lib/neo4j-embedded/embedded_relationship.rb~ +62 -0
- data/lib/neo4j-embedded/embedded_session.rb +20 -12
- data/lib/neo4j-embedded/embedded_session.rb~ +145 -0
- data/lib/neo4j-server/cypher_relationship.rb +6 -11
- data/lib/neo4j-server/cypher_response.rb +43 -5
- data/lib/neo4j-server/cypher_response.rb~ +155 -0
- data/lib/neo4j-server/cypher_session.rb +54 -19
- data/lib/neo4j/label.rb +7 -51
- data/lib/neo4j/node.rb +21 -19
- data/lib/neo4j/relationship.rb +7 -7
- data/lib/neo4j/session.rb +70 -28
- data/lib/neo4j/session.rb~ +202 -0
- data/neo4j-core.gemspec +0 -1
- metadata +49 -16
data/lib/mydb/neostore
ADDED
Binary file
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
data/lib/mydb/store_lock
ADDED
File without changes
|
File without changes
|
data/lib/neo4j-core.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
|
-
require 'neo4j-cypher'
|
5
|
-
|
6
4
|
require 'neo4j/property_validator'
|
7
5
|
require 'neo4j/property_container'
|
8
6
|
require 'neo4j-core/helpers'
|
9
7
|
require 'neo4j-core/cypher_translator'
|
8
|
+
require 'neo4j-core/query_builder'
|
10
9
|
|
11
10
|
require 'neo4j/entity_equality'
|
12
11
|
require 'neo4j/node'
|
@@ -0,0 +1,200 @@
|
|
1
|
+
module Neo4j::Core
|
2
|
+
|
3
|
+
class QueryBuilder
|
4
|
+
include CypherTranslator
|
5
|
+
|
6
|
+
DEFAULT_VAR_NAME = :n
|
7
|
+
|
8
|
+
class InvalidQueryError < StandardError;
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(map_return={})
|
12
|
+
@map_return = map_return
|
13
|
+
@map_return[:node] = ->(id) { "ID(#{id})" }
|
14
|
+
end
|
15
|
+
|
16
|
+
# TODO should be moved somewhere else
|
17
|
+
def self.default_cypher_map_return_procs
|
18
|
+
{
|
19
|
+
id_to_node: ->(column) { Neo4j::Node.load(column) },
|
20
|
+
to_node: ->(column) { column.wrapper }, # for embedded db
|
21
|
+
value: ->(column) { column },
|
22
|
+
id_to_rel: ->(column) { Neo4j::Relationship.load(column) },
|
23
|
+
to_rel: ->(column) { column.wrapper } # for embedded db
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def to_query_hash(params, default_map_return)
|
29
|
+
if params.first.is_a?(Hash)
|
30
|
+
hash = params.first.clone
|
31
|
+
hash[:map_return] ||= default_map_return unless hash[:q] || hash[:return]
|
32
|
+
hash[:map_return] ||= :value if hash[:return].is_a?(Symbol)
|
33
|
+
return hash
|
34
|
+
else
|
35
|
+
hash = (params[1] && params[1].clone) || {}
|
36
|
+
hash[:q] = params[0]
|
37
|
+
return hash
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_map_return_procs(query_hash)
|
42
|
+
map_return_procs = query_hash[:map_return_procs] || self.class.default_cypher_map_return_procs
|
43
|
+
map_return = query_hash[:map_return]
|
44
|
+
case map_return
|
45
|
+
when NilClass
|
46
|
+
return {}
|
47
|
+
when Symbol, String
|
48
|
+
return map_return_procs[map_return.to_sym]
|
49
|
+
when Hash
|
50
|
+
map_return.keys.inject({}) do |ack, key|
|
51
|
+
proc_key = map_return[key]
|
52
|
+
ack[key] = map_return_procs[proc_key]
|
53
|
+
raise InvalidQueryError.new("Illegal map_return, '#{ack[key]}' not defined for #{key}") unless ack[key]
|
54
|
+
ack
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_cypher(query_hash)
|
60
|
+
return query_hash[:q] if query_hash[:q]
|
61
|
+
match_parts = label_parts(query_hash[:label])
|
62
|
+
match_parts += match_parts(query_hash[:match])
|
63
|
+
conditions_parts = conditions_parts(query_hash[:conditions])
|
64
|
+
conditions_parts += where_parts(query_hash[:where])
|
65
|
+
|
66
|
+
return_parts = return_parts(query_hash)
|
67
|
+
return_parts += order_parts(query_hash[:order])
|
68
|
+
return_parts += skip_parts(query_hash[:skip])
|
69
|
+
return_parts += limit_parts(query_hash[:limit])
|
70
|
+
|
71
|
+
cypher = "MATCH #{match_parts.join(',')}"
|
72
|
+
cypher += " WHERE #{conditions_parts.join(' AND ')}" if !conditions_parts.empty?
|
73
|
+
cypher + " RETURN #{return_parts.join(' ')}"
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def order_parts(order)
|
78
|
+
return [] unless order
|
79
|
+
cypher = "ORDER BY "
|
80
|
+
|
81
|
+
handleHash = Proc.new do |hash|
|
82
|
+
if (hash.is_a?(Hash))
|
83
|
+
k, v = hash.first
|
84
|
+
raise "only :asc or :desc allowed in order, got #{query.inspect}" unless [:asc, :desc].include?(v)
|
85
|
+
v.to_sym == :asc ? "#{DEFAULT_VAR_NAME}.`#{k}`" : "#{DEFAULT_VAR_NAME}.`#{k}` DESC"
|
86
|
+
else
|
87
|
+
"#{DEFAULT_VAR_NAME}.`#{hash}`" unless hash.is_a?(Hash)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
case order
|
92
|
+
when Array
|
93
|
+
cypher += order.map(&handleHash).join(', ')
|
94
|
+
when Hash
|
95
|
+
cypher += handleHash.call(order)
|
96
|
+
else
|
97
|
+
cypher += "#{DEFAULT_VAR_NAME}.`#{order}`"
|
98
|
+
end
|
99
|
+
|
100
|
+
[cypher]
|
101
|
+
end
|
102
|
+
|
103
|
+
def return_parts(query_hash)
|
104
|
+
query_hash[:return] ? [cypher_return(query_hash[:return])] : [cypher_default_return(query_hash[:label], query_hash)]
|
105
|
+
end
|
106
|
+
|
107
|
+
def cypher_return(ret)
|
108
|
+
case ret
|
109
|
+
when Array
|
110
|
+
ret.map { |r| cypher_return_val(r) }.join(',')
|
111
|
+
when String, Symbol
|
112
|
+
cypher_return_val(ret)
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
def cypher_default_return(label, query_hash)
|
118
|
+
raise InvalidQueryError, "Can't have default return for two labels" if label.is_a?(Hash) && label.key.size > 1
|
119
|
+
if (query_hash[:map_return] == :id_to_node)
|
120
|
+
label.is_a?(Hash) ? "ID(#{label.key.first})" : "ID(#{DEFAULT_VAR_NAME})"
|
121
|
+
elsif (query_hash[:map_return] == :to_node)
|
122
|
+
label.is_a?(Hash) ? "#{label.key.first}" : "#{DEFAULT_VAR_NAME}"
|
123
|
+
else
|
124
|
+
raise InvalidQueryError.new("Don't know how to generate a cypher return #{query_hash.inspect}")
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
def where_parts(conditions)
|
131
|
+
return [] unless conditions
|
132
|
+
conditions.is_a?(Array) ? conditions : [conditions]
|
133
|
+
end
|
134
|
+
|
135
|
+
def limit_parts(limit)
|
136
|
+
return [] unless limit
|
137
|
+
raise InvalidQueryError.new ":limit value not a number" unless limit.is_a?(Integer)
|
138
|
+
return ["LIMIT #{limit}"]
|
139
|
+
end
|
140
|
+
|
141
|
+
def skip_parts(skip)
|
142
|
+
return [] unless skip
|
143
|
+
raise InvalidQueryError.new ":skip value not a number" unless skip.is_a?(Integer)
|
144
|
+
return ["SKIP #{skip}"]
|
145
|
+
end
|
146
|
+
|
147
|
+
def conditions_parts(conditions)
|
148
|
+
|
149
|
+
return [] unless conditions
|
150
|
+
neo_id = conditions.delete(:neo_id)
|
151
|
+
conditions["id(#{as})"] = neo_id if neo_id
|
152
|
+
|
153
|
+
conditions.map do |key, value|
|
154
|
+
operator, value_string = case value
|
155
|
+
when Regexp
|
156
|
+
pattern = (value.casefold? ? "(?i)" : "") + value.source
|
157
|
+
['=~', escape_value(pattern.gsub(/\\/, '\\\\\\'))]
|
158
|
+
else
|
159
|
+
['=', escape_value(value)]
|
160
|
+
end
|
161
|
+
|
162
|
+
k = key.to_s.dup
|
163
|
+
k = "#{DEFAULT_VAR_NAME}.#{k}" unless k.match(/[\(\.]/)
|
164
|
+
k + operator + value_string.to_s
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def label_parts(label)
|
169
|
+
case label
|
170
|
+
when NilClass then
|
171
|
+
[]
|
172
|
+
when Hash
|
173
|
+
label.map { |variable, label_name| "(#{variable}:`#{label_name}`)" }
|
174
|
+
else
|
175
|
+
["(n:`#{label}`)"]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
def match_parts(match)
|
181
|
+
case match
|
182
|
+
when Array then
|
183
|
+
return match
|
184
|
+
when String then
|
185
|
+
return [match]
|
186
|
+
when NilClass
|
187
|
+
return []
|
188
|
+
else
|
189
|
+
raise InvalidQueryError, "Invalid value for 'match' query key #{match.inspect}"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def cypher_return_val(val)
|
194
|
+
val.is_a?(Symbol) ? "#{DEFAULT_VAR_NAME}.`#{val}` AS `#{val}`" : val
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
data/lib/neo4j-core/version.rb
CHANGED
data/lib/neo4j-embedded.rb
CHANGED
@@ -8,6 +8,7 @@ require 'neo4j-embedded/embedded_label'
|
|
8
8
|
require 'neo4j-embedded/embedded_node'
|
9
9
|
require 'neo4j-embedded/embedded_relationship'
|
10
10
|
require 'neo4j-embedded/embedded_label'
|
11
|
+
require 'neo4j-embedded/cypher_response'
|
11
12
|
|
12
13
|
# TODO replace this with https://github.com/intridea/hashie gem
|
13
14
|
require 'neo4j-core/hash_with_indifferent_access'
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Neo4j::Embedded
|
2
|
+
|
3
|
+
# Wraps the Cypher query result.
|
4
|
+
# Loads the node and relationships wrapper if possible and use symbol as column keys.
|
5
|
+
# This is typically used in the native neo4j bindings since result does is not a Ruby enumerable with symbols as keys.
|
6
|
+
# @note The result is a once forward read only Enumerable, work if you need to read the result twice - use #to_a
|
7
|
+
#
|
8
|
+
class ResultWrapper
|
9
|
+
class ResultsAlreadyConsumedException < Exception;
|
10
|
+
end
|
11
|
+
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
# @return the original result from the Neo4j Cypher Engine, once forward read only !
|
15
|
+
attr_reader :source
|
16
|
+
|
17
|
+
def initialize(source, map_return_procs, query)
|
18
|
+
@source = source
|
19
|
+
@unread = true
|
20
|
+
@map_return_procs = map_return_procs
|
21
|
+
@query = query
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
@query
|
26
|
+
end
|
27
|
+
|
28
|
+
def inspect
|
29
|
+
"Enumerable query: '#{@query}'"
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Array<Symbol>] the columns in the query result
|
33
|
+
def columns
|
34
|
+
@source.columns.map { |x| x.to_sym }
|
35
|
+
end
|
36
|
+
|
37
|
+
# for the Enumerable contract
|
38
|
+
def each(&block)
|
39
|
+
raise ResultsAlreadyConsumedException unless @unread
|
40
|
+
|
41
|
+
if (block)
|
42
|
+
case @map_return_procs
|
43
|
+
when NilClass then
|
44
|
+
each_no_mapping &block
|
45
|
+
when Hash then
|
46
|
+
each_multi_column_mapping &block
|
47
|
+
else
|
48
|
+
each_single_column_mapping &block
|
49
|
+
end
|
50
|
+
else
|
51
|
+
Enumerator.new(self)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def each_no_mapping
|
59
|
+
@source.each do |row|
|
60
|
+
hash = {}
|
61
|
+
row.each do |key, value|
|
62
|
+
out[key.to_sym] = value
|
63
|
+
end
|
64
|
+
yield hash
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def each_multi_column_mapping
|
69
|
+
@source.each do |row|
|
70
|
+
hash = {}
|
71
|
+
row.each do |key, value|
|
72
|
+
k = key.to_sym
|
73
|
+
proc = @map_return_procs[k]
|
74
|
+
hash[k] = proc ? proc.call(value) : value
|
75
|
+
end
|
76
|
+
yield hash
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def each_single_column_mapping
|
81
|
+
@source.each do |row|
|
82
|
+
result = @map_return_procs.call(row.values.first)
|
83
|
+
yield result
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Neo4j::Embedded
|
2
|
+
|
3
|
+
# Wraps the Cypher query result.
|
4
|
+
# Loads the node and relationships wrapper if possible and use symbol as column keys.
|
5
|
+
# This is typically used in the native neo4j bindings since result does is not a Ruby enumerable with symbols as keys.
|
6
|
+
# @note The result is a once forward read only Enumerable, work if you need to read the result twice - use #to_a
|
7
|
+
#
|
8
|
+
class ResultWrapper
|
9
|
+
class ResultsAlreadyConsumedException < Exception;
|
10
|
+
end
|
11
|
+
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
# @return the original result from the Neo4j Cypher Engine, once forward read only !
|
15
|
+
attr_reader :source
|
16
|
+
|
17
|
+
def initialize(source, map_return_procs, query)
|
18
|
+
@source = source
|
19
|
+
@unread = true
|
20
|
+
@map_return_procs = map_return_procs
|
21
|
+
@query = query
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
@query
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Array<Symbol>] the columns in the query result
|
29
|
+
def columns
|
30
|
+
@source.columns.map { |x| x.to_sym }
|
31
|
+
end
|
32
|
+
|
33
|
+
# for the Enumerable contract
|
34
|
+
def each(&block)
|
35
|
+
raise ResultsAlreadyConsumedException unless @unread
|
36
|
+
|
37
|
+
if (block)
|
38
|
+
case @map_return_procs
|
39
|
+
when NilClass then
|
40
|
+
each_no_mapping &block
|
41
|
+
when Hash then
|
42
|
+
each_multi_column_mapping &block
|
43
|
+
else
|
44
|
+
each_single_column_mapping &block
|
45
|
+
end
|
46
|
+
else
|
47
|
+
Enumerator.new(self)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def each_no_mapping
|
55
|
+
@source.each do |row|
|
56
|
+
hash = {}
|
57
|
+
row.each do |key, value|
|
58
|
+
out[key.to_sym] = value
|
59
|
+
end
|
60
|
+
yield hash
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def each_multi_column_mapping
|
65
|
+
@source.each do |row|
|
66
|
+
hash = {}
|
67
|
+
row.each do |key, value|
|
68
|
+
k = key.to_sym
|
69
|
+
proc = @map_return_procs[k]
|
70
|
+
hash[k] = proc ? proc.call(value) : value
|
71
|
+
end
|
72
|
+
yield hash
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def each_single_column_mapping
|
77
|
+
@source.each do |row|
|
78
|
+
result = @map_return_procs.call(row.values.first)
|
79
|
+
yield result
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|