Skip to content
Snippets Groups Projects
Commit bfadd26a authored by Lelieveld,J.R.J. (Joris)'s avatar Lelieveld,J.R.J. (Joris)
Browse files

Merge branch 'feature/288-Query-service-Doc' into 'develop'

Feature/288 query service doc

See merge request datastrophe/microservices-backbone/query-service!13
parents e9d464cf a51b5e68
No related branches found
No related tags found
No related merge requests found
...@@ -5,58 +5,12 @@ import ( ...@@ -5,58 +5,12 @@ import (
"fmt" "fmt"
) )
// Service is a model for the convertquery use case /*
type Service struct { ConvertQuery converts a json string to an AQL query
}
// NewService creates a new convertquery service
func NewService() *Service {
return &Service{}
}
// Constraint datatypes
// text MatchTypes: exact/contains/startswith/endswith
// number MatchTypes: GT/LT/EQ
// bool MatchTypes: EQ/NEQ
// Ranges dus tussen 10 half 5 bijv.
// Struct used for JSON conversion
type parsedJSON struct {
Return returnStruct //`json:"return"`
Entities []entityStruct //`json:"entities"`
Relations []relationStruct //`json:"relations"`
}
type returnStruct struct {
Entities []int //`json:"entities"`
Relations []int //`json:"relation"`
}
type entityStruct struct {
Type string //`json:"type"`
Constraints []constraintStruct //`json:"constraints"`
}
type relationStruct struct {
Type string //`json:"type"`
EntityFrom int
EntityTo int
Depth searchDepthStruct
Constraints []constraintStruct
}
type searchDepthStruct struct {
Min int
Max int
}
type constraintStruct struct { Parameters: jsonMsg is the JSON file directly outputted by the drag and drop query builder in the frontend
Attribute string //`json:"attribute"`
Value string //`json:"value"`
DataType string //`json:"dataType"`
MatchType string //`json:"matchType"`
}
// ConvertQuery converts a json string to an AQL query Return: a string containing the corresponding AQL query and an error */
func (s *Service) ConvertQuery(jsonMsg *[]byte) (*string, error) { func (s *Service) ConvertQuery(jsonMsg *[]byte) (*string, error) {
jsonStruct, err := convertJSONToStruct(jsonMsg) jsonStruct, err := convertJSONToStruct(jsonMsg)
...@@ -69,7 +23,11 @@ func (s *Service) ConvertQuery(jsonMsg *[]byte) (*string, error) { ...@@ -69,7 +23,11 @@ func (s *Service) ConvertQuery(jsonMsg *[]byte) (*string, error) {
return result, nil return result, nil
} }
//convertJSONtoStruct reads a JSON file and sorts the data into the appropriate structs /* convertJSONtoStruct reads a JSON file and sorts the data into the appropriate structs
Parameters: jsonMsg is the JSON file directly outputted by the drag and drop query builder in the frontend
Return: parsedJSON is a struct with the same structure and holding the same data as jsonMsg
*/
func convertJSONToStruct(jsonMsg *[]byte) (*parsedJSON, error) { func convertJSONToStruct(jsonMsg *[]byte) (*parsedJSON, error) {
jsonStruct := parsedJSON{} jsonStruct := parsedJSON{}
err := json.Unmarshal(*jsonMsg, &jsonStruct) err := json.Unmarshal(*jsonMsg, &jsonStruct)
...@@ -81,7 +39,11 @@ func convertJSONToStruct(jsonMsg *[]byte) (*parsedJSON, error) { ...@@ -81,7 +39,11 @@ func convertJSONToStruct(jsonMsg *[]byte) (*parsedJSON, error) {
return &jsonStruct, nil return &jsonStruct, nil
} }
//createQuery generates a query based on the json file provided /* createQuery generates a query based on the json file provided
Parameters: jsonQuery is a parsedJSON struct holding all the data needed to form a query
Return: a string containing the corresponding AQL query and an error
*/
func createQuery(jsonQuery *parsedJSON) *string { func createQuery(jsonQuery *parsedJSON) *string {
// GROTE SIDENOTE: // GROTE SIDENOTE:
// Vrij zeker dat een query waar alléén edges worden opgevraagd (#4) // Vrij zeker dat een query waar alléén edges worden opgevraagd (#4)
...@@ -144,6 +106,7 @@ func createQuery(jsonQuery *parsedJSON) *string { ...@@ -144,6 +106,7 @@ func createQuery(jsonQuery *parsedJSON) *string {
} }
// Create UNION statements that create unique lists of all the nodes and relations // Create UNION statements that create unique lists of all the nodes and relations
// Thus removing all duplicates
nodeUnion = "\nLET nodes = first(RETURN UNION_DISTINCT(" nodeUnion = "\nLET nodes = first(RETURN UNION_DISTINCT("
for _, relation := range relationsToReturn { for _, relation := range relationsToReturn {
nodeUnion += fmt.Sprintf("flatten(%v[**].vertices), ", relation) nodeUnion += fmt.Sprintf("flatten(%v[**].vertices), ", relation)
...@@ -166,7 +129,12 @@ func createQuery(jsonQuery *parsedJSON) *string { ...@@ -166,7 +129,12 @@ func createQuery(jsonQuery *parsedJSON) *string {
return &ret return &ret
} }
//createNodeLet generates a 'LET' statement for a node related query /* createNodeLet generates a 'LET' statement for a node related query
Parameters: node is an entityStruct containing the information of a single node,
name is the autogenerated name of the node consisting of "n" + the index of the node
Return: a string containing a single LET-statement in AQL
*/
func createNodeLet(node *entityStruct, name *string) *string { func createNodeLet(node *entityStruct, name *string) *string {
header := fmt.Sprintf("LET %v = (\n\tFOR x IN %v \n", *name, node.Type) header := fmt.Sprintf("LET %v = (\n\tFOR x IN %v \n", *name, node.Type)
footer := "\tRETURN x\n)\n" footer := "\tRETURN x\n)\n"
...@@ -176,7 +144,13 @@ func createNodeLet(node *entityStruct, name *string) *string { ...@@ -176,7 +144,13 @@ func createNodeLet(node *entityStruct, name *string) *string {
return &ret return &ret
} }
//createRelationLetWithFromEntity generates a 'LET' statement for relations with an 'EntityFrom' property /* createRelationLetWithFromEntity generates a 'LET' statement for relations with an 'EntityFrom' property and optionally an 'EntitiyTo' property
Parameters: relation is a relation struct containing the information of a single relation,
name is the autogenerated name of the node consisting of "r" + the index of the relation,
entities is a list of entityStructs that are needed to form the relation LET-statement
Return: a string containing a single LET-statement in AQL
*/
func createRelationLetWithFromEntity(relation *relationStruct, name string, entities *[]entityStruct) *string { func createRelationLetWithFromEntity(relation *relationStruct, name string, entities *[]entityStruct) *string {
header := fmt.Sprintf("LET %v = (\n\tFOR x IN n%v \n", name, relation.EntityFrom) header := fmt.Sprintf("LET %v = (\n\tFOR x IN n%v \n", name, relation.EntityFrom)
forStatement := fmt.Sprintf("\tFOR v, e, p IN %v..%v OUTBOUND x %s \n", relation.Depth.Min, relation.Depth.Max, relation.Type) forStatement := fmt.Sprintf("\tFOR v, e, p IN %v..%v OUTBOUND x %s \n", relation.Depth.Min, relation.Depth.Max, relation.Type)
...@@ -204,7 +178,13 @@ func createRelationLetWithFromEntity(relation *relationStruct, name string, enti ...@@ -204,7 +178,13 @@ func createRelationLetWithFromEntity(relation *relationStruct, name string, enti
return &ret return &ret
} }
//createRelationLetWithOnlyToEntity generates a 'LET' statement for relations with only an 'EntityTo' property /* createRelationLetWithOnlyToEntity generates a 'LET' statement for relations with only an 'EntityTo' property
Parameters: relation is a relation struct containing the information of a single relation,
name is the autogenerated name of the node consisting of "r" + the index of the relation,
entities is a list of entityStructs that are needed to form the relation LET-statement
Return: a string containing a single LET-statement in AQL
*/
func createRelationLetWithOnlyToEntity(relation *relationStruct, name string, entities *[]entityStruct) *string { func createRelationLetWithOnlyToEntity(relation *relationStruct, name string, entities *[]entityStruct) *string {
header := fmt.Sprintf("LET %v = (\n\tFOR x IN n%v \n", name, relation.EntityTo) header := fmt.Sprintf("LET %v = (\n\tFOR x IN n%v \n", name, relation.EntityTo)
forStatement := fmt.Sprintf("\tFOR v, e, p IN %v..%v INBOUND x %s \n", relation.Depth.Min, relation.Depth.Max, relation.Type) forStatement := fmt.Sprintf("\tFOR v, e, p IN %v..%v INBOUND x %s \n", relation.Depth.Min, relation.Depth.Max, relation.Type)
......
package convertquery
// Service is a model for the convertquery use case
type Service struct {
}
// NewService creates a new convertquery service
func NewService() *Service {
return &Service{}
}
// Constraint datatypes
// text MatchTypes: exact/contains/startswith/endswith
// number MatchTypes: GT/LT/EQ
// bool MatchTypes: EQ/NEQ
// Ranges dus tussen 10 half 5 bijv.
// Struct used for JSON conversion of the incoming byte array
type parsedJSON struct {
Return returnStruct //`json:"return"`
Entities []entityStruct //`json:"entities"`
Relations []relationStruct //`json:"relations"`
}
// returnStruct holds the indices of the entities and relations that need to be returned
type returnStruct struct {
Entities []int //`json:"entities"`
Relations []int //`json:"relation"`
}
// entityStruct encapsulates a single entity with its corresponding constraints
type entityStruct struct {
Type string //`json:"type"`
Constraints []constraintStruct //`json:"constraints"`
}
// relationStruct encapsulates a single relation with its corresponding constraints
type relationStruct struct {
Type string //`json:"type"`
EntityFrom int
EntityTo int
Depth searchDepthStruct
Constraints []constraintStruct
}
// searchDepthStruct holds the range of traversals for the relation
type searchDepthStruct struct {
Min int
Max int
}
// constraintStruct holds the information of the constraint
type constraintStruct struct {
Attribute string //`json:"attribute"`
Value string //`json:"value"`
DataType string //`json:"dataType"`
MatchType string //`json:"matchType"`
}
...@@ -2,7 +2,13 @@ package convertquery ...@@ -2,7 +2,13 @@ package convertquery
import "fmt" import "fmt"
// createConstraintStatements generates the appropriate amount of constraint lines calling createConstraingBoolExpression /* createConstraintStatements generates the appropriate amount of constraint lines calling createConstraingBoolExpression
Parameters: constraints is a list of constraintStructs that specify the constraints of a node or relation,
name is the id of the corresponding relation/node,
isRelation is a boolean specifying if this constraint comes from a node or relation
Return: a string containing a FILTER-statement with all the constraints
*/
func createConstraintStatements(constraints *[]constraintStruct, name string, isRelation bool) *string { func createConstraintStatements(constraints *[]constraintStruct, name string, isRelation bool) *string {
s := "" s := ""
if len(*constraints) == 0 { if len(*constraints) == 0 {
...@@ -19,8 +25,15 @@ func createConstraintStatements(constraints *[]constraintStruct, name string, is ...@@ -19,8 +25,15 @@ func createConstraintStatements(constraints *[]constraintStruct, name string, is
return &s return &s
} }
// createConstraintBoolExpression generates a bool expression, e.g. {name}.city == "New York". /* createConstraintBoolExpression generates a single boolean expression,
// when isRelation is true, {name}.edges[*] ALL == "New York" e.g. {name}.city == "New York".
Parameters: constraint is a single constraint of a node or relation,
name is the id of the corresponding relation/node,
isRelation is a boolean specifying if this constraint comes from a node or relation, that changes the structure of the expression
Return: a string containing an boolean expression of a single constraint
*/
func createConstraintBoolExpression(constraint *constraintStruct, name string, isRelation bool) *string { func createConstraintBoolExpression(constraint *constraintStruct, name string, isRelation bool) *string {
var ( var (
match string match string
...@@ -28,7 +41,6 @@ func createConstraintBoolExpression(constraint *constraintStruct, name string, i ...@@ -28,7 +41,6 @@ func createConstraintBoolExpression(constraint *constraintStruct, name string, i
line string line string
) )
//Wicked switches letsgo
switch constraint.DataType { switch constraint.DataType {
case "text": case "text":
value = fmt.Sprintf("\"%s\"", constraint.Value) value = fmt.Sprintf("\"%s\"", constraint.Value)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment