neography 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +3 -1
- data/README.rdoc +69 -3
- data/lib/neography/config.rb +14 -0
- data/lib/neography/equal.rb +21 -0
- data/lib/neography/neography.rb +10 -0
- data/lib/neography/node.rb +43 -0
- data/lib/neography/node_relationship.rb +45 -0
- data/lib/neography/node_traverser.rb +23 -0
- data/lib/neography/property.rb +55 -0
- data/lib/neography/property_container.rb +17 -0
- data/lib/neography/relationship.rb +54 -0
- data/lib/neography/relationship_traverser.rb +59 -0
- data/lib/neography/rest.rb +73 -8
- data/lib/neography/version.rb +1 -1
- data/lib/neography.rb +16 -0
- data/spec/integration/neography_spec.rb +10 -0
- data/spec/integration/node_spec.rb +198 -0
- data/spec/integration/relationship_spec.rb +71 -0
- data/spec/integration/rest_bulk_spec.rb +106 -0
- data/spec/integration/rest_experimental_spec.rb +23 -0
- data/spec/spec_helper.rb +1 -0
- metadata +18 -3
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
neography (0.0.
|
4
|
+
neography (0.0.4)
|
5
5
|
httparty (~> 0.6.1)
|
6
6
|
json
|
7
7
|
|
@@ -13,6 +13,7 @@ GEM
|
|
13
13
|
fakeweb (1.3.0)
|
14
14
|
httparty (0.6.1)
|
15
15
|
crack (= 0.1.8)
|
16
|
+
json (1.4.6)
|
16
17
|
json (1.4.6-java)
|
17
18
|
net-http-spy (0.2.1)
|
18
19
|
rspec (2.0.1)
|
@@ -28,6 +29,7 @@ GEM
|
|
28
29
|
|
29
30
|
PLATFORMS
|
30
31
|
java
|
32
|
+
ruby
|
31
33
|
|
32
34
|
DEPENDENCIES
|
33
35
|
fakeweb (~> 1.3.0)
|
data/README.rdoc
CHANGED
@@ -35,12 +35,12 @@ Just add gem 'neography' to your Gemfile and run bundle install
|
|
35
35
|
|
36
36
|
A thin ruby wrapper Neography::Rest which tries to mirror the Neo4j Rest API and returns JSON or Nil:
|
37
37
|
|
38
|
-
# protocol, server, port, log_file, log_enabled
|
39
|
-
@neo = Neography::Rest.new ('http://', '192.168.10.1', 7479, 'log/neography.log', true)
|
38
|
+
# protocol, server, port, log_file, log_enabled, max_threads
|
39
|
+
@neo = Neography::Rest.new ('http://', '192.168.10.1', 7479, 'log/neography.log', true, 50)
|
40
40
|
|
41
41
|
Default Parameters are:
|
42
42
|
|
43
|
-
@neo = Neography::Rest.new ('http://', 'localhost', 7474, '/neography.log', false)
|
43
|
+
@neo = Neography::Rest.new ('http://', 'localhost', 7474, '/neography.log', false, 20)
|
44
44
|
|
45
45
|
To Use:
|
46
46
|
|
@@ -104,6 +104,72 @@ To Use:
|
|
104
104
|
|
105
105
|
Please see the specs for more examples.
|
106
106
|
|
107
|
+
Experimental:
|
108
|
+
|
109
|
+
nodes = @neo.create_nodes(5) # Create 5 empty nodes
|
110
|
+
nodes = @neo.create_nodes_threaded(5) # Create 5 empty nodes using threads
|
111
|
+
nodes = @neo.create_node_nodes([{"age" => 31, "name" => "Max"},
|
112
|
+
{"age" => 24, "name" => "Alex"}) # Create two nodes with properties
|
113
|
+
nodes = @neo.create_node_nodes_threaded([{"age" => 31, "name" => "Max"},
|
114
|
+
{"age" => 24, "name" => "Alex"}) # Create two nodes with properties threaded
|
115
|
+
nodes = @neo.get_nodes([17,86,397,33]) # Get four nodes by their id
|
116
|
+
|
117
|
+
one_set_nodes = @neo.create_nodes(3)
|
118
|
+
another_node = @neo.create_node("age" => 31, "name" => "Max")
|
119
|
+
nodes = @neo.get_nodes([one_set_nodes, another_node]) # Get four nodes
|
120
|
+
|
121
|
+
=== Phase 2 (work in progress):
|
122
|
+
|
123
|
+
Trying to mimic the Neo4j.rb API.
|
124
|
+
|
125
|
+
Now we are returning full objects. The properties of the node or relationship can be accessed directly (node.name).
|
126
|
+
The Neo4j ID is available by using node.neo_id .
|
127
|
+
|
128
|
+
@neo2 = Neography::Rest.new ('http://', '192.168.10.1')
|
129
|
+
|
130
|
+
Neography::Node.create # Create an empty node
|
131
|
+
Neography::Node.create("age" => 31, "name" => "Max") # Create a node with some properties
|
132
|
+
Neography::Node.create(@neo2, {"age" => 31, "name" => "Max"}) # Create a node on the server defined in @neo2
|
133
|
+
Neography::Node.create({"age" => 31, "name" => "Max"}, @neo2) # Same as above, but different order
|
134
|
+
|
135
|
+
Neography::Node.load(5) # Get a node and its properties by id
|
136
|
+
Neography::Node.load(existing_node) # Get a node and its properties by Node
|
137
|
+
Neography::Node.load("http://localhost:7474/db/data/node/2") # Get a node and its properties by String
|
138
|
+
|
139
|
+
Neography::Node.load(@neo2, 5) # Get a node on the server defined in @neo2
|
140
|
+
Neography::Node.load(5, @neo2) # Same as above, but different order
|
141
|
+
|
142
|
+
n1 = Node.create
|
143
|
+
n1.del # Deletes the node
|
144
|
+
n1.exist? # returns true/false if node exists in Neo4j
|
145
|
+
|
146
|
+
n1 = Node.create("age" => 31, "name" => "Max")
|
147
|
+
n1[:age] #returns 31 # Get a node property using [:key]
|
148
|
+
n1.name #returns "Max" # Get a node property as a method
|
149
|
+
n1[:age] = 24 # Set a node property using [:key] =
|
150
|
+
n1.name = "Alex" # Set a node property as a method
|
151
|
+
n1[:hair] = "black" # Add a node property using [:key] =
|
152
|
+
n1.weight = 190 # Add a node property as a method
|
153
|
+
n1[:name] = nil # Delete a node property using [:key] = nil
|
154
|
+
n1.name = nil # Delete a node property by setting it to nil
|
155
|
+
|
156
|
+
n2 = Neography::Node.create
|
157
|
+
new_rel = Neography::Relationship.create(:family, n1, n2) # Create a relationship from my_node to node2
|
158
|
+
new_rel.start_node # Get the start/from node of a relationship
|
159
|
+
new_rel.end_node # Get the end/to node of a relationship
|
160
|
+
existing_rel = Neography::Relationship.load(12) # Get an existing relationship by id
|
161
|
+
existing_rel.del # Delete a relationship
|
162
|
+
|
163
|
+
Neography::Relationship.create(:friends, n1, n2)
|
164
|
+
n1.rel?(:friends) # Has a friends relationship
|
165
|
+
n1.rel?(:outgoing, :friends) # Has outgoing friends relationship
|
166
|
+
n1.rel?(:friends, :outgoing) # same, just the other way
|
167
|
+
n1.rel?(:outgoing) # Has any outgoing relationships
|
168
|
+
n1.rel?(:both) # Has any relationships
|
169
|
+
n1.rel?(:all) # same as above
|
170
|
+
n1.rel? # same as above
|
171
|
+
|
172
|
+
|
107
173
|
See Neo4j API for:
|
108
174
|
* {Order}[http://components.neo4j.org/neo4j-examples/1.2.M04/apidocs/org/neo4j/graphdb/Traverser.Order.html]
|
109
175
|
* {Uniqueness}[http://components.neo4j.org/neo4j-examples/1.2.M04/apidocs/org/neo4j/kernel/Uniqueness.html]
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Neography
|
2
|
+
class Config
|
3
|
+
class << self; attr_accessor :protocol, :server, :port, :log_file, :log_enabled, :logger, :max_threads end
|
4
|
+
|
5
|
+
@protocol = 'http://'
|
6
|
+
@server = 'localhost'
|
7
|
+
@port = 7474
|
8
|
+
@log_file = 'neography.log'
|
9
|
+
@log_enabled = false
|
10
|
+
@logger = Logger.new(@log_file) if @log_enabled
|
11
|
+
@max_threads = 20
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Neography
|
2
|
+
|
3
|
+
# == This mixin is used for both nodes and relationships to decide if two entities are equal or not.
|
4
|
+
#
|
5
|
+
module Equal
|
6
|
+
def equal?(o)
|
7
|
+
eql?(o)
|
8
|
+
end
|
9
|
+
|
10
|
+
def eql?(o)
|
11
|
+
return false unless o.respond_to?(:neo_id)
|
12
|
+
o.neo_id == neo_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(o)
|
16
|
+
eql?(o)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Neography
|
2
|
+
class Node < PropertyContainer
|
3
|
+
include Neography::NodeRelationship
|
4
|
+
include Neography::Equal
|
5
|
+
include Neography::Property
|
6
|
+
|
7
|
+
attr_accessor :neo_server
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def create(*args)
|
11
|
+
# the arguments can be an hash of properties to set or a rest instance
|
12
|
+
props = (args[0].respond_to?(:each_pair) && args[0]) || args[1]
|
13
|
+
db = (args[0].is_a?(Neography::Rest) && args[0]) || args[1] || Neography::Rest.new
|
14
|
+
node = Neography::Node.new(db.create_node(props))
|
15
|
+
node.neo_server = db
|
16
|
+
node
|
17
|
+
end
|
18
|
+
|
19
|
+
def load(*args)
|
20
|
+
# the first argument can be an hash of properties to set
|
21
|
+
node = !args[0].is_a?(Neography::Rest) && args[0] || args[1]
|
22
|
+
|
23
|
+
# a db instance can be given, it is the first argument or the second
|
24
|
+
db = (args[0].is_a?(Neography::Rest) && args[0]) || args[1] || Neography::Rest.new
|
25
|
+
node = db.get_node(node)
|
26
|
+
node = Neography::Node.new(node) unless node.nil?
|
27
|
+
node.neo_server = db unless node.nil?
|
28
|
+
node
|
29
|
+
end
|
30
|
+
|
31
|
+
#alias_method :new, :create
|
32
|
+
end
|
33
|
+
|
34
|
+
def del
|
35
|
+
self.neo_server.delete_node!(self.neo_id)
|
36
|
+
end
|
37
|
+
|
38
|
+
def exist?
|
39
|
+
!self.neo_server.get_node(self.neo_id).nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Neography
|
2
|
+
module NodeRelationship
|
3
|
+
|
4
|
+
def outgoing(types=nil)
|
5
|
+
if types
|
6
|
+
NodeTraverser.new(self).outgoing(types)
|
7
|
+
else
|
8
|
+
NodeTraverser.new(self).outgoing
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def incoming(types=nil)
|
13
|
+
if types
|
14
|
+
NodeTraverser.new(self).incoming(types)
|
15
|
+
else
|
16
|
+
NodeTraverser.new(self).incoming
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def both(types=nil)
|
21
|
+
if types
|
22
|
+
NodeTraverser.new(self).both(types)
|
23
|
+
else
|
24
|
+
NodeTraverser.new(self) # default is both
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def rels(*types)
|
29
|
+
Neography::RelationshipTraverser.new(self, types, :both)
|
30
|
+
end
|
31
|
+
|
32
|
+
def rel(dir, type)
|
33
|
+
Neography::RelationshipTraverser.new(self, type, dir).first
|
34
|
+
end
|
35
|
+
|
36
|
+
def rel?(dir=nil, type=nil)
|
37
|
+
if DIRECTIONS.include?(dir.to_s)
|
38
|
+
!self.neo_server.get_node_relationships(self, dir, type).nil?
|
39
|
+
else
|
40
|
+
!self.neo_server.get_node_relationships(self, type, dir).nil?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Neography
|
2
|
+
class NodeTraverser
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_accessor :order, :uniqueness, :depth, :prune, :filter
|
6
|
+
|
7
|
+
def initialize(from, types = nil, dir=nil)
|
8
|
+
@from = from
|
9
|
+
@depth = 1
|
10
|
+
@order = "depth first"
|
11
|
+
@uniqueness = "none"
|
12
|
+
if types.nil? || dir.nil?
|
13
|
+
# @td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first()
|
14
|
+
else
|
15
|
+
# @types = type_to_java(type)
|
16
|
+
# @dir = dir_to_java(dir)
|
17
|
+
# @td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first().relationships(@type, @dir)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Neography
|
2
|
+
module Property
|
3
|
+
|
4
|
+
|
5
|
+
def [](key)
|
6
|
+
return unless respond_to?(key)
|
7
|
+
@table[key]
|
8
|
+
end
|
9
|
+
|
10
|
+
def []=(key, value)
|
11
|
+
k = key.to_s
|
12
|
+
if value.nil?
|
13
|
+
if self.is_a? Neography::Node
|
14
|
+
neo_server.remove_node_properties(self.neo_id, [key])
|
15
|
+
@table[key] = nil
|
16
|
+
else
|
17
|
+
neo_server.remove_relationship_properties(self.neo_id, [key])
|
18
|
+
@table[key] = nil
|
19
|
+
end
|
20
|
+
else
|
21
|
+
if self.is_a? Neography::Node
|
22
|
+
neo_server.set_node_properties(self.neo_id, {k => value})
|
23
|
+
else
|
24
|
+
neo_server.set_relationship_properties(self.neo_id, {k => value})
|
25
|
+
end
|
26
|
+
|
27
|
+
new_ostruct_member(k) unless self.respond_to?(key)
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def new_ostruct_member(name)
|
34
|
+
name = name.to_sym
|
35
|
+
unless self.respond_to?(name)
|
36
|
+
meta = class << self; self; end
|
37
|
+
meta.send(:define_method, name) { @table[name] }
|
38
|
+
meta.send(:define_method, "#{name}=") do |x|
|
39
|
+
@table[name] = x
|
40
|
+
self[name.to_sym] = x
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def self.method_missing(method_sym, *arguments, &block)
|
47
|
+
if (method_sym.to_s =~ /$=/) != nil
|
48
|
+
new_ostruct_member(method_sym.to_s.chomp("="))
|
49
|
+
else
|
50
|
+
super
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Neography
|
2
|
+
class PropertyContainer < OpenStruct
|
3
|
+
attr_reader :neo_id
|
4
|
+
|
5
|
+
def initialize(hash=nil)
|
6
|
+
@table = {}
|
7
|
+
if hash
|
8
|
+
@neo_id = hash["self"].split('/').last
|
9
|
+
for k,v in hash["data"]
|
10
|
+
@table[k.to_sym] = v
|
11
|
+
new_ostruct_member(k)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Neography
|
2
|
+
class Relationship < PropertyContainer
|
3
|
+
include Neography::Equal
|
4
|
+
include Neography::Property
|
5
|
+
|
6
|
+
attr_accessor :start_node, :end_node, :rel_type
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def create(type, from_node, to_node, props=nil)
|
11
|
+
rel = Neography::Relationship.new(from_node.neo_server.create_relationship(type, from_node, to_node, props))
|
12
|
+
rel.start_node = from_node
|
13
|
+
rel.end_node = to_node
|
14
|
+
rel.rel_type = type
|
15
|
+
rel
|
16
|
+
end
|
17
|
+
|
18
|
+
def load(*args)
|
19
|
+
# the first argument can be an hash of properties to set
|
20
|
+
rel = !args[0].is_a?(Neography::Rest) && args[0] || args[1]
|
21
|
+
|
22
|
+
# a db instance can be given, it is the first argument or the second
|
23
|
+
db = (args[0].is_a?(Neography::Rest) && args[0]) || args[1] || Neography::Rest.new
|
24
|
+
rel = db.get_relationship(rel)
|
25
|
+
unless rel.nil?
|
26
|
+
rel = Neography::Relationship.new(rel)
|
27
|
+
rel.start_node = Neography::Node.load(rel.start_node)
|
28
|
+
rel.end_node = Neography::Node.load(rel.end_node)
|
29
|
+
end
|
30
|
+
rel
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(hash=nil, neo_server=nil)
|
35
|
+
super(hash)
|
36
|
+
@start_node = hash["start"].split('/').last
|
37
|
+
@end_node = hash["end"].split('/').last
|
38
|
+
@rel_type = hash["type"]
|
39
|
+
end
|
40
|
+
|
41
|
+
def del
|
42
|
+
self.start_node.neo_server.delete_relationship(self.neo_id)
|
43
|
+
end
|
44
|
+
|
45
|
+
def other_node(node)
|
46
|
+
if node = @start_node
|
47
|
+
@end_node
|
48
|
+
else
|
49
|
+
@start_node
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Neography
|
2
|
+
class RelationshipTraverser
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(node, types, direction)
|
6
|
+
@node = node
|
7
|
+
@types = [types]
|
8
|
+
@direction = direction
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
if @types.size == 1 && !@types.empty?
|
13
|
+
"#{self.class} [type: #{@type} dir:#{@direction}]"
|
14
|
+
elsif !@types.empty?
|
15
|
+
"#{self.class} [types: #{@types.join(',')} dir:#{@direction}]"
|
16
|
+
else
|
17
|
+
"#{self.class} [types: ANY dir:#{@direction}]"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def each
|
22
|
+
iterator.each { |i| yield Neography::Relationship.new(i, @node.neo_server) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def empty?
|
26
|
+
first == nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def iterator
|
30
|
+
@node.neo_server.get_node_relationships(@node, @direction, @types)
|
31
|
+
end
|
32
|
+
|
33
|
+
def del
|
34
|
+
each { |rel| @node.neo_server.delete_relationship(rel) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def size
|
38
|
+
[*self].size
|
39
|
+
end
|
40
|
+
|
41
|
+
def both
|
42
|
+
@direction = :both
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def incoming
|
47
|
+
raise "Not allowed calling incoming when finding several relationships types" if @types
|
48
|
+
@direction = :incoming
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def outgoing
|
53
|
+
raise "Not allowed calling outgoing when finding several relationships types" if @types
|
54
|
+
@direction = :outgoing
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
data/lib/neography/rest.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
module Neography
|
2
2
|
class Rest
|
3
3
|
include HTTParty
|
4
|
-
attr_accessor :protocol, :server, :port, :log_file, :log_enabled, :logger
|
5
|
-
|
6
|
-
def initialize(protocol=
|
4
|
+
attr_accessor :protocol, :server, :port, :log_file, :log_enabled, :logger, :max_threads
|
5
|
+
|
6
|
+
def initialize(protocol=Neography::Config.protocol,
|
7
|
+
server=Neography::Config.server,
|
8
|
+
port=Neography::Config.port,
|
9
|
+
log_file=Neography::Config.log_file,
|
10
|
+
log_enabled=Neography::Config.log_enabled,
|
11
|
+
max_threads=Neography::Config.max_threads)
|
7
12
|
@protocol = protocol
|
8
13
|
@server = server
|
9
14
|
@port = port
|
10
15
|
@log_file = log_file
|
11
16
|
@log_enabled = log_enabled
|
12
17
|
@logger = Logger.new(@log_file) if @log_enabled
|
18
|
+
@max_threads = max_threads
|
13
19
|
end
|
14
20
|
|
15
21
|
def configure(protocol, server, port)
|
@@ -35,10 +41,67 @@ module Neography
|
|
35
41
|
end
|
36
42
|
end
|
37
43
|
|
44
|
+
def create_nodes(nodes)
|
45
|
+
nodes = Array.new(nodes) if nodes.kind_of? Fixnum
|
46
|
+
created_nodes = Array.new
|
47
|
+
nodes.each do |node|
|
48
|
+
created_nodes << create_node(node)
|
49
|
+
end
|
50
|
+
created_nodes
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_nodes_threaded(nodes)
|
54
|
+
nodes = Array.new(nodes) if nodes.kind_of? Fixnum
|
55
|
+
|
56
|
+
node_queue = Queue.new
|
57
|
+
thread_pool = []
|
58
|
+
responses = Queue.new
|
59
|
+
|
60
|
+
nodes.each do |node|
|
61
|
+
node_queue.push node
|
62
|
+
end
|
63
|
+
|
64
|
+
[nodes.size, @max_threads].min.times do
|
65
|
+
thread_pool << Thread.new do
|
66
|
+
until node_queue.empty? do
|
67
|
+
node = node_queue.pop
|
68
|
+
if node.respond_to?(:each_pair)
|
69
|
+
responses.push( post("/node", { :body => node.to_json, :headers => {'Content-Type' => 'application/json'} } ) )
|
70
|
+
else
|
71
|
+
responses.push( post("/node") )
|
72
|
+
end
|
73
|
+
end
|
74
|
+
self.join
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
created_nodes = Array.new
|
79
|
+
|
80
|
+
while created_nodes.size < nodes.size
|
81
|
+
created_nodes << responses.pop
|
82
|
+
end
|
83
|
+
created_nodes
|
84
|
+
end
|
85
|
+
|
86
|
+
# This is not yet implemented in the REST API
|
87
|
+
#
|
88
|
+
# def get_all_node
|
89
|
+
# puts "get all nodes"
|
90
|
+
# get("/nodes/")
|
91
|
+
# end
|
92
|
+
|
38
93
|
def get_node(id)
|
39
94
|
get("/node/#{get_id(id)}")
|
40
95
|
end
|
41
96
|
|
97
|
+
def get_nodes(*nodes)
|
98
|
+
gotten_nodes = Array.new
|
99
|
+
Array(nodes).flatten.each do |node|
|
100
|
+
gotten_nodes << get_node(node)
|
101
|
+
end
|
102
|
+
gotten_nodes
|
103
|
+
end
|
104
|
+
|
42
105
|
def reset_node_properties(id, properties)
|
43
106
|
options = { :body => properties.to_json, :headers => {'Content-Type' => 'application/json'} }
|
44
107
|
put("/node/#{get_id(id)}/properties", options)
|
@@ -49,7 +112,7 @@ module Neography
|
|
49
112
|
get("/node/#{get_id(id)}/properties")
|
50
113
|
else
|
51
114
|
node_properties = Hash.new
|
52
|
-
properties.
|
115
|
+
Array(properties).each do |property|
|
53
116
|
value = get("/node/#{get_id(id)}/properties/#{property}")
|
54
117
|
node_properties[property] = value unless value.nil?
|
55
118
|
end
|
@@ -62,7 +125,7 @@ module Neography
|
|
62
125
|
if properties.nil?
|
63
126
|
delete("/node/#{get_id(id)}/properties")
|
64
127
|
else
|
65
|
-
properties.
|
128
|
+
Array(properties).each do |property|
|
66
129
|
delete("/node/#{get_id(id)}/properties/#{property}")
|
67
130
|
end
|
68
131
|
end
|
@@ -98,7 +161,7 @@ module Neography
|
|
98
161
|
get("/relationship/#{get_id(id)}/properties")
|
99
162
|
else
|
100
163
|
relationship_properties = Hash.new
|
101
|
-
properties.
|
164
|
+
Array(properties).each do |property|
|
102
165
|
value = get("/relationship/#{get_id(id)}/properties/#{property}")
|
103
166
|
relationship_properties[property] = value unless value.nil?
|
104
167
|
end
|
@@ -111,7 +174,7 @@ module Neography
|
|
111
174
|
if properties.nil?
|
112
175
|
delete("/relationship/#{get_id(id)}/properties")
|
113
176
|
else
|
114
|
-
properties.
|
177
|
+
Array(properties).each do |property|
|
115
178
|
delete("/relationship/#{get_id(id)}/properties/#{property}")
|
116
179
|
end
|
117
180
|
end
|
@@ -134,7 +197,7 @@ module Neography
|
|
134
197
|
if types.nil?
|
135
198
|
node_relationships = get("/node/#{get_id(id)}/relationships/#{dir}") || Array.new
|
136
199
|
else
|
137
|
-
node_relationships = get("/node/#{get_id(id)}/relationships/#{dir}/#{types.
|
200
|
+
node_relationships = get("/node/#{get_id(id)}/relationships/#{dir}/#{Array(types).join('&')}") || Array.new
|
138
201
|
end
|
139
202
|
return nil if node_relationships.empty?
|
140
203
|
node_relationships
|
@@ -235,6 +298,8 @@ module Neography
|
|
235
298
|
id["self"].split('/').last
|
236
299
|
when String
|
237
300
|
id.split('/').last
|
301
|
+
when Neography::Node, Neography::Relationship
|
302
|
+
id.neo_id
|
238
303
|
else
|
239
304
|
id
|
240
305
|
end
|
data/lib/neography/version.rb
CHANGED
data/lib/neography.rb
CHANGED
@@ -15,12 +15,28 @@ def find_and_require_user_defined_code
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
DIRECTIONS = ["incoming", "in", "outgoing", "out", "all", "both"]
|
19
|
+
|
18
20
|
|
19
21
|
require 'httparty'
|
20
22
|
require 'json'
|
21
23
|
require 'logger'
|
24
|
+
require 'ostruct'
|
22
25
|
|
26
|
+
require 'neography/config'
|
23
27
|
require 'neography/rest'
|
28
|
+
require 'neography/neography'
|
29
|
+
|
30
|
+
require 'neography/property_container'
|
31
|
+
require 'neography/property'
|
32
|
+
require 'neography/node_relationship'
|
33
|
+
require 'neography/relationship_traverser'
|
34
|
+
require 'neography/node_traverser'
|
35
|
+
require 'neography/equal'
|
36
|
+
|
37
|
+
|
38
|
+
require 'neography/node'
|
39
|
+
require 'neography/relationship'
|
24
40
|
|
25
41
|
find_and_require_user_defined_code
|
26
42
|
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Neography::Node do
|
4
|
+
|
5
|
+
describe "create and new" do
|
6
|
+
it "can create an empty node" do
|
7
|
+
new_node = Neography::Node.create
|
8
|
+
new_node.should_not be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it "can create a node with one property" do
|
12
|
+
new_node = Neography::Node.create("name" => "Max")
|
13
|
+
new_node.name.should == "Max"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can create a node with more than one property" do
|
17
|
+
new_node = Neography::Node.create("age" => 31, "name" => "Max")
|
18
|
+
new_node.name.should == "Max"
|
19
|
+
new_node.age.should == 31
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can create a node with more than one property not on the default rest server" do
|
23
|
+
@neo = Neography::Rest.new
|
24
|
+
new_node = Neography::Node.create({"age" => 31, "name" => "Max"}, @neo)
|
25
|
+
new_node.name.should == "Max"
|
26
|
+
new_node.age.should == 31
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can create a node with more than one property not on the default rest server the other way" do
|
30
|
+
@neo = Neography::Rest.new
|
31
|
+
new_node = Neography::Node.create(@neo, {"age" => 31, "name" => "Max"})
|
32
|
+
new_node.name.should == "Max"
|
33
|
+
new_node.age.should == 31
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
describe "load" do
|
39
|
+
it "can get a node that exists" do
|
40
|
+
new_node = Neography::Node.create
|
41
|
+
existing_node = Neography::Node.load(new_node)
|
42
|
+
existing_node.should_not be_nil
|
43
|
+
existing_node.neo_id.should_not be_nil
|
44
|
+
existing_node.neo_id.should == new_node.neo_id
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns nil if it tries to load a node that does not exist" do
|
48
|
+
new_node = Neography::Node.create
|
49
|
+
fake_node = new_node.neo_id.to_i + 1000
|
50
|
+
existing_node = Neography::Node.load(fake_node)
|
51
|
+
existing_node.should be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "can load a node that exists not on the default rest server" do
|
55
|
+
@neo = Neography::Rest.new
|
56
|
+
new_node = Neography::Node.create(@neo)
|
57
|
+
existing_node = Neography::Node.load(new_node, @neo)
|
58
|
+
existing_node.should_not be_nil
|
59
|
+
existing_node.neo_id.should_not be_nil
|
60
|
+
existing_node.neo_id.should == new_node.neo_id
|
61
|
+
end
|
62
|
+
|
63
|
+
it "can load a node that exists not on the default rest server the other way" do
|
64
|
+
@neo = Neography::Rest.new
|
65
|
+
new_node = Neography::Node.create(@neo)
|
66
|
+
existing_node = Neography::Node.load(@neo, new_node)
|
67
|
+
existing_node.should_not be_nil
|
68
|
+
existing_node.neo_id.should_not be_nil
|
69
|
+
existing_node.neo_id.should == new_node.neo_id
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "del" do
|
74
|
+
it "can delete itself" do
|
75
|
+
new_node = Neography::Node.create
|
76
|
+
node_id = new_node.neo_id
|
77
|
+
new_node.del
|
78
|
+
deleted_node = Neography::Node.load(node_id)
|
79
|
+
deleted_node.should be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "exists?" do
|
84
|
+
it "can tell if it exists" do
|
85
|
+
new_node = Neography::Node.create
|
86
|
+
new_node.exist?.should be_true
|
87
|
+
end
|
88
|
+
|
89
|
+
it "can tell if does not exists" do
|
90
|
+
new_node = Neography::Node.create
|
91
|
+
new_node.del
|
92
|
+
new_node.exist?.should be_false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "equality" do
|
97
|
+
it "can tell two nodes are the same with equal?" do
|
98
|
+
new_node = Neography::Node.create
|
99
|
+
another_node = Neography::Node.load(new_node)
|
100
|
+
new_node.equal?(another_node).should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
it "can tell two nodes are the same with eql?" do
|
104
|
+
new_node = Neography::Node.create
|
105
|
+
another_node = Neography::Node.load(new_node)
|
106
|
+
new_node.eql?(another_node).should be_true
|
107
|
+
end
|
108
|
+
|
109
|
+
it "can tell two nodes are the same with ==" do
|
110
|
+
new_node = Neography::Node.create
|
111
|
+
another_node = Neography::Node.load(new_node)
|
112
|
+
(new_node == another_node).should be_true
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "set properties" do
|
117
|
+
it "can change a node's properties that already exist using []=" do
|
118
|
+
new_node = Neography::Node.create("weight" => 150, "eyes" => "green")
|
119
|
+
|
120
|
+
new_node[:weight] = 200
|
121
|
+
new_node[:eyes] = "brown"
|
122
|
+
|
123
|
+
existing_node = Neography::Node.load(new_node)
|
124
|
+
existing_node.weight.should == 200
|
125
|
+
existing_node.eyes.should == "brown"
|
126
|
+
end
|
127
|
+
|
128
|
+
it "can change a node's properties that already exist" do
|
129
|
+
new_node = Neography::Node.create("weight" => 150, "eyes" => "green")
|
130
|
+
|
131
|
+
new_node.weight = 200
|
132
|
+
new_node.eyes = "brown"
|
133
|
+
|
134
|
+
existing_node = Neography::Node.load(new_node)
|
135
|
+
existing_node.weight.should == 200
|
136
|
+
existing_node.eyes.should == "brown"
|
137
|
+
end
|
138
|
+
|
139
|
+
it "can change a node's properties that does not already exist" do
|
140
|
+
new_node = Neography::Node.create("weight" => 150, "eyes" => "green")
|
141
|
+
|
142
|
+
new_node.weight = 200
|
143
|
+
new_node.eyes = "brown"
|
144
|
+
new_node[:hair] = "black"
|
145
|
+
|
146
|
+
existing_node = Neography::Node.load(new_node)
|
147
|
+
existing_node.weight.should == 200
|
148
|
+
existing_node.eyes.should == "brown"
|
149
|
+
existing_node.hair.should == "black"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "get node properties" do
|
154
|
+
it "can get node properties using []" do
|
155
|
+
new_node = Neography::Node.create("weight" => 150, "eyes" => "green")
|
156
|
+
new_node[:weight].should == 150
|
157
|
+
new_node[:eyes].should == "green"
|
158
|
+
end
|
159
|
+
|
160
|
+
it "can get node properties" do
|
161
|
+
new_node = Neography::Node.create("weight" => 150, "eyes" => "green")
|
162
|
+
new_node.weight.should == 150
|
163
|
+
new_node.eyes.should == "green"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "delete node properties" do
|
168
|
+
it "can delete node properties using []" do
|
169
|
+
new_node = Neography::Node.create("weight" => 150, "eyes" => "green")
|
170
|
+
|
171
|
+
new_node[:weight] = nil
|
172
|
+
new_node[:eyes] = nil
|
173
|
+
|
174
|
+
new_node[:weight].should be_nil
|
175
|
+
new_node[:eyes].should be_nil
|
176
|
+
|
177
|
+
existing_node = Neography::Node.load(new_node)
|
178
|
+
existing_node.weight.should be_nil
|
179
|
+
existing_node.eyes.should be_nil
|
180
|
+
end
|
181
|
+
|
182
|
+
it "can delete node properties" do
|
183
|
+
new_node = Neography::Node.create("weight" => 150, "eyes" => "green")
|
184
|
+
|
185
|
+
new_node.weight = nil
|
186
|
+
new_node.eyes = nil
|
187
|
+
|
188
|
+
new_node.weight.should be_nil
|
189
|
+
new_node.eyes.should be_nil
|
190
|
+
|
191
|
+
existing_node = Neography::Node.load(new_node)
|
192
|
+
existing_node.weight.should be_nil
|
193
|
+
existing_node.eyes.should be_nil
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Neography::Relationship do
|
4
|
+
describe "create relationship" do
|
5
|
+
it "#new(:family, p1, p2) creates a new relationship between to nodes of given type" do
|
6
|
+
p1 = Neography::Node.create
|
7
|
+
p2 = Neography::Node.create
|
8
|
+
|
9
|
+
new_rel = Neography::Relationship.create(:family, p1, p2)
|
10
|
+
puts new_rel.inspect
|
11
|
+
new_rel.start_node.should == p1
|
12
|
+
new_rel.end_node.should == p2
|
13
|
+
|
14
|
+
|
15
|
+
# p1.outgoing(:family).should include(p2)
|
16
|
+
# p2.incoming(:family).should include(p1)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#new(:family, p1, p2, :since => '1998', :colour => 'blue') creates relationship and sets its properties" do
|
20
|
+
p1 = Neography::Node.create
|
21
|
+
p2 = Neography::Node.create
|
22
|
+
|
23
|
+
rel = Neography::Relationship.create(:family, p1, p2, :since => 1998, :colour => 'blue')
|
24
|
+
rel[:since].should == 1998
|
25
|
+
rel[:colour].should == 'blue'
|
26
|
+
rel.since.should == 1998
|
27
|
+
rel.colourshould == 'blue'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "#outgoing(:friends).create(other) creates a new relationship between self and other node" do
|
31
|
+
p1 = Neography::Node.create
|
32
|
+
p2 = Neography::Node.create
|
33
|
+
|
34
|
+
rel = p1.outgoing(:foo).create(p2)
|
35
|
+
p1.outgoing(:foo).first.should == p2
|
36
|
+
rel.should be_kind_of(Neography::Relationship)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "rel?" do
|
41
|
+
it "#rel? returns true if there are any relationships" do
|
42
|
+
n1 = Neography::Node.create
|
43
|
+
n2 = Neography::Node.create
|
44
|
+
new_rel = Neography::Relationship.create(:foo, n1, n2)
|
45
|
+
n1.rel?.should be_true
|
46
|
+
n1.rel?(:bar).should be_false
|
47
|
+
n1.rel?(:foo).should be_true
|
48
|
+
n1.rel?(:incoming, :foo).should be_false
|
49
|
+
n1.rel?(:outgoing, :foo).should be_true
|
50
|
+
n1.rel?(:foo, :incoming).should be_false
|
51
|
+
n1.rel?(:foo, :outgoing).should be_true
|
52
|
+
|
53
|
+
n1.rel?(:incoming).should be_false
|
54
|
+
n1.rel?(:outgoing).should be_true
|
55
|
+
n1.rel?(:both).should be_true
|
56
|
+
n1.rel?(:all).should be_true
|
57
|
+
n1.rel?.should be_true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
describe "delete relationship" do
|
63
|
+
it "can delete an existing relationship" do
|
64
|
+
p1 = Neography::Node.create
|
65
|
+
p2 = Neography::Node.create
|
66
|
+
new_rel = Neography::Relationship.create(:family, p1, p2)
|
67
|
+
new_rel.del
|
68
|
+
Neography::Relationship.load(new_rel).should be_nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Neography::Rest do
|
4
|
+
before(:each) do
|
5
|
+
@neo = Neography::Rest.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "can create many nodes threaded" do
|
9
|
+
it "can create empty nodes threaded" do
|
10
|
+
new_nodes = @neo.create_nodes_threaded(2)
|
11
|
+
new_nodes.should_not be_nil
|
12
|
+
new_nodes.size.should == 2
|
13
|
+
end
|
14
|
+
|
15
|
+
it "is faster than non-threaded?" do
|
16
|
+
Benchmark.bm do |x|
|
17
|
+
x.report("create 500 nodes ") { @not_threaded = @neo.create_nodes(500) }
|
18
|
+
x.report("create 500 nodes threaded") { @threaded = @neo.create_nodes_threaded(500) }
|
19
|
+
x.report("create 1000 nodes threaded") { @threaded2c = @neo.create_nodes_threaded(1000) }
|
20
|
+
end
|
21
|
+
|
22
|
+
@not_threaded[99].should_not be_nil
|
23
|
+
@threaded[99].should_not be_nil
|
24
|
+
@threaded2c[199].should_not be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "can create many nodes" do
|
30
|
+
it "can create empty nodes" do
|
31
|
+
new_nodes = @neo.create_nodes(2)
|
32
|
+
new_nodes.should_not be_nil
|
33
|
+
new_nodes.size.should == 2
|
34
|
+
end
|
35
|
+
|
36
|
+
it "can create nodes with one property" do
|
37
|
+
new_nodes = @neo.create_nodes([{"name" => "Max"}, {"name" => "Alex"}])
|
38
|
+
new_nodes[0]["data"]["name"].should == "Max"
|
39
|
+
new_nodes[1]["data"]["name"].should == "Alex"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "can create nodes with one property that are different" do
|
43
|
+
new_nodes = @neo.create_nodes([{"name" => "Max"}, {"age" => 24}])
|
44
|
+
new_nodes[0]["data"]["name"].should == "Max"
|
45
|
+
new_nodes[1]["data"]["age"].should == 24
|
46
|
+
end
|
47
|
+
|
48
|
+
it "can create nodes with more than one property" do
|
49
|
+
new_nodes = @neo.create_nodes([{"age" => 31, "name" => "Max"}, {"age" => 24, "name" => "Alex"}])
|
50
|
+
new_nodes[0]["data"]["name"].should == "Max"
|
51
|
+
new_nodes[0]["data"]["age"].should == 31
|
52
|
+
new_nodes[1]["data"]["name"].should == "Alex"
|
53
|
+
new_nodes[1]["data"]["age"].should == 24
|
54
|
+
end
|
55
|
+
|
56
|
+
it "can create nodes with more than one property that are different" do
|
57
|
+
new_nodes = @neo.create_nodes([{"age" => 31, "name" => "Max"}, {"height" => "5-11", "weight" => 215}])
|
58
|
+
new_nodes[0]["data"]["name"].should == "Max"
|
59
|
+
new_nodes[0]["data"]["age"].should == 31
|
60
|
+
new_nodes[1]["data"]["height"].should == "5-11"
|
61
|
+
new_nodes[1]["data"]["weight"].should == 215
|
62
|
+
end
|
63
|
+
|
64
|
+
it "is not super slow?" do
|
65
|
+
Benchmark.bm do |x|
|
66
|
+
x.report( "create 1 node" ) { @neo.create_nodes( 1) }
|
67
|
+
x.report( "create 10 nodes") { @neo.create_nodes( 10) }
|
68
|
+
x.report("create 100 nodes") { @neo.create_nodes(100) }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "can get many nodes" do
|
74
|
+
it "can get 2 nodes passed in as an array" do
|
75
|
+
new_nodes = @neo.create_nodes(2)
|
76
|
+
existing_nodes = @neo.get_nodes(new_nodes)
|
77
|
+
existing_nodes.should_not be_nil
|
78
|
+
existing_nodes.size.should == 2
|
79
|
+
end
|
80
|
+
|
81
|
+
it "can get 2 nodes passed in by commas" do
|
82
|
+
new_nodes = @neo.create_nodes(2)
|
83
|
+
new_node1 = new_nodes[0]["self"].split('/').last
|
84
|
+
new_node2 = new_nodes[1]["self"].split('/').last
|
85
|
+
existing_nodes = @neo.get_nodes(new_node1, new_node2)
|
86
|
+
existing_nodes.should_not be_nil
|
87
|
+
existing_nodes.size.should == 2
|
88
|
+
existing_nodes[0]["self"] == new_node1["self"]
|
89
|
+
existing_nodes[1]["self"] == new_node2["self"]
|
90
|
+
end
|
91
|
+
|
92
|
+
it "is not super slow?" do
|
93
|
+
one_node = @neo.create_nodes( 1)
|
94
|
+
ten_nodes = @neo.create_nodes( 10)
|
95
|
+
one_hundred_nodes = @neo.create_nodes(100)
|
96
|
+
|
97
|
+
Benchmark.bm do |x|
|
98
|
+
x.report( "get 1 node ") { @neo.get_nodes(one_node) }
|
99
|
+
x.report( "get 10 nodes") { @neo.get_nodes(ten_nodes) }
|
100
|
+
x.report("get 100 nodes") { @neo.get_nodes(one_hundred_nodes) }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Neography::Rest do
|
4
|
+
before(:each) do
|
5
|
+
@neo = Neography::Rest.new
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
describe "get_nodes" do
|
10
|
+
it "can get nodes that exists" do
|
11
|
+
existing_nodes = @neo.get_nodes
|
12
|
+
existing_nodes.should_not be_nil
|
13
|
+
puts existing_nodes.inspect
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can get all nodes that exists the ugly way" do
|
17
|
+
new_node = @neo.create_node
|
18
|
+
last_node_id = new_node["self"].split('/').last.to_i
|
19
|
+
existing_nodes = @neo.get_nodes((1..last_node_id).to_a)
|
20
|
+
existing_nodes.should_not be_nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 5
|
9
|
+
version: 0.0.5
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Max De Marzi
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-12-08 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -112,9 +112,24 @@ files:
|
|
112
112
|
- examples/linkedin.rb
|
113
113
|
- examples/traversal_example1.rb
|
114
114
|
- lib/neography.rb
|
115
|
+
- lib/neography/config.rb
|
116
|
+
- lib/neography/equal.rb
|
117
|
+
- lib/neography/neography.rb
|
118
|
+
- lib/neography/node.rb
|
119
|
+
- lib/neography/node_relationship.rb
|
120
|
+
- lib/neography/node_traverser.rb
|
121
|
+
- lib/neography/property.rb
|
122
|
+
- lib/neography/property_container.rb
|
123
|
+
- lib/neography/relationship.rb
|
124
|
+
- lib/neography/relationship_traverser.rb
|
115
125
|
- lib/neography/rest.rb
|
116
126
|
- lib/neography/version.rb
|
117
127
|
- neography.gemspec
|
128
|
+
- spec/integration/neography_spec.rb
|
129
|
+
- spec/integration/node_spec.rb
|
130
|
+
- spec/integration/relationship_spec.rb
|
131
|
+
- spec/integration/rest_bulk_spec.rb
|
132
|
+
- spec/integration/rest_experimental_spec.rb
|
118
133
|
- spec/integration/rest_index_spec.rb
|
119
134
|
- spec/integration/rest_node_spec.rb
|
120
135
|
- spec/integration/rest_path_spec.rb
|