From f42f9ee2a65423019eb77df5462ae87bb2d81015 Mon Sep 17 00:00:00 2001 From: Joris <j.r.j.lelieveld@students.uu.nl> Date: Fri, 16 Apr 2021 15:35:49 +0200 Subject: [PATCH] Documentation of the functions in the query service --- internal/usecases/convertquery/aql.go | 90 +++++++------------ internal/usecases/convertquery/aqlStructs.go | 59 ++++++++++++ .../convertquery/createConstraints.go | 20 ++++- 3 files changed, 109 insertions(+), 60 deletions(-) create mode 100644 internal/usecases/convertquery/aqlStructs.go diff --git a/internal/usecases/convertquery/aql.go b/internal/usecases/convertquery/aql.go index 996c96a..8adcb06 100644 --- a/internal/usecases/convertquery/aql.go +++ b/internal/usecases/convertquery/aql.go @@ -5,58 +5,10 @@ import ( "fmt" ) -// 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 -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 -} +/* ConvertQuery converts a json string to an AQL query +Parameters: jsonMsg is the JSON file directly outputted by the drag and drop query builder in the frontend -type constraintStruct struct { - 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) { jsonStruct, err := convertJSONToStruct(jsonMsg) @@ -69,7 +21,11 @@ func (s *Service) ConvertQuery(jsonMsg *[]byte) (*string, error) { 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) { jsonStruct := parsedJSON{} err := json.Unmarshal(*jsonMsg, &jsonStruct) @@ -81,7 +37,11 @@ func convertJSONToStruct(jsonMsg *[]byte) (*parsedJSON, error) { 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 { // GROTE SIDENOTE: // Vrij zeker dat een query waar alléén edges worden opgevraagd (#4) @@ -144,6 +104,7 @@ func createQuery(jsonQuery *parsedJSON) *string { } // Create UNION statements that create unique lists of all the nodes and relations + // Thus removing all duplicates nodeUnion = "\nLET nodes = first(RETURN UNION_DISTINCT(" for _, relation := range relationsToReturn { nodeUnion += fmt.Sprintf("flatten(%v[**].vertices), ", relation) @@ -166,7 +127,12 @@ func createQuery(jsonQuery *parsedJSON) *string { 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 { header := fmt.Sprintf("LET %v = (\n\tFOR x IN %v \n", *name, node.Type) footer := "\tRETURN x\n)\n" @@ -176,7 +142,13 @@ func createNodeLet(node *entityStruct, name *string) *string { 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 { 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) @@ -204,7 +176,13 @@ func createRelationLetWithFromEntity(relation *relationStruct, name string, enti 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 { 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) diff --git a/internal/usecases/convertquery/aqlStructs.go b/internal/usecases/convertquery/aqlStructs.go new file mode 100644 index 0000000..24f6a49 --- /dev/null +++ b/internal/usecases/convertquery/aqlStructs.go @@ -0,0 +1,59 @@ +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"` +} diff --git a/internal/usecases/convertquery/createConstraints.go b/internal/usecases/convertquery/createConstraints.go index ae5fc33..2f92a5c 100644 --- a/internal/usecases/convertquery/createConstraints.go +++ b/internal/usecases/convertquery/createConstraints.go @@ -2,7 +2,13 @@ package convertquery 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 { s := "" if len(*constraints) == 0 { @@ -19,8 +25,15 @@ func createConstraintStatements(constraints *[]constraintStruct, name string, is return &s } -// createConstraintBoolExpression generates a bool expression, e.g. {name}.city == "New York". -// when isRelation is true, {name}.edges[*] ALL == "New York" +/* createConstraintBoolExpression generates a single boolean expression, +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 { var ( match string @@ -28,7 +41,6 @@ func createConstraintBoolExpression(constraint *constraintStruct, name string, i line string ) - //Wicked switches letsgo switch constraint.DataType { case "text": value = fmt.Sprintf("\"%s\"", constraint.Value) -- GitLab