Skip to content

Commit 2c4220d

Browse files
committed
Improve documentation.
1 parent e4f6afe commit 2c4220d

File tree

5 files changed

+50
-37
lines changed

5 files changed

+50
-37
lines changed

internal/knowledge/query_limit_visitor.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package knowledge
22

33
import "github.com/clems4ever/go-graphkb/internal/query"
44

5+
// QueryLimitVisitor a visitor for the limit clause
56
type QueryLimitVisitor struct {
67
ExpressionVisitorBase
78

@@ -26,6 +27,7 @@ func (qlv *QueryLimitVisitor) ParseExpression(q *query.QueryExpression) error {
2627
return nil
2728
}
2829

30+
// OnIntegerLiteral handler called when an integer literal is visited
2931
func (qlv *QueryLimitVisitor) OnIntegerLiteral(value int64) error {
3032
qlv.Limit = value
3133
return nil

internal/knowledge/query_skip_visitor.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ package knowledge
22

33
import "github.com/clems4ever/go-graphkb/internal/query"
44

5+
// QuerySkipVisitor a visitor for the skip clause
56
type QuerySkipVisitor struct {
67
ExpressionVisitorBase
78

89
queryGraph *QueryGraph
910
Skip int64
1011
}
1112

13+
// NewQuerySkipVisitor create an instance of the skip visitor
1214
func NewQuerySkipVisitor(queryGraph *QueryGraph) *QuerySkipVisitor {
1315
return &QuerySkipVisitor{
1416
queryGraph: queryGraph,
@@ -24,6 +26,7 @@ func (qsv *QuerySkipVisitor) ParseExpression(q *query.QueryExpression) error {
2426
return nil
2527
}
2628

29+
// OnIntegerLiteral handler called when an integer literal is visited
2730
func (qsv *QuerySkipVisitor) OnIntegerLiteral(value int64) error {
2831
qsv.Skip = value
2932
return nil

internal/knowledge/query_sql.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,27 @@ import (
77
"github.com/clems4ever/go-graphkb/internal/query"
88
)
99

10+
// SQLQueryTranslator represent an SQL translator object converting cypher queries into SQL
1011
type SQLQueryTranslator struct {
1112
QueryGraph QueryGraph
1213
}
1314

15+
// NewSQLQueryTranslator create an instance of SQL query translator
1416
func NewSQLQueryTranslator() *SQLQueryTranslator {
1517
return &SQLQueryTranslator{QueryGraph: NewQueryGraph()}
1618
}
1719

20+
// Projection represent the type and alias of one item in the RETURN statement (called a projection).
1821
type Projection struct {
1922
Alias string
2023
ExpressionType ExpressionType
2124
}
2225

26+
// SQLTranslation the resulting object of the translation
2327
type SQLTranslation struct {
24-
Query string
28+
// Query is the SQL query built from the Cypher query
29+
Query string
30+
// ProjectionTypes helps the clients know how to serialize the results
2531
ProjectionTypes []Projection
2632
}
2733

@@ -228,10 +234,10 @@ func (sqt *SQLQueryTranslator) Translate(query *query.QueryCypher) (*SQLTranslat
228234
out := AndOrExpression{
229235
And: true,
230236
Children: []AndOrExpression{
231-
AndOrExpression{
237+
{
232238
Expression: fmt.Sprintf("%s.from_id = a%d.id", alias, r.LeftIdx),
233239
},
234-
AndOrExpression{
240+
{
235241
Expression: fmt.Sprintf("%s.to_id = a%d.id", alias, r.RightIdx),
236242
},
237243
},
@@ -240,10 +246,10 @@ func (sqt *SQLQueryTranslator) Translate(query *query.QueryCypher) (*SQLTranslat
240246
in := AndOrExpression{
241247
And: true,
242248
Children: []AndOrExpression{
243-
AndOrExpression{
249+
{
244250
Expression: fmt.Sprintf("%s.from_id = a%d.id", alias, r.RightIdx),
245251
},
246-
AndOrExpression{
252+
{
247253
Expression: fmt.Sprintf("%s.to_id = a%d.id", alias, r.LeftIdx),
248254
},
249255
},

internal/knowledge/query_sql_test.go

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,57 +18,57 @@ type QueryCase struct {
1818

1919
func TestQueryTranslation(t *testing.T) {
2020
cases := []QueryCase{
21-
QueryCase{
21+
{
2222
Cypher: "MATCH (n:ip) RETURN n",
2323
SQL: `SELECT a0.id, a0.value, a0.type FROM assets a0
2424
WHERE a0.type = 'ip'`,
2525
},
26-
QueryCase{
26+
{
2727
Cypher: "MATCH (n:ip), (n:name) RETURN n",
2828
Error: "Variable 'n' already defined with a different type",
2929
},
30-
QueryCase{
30+
{
3131
Cypher: "MATCH (n:ip) RETURN n, n",
3232
SQL: `SELECT a0.id, a0.value, a0.type, a0.id, a0.value, a0.type FROM assets a0
3333
WHERE a0.type = 'ip'`,
3434
},
35-
QueryCase{
35+
{
3636
Cypher: "MATCH (n) WHERE n.value = 'prod' RETURN n",
3737
SQL: "SELECT a0.id, a0.value, a0.type FROM assets a0\nWHERE a0.value = 'prod'",
3838
},
39-
QueryCase{
39+
{
4040
Cypher: "MATCH (n) WHERE NOT n.value = 'prod' RETURN n",
4141
SQL: "SELECT a0.id, a0.value, a0.type FROM assets a0\nWHERE NOT a0.value = 'prod'",
4242
},
43-
QueryCase{
43+
{
4444
Cypher: "MATCH (n) WHERE NOT n.value = 'prod' AND n.value = 'preprod' RETURN n",
4545
SQL: "SELECT a0.id, a0.value, a0.type FROM assets a0\nWHERE NOT a0.value = 'prod' AND a0.value = 'preprod'",
4646
},
47-
QueryCase{
47+
{
4848
Cypher: "MATCH (n) WHERE n.value STARTS WITH 'prod' RETURN n",
4949
SQL: "SELECT a0.id, a0.value, a0.type FROM assets a0\nWHERE a0.value LIKE 'prod%'",
5050
},
51-
QueryCase{
51+
{
5252
Cypher: "MATCH (n) WHERE n.value ENDS WITH 'prod' RETURN n",
5353
SQL: "SELECT a0.id, a0.value, a0.type FROM assets a0\nWHERE a0.value LIKE '%prod'",
5454
},
55-
QueryCase{
55+
{
5656
Cypher: "MATCH (n) WHERE n.value CONTAINS 'prod' RETURN n",
5757
SQL: "SELECT a0.id, a0.value, a0.type FROM assets a0\nWHERE a0.value LIKE '%prod%'",
5858
},
59-
QueryCase{
59+
{
6060
Cypher: "MATCH (:variable)-[:has]->(n:name) RETURN n",
6161
SQL: `
6262
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
6363
WHERE (((a0.type = 'variable' AND a1.type = 'name') AND r0.type = 'has') AND (r0.from_id = a0.id AND r0.to_id = a1.id))`,
6464
},
65-
QueryCase{
65+
{
6666
Cypher: "MATCH (:variable)<-[:has]-(n:name) RETURN n",
6767
SQL: `
6868
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
6969
WHERE (((a0.type = 'variable' AND a1.type = 'name') AND r0.type = 'has') AND (r0.from_id = a1.id AND r0.to_id = a0.id))`,
7070
},
71-
QueryCase{
71+
{
7272
Cypher: "MATCH (v:variable)--(n:name) RETURN n",
7373
SQL: `
7474
(SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
@@ -77,7 +77,7 @@ UNION ALL
7777
(SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
7878
WHERE ((a0.type = 'variable' AND a1.type = 'name') AND (r0.from_id = a1.id AND r0.to_id = a0.id)))`,
7979
},
80-
QueryCase{
80+
{
8181
Cypher: "MATCH (v:variable)-[r]-(n:name) RETURN n",
8282
SQL: `
8383
(SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
@@ -86,7 +86,7 @@ UNION ALL
8686
(SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
8787
WHERE ((a0.type = 'variable' AND a1.type = 'name') AND (r0.from_id = a1.id AND r0.to_id = a0.id)))`,
8888
},
89-
QueryCase{
89+
{
9090
Cypher: "MATCH (v:variable)-[r]-(n:name) RETURN n LIMIT 10",
9191
SQL: `
9292
(SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
@@ -96,7 +96,7 @@ UNION ALL
9696
WHERE ((a0.type = 'variable' AND a1.type = 'name') AND (r0.from_id = a1.id AND r0.to_id = a0.id)))
9797
LIMIT 10`,
9898
},
99-
QueryCase{
99+
{
100100
Cypher: "MATCH (v:variable)-[r]-(n:name) RETURN v.name, COUNT(n.name)",
101101
SQL: `
102102
SELECT a0.name, COUNT(*) FROM
@@ -107,7 +107,7 @@ UNION ALL
107107
WHERE ((a0.type = 'variable' AND a1.type = 'name') AND (r0.from_id = a1.id AND r0.to_id = a0.id))))
108108
GROUP BY a0.name`,
109109
},
110-
QueryCase{
110+
{
111111
Cypher: "MATCH (v:variable)-[r]-(n:name) RETURN DISTINCT n.value LIMIT 10",
112112
SQL: `
113113
(SELECT a1.value FROM assets a0, assets a1, relations r0
@@ -117,7 +117,7 @@ UNION
117117
WHERE ((a0.type = 'variable' AND a1.type = 'name') AND (r0.from_id = a1.id AND r0.to_id = a0.id)))
118118
LIMIT 10`,
119119
},
120-
QueryCase{
120+
{
121121
Cypher: "MATCH (v:variable)-[r]-(n:name) RETURN v.name, COUNT(DISTINCT n.name)",
122122
SQL: `
123123
SELECT a0.name, COUNT(DISTINCT a1.name) FROM
@@ -128,81 +128,81 @@ UNION ALL
128128
WHERE ((a0.type = 'variable' AND a1.type = 'name') AND (r0.from_id = a1.id AND r0.to_id = a0.id))))
129129
GROUP BY a0.name`,
130130
},
131-
QueryCase{
131+
{
132132
Cypher: "MATCH (v)-[r]-(n) RETURN n LIMIT 10",
133133
SQL: `
134134
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
135135
WHERE (r0.from_id = a0.id AND r0.to_id = a1.id)
136136
LIMIT 10`,
137137
},
138-
QueryCase{
138+
{
139139
Cypher: "MATCH (v:variable)<-[r]-(n:name), (v)-[r1]->(n) RETURN n",
140140
SQL: `
141141
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0, relations r1
142142
WHERE (((a0.type = 'variable' AND a1.type = 'name') AND (r0.from_id = a1.id AND r0.to_id = a0.id)) AND (r1.from_id = a0.id AND r1.to_id = a1.id))`,
143143
},
144-
QueryCase{
144+
{
145145
Cypher: "MATCH (:variable)<-[:has]-(n:name) RETURN n.value",
146146
SQL: `
147147
SELECT a1.value FROM assets a0, assets a1, relations r0
148148
WHERE (((a0.type = 'variable' AND a1.type = 'name') AND r0.type = 'has') AND (r0.from_id = a1.id AND r0.to_id = a0.id))`,
149149
},
150-
QueryCase{
150+
{
151151
Cypher: "MATCH (v:variable)<-[r:has]-(n:name) RETURN v, r, n",
152152
SQL: `
153153
SELECT a0.id, a0.value, a0.type, r0.from_id, r0.to_id, r0.type, a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
154154
WHERE (((a0.type = 'variable' AND a1.type = 'name') AND r0.type = 'has') AND (r0.from_id = a1.id AND r0.to_id = a0.id))`,
155155
},
156-
QueryCase{
156+
{
157157
Cypher: "MATCH (v:variable)<-[r]-(n) RETURN v, r, n",
158158
SQL: `
159159
SELECT a0.id, a0.value, a0.type, r0.from_id, r0.to_id, r0.type, a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
160160
WHERE (a0.type = 'variable' AND (r0.from_id = a1.id AND r0.to_id = a0.id))`,
161161
},
162-
QueryCase{
162+
{
163163
Cypher: "MATCH (v:variable)<-[:has]-(:name)-[:is_in]->(:program) RETURN v",
164164
SQL: `
165165
SELECT a0.id, a0.value, a0.type FROM assets a0, assets a1, assets a2, relations r0, relations r1
166166
WHERE ((((((a0.type = 'variable' AND a1.type = 'name') AND a2.type = 'program') AND r0.type = 'has') AND (r0.from_id = a1.id AND r0.to_id = a0.id)) AND r1.type = 'is_in') AND (r1.from_id = a1.id AND r1.to_id = a2.id))`,
167167
},
168-
QueryCase{
168+
{
169169
Cypher: `MATCH (p:port)<-[:bind]-(c:consul_service)-[:is_in]->(d:datacenter) WHERE d.value = 'pa4'
170170
MATCH (c)-[:is_in]->(e:environment) WHERE e.value = 'preprod'
171171
RETURN c`,
172172
SQL: `
173173
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, assets a2, assets a3, relations r0, relations r1, relations r2
174174
WHERE ((((((((((a0.type = 'port' AND a1.type = 'consul_service') AND a2.type = 'datacenter') AND a3.type = 'environment') AND r0.type = 'bind') AND (r0.from_id = a1.id AND r0.to_id = a0.id)) AND r1.type = 'is_in') AND (r1.from_id = a1.id AND r1.to_id = a2.id)) AND r2.type = 'is_in') AND (r2.from_id = a1.id AND r2.to_id = a3.id)) AND (a2.value = 'pa4' AND a3.value = 'preprod'))`,
175175
},
176-
QueryCase{
176+
{
177177
Cypher: `MATCH (p:port)<-[:bind]-(c:consul_service)-[:is_in]->(d:datacenter) WHERE d.value = 'pa4'
178178
MATCH (c)-[:is_in]->(e:environment) WHERE e.value <> 'preprod'
179179
RETURN c`,
180180
SQL: `
181181
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, assets a2, assets a3, relations r0, relations r1, relations r2
182182
WHERE ((((((((((a0.type = 'port' AND a1.type = 'consul_service') AND a2.type = 'datacenter') AND a3.type = 'environment') AND r0.type = 'bind') AND (r0.from_id = a1.id AND r0.to_id = a0.id)) AND r1.type = 'is_in') AND (r1.from_id = a1.id AND r1.to_id = a2.id)) AND r2.type = 'is_in') AND (r2.from_id = a1.id AND r2.to_id = a3.id)) AND (a2.value = 'pa4' AND a3.value <> 'preprod'))`,
183183
},
184-
QueryCase{
184+
{
185185
Cypher: "MATCH (:variable)<-[:has]-(n:name) RETURN n LIMIT 10",
186186
SQL: `
187187
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
188188
WHERE (((a0.type = 'variable' AND a1.type = 'name') AND r0.type = 'has') AND (r0.from_id = a1.id AND r0.to_id = a0.id))
189189
LIMIT 10`,
190190
},
191-
QueryCase{
191+
{
192192
Cypher: "MATCH (:variable)<-[:has]-(n:name) RETURN n SKIP 20 LIMIT 10",
193193
SQL: `
194194
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
195195
WHERE (((a0.type = 'variable' AND a1.type = 'name') AND r0.type = 'has') AND (r0.from_id = a1.id AND r0.to_id = a0.id))
196196
LIMIT 10
197197
OFFSET 20`,
198198
},
199-
QueryCase{
199+
{
200200
Cypher: "MATCH (:variable)<-[:has]-(n:name) RETURN DISTINCT n",
201201
SQL: `
202202
SELECT DISTINCT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
203203
WHERE (((a0.type = 'variable' AND a1.type = 'name') AND r0.type = 'has') AND (r0.from_id = a1.id AND r0.to_id = a0.id))`,
204204
},
205-
QueryCase{
205+
{
206206
Cypher: `MATCH (r:rack)<-[:is_in]-(cn:chef_name)-[:is_in]->(e:environment)
207207
WHERE r.value = '01.04'
208208
RETURN e.value, COUNT(cn.value)`,
@@ -211,19 +211,19 @@ SELECT a2.value, COUNT(*) FROM assets a0, assets a1, assets a2, relations r0, re
211211
WHERE (((((((a0.type = 'rack' AND a1.type = 'chef_name') AND a2.type = 'environment') AND r0.type = 'is_in') AND (r0.from_id = a1.id AND r0.to_id = a0.id)) AND r1.type = 'is_in') AND (r1.from_id = a1.id AND r1.to_id = a2.id)) AND a0.value = '01.04')
212212
GROUP BY a2.value`,
213213
},
214-
QueryCase{
214+
{
215215
Cypher: `MATCH (r:rack)<-[:is_in]-(cn:chef_name) RETURN COUNT(cn.value)`,
216216
SQL: `
217217
SELECT COUNT(*) FROM assets a0, assets a1, relations r0
218218
WHERE (((a0.type = 'rack' AND a1.type = 'chef_name') AND r0.type = 'is_in') AND (r0.from_id = a1.id AND r0.to_id = a0.id))`,
219219
},
220-
QueryCase{
220+
{
221221
Cypher: "MATCH (v:variable)-[:has]->(n:name) WHERE v.value = '0x16' AND (n.value = 'myvar' OR n.value = 'myvar2') RETURN n",
222222
SQL: `
223223
SELECT a1.id, a1.value, a1.type FROM assets a0, assets a1, relations r0
224224
WHERE ((((a0.type = 'variable' AND a1.type = 'name') AND r0.type = 'has') AND (r0.from_id = a0.id AND r0.to_id = a1.id)) AND (a0.value = '0x16' AND a1.value = 'myvar' OR a1.value = 'myvar2'))`,
225225
},
226-
QueryCase{
226+
{
227227
Cypher: `
228228
MATCH (ip:ip)<-[:observed]-(:device)
229229
WHERE (ip)<-[:scanned]-(:task)

internal/knowledge/query_where_visitor.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package knowledge
22

33
import "github.com/clems4ever/go-graphkb/internal/query"
44

5+
// QueryWhereVisitor a visitor for the where clauses
56
type QueryWhereVisitor struct {
67
ExpressionVisitorBase
78

@@ -25,6 +26,7 @@ func (qwv *QueryWhereVisitor) ParseExpression(q *query.QueryExpression) (string,
2526
return expression, nil
2627
}
2728

29+
// OnVariable handler called when a variable is visited in the where clause
2830
func (qwv *QueryWhereVisitor) OnVariable(name string) error {
2931
qwv.Variables = append(qwv.Variables, name)
3032
return nil

0 commit comments

Comments
 (0)