diff --git a/cmd/query-service/main.go b/cmd/query-service/main.go index 276728cc10608eac4c575821139a9f778c1d8c06..39009d83626c5fdf121a6cd894b09b46396522e2 100644 --- a/cmd/query-service/main.go +++ b/cmd/query-service/main.go @@ -12,6 +12,7 @@ import ( ) func main() { + logger.Start() // MARK: Create relevant services diff --git a/internal/usecases/convertquery/aql.go b/internal/usecases/convertquery/aql.go index dd776e223e749bf1251b2be9e3cb2f42196379d0..bc33f4aae307bcb01ead940889e184cc6417e99c 100644 --- a/internal/usecases/convertquery/aql.go +++ b/internal/usecases/convertquery/aql.go @@ -339,7 +339,7 @@ func createEdgeQuery(q *parsedJSON, name string) *string { // finalReturn += fmt.Sprintf("e%v }", q.Return.Relations[0]) // query += finalReturn - query += "\nRETURN e0" + query += "\nRETURN {e0:e0}" return &query } diff --git a/internal/usecases/request/interface.go b/internal/usecases/request/interface.go index e8847b81e2001e2770445db49c22fb978c270a60..7a30fb2ece5001330752ae924eabad893fc37f2a 100644 --- a/internal/usecases/request/interface.go +++ b/internal/usecases/request/interface.go @@ -2,5 +2,5 @@ package request // UseCase is an interface describing the request usecases type UseCase interface { - SendAQLQuery(query string) (*[]Document, error) + SendAQLQuery(query string) (*map[string][]Document, error) } diff --git a/internal/usecases/request/request.go b/internal/usecases/request/request.go index 8fc000d6335da220711f549b7710f113b2f31744..454cbbe463230c7936c9cd935a684ffaeb51e226 100644 --- a/internal/usecases/request/request.go +++ b/internal/usecases/request/request.go @@ -3,6 +3,7 @@ package request import ( "context" "crypto/tls" + "fmt" "log" "encoding/json" @@ -27,13 +28,19 @@ type Document map[string]interface{} // GeneralFormat with Empty struct to retrieve all data from the DB Document type GeneralFormat map[string][]Document +// ListContainer is a struct that keeps track of the nodes and edges that need to be returned +type ListContainer struct { + nodeList []Document + edgeList []Document +} + //attr interface{} //map[1 , 2 , 3 map [ .. ]] // SendAQLQuery send AQL string query to database and returns a JSON object in a general format -func (s *Service) SendAQLQuery(AQLQuery string) (*[]Document, error) { - var queryResult []Document +func (s *Service) SendAQLQuery(AQLQuery string) (*map[string][]Document, error) { + var queryResult = make(map[string][]Document) conn, err := http.NewConnection(http.ConnectionConfig{ Endpoints: []string{"https://aae8f5c054da.arangodb.cloud:8529"}, TLSConfig: &tls.Config{InsecureSkipVerify: true}, @@ -76,8 +83,10 @@ func (s *Service) SendAQLQuery(AQLQuery string) (*[]Document, error) { return nil, err } defer cursor.Close() + + lcontainer := ListContainer{} for { - var doc GeneralFormat + var doc map[string][]interface{} _, err := cursor.ReadDocument(ctx, &doc) if driver.IsNoMoreDocuments(err) { break @@ -85,41 +94,123 @@ func (s *Service) SendAQLQuery(AQLQuery string) (*[]Document, error) { // handle other errors return nil, err } - // fmt.Printf("%T\n", doc) - queryResult = append(queryResult, formatToJSON(doc)...) - //fmt.Println(doc) - //formatToJSON(doc) + //fmt.Printf("%s\n", doc) + + //GEDACHTEGANG TIJD: + //Normaal een lijst van n0, n1. Nu kan er ook e0 bij zitten, die heeft een andere structuur + //Dus nu een returnstruct maken met een nodelist en edgelist + //Vervolgens door de keys van de doc (n0 e0 etc) loopen en een verschillende parser aanroepen die de + //returnstruct vult. Daarna de returnstruct omzetten tot een nodelist (en maybe edgelist) + + //ret = parseDocToReturn() { + // for key in doc: + // if key starts with n: Nodeparsen + // if key starts with e: Edgeparsen + // return listContainer {nodelist edgelist} + //} + // + //result = parseContainerToString(ret) + + parseResult(doc, &lcontainer) } - // writeJSON(queryResult) + queryResult["nodes"] = lcontainer.nodeList + queryResult["edges"] = lcontainer.edgeList + + //writeJSON(queryResult) //file, err := json.MarshalIndent(queryResult, "", " ") return &queryResult, nil } -func formatToJSON(doc GeneralFormat) []Document { - //b, err := json.Marshal(doc) - //if err != nil { - //handle error - //} - // fmt.Println(doc) - - var nodeList []Document - for _, v := range doc { - for _, j := range v { - nodeList = append(nodeList, parseData(j)) +// parseResult takes the result of the query and translates this to two lists: a nodelist and an edgelist, stored in a listcontainer +func parseResult(doc map[string][]interface{}, lcontainer *ListContainer) { + + for k, v := range doc { + switch letter := []byte(k)[0]; letter { + case 'e': + //fmt.Println(v) + //Parsing of edges + for _, j := range v { + //fmt.Println(j) + + //fmt.Printf("\n%T\n", j) + d := j.(map[string]interface{}) + //fmt.Printf("\n%T\n", d["vertices"]) + vert := d["vertices"].([]interface{}) + edg := d["edges"].([]interface{}) + + lcontainer.nodeList = append(lcontainer.nodeList, parseNode(vert[0])) + lcontainer.nodeList = append(lcontainer.nodeList, parseNode(vert[1])) + lcontainer.edgeList = append(lcontainer.edgeList, parseEdge(edg[0])) + } + case 'n': + //Parsing of nodes + for _, j := range v { + + //fmt.Printf("\n%T\n", j) + doc := j.(map[string]interface{}) + lcontainer.nodeList = append(lcontainer.nodeList, parseNode(doc)) + } + default: + //Error + fmt.Println("Empty document") } } - // fmt.Println(nodeList) - return nodeList } -func writeJSON(queryResult []Document) { +// parseEdge parses the data of an edge to an output-friendly format +func parseEdge(d interface{}) Document { + doc := d.(map[string]interface{}) + + data := make(Document) + data["_id"] = doc["_id"] + delete(doc, "_id") + data["_key"] = doc["_key"] + delete(doc, "_key") + data["_rev"] = doc["_rev"] + delete(doc, "_rev") + data["_from"] = doc["_from"] + delete(doc, "_from") + data["_to"] = doc["_to"] + delete(doc, "_to") + data["attributes"] = doc + + //delete(doc, "_key") + //data.rev = fmt.Sprintf("%v", doc["_rev"]) + + // delete(doc, "_rev") + // data.attr = doc + return data +} + +// func formatToJSON(doc GeneralFormat) []Document { +// //b, err := json.Marshal(doc) +// //if err != nil { +// //handle error +// //} +// fmt.Println(doc) + +// var nodeList []Document +// for _, v := range doc { +// for _, j := range v { +// nodeList = append(nodeList, parseNode(j)) +// } +// } +// // fmt.Println(nodeList) +// return nodeList +// } + +// writeJSON writes a json file for testing purposes +func writeJSON(queryResult map[string][]Document) { file, _ := json.MarshalIndent(queryResult, "", " ") _ = ioutil.WriteFile("result.json", file, 0644) } -func parseData(doc Document) Document { +// parseNode parses the data of a node to an output-friendly format +func parseNode(d interface{}) Document { + doc := d.(map[string]interface{}) + data := make(Document) data["_id"] = doc["_id"] delete(doc, "_id") diff --git a/result.json b/result.json new file mode 100644 index 0000000000000000000000000000000000000000..d592c9aa0551e27e723f7aa34299d3dd239a1a44 --- /dev/null +++ b/result.json @@ -0,0 +1,89 @@ +{ + "edges": null, + "nodes": [ + { + "_id": "airports/6N5", + "_key": "6N5", + "_rev": "_cIYKbr6-Aw", + "attributes": { + "city": "New York", + "country": "USA", + "lat": 40.74260167, + "long": -73.97208306, + "name": "E 34th St Heliport", + "state": "NY", + "vip": false + } + }, + { + "_id": "airports/6N7", + "_key": "6N7", + "_rev": "_cIYKbr6-Ay", + "attributes": { + "city": "New York", + "country": "USA", + "lat": 40.73399083, + "long": -73.97291639, + "name": "New York Skyports Inc. SPB", + "state": "NY", + "vip": false + } + }, + { + "_id": "airports/JFK", + "_key": "JFK", + "_rev": "_cIYKbs2-_F", + "attributes": { + "city": "New York", + "country": "USA", + "lat": 40.63975111, + "long": -73.77892556, + "name": "John F Kennedy Intl", + "state": "NY", + "vip": true + } + }, + { + "_id": "airports/JRA", + "_key": "JRA", + "_rev": "_cIYKbs2-_h", + "attributes": { + "city": "New York", + "country": "USA", + "lat": 40.75454583, + "long": -74.00708389, + "name": "Port Authority-W 30th St Midtown Heliport", + "state": "NY", + "vip": false + } + }, + { + "_id": "airports/JRB", + "_key": "JRB", + "_rev": "_cIYKbs2-_j", + "attributes": { + "city": "New York", + "country": "USA", + "lat": 40.70121361, + "long": -74.00902833, + "name": "Downtown Manhattan/Wall St. Heliport", + "state": "NY", + "vip": false + } + }, + { + "_id": "airports/LGA", + "_key": "LGA", + "_rev": "_cIYKbt---s", + "attributes": { + "city": "New York", + "country": "USA", + "lat": 40.77724306, + "long": -73.87260917, + "name": "LaGuardia", + "state": "NY", + "vip": false + } + } + ] +} \ No newline at end of file