redgraph 0.2.0 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +76 -43
- data/lib/redgraph.rb +5 -0
- data/lib/redgraph/graph.rb +1 -0
- data/lib/redgraph/graph/node_methods.rb +19 -0
- data/lib/redgraph/node_model.rb +11 -35
- data/lib/redgraph/node_model/class_methods.rb +9 -2
- data/lib/redgraph/node_model/graph_manipulation.rb +24 -0
- data/lib/redgraph/node_model/persistence.rb +56 -0
- data/lib/redgraph/query_response.rb +12 -3
- data/lib/redgraph/version.rb +1 -1
- data/test/node_model_class_methods_test.rb +27 -0
- data/test/node_model_persistence_test.rb +70 -0
- data/test/node_model_test.rb +10 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fd53776ff217146cd6ca4924da40a43f5bf929fad03b73b79f32d371ea955e8
|
4
|
+
data.tar.gz: 551afc973f8e732ad532e74395e6c73251f14d68db73f667a207b234bd64163b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd7f88ae09acb7f09b6c8de949d4f31bbc52b12e4b914f035de99c7cd9b409c14eac3e592f834cc968517b796fed0cf3a085f7eba4915e630b2e66c424ae9870
|
7
|
+
data.tar.gz: 979aac39193d3150441ddf5baca14772a35c6cfd00f09df42752277aed3d955869822b2d97150209f1e71ad5ab95e566dc645d15d3e8262675dd858bd6fbb1dd
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Redgraph
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/redgraph)
|
4
|
+
[](https://codeclimate.com/github/pzac/redgraph)
|
5
|
+
|
3
6
|
A simple RedisGraph library. This gem owes **a lot** to the existing [redisgraph-rb](https://github.com/RedisGraph/redisgraph-rb) gem, but tries to provide a friendlier interface, similar to the existing [Python](https://github.com/RedisGraph/redisgraph-py) and [Elixir](https://github.com/crflynn/redisgraph-ex) clients.
|
4
7
|
|
5
8
|
## Installation
|
@@ -24,92 +27,122 @@ The gem assumes you have a recent version of [RedisGraph](https://oss.redislabs.
|
|
24
27
|
|
25
28
|
Basic usage:
|
26
29
|
|
27
|
-
|
28
|
-
|
30
|
+
```ruby
|
31
|
+
graph = Redgraph::Graph.new('movies', url: "redis://localhost:6379/1")
|
32
|
+
=> #<Redgraph::Graph:0x00007f8d5c2b7e38 @connection=#<Redis client v4.2.5 for redis://localhost:6379/1>, @graph_name="movies", @module_version=999999>
|
33
|
+
```
|
29
34
|
|
30
35
|
Create a couple nodes:
|
31
36
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
```ruby
|
38
|
+
actor = Redgraph::Node.new(label: 'actor', properties: {name: "Al Pacino"})
|
39
|
+
=> #<Redgraph::Node:0x00007f8d5f95cf88 @label="actor", @properties={:name=>"Al Pacino"}>
|
40
|
+
graph.add_node(actor)
|
41
|
+
=> #<Redgraph::Node:0x00007f8d5f95cf88 @id=0, @label="actor", @properties={:name=>"Al Pacino"}>
|
42
|
+
film = Redgraph::Node.new(label: 'film', properties: {name: "Scarface"})
|
43
|
+
=> #<Redgraph::Node:0x00007f8d5f85ccc8 @label="film", @properties={:name=>"Scarface"}>
|
44
|
+
graph.add_node(film)
|
45
|
+
=> #<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>
|
46
|
+
```
|
40
47
|
|
41
48
|
Create an edge between those nodes:
|
42
49
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
50
|
+
```ruby
|
51
|
+
edge = Redgraph::Edge.new(src: actor, dest: film, type: 'ACTOR_IN', properties: {role: "Tony Montana"})
|
52
|
+
=> #<Redgraph::Edge:0x00007f8d5f9ae3d8 @dest=#<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>, @dest_id=1, @properties={:role=>"Tony Montana"}, @src=#<Redgraph::Node:0x00007f8d5f95cf88 @id=0, @label="actor", @properties={:name=>"Al Pacino"}>, @src_id=0, @type="ACTOR_IN">
|
53
|
+
@graph.add_edge(edge)
|
54
|
+
=> #<Redgraph::Edge:0x00007f8d5f9ae3d8 @dest=#<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>, @dest_id=1, @id=0, @properties={:role=>"Tony Montana"}, @src=#<Redgraph::Node:0x00007f8d5f95cf88 @id=0, @label="actor", @properties={:name=>"Al Pacino"}>, @src_id=0, @type="ACTOR_IN">
|
55
|
+
```
|
47
56
|
|
48
57
|
You can merge nodes - the node will be created only if there isn't another with the same label and properties:
|
49
58
|
|
50
|
-
|
51
|
-
|
59
|
+
```ruby
|
60
|
+
graph.merge_node(film)
|
61
|
+
=> #<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>
|
62
|
+
```
|
52
63
|
|
53
64
|
Same with edges:
|
54
65
|
|
55
|
-
|
56
|
-
|
66
|
+
```ruby
|
67
|
+
@graph.merge_edge(edge)
|
68
|
+
=> #<Redgraph::Edge:0x00007f8d5f9ae3d8 @dest=#<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>, @dest_id=1, @id=0, @properties={:role=>"Tony Montana"}, @src=#<Redgraph::Node:0x00007f8d5f95cf88 @id=0, @label="actor", @properties={:name=>"Al Pacino"}>, @src_id=0, @type="ACTOR_IN">
|
69
|
+
```
|
57
70
|
|
58
71
|
Find a node by id:
|
59
72
|
|
60
|
-
|
61
|
-
|
73
|
+
```ruby
|
74
|
+
@graph.find_node_by_id(1)
|
75
|
+
=> #<Redgraph::Node:0x00007f8d5c2c6e88 @id=1, @label="film", @properties={"name"=>"Scarface"}>
|
76
|
+
```
|
62
77
|
|
63
78
|
To get all nodes:
|
64
79
|
|
65
|
-
|
66
|
-
|
80
|
+
```ruby
|
81
|
+
@graph.nodes
|
82
|
+
=> [#<Redgraph::Node:0x00007f8d5c2ee0a0 @id=0, @label="actor", @properties={"name"=>"Al Pacino"}>, #<Redgraph::Node:0x00007f8d5c2edfd8 @id=1, @label="film", @properties={"name"=>"Scarface"}>]
|
83
|
+
```
|
67
84
|
|
68
85
|
Optional filters that can be combined:
|
69
86
|
|
70
|
-
|
71
|
-
|
72
|
-
|
87
|
+
```ruby
|
88
|
+
@graph.nodes(label: 'actor')
|
89
|
+
@graph.nodes(properties: {name: "Al Pacino"})
|
90
|
+
@graph.nodes(limit: 10, skip: 20)
|
91
|
+
```
|
73
92
|
|
74
93
|
Counting nodes
|
75
94
|
|
76
|
-
|
77
|
-
|
95
|
+
```ruby
|
96
|
+
@graph.count_nodes(label: 'actor')
|
97
|
+
=> 1
|
98
|
+
```
|
78
99
|
|
79
100
|
Getting edges:
|
80
101
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
102
|
+
```ruby
|
103
|
+
@graph.edges
|
104
|
+
@graph.edges(src: actor, dest: film)
|
105
|
+
@graph.edges(kind: 'FRIEND_OF', limit: 10, skip: 20)
|
106
|
+
@graph.count_edges
|
107
|
+
```
|
85
108
|
|
86
109
|
Running custom queries
|
87
110
|
|
88
|
-
|
111
|
+
```ruby
|
112
|
+
@graph.query("MATCH (src)-[edge:FRIEND_OF]->(dest) RETURN src, edge")
|
113
|
+
```
|
89
114
|
|
90
115
|
### NodeModel
|
91
116
|
|
92
117
|
You can use the `NodeModel` mixin for a limited ActiveRecord-like interface:
|
93
118
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
119
|
+
```ruby
|
120
|
+
class Actor
|
121
|
+
include Redgraph::NodeModel
|
122
|
+
self.graph = Redgraph::Graph.new("movies", url: $REDIS_URL)
|
123
|
+
attribute :name
|
124
|
+
end
|
125
|
+
```
|
99
126
|
|
100
127
|
And this will give you stuff such as
|
101
128
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
129
|
+
```ruby
|
130
|
+
Actor.count
|
131
|
+
john = Actor.new(name: "John Travolta")
|
132
|
+
john.add_to_graph # Will add the node to the graph
|
133
|
+
john.add_relation(type: "ACTED_IN", node: film, properties: {role: "Tony Manero"})
|
134
|
+
john.reload
|
135
|
+
john.destroy
|
136
|
+
Actor.create(name: "Al Pacino")
|
137
|
+
```
|
106
138
|
|
107
139
|
`NodeModel` models will automatically set a `_type` property to keep track of the object class.
|
108
140
|
|
109
141
|
You will then be able to run custom queries such as:
|
110
142
|
|
111
|
-
|
112
|
-
|
143
|
+
```ruby
|
144
|
+
Actor.query("MATCH (node) RETURN node ORDER BY node.name")
|
145
|
+
```
|
113
146
|
And the result rows object will be instances of the classes defined by the `_type` attribute.
|
114
147
|
|
115
148
|
## Development
|
data/lib/redgraph.rb
CHANGED
data/lib/redgraph/graph.rb
CHANGED
@@ -73,6 +73,24 @@ module Redgraph
|
|
73
73
|
query(cmd).flatten[0] || 0
|
74
74
|
end
|
75
75
|
|
76
|
+
def update_node(node)
|
77
|
+
return false unless node.persisted?
|
78
|
+
_set = node.properties.map do |(key, val)|
|
79
|
+
"node.#{key} = #{escape_value(val)}"
|
80
|
+
end.join(", ")
|
81
|
+
|
82
|
+
cmd = "MATCH (node) WHERE ID(node) = #{node.id} SET #{_set} RETURN node"
|
83
|
+
result = _query(cmd)
|
84
|
+
node_from_resultset_item(result.resultset.first["node"])
|
85
|
+
end
|
86
|
+
|
87
|
+
def destroy_node(node)
|
88
|
+
return false unless node.persisted?
|
89
|
+
cmd = "MATCH (node) WHERE ID(node) = #{node.id} DELETE node"
|
90
|
+
result = _query(cmd)
|
91
|
+
result.stats["nodes_deleted"] == 1
|
92
|
+
end
|
93
|
+
|
76
94
|
private
|
77
95
|
|
78
96
|
# Builds a Node object from the raw data
|
@@ -99,6 +117,7 @@ module Redgraph
|
|
99
117
|
node
|
100
118
|
end
|
101
119
|
|
120
|
+
|
102
121
|
end
|
103
122
|
end
|
104
123
|
end
|
data/lib/redgraph/node_model.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require_relative 'node_model/class_methods'
|
3
|
+
require_relative 'node_model/graph_manipulation'
|
4
|
+
require_relative 'node_model/persistence'
|
3
5
|
|
4
6
|
module Redgraph
|
5
7
|
# This mixin allows you to use an interface similar to ActiveRecord
|
@@ -24,10 +26,12 @@ module Redgraph
|
|
24
26
|
extend ActiveSupport::Concern
|
25
27
|
|
26
28
|
included do |base|
|
29
|
+
include Persistence
|
30
|
+
include GraphManipulation
|
31
|
+
|
27
32
|
@attribute_names = [:id]
|
28
33
|
|
29
|
-
attr_accessor :id
|
30
|
-
attr_accessor :_type
|
34
|
+
attr_accessor :id, :_type
|
31
35
|
|
32
36
|
class << self
|
33
37
|
attr_reader :attribute_names
|
@@ -35,7 +39,7 @@ module Redgraph
|
|
35
39
|
|
36
40
|
def attribute(name)
|
37
41
|
@attribute_names << name
|
38
|
-
|
42
|
+
attr_accessor(name)
|
39
43
|
end
|
40
44
|
|
41
45
|
private
|
@@ -76,32 +80,10 @@ module Redgraph
|
|
76
80
|
self.class.attribute_names.to_h { |name| [name, public_send(name)] }
|
77
81
|
end
|
78
82
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
# Adds the node to the graph
|
84
|
-
#
|
85
|
-
# - allow_duplicates: if false it will create a node with the same type and properties only if
|
86
|
-
# not present
|
87
|
-
#
|
88
|
-
def add_to_graph(allow_duplicates: true)
|
89
|
-
item = allow_duplicates ? graph.add_node(to_node) : graph.merge_node(to_node)
|
90
|
-
self.id = item.id
|
91
|
-
self
|
92
|
-
end
|
93
|
-
|
94
|
-
# Adds a relation between the node and another node.
|
95
|
-
#
|
96
|
-
# - type: type of relation
|
97
|
-
# - node: the destination node
|
98
|
-
# - properties: optional properties hash
|
99
|
-
# - allow_duplicates: if false it will create a relation between two nodes with the same type
|
100
|
-
# and properties only if not present
|
101
|
-
#
|
102
|
-
def add_relation(type:, node:, properties: nil, allow_duplicates: true)
|
103
|
-
edge = Edge.new(type: type, src: to_node, dest: node.to_node, properties: properties)
|
104
|
-
allow_duplicates ? graph.add_edge(edge) : graph.merge_edge(edge)
|
83
|
+
def assign_attributes(attrs = {})
|
84
|
+
attrs.each do |name, value|
|
85
|
+
instance_variable_set("@#{name}", value)
|
86
|
+
end
|
105
87
|
end
|
106
88
|
|
107
89
|
def to_node
|
@@ -109,12 +91,6 @@ module Redgraph
|
|
109
91
|
Redgraph::Node.new(id: id, label: label, properties: props)
|
110
92
|
end
|
111
93
|
|
112
|
-
# Converts a Node object into NodeModel
|
113
|
-
#
|
114
|
-
def reify_from_node(node)
|
115
|
-
self.class.reify_from_node(node)
|
116
|
-
end
|
117
|
-
|
118
94
|
def ==(other)
|
119
95
|
attributes == other.attributes && id == other.id
|
120
96
|
end
|
@@ -3,12 +3,13 @@ module Redgraph
|
|
3
3
|
module ClassMethods
|
4
4
|
# Returns an array of nodes. Options:
|
5
5
|
#
|
6
|
+
# - label: filter by label
|
6
7
|
# - properties: filter by properties
|
7
8
|
# - order: node.name ASC, node.year DESC
|
8
9
|
# - limit: number of items
|
9
10
|
# - skip: items offset (useful for pagination)
|
10
11
|
#
|
11
|
-
def all(properties: {}, limit: nil, skip: nil, order: nil)
|
12
|
+
def all(label: nil, properties: {}, limit: nil, skip: nil, order: nil)
|
12
13
|
graph.nodes(label: label, properties: properties_plus_type(properties),
|
13
14
|
limit: limit, skip: skip, order: nil).map do |node|
|
14
15
|
reify_from_node(node)
|
@@ -19,7 +20,7 @@ module Redgraph
|
|
19
20
|
#
|
20
21
|
# - properties: filter by properties
|
21
22
|
#
|
22
|
-
def count(properties: nil)
|
23
|
+
def count(label: nil, properties: nil)
|
23
24
|
graph.count_nodes(label: label, properties: properties_plus_type(properties))
|
24
25
|
end
|
25
26
|
|
@@ -55,6 +56,8 @@ module Redgraph
|
|
55
56
|
# Returns an array of rows.
|
56
57
|
#
|
57
58
|
def query(cmd)
|
59
|
+
raise MissingGraphError unless graph
|
60
|
+
|
58
61
|
graph.query(cmd).map do |row|
|
59
62
|
row.map do |item|
|
60
63
|
item.is_a?(Node) ? reify_from_node(item) : item
|
@@ -62,6 +65,10 @@ module Redgraph
|
|
62
65
|
end
|
63
66
|
end
|
64
67
|
|
68
|
+
def create(properties)
|
69
|
+
new(**properties).add_to_graph
|
70
|
+
end
|
71
|
+
|
65
72
|
private
|
66
73
|
|
67
74
|
def default_label
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Redgraph
|
2
|
+
module NodeModel
|
3
|
+
module GraphManipulation
|
4
|
+
# Adds a relation between the node and another node.
|
5
|
+
#
|
6
|
+
# - type: type of relation
|
7
|
+
# - node: the destination node
|
8
|
+
# - properties: optional properties hash
|
9
|
+
# - allow_duplicates: if false it will create a relation between two nodes with the same type
|
10
|
+
# and properties only if not present
|
11
|
+
#
|
12
|
+
def add_relation(type:, node:, properties: nil, allow_duplicates: true)
|
13
|
+
edge = Edge.new(type: type, src: to_node, dest: node.to_node, properties: properties)
|
14
|
+
allow_duplicates ? graph.add_edge(edge) : graph.merge_edge(edge)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Runs a custom query on the graph
|
18
|
+
#
|
19
|
+
def query(cmd)
|
20
|
+
self.class.query(cmd)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Redgraph
|
2
|
+
module NodeModel
|
3
|
+
module Persistence
|
4
|
+
# Adds the node to the graph
|
5
|
+
#
|
6
|
+
# - allow_duplicates: if false it will create a node with the same type and properties only if
|
7
|
+
# not present
|
8
|
+
#
|
9
|
+
def add_to_graph(allow_duplicates: true)
|
10
|
+
raise MissingGraphError unless graph
|
11
|
+
item = allow_duplicates ? graph.add_node(to_node) : graph.merge_node(to_node)
|
12
|
+
self.id = item.id
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
# Creates a new record or updates the existing
|
17
|
+
#
|
18
|
+
def save
|
19
|
+
if persisted?
|
20
|
+
item = graph.update_node(to_node)
|
21
|
+
self.class.reify_from_node(item)
|
22
|
+
else
|
23
|
+
add_to_graph
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def persisted?
|
28
|
+
id.present?
|
29
|
+
end
|
30
|
+
|
31
|
+
def reload
|
32
|
+
item = self.class.find(id)
|
33
|
+
@label = item.label
|
34
|
+
assign_attributes(item.attributes)
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
# Deletes the record from the graph
|
39
|
+
#
|
40
|
+
def destroy
|
41
|
+
@destroyed = true
|
42
|
+
if graph.destroy_node(self)
|
43
|
+
self
|
44
|
+
else
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns true if this object has been destroyed, otherwise returns false.
|
50
|
+
#
|
51
|
+
def destroyed?
|
52
|
+
!!@destroyed
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -29,9 +29,16 @@ module Redgraph
|
|
29
29
|
@response = response
|
30
30
|
@graph = graph
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
case @response.size
|
33
|
+
when 3
|
34
|
+
@header_row = @response[0]
|
35
|
+
@result_rows = @response[1]
|
36
|
+
@query_statistics = @response[2]
|
37
|
+
when 1 # queries with no RETURN clause
|
38
|
+
@header_row = []
|
39
|
+
@result_rows = []
|
40
|
+
@query_statistics = @response[0]
|
41
|
+
end
|
35
42
|
end
|
36
43
|
|
37
44
|
def stats
|
@@ -121,6 +128,8 @@ module Redgraph
|
|
121
128
|
case label
|
122
129
|
when /^Nodes created/
|
123
130
|
stats[:nodes_created] = value.to_i
|
131
|
+
when /^Nodes deleted/
|
132
|
+
stats[:nodes_deleted] = value.to_i
|
124
133
|
when /^Relationships created/
|
125
134
|
stats[:relationships_created] = value.to_i
|
126
135
|
when /^Properties set/
|
data/lib/redgraph/version.rb
CHANGED
@@ -24,6 +24,11 @@ class NodeModelClassMethodsTest < Minitest::Test
|
|
24
24
|
attribute :name
|
25
25
|
end
|
26
26
|
|
27
|
+
class MissingGraphActor
|
28
|
+
include Redgraph::NodeModel
|
29
|
+
attribute :name
|
30
|
+
end
|
31
|
+
|
27
32
|
# tests
|
28
33
|
#
|
29
34
|
|
@@ -63,4 +68,26 @@ class NodeModelClassMethodsTest < Minitest::Test
|
|
63
68
|
item = Actor.find("-1")
|
64
69
|
assert_nil(item)
|
65
70
|
end
|
71
|
+
|
72
|
+
def test_create
|
73
|
+
assert_equal(0, Actor.count)
|
74
|
+
|
75
|
+
actor = Actor.create(name: "Harrison Ford")
|
76
|
+
|
77
|
+
assert_equal(1, Actor.count)
|
78
|
+
assert_predicate(actor, :persisted?)
|
79
|
+
assert_equal("Harrison Ford", actor.name)
|
80
|
+
assert_equal("actor", actor.label)
|
81
|
+
|
82
|
+
found = Actor.find(actor.id)
|
83
|
+
assert_equal("Harrison Ford", found.name)
|
84
|
+
assert_equal("actor", found.label)
|
85
|
+
assert_equal(Actor.name, found._type)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_create_with_missing_graph
|
89
|
+
assert_raises(Redgraph::MissingGraphError) do
|
90
|
+
MissingGraphActor.create(name: "Harrison Ford")
|
91
|
+
end
|
92
|
+
end
|
66
93
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class NodeModelPersistenceTest < Minitest::Test
|
6
|
+
include TestHelpers
|
7
|
+
|
8
|
+
GRAPH = Redgraph::Graph.new("movies", url: $REDIS_URL)
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@graph = GRAPH
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
@graph.delete
|
16
|
+
end
|
17
|
+
|
18
|
+
# test classes
|
19
|
+
#
|
20
|
+
|
21
|
+
class Film
|
22
|
+
include Redgraph::NodeModel
|
23
|
+
self.graph = GRAPH
|
24
|
+
attribute :name
|
25
|
+
end
|
26
|
+
|
27
|
+
# tests
|
28
|
+
#
|
29
|
+
|
30
|
+
def test_save_new
|
31
|
+
assert_equal(0, Film.count)
|
32
|
+
|
33
|
+
film = Film.new(name: "Star Wars")
|
34
|
+
film.save
|
35
|
+
|
36
|
+
assert_predicate(film, :persisted?)
|
37
|
+
assert_equal(1, Film.count)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_save_existing
|
41
|
+
film = Film.create(name: "Star Wars")
|
42
|
+
film.name = "Commando"
|
43
|
+
film.save
|
44
|
+
|
45
|
+
assert_equal(1, Film.count)
|
46
|
+
item = Film.find(film.id)
|
47
|
+
assert_equal("Commando", item.name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_reload
|
51
|
+
film = Film.create(name: "Star Wars")
|
52
|
+
copy = Film.find(film.id)
|
53
|
+
|
54
|
+
assert_equal("Star Wars", copy.name)
|
55
|
+
|
56
|
+
film.name = "Commando"
|
57
|
+
film.save
|
58
|
+
|
59
|
+
assert_equal("Star Wars", copy.name)
|
60
|
+
assert_equal("Commando", copy.reload.name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_destroy
|
64
|
+
film = Film.create(name: "Star Wars")
|
65
|
+
assert_equal(1, Film.count)
|
66
|
+
film.destroy
|
67
|
+
assert_predicate(film, :destroyed?)
|
68
|
+
assert_equal(0, Film.count)
|
69
|
+
end
|
70
|
+
end
|
data/test/node_model_test.rb
CHANGED
@@ -123,4 +123,14 @@ class NodeModelTest < Minitest::Test
|
|
123
123
|
assert_kind_of(Film, items[1][0])
|
124
124
|
end
|
125
125
|
|
126
|
+
def test_casting_query_from_model
|
127
|
+
film = Film.create(name: "Star Wars", year: 1977)
|
128
|
+
Actor.create(name: "Harrison Ford")
|
129
|
+
|
130
|
+
items = film.query("MATCH (node) RETURN node ORDER BY node.name")
|
131
|
+
assert_equal(2, items.size)
|
132
|
+
assert_kind_of(Actor, items[0][0])
|
133
|
+
assert_kind_of(Film, items[1][0])
|
134
|
+
end
|
135
|
+
|
126
136
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redgraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paolo Zaccagnini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -63,6 +63,8 @@ files:
|
|
63
63
|
- lib/redgraph/node.rb
|
64
64
|
- lib/redgraph/node_model.rb
|
65
65
|
- lib/redgraph/node_model/class_methods.rb
|
66
|
+
- lib/redgraph/node_model/graph_manipulation.rb
|
67
|
+
- lib/redgraph/node_model/persistence.rb
|
66
68
|
- lib/redgraph/query_response.rb
|
67
69
|
- lib/redgraph/util.rb
|
68
70
|
- lib/redgraph/version.rb
|
@@ -75,6 +77,7 @@ files:
|
|
75
77
|
- test/graph_test.rb
|
76
78
|
- test/node_model_class_methods_test.rb
|
77
79
|
- test/node_model_labels_test.rb
|
80
|
+
- test/node_model_persistence_test.rb
|
78
81
|
- test/node_model_test.rb
|
79
82
|
- test/redgraph_test.rb
|
80
83
|
- test/test_helper.rb
|