From ccd91cc1ea3f35f22e2d1738d360903250e84119 Mon Sep 17 00:00:00 2001
From: Douwe <d.geurtjens@students.uu.nl>
Date: Fri, 29 Oct 2021 14:40:14 +0200
Subject: [PATCH] ADDED: chained query hierarchy enforcment with pointer arrays

---
 aql/convertQuery.go |   1 +
 aql/hierarchy.go    | 146 ++++++++++++++++++++++++++++++++++++++++++++
 test.json           |  59 ++++++++----------
 3 files changed, 173 insertions(+), 33 deletions(-)
 create mode 100644 aql/hierarchy.go

diff --git a/aql/convertQuery.go b/aql/convertQuery.go
index 271c01b..b6b9360 100644
--- a/aql/convertQuery.go
+++ b/aql/convertQuery.go
@@ -49,6 +49,7 @@ func (s *Service) ConvertQuery(JSONQuery *entity.IncomingQueryJSON) (*string, er
 			return nil, errors.New("non-existing relation referenced in return")
 		}
 	}
+	search(JSONQuery)
 	result := createQuery(JSONQuery)
 	return result, nil
 }
diff --git a/aql/hierarchy.go b/aql/hierarchy.go
new file mode 100644
index 0000000..d8c3cfd
--- /dev/null
+++ b/aql/hierarchy.go
@@ -0,0 +1,146 @@
+package aql
+
+import (
+	"fmt"
+	"strconv"
+
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
+)
+
+type pdict struct {
+	typename string
+	pointer  int
+}
+
+var listoflists [][]pdict
+var reldone map[int]bool
+var entdone map[int]bool
+var funcdone map[int]bool
+var layercounter int
+
+func search(JSONQuery *entity.IncomingQueryJSON) {
+	reldone = make(map[int]bool)
+	entdone = make(map[int]bool)
+	var s []pdict
+	//printSlice(s)
+
+	initval := pdict{
+		typename: "relation",
+		pointer:  0,
+	}
+	s = append(s, initval)
+	listoflists = append(listoflists, s)
+	layercounter = 0
+	RelToEnt(JSONQuery, initval)
+	for i := range listoflists {
+		for j := range listoflists[i] {
+			fmt.Println(listoflists[i][j])
+		}
+		fmt.Println("")
+	}
+
+}
+
+func RelToEnt(JSONQuery *entity.IncomingQueryJSON, rel pdict) {
+	var newlist []pdict
+	for i := range JSONQuery.Entities {
+		if _, ok := entdone[i]; !ok {
+			if JSONQuery.Relations[rel.pointer].EntityFrom == i {
+				fromentity := pdict{
+					typename: "entity",
+					pointer:  i,
+				}
+				newlist = append(newlist, fromentity)
+			} else if JSONQuery.Relations[rel.pointer].EntityTo == i {
+				toentity := pdict{
+					typename: "entity",
+					pointer:  i,
+				}
+				newlist = append(newlist, toentity)
+			}
+		}
+	}
+
+	reldone[rel.pointer] = true
+	// If we are in the formost list inside the listoflists (index 0) then we have to prepend an entirely new list into listoflists
+	// Otherwise, we just add the values inside our newlist to the list infront of our current list
+	// We only decrease the layercounter if we are not already on layer 0 (index 0)
+	if len(newlist) != 0 {
+		if layercounter == 0 {
+			listoflists = prepend(listoflists, newlist)
+			fmt.Println("Layercounter 0 prepend")
+
+		} else {
+			layercounter--
+			for i := range newlist {
+				listoflists[layercounter] = append(listoflists[layercounter], newlist[i])
+
+				fmt.Println("Layercounter " + strconv.Itoa(layercounter) + " append to layer above us")
+			}
+
+		}
+
+		// Recursion here
+		for i := range newlist {
+			fmt.Println("EntToRel being called with index?: " + strconv.Itoa(i))
+			EntToRel(JSONQuery, newlist[i])
+
+		}
+	}
+
+}
+
+func EntToRel(JSONQuery *entity.IncomingQueryJSON, ent pdict) {
+	var newlist []pdict
+	for i := range JSONQuery.Relations {
+		if _, ok := reldone[i]; !ok {
+			if JSONQuery.Relations[i].EntityFrom == ent.pointer {
+				rel := pdict{
+					typename: "relation",
+					pointer:  i,
+				}
+				newlist = append(newlist, rel)
+			} else if JSONQuery.Relations[i].EntityTo == ent.pointer {
+				rel := pdict{
+					typename: "relation",
+					pointer:  i,
+				}
+				newlist = append(newlist, rel)
+			}
+		}
+	}
+	entdone[ent.pointer] = true
+	// If the layercounter points to the last index we simply append the whole list behind (relations always get added behind entities)
+	// Otherwise we append each item to the existing list
+	if len(newlist) != 0 {
+		if layercounter == len(listoflists)-1 {
+			listoflists = append(listoflists, newlist)
+			layercounter++
+		} else {
+			layercounter++
+			for i := range newlist {
+				listoflists[layercounter] = append(listoflists[layercounter], newlist[i])
+			}
+
+		}
+
+		// Recursion here
+		for i := range newlist {
+			fmt.Println("RelToEnt being called with index?: " + strconv.Itoa(i))
+			RelToEnt(JSONQuery, newlist[i])
+		}
+	}
+}
+
+func prepend(list [][]pdict, element []pdict) [][]pdict {
+	var dummylist []pdict
+	dummy := pdict{
+		typename: "dummy",
+		pointer:  -1,
+	}
+	dummylist = append(dummylist, dummy)
+	list = append(list, dummylist)
+	copy(list[1:], list)
+	list[0] = element
+	return list
+}
diff --git a/test.json b/test.json
index 7922e95..9d12f5f 100644
--- a/test.json
+++ b/test.json
@@ -2,13 +2,19 @@
     "return": {
         "entities": [
             0,
-            1
+            1,
+            2
         ],
         "relations": [
-            0
+            0,
+            1
         ]
     },
     "entities": [
+        {
+            "type": "parties",
+            "constraints": []
+        },
         {
             "type": "parliament",
             "constraints": []
@@ -20,49 +26,36 @@
     ],
     "relations": [
         {
-            "type": "part_of",
+            "type": "member_of",
             "depth": {
                 "min": 1,
                 "max": 1
             },
-            "entityFrom": 0,
-            "entityTo": 1,
+            "entityFrom": 1,
+            "entityTo": 0,
             "constraints": [],
             "functionPointer": {
                 "from": -1,
                 "to": -1
             }
-   
-        }
-    ],
-    "functions": [
+        },
         {
-            "type": "groupBy",
-            "typeID": 0,
-            "groupType": "entity",
-            "groupID": 0,
-            "groupAttribute": "age",
-            "byType": "entity",
-            "byID": 1,
-            "byAttribute": "name",
-            "appliedModifier": "AVG",
-            "relationID": 0,
-            "constraints": [
-                {
-                    "attribute": "age",
-                    "value": "45",
-                    "dataType": "number",
-                    "matchType": "GT",
-                    "functionPointer": {
-                        "from": -1,
-                        "to": -1
-                    }
-           
-                }
-            ]
+            "type": "part_of",
+            "depth": {
+                "min": 1,
+                "max": 1
+            },
+            "entityFrom": 1,
+            "entityTo": 2,
+            "constraints": [],
+            "functionPointer": {
+                "from": -1,
+                "to": -1
+            }
         }
     ],
+    "functions": [],
     "limit": 5000,
     "modifiers": [],
-    "databaseName": "TweedeKamer"
+    "databaseName": "Tweede Kamer Dataset"
 }
-- 
GitLab