Skip to content

Commit d368e34

Browse files
authored
Merge pull request #20 from RedisGraph/path_type
added path support
2 parents 1b74aa6 + 10be6f2 commit d368e34

File tree

5 files changed

+153
-2
lines changed

5 files changed

+153
-2
lines changed

.circleci/config.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
# Golang CircleCI 2.0 configuration file
22
#
33
# Check https://circleci.com/docs/2.0/language-go/ for more details
4-
version: 2
4+
version: 2.1
5+
commands:
6+
early_return_for_forked_pull_requests:
7+
description: >-
8+
If this build is from a fork, stop executing the current job and return success.
9+
This is useful to avoid steps that will fail due to missing credentials.
10+
steps:
11+
- run:
12+
name: Early return if this build is from a forked PR
13+
command: |
14+
if [ -n "$CIRCLE_PR_NUMBER" ]; then
15+
echo "Nothing to do for forked PRs, so marking this step successful"
16+
circleci step halt
17+
fi
518
jobs:
619
build:
720
docker:
821
- image: circleci/golang:1.9
922

1023
- image: redislabs/redisgraph:edge
11-
port: 6379:6379
1224

1325
working_directory: /go/src/github.com/RedisGraph/redisgraph-go
1426
steps:
1527
- checkout
1628
- run: go get -v -t -d ./...
1729
- run: go test -v ./... -race -coverprofile=coverage.txt -covermode=atomic
30+
- early_return_for_forked_pull_requests
1831
- run: bash <(curl -s https://codecov.io/bash) -t ${CODECOV_TOKEN}
1932

2033
workflows:

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ func main() {
8686
p_age, _ := r.Get("p.age")
8787
fmt.Printf("\nAge: %d\n", p_age)
8888
}
89+
90+
// Path matching example.
91+
query = "MATCH p = (:Person)-[:Visited]->(:Country) RETURN p"
92+
result, _ = graph.Query(query)
93+
res.Next()
94+
r := res.Record()
95+
p, ok := r.GetByIndex(0).(Path)
96+
fmt.Printf("%s", p)
8997
}
9098
```
9199

client_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,44 @@ func TestArray(t *testing.T) {
215215
assert.Equal(t, b.GetProperty("age"), resB.GetProperty("age"), "Unexpected property value.")
216216
assert.Equal(t, b.GetProperty("array"), resB.GetProperty("array"), "Unexpected property value.")
217217
}
218+
219+
func TestPath(t *testing.T) {
220+
createGraph()
221+
q := "MATCH p = (:Person)-[:Visited]->(:Country) RETURN p"
222+
res, err := graph.Query(q)
223+
if err != nil {
224+
t.Error(err)
225+
}
226+
227+
assert.Equal(t, len(res.results), 1, "expecting 1 result record")
228+
229+
res.Next()
230+
r := res.Record()
231+
232+
p, ok := r.GetByIndex(0).(Path)
233+
assert.True(t, ok, "First column should contain path.")
234+
235+
assert.Equal(t, 2, p.NodesCount(), "Path should contain two nodes")
236+
assert.Equal(t, 1, p.EdgeCount(), "Path should contain one edge")
237+
238+
s := p.FirstNode()
239+
e := p.GetEdge(0)
240+
d := p.LastNode()
241+
242+
assert.Equal(t, s.Label, "Person", "Node should be of type 'Person'")
243+
assert.Equal(t, e.Relation, "Visited", "Edge should be of relation type 'Visited'")
244+
assert.Equal(t, d.Label, "Country", "Node should be of type 'Country'")
245+
246+
assert.Equal(t, len(s.Properties), 4, "Person node should have 4 properties")
247+
248+
assert.Equal(t, s.GetProperty("name"), "John Doe", "Unexpected property value.")
249+
assert.Equal(t, s.GetProperty("age"), 33, "Unexpected property value.")
250+
assert.Equal(t, s.GetProperty("gender"), "male", "Unexpected property value.")
251+
assert.Equal(t, s.GetProperty("status"), "single", "Unexpected property value.")
252+
253+
assert.Equal(t, e.GetProperty("year"), 2017, "Unexpected property value.")
254+
255+
assert.Equal(t, d.GetProperty("name"), "Japan", "Unexpected property value.")
256+
assert.Equal(t, d.GetProperty("population"), 126800000, "Unexpected property value.")
257+
258+
}

path.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package redisgraph
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
type Path struct {
9+
Nodes []*Node
10+
Edges []*Edge
11+
}
12+
13+
func PathNew(nodes []interface{}, edges []interface{}) Path {
14+
Nodes := make([]*Node, len(nodes))
15+
for i := 0; i < len(nodes); i++ {
16+
Nodes[i] = nodes[i].(*Node)
17+
}
18+
Edges := make([]*Edge, len(edges))
19+
for i := 0; i < len(edges); i++ {
20+
Edges[i] = edges[i].(*Edge)
21+
}
22+
23+
return Path{
24+
Edges : Edges,
25+
Nodes : Nodes,
26+
}
27+
}
28+
29+
func (p Path) GetNodes() []*Node {
30+
return p.Nodes
31+
}
32+
33+
func (p Path) GetEdges() []*Edge {
34+
return p.Edges
35+
}
36+
37+
func (p Path) GetNode(index int) *Node {
38+
return p.Nodes[index]
39+
}
40+
41+
func (p Path) GetEdge(index int) *Edge{
42+
return p.Edges[index]
43+
}
44+
45+
func (p Path) FirstNode() *Node {
46+
return p.GetNode(0)
47+
}
48+
49+
func (p Path) LastNode() *Node {
50+
return p.GetNode(p.NodesCount() - 1)
51+
}
52+
53+
func (p Path) NodesCount() int {
54+
return len(p.Nodes)
55+
}
56+
57+
func (p Path) EdgeCount() int {
58+
return len(p.Edges)
59+
}
60+
61+
func (p Path) String() string {
62+
s := []string{"<"}
63+
edgeCount := p.EdgeCount()
64+
for i := 0; i < edgeCount; i++ {
65+
var node = p.GetNode(i)
66+
s = append(s, "(" , fmt.Sprintf("%v", node.ID) , ")")
67+
var edge = p.GetEdge(i)
68+
if node.ID == edge.srcNodeID {
69+
s = append(s, "-[" , fmt.Sprintf("%v", edge.ID) , "]->")
70+
} else {
71+
s= append(s, "<-[" , fmt.Sprintf("%v", edge.ID) , "]-")
72+
}
73+
}
74+
s = append(s, "(" , fmt.Sprintf("%v", p.GetNode(edgeCount).ID) , ")")
75+
s = append(s, ">")
76+
77+
return strings.Join(s, "")
78+
}

query_result.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const (
4141
VALUE_ARRAY
4242
VALUE_EDGE
4343
VALUE_NODE
44+
VALUE_PATH
4445
)
4546

4647
type QueryResultHeader struct {
@@ -217,6 +218,13 @@ func (qr *QueryResult) parseArray(cell interface{}) []interface{} {
217218
return array
218219
}
219220

221+
func (qr *QueryResult) parsePath(cell interface{}) Path {
222+
arrays := cell.([]interface{})
223+
nodes := qr.parseScalar(arrays[0].([]interface{}))
224+
edges := qr.parseScalar(arrays[1].([]interface{}))
225+
return PathNew(nodes.([]interface{}), edges.([]interface{}))
226+
}
227+
220228
func (qr *QueryResult) parseScalar(cell []interface{}) interface{} {
221229
t, _ := redis.Int(cell[0], nil)
222230
v := cell[1]
@@ -246,6 +254,9 @@ func (qr *QueryResult) parseScalar(cell []interface{}) interface{} {
246254
case VALUE_NODE:
247255
s = qr.parseNode(v)
248256

257+
case VALUE_PATH:
258+
s = qr.parsePath(v)
259+
249260
case VALUE_UNKNOWN:
250261
panic("Unknown scalar type\n")
251262
}

0 commit comments

Comments
 (0)