-
Notifications
You must be signed in to change notification settings - Fork 0
/
neo4j_structs.go
159 lines (146 loc) · 3.68 KB
/
neo4j_structs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package neo4j_extended
import (
"errors"
)
//NeoRequest helper struct for building neo4j Requests
type NeoRequest struct {
multiCypher []string
params map[string]interface{}
names map[string]struct{}
returns []string
}
//NewNeoRequest default constructor
func NewNeoRequest() *NeoRequest {
neoReq := NeoRequest{
multiCypher: []string{},
params: make(map[string]interface{}),
names: make(map[string]struct{}),
returns: []string{},
}
return &neoReq
}
//NeoField name value parameter tuple
type NeoField struct {
Name string
Val interface{}
}
//NeoRelation relation
type NeoRelation struct {
Name string
Label string
Fields *[]NeoField
NextNode *NeoNode
Direction int
}
//NeoNode name label variable tuple
type NeoNode struct {
Name string
Label string
Fields *[]NeoField
NextRel *NeoRelation
}
//if the node has been used before we can reuse its declaration
func (node *NeoNode) ReuseNode() (reuseNode *NeoNode) {
_reuseNode := NeoNode{
Name: node.Name,
Label: "",
Fields: nil,
NextRel: nil,
}
return &_reuseNode
}
//toCypher returns the cypher representation of the node-rel LinkedList and adds params to req
func (node *NeoNode) toCypher(req *NeoRequest) (cypher string, err error) {
//Create Cypher Node Statement
cypher = "(" + node.Name
if node.Label != "" {
cypher += ":" + node.Label + " "
cypher += " "
}
if (*node).Fields != nil && len(*node.Fields) > 0 {
fieldsstring, err := getFieldsCypher(req, node.Fields)
if err != nil {
return "", err
}
cypher += fieldsstring
}
cypher += ")"
if rel := node.NextRel; rel != nil {
beginArrow := "-"
endArrow := "->"
if rel.Direction == -1 {
beginArrow = "<-"
endArrow = "-"
}
cypher += beginArrow + "[" + rel.Name
if rel.Label != "" {
cypher += ":" + rel.Label
}
if (*rel).Fields != nil && len(*rel.Fields) > 0 {
fieldsstring, err := getFieldsCypher(req, rel.Fields)
if err != nil {
return "", err
}
cypher += fieldsstring
}
cypher += "]" + endArrow
if rel.NextNode == nil {
return "", errors.New("@toCpyher: relation points to nil")
}
nextNodeCypher, err := rel.NextNode.toCypher(req)
if err != nil {
return "", err
}
cypher += nextNodeCypher
}
return cypher, nil
}
//NewNeoNode creats the Node and does some checks if it is valid
func (req *NeoRequest) NewNeoNode(name string, label string, fields *[]NeoField) (node *NeoNode, err error) {
if label != "" {
if _, ok := req.names[name]; ok {
return nil, errors.New("@NewNeoNode: name is already declared")
}
}
node = &NeoNode{
Name: name,
Label: label,
Fields: fields,
NextRel: nil,
}
req.names[node.Name] = struct{}{}
return node, nil
}
//AddRelation NeoNode attaches a Node to a relation
func (node *NeoNode) AddRelation(name string, label string, fields *[]NeoField, direction int, req *NeoRequest) (rel *NeoRelation, err error) {
if label != "" {
if _, ok := req.names[name]; ok {
return &NeoRelation{}, errors.New("@AddRelation: name is already declared")
}
}
node.NextRel = &NeoRelation{
Name: name,
Label: label,
Fields: fields,
Direction: direction,
NextNode: nil,
}
req.names[node.NextRel.Name] = struct{}{}
return node.NextRel, nil
}
//AddNode attaches a Node to a relation
func (rel *NeoRelation) AddNode(name string, label string, fields *[]NeoField, req *NeoRequest) (node *NeoNode, err error) {
if label != "" {
if _, ok := req.names[name]; ok {
return &NeoNode{}, errors.New("@AddNode: name is already declared")
}
}
rel.NextNode = &NeoNode{
Name: name,
Label: label,
Fields: fields,
NextRel: nil,
}
req.names[rel.NextNode.Name] = struct{}{}
return rel.NextNode, nil
}