-
Notifications
You must be signed in to change notification settings - Fork 0
/
khadijah.go
206 lines (167 loc) · 8.21 KB
/
khadijah.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package khadijah
var (
DefaultTagName = "json"
DefaultVariable = "flava"
DefaultStartVariable = "start"
DefaultEndVariable = "end"
DefaultMatchClause = M{"id(+v+)": "id"}
DefaultSettings = []KhadijahSetting{
SetTagName(DefaultTagName),
SetVariable(DefaultVariable),
SetStartVariable(DefaultStartVariable),
SetEndVariable(DefaultEndVariable),
SetMatchClause(DefaultMatchClause),
}
)
// KhadijahSetting type that defines a setting for Khadijah
type KhadijahSetting func(instance *Khadijah)
// SetTagName will set Khadijah.TagName
func SetTagName(tagName string) KhadijahSetting {
return func(instance *Khadijah) {
instance.TagName = tagName
}
}
// SetVariable will set Khadijah.Variable
func SetVariable(variable string) KhadijahSetting {
return func(instance *Khadijah) {
instance.Variable = variable
}
}
// SetMatchClause will set Khadijah.MatchCaluse
func SetMatchClause(matchClause M) KhadijahSetting {
return func(instance *Khadijah) {
instance.MatchClause = matchClause
}
}
// SetMatchClauseSlice allows a slice of strings to be defined for the default
// match clause. It will make a key=>val map where both are the entry in the slice
// []string{"param"} => M{"param": "param"}
func SetMatchClauseSlice(matchClause []string) KhadijahSetting {
clause := M{}
for _, v := range matchClause {
clause[v] = v
}
return SetMatchClause(clause)
}
// SetMatchClause will set Khadijah.StartVariable
func SetStartVariable(startVariable string) KhadijahSetting {
return func(instance *Khadijah) {
instance.StartVariable = startVariable
}
}
// SetMatchClause will set Khadijah.EndVariable
func SetEndVariable(endVariable string) KhadijahSetting {
return func(instance *Khadijah) {
instance.EndVariable = endVariable
}
}
// SetMatchClause will set Khadijah.ParamPrefix
func SetParamPrefix(paramPrefix string) KhadijahSetting {
return func(instance *Khadijah) {
instance.ParamPrefix = paramPrefix
}
}
// New creates an instance of Khadijah with "json" as the default tag name
// used to pull values from the passed in structs and "flava" as the default
// variable that is used in the returned queries
func New(settings ...KhadijahSetting) *Khadijah {
// set defaults and override them
settings = append(DefaultSettings, settings...)
instance := &Khadijah{}
instance.Apply(settings...)
instance.RootMaxx = NewMaxine(instance.TagName, instance.Variable, instance.ParamPrefix, instance.MatchClause)
return instance
}
type Khadijah struct {
TagName string
Variable string
StartVariable string
EndVariable string
MatchClause M
ParamPrefix string
RootMaxx *Maxine
}
// Apply will set some properties on the instance
func (k *Khadijah) Apply(settings ...KhadijahSetting) {
for _, setFn := range settings {
setFn(k)
}
}
// NodeWithProperties creates a simple (var:label {propts}) string
func (k *Khadijah) NodeWithProperties(entity interface{}, label *string) *Maxine {
reg := newRegine(k.MatchClause, k.RootMaxx)
return reg.nodeWithProperties(entity, label)
}
// MatchNode creates a simple Match (var:label {props}) cypther query
func (k *Khadijah) MatchNode(entity interface{}, label *string, withReturn bool) *Maxine {
reg := newRegine(k.MatchClause, k.RootMaxx)
return reg.matchNode(entity, label, withReturn)
}
// CreateNode builds a simple cypher CREATE query that looks like:
// CREATE (x:Label {param: $param}) RETURN x
func (k *Khadijah) CreateNode(entity interface{}, label *string, withReturn bool, excludes ...string) *Maxine {
reg := newRegine(k.MatchClause, k.RootMaxx)
return reg.createNode(entity, label, withReturn, excludes...)
}
// UpdateNodeWithMatch builds a simpole cyper Merge ... SET query that looks like:
// MERGE (x:Label {param: $param}) SET param1 = $param1 RETURN x
func (k *Khadijah) UpdateNodeWithMatch(entity interface{}, label *string, matchClause M, withReturn bool, excludes ...string) *Maxine {
reg := newRegine(k.MatchClause, k.RootMaxx)
return reg.updateNodeWithMatch(entity, label, matchClause, withReturn, excludes...)
}
// UpdateNode works like UpdateNodeWithMatch, but defaults the matchClause to {id: $id}
// creates a query that looks like:
// MATCH (x:Label {id: $id}) SET param1 = $param1 RETURN x
func (k *Khadijah) UpdateNode(entity interface{}, label *string, withReturn bool, excludes ...string) *Maxine {
return k.UpdateNodeWithMatch(entity, label, k.MatchClause, withReturn, excludes...)
}
// DeleteNodeWithMatch builds a cypher MATCH .. DELETE quer that looks like:
// MATCH (x {param: $param}) [DETACH] DELETE x
func (k *Khadijah) DeleteNodeWithMatch(entity interface{}, detach bool, matchClause M) *Maxine {
reg := newRegine(k.MatchClause, k.RootMaxx)
return reg.deleteNodeWithMatch(entity, detach, matchClause)
}
// DetachDeleteNodeWithMatch build a MATCH ... DETACH DELETE cypher query using
// the provided matching clause
// MATCH (x {param: $param}) [DETACH] DELETE x
func (k *Khadijah) DetachDeleteNodeWithMatch(entity interface{}, matchClause M) *Maxine {
return k.DeleteNodeWithMatch(entity, true, matchClause)
}
// DetachDeleteNode build a MATCH ... DETACH DELETE cypher query using the default
// matching clause
// MATCH (x {param: $param}) [DETACH] DELETE x
func (k *Khadijah) DetachDeleteNode(entity interface{}) *Maxine {
return k.DeleteNodeWithMatch(entity, true, k.MatchClause)
}
// DeleteNode build a MATCH ... [DETACH] DELETE cypher query using the default
// matching clause
// MATCH (x {param: $param}) [DETACH] DELETE x
func (k *Khadijah) DeleteNode(entity interface{}, detach bool) *Maxine {
return k.DeleteNodeWithMatch(entity, detach, k.MatchClause)
}
// CreateEdge builds a complex MATCh (nodeA), (nodeB) CREATE query
// MATCH (start:Lable {matches}), (end:Label {props}) CREATE (start)-[edge:label {matches}]->(end) RETURN start, end, edge
func (k *Khadijah) CreateEdge(start, end, edge interface{}, direction string, startLabel *string, endLabel, edgeLabel *string, withReturn bool, excldues ...string) *Maxine {
return k.CreateEdgeWithMatches(start, startLabel, DefaultMatchClause, direction, end, endLabel, DefaultMatchClause, edge, edgeLabel, withReturn, excldues...)
}
// CreateEdgeWithMatches a complex MATCh (nodeA), (nodeB) CREATE query
// MATCH (start:Lable {matches}), (end:Label {props}) CREATE (start)-[edge:label {matches}]->(end) RETURN start, end, edge
func (k *Khadijah) CreateEdgeWithMatches(start interface{}, startLabel *string, startMatchClause M, direction string, end interface{}, endLabel *string, endMatchClause M, edge interface{}, edgeLabel *string, withReturn bool, excldues ...string) *Maxine {
syn := newSynclaire(k.MatchClause, k.StartVariable, k.EndVariable, k.RootMaxx)
return syn.createEdgeWithMatches(start, startLabel, startMatchClause, direction, end, endLabel, endMatchClause, edge, edgeLabel, withReturn, excldues...)
}
func (k *Khadijah) UpdateEdgeWithMatches(start interface{}, startLabel *string, startMatchClause M, direction string, end interface{}, endLabel *string, endMatchClause M, edge interface{}, edgeLabel *string, edgeMatchClause M, withReturn bool, excldues ...string) *Maxine {
syn := newSynclaire(k.MatchClause, k.StartVariable, k.EndVariable, k.RootMaxx)
return syn.updateEdgeWithMatches(start, startLabel, startMatchClause, direction, end, endLabel, endMatchClause, edge, edgeLabel, edgeMatchClause, withReturn, excldues...)
}
func (k *Khadijah) UpdateEdge(start interface{}, startLabel *string, direction string, end interface{}, endLabel *string, edge interface{}, edgeLabel *string, withReturn bool, excldues ...string) *Maxine {
return k.UpdateEdgeWithMatches(start, startLabel, DefaultMatchClause, direction, end, endLabel, DefaultMatchClause, edge, edgeLabel, DefaultMatchClause, withReturn, excldues...)
}
func (k *Khadijah) DeleteEdgeWithMatchingLabels(startLabel, direction, endLabel string, edge interface{}, edgeLabel string, edgeMatchClause M) *Maxine {
syn := newSynclaire(k.MatchClause, k.StartVariable, k.EndVariable, k.RootMaxx)
return syn.deleteEdgeWithMatchingLabels(startLabel, direction, endLabel, edge, edgeLabel, edgeMatchClause)
}
func (k *Khadijah) DeleteEdge(edge interface{}, edgeLabel, direction string, edgeMatchClause M) *Maxine {
syn := newSynclaire(k.MatchClause, k.StartVariable, k.EndVariable, k.RootMaxx)
return syn.deleteEdge(edge, edgeLabel, direction, edgeMatchClause)
}