From ddc31e4ca5ecf09fb86c7b8f9cf1fce1a8b7e070 Mon Sep 17 00:00:00 2001 From: Arnas Udovic Date: Sun, 16 Mar 2025 02:18:12 +0200 Subject: [PATCH] add Length, GetRandomNode; fix FixType --- CHANGELOG | 7 +++++ zordfsdb.go | 36 ++++++++++++++++++++++++ zordfsdb_test.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 0f3cb13..a72b827 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +v1.0.5, released 2025-03-16 + * bugfixes + - FixType - run recursevily into child nodes to get correct value + * features + - Length - get length of list + - GetRandomNode - get random node from list + v1.0.4, released 2025-01-07 * abcex to v4 diff --git a/zordfsdb.go b/zordfsdb.go index e297448..5b56f53 100644 --- a/zordfsdb.go +++ b/zordfsdb.go @@ -2,6 +2,7 @@ package zordfsdb import ( "fmt" + "math/rand" "os" "path" "strings" @@ -111,6 +112,8 @@ func (node *Node) FixType() { node.List = false node.Object = false for _, child := range node.Nodes { + child.FixType() + if child.Object { node.List = true break @@ -313,3 +316,36 @@ func (db *DB) AddObject(vpath string) (string, error) { return abcex.Encode(maxId, abcex.BASE62), nil } + +func (db *DB) Length(vpath string) (int64, error) { + node, found := db.GetNode(vpath) + if !found { + return 0, fmt.Errorf("Node not found") + } + + if !node.List { + return 0, fmt.Errorf("Node is not a list") + } + + return int64(len(node.Nodes)), nil +} + +func (db *DB) getRandomNode(vpath string) (Node, error) { + node, found := db.GetNode(vpath) + if !found { + return Node{}, fmt.Errorf("Node not found") + } + + if !node.List { + return Node{}, fmt.Errorf("Not a list") + } + + if len(node.Nodes) == 0 { + return Node{}, fmt.Errorf("List is empty") + } + + keys := db.Keys(vpath) + randomKey := keys[rand.Intn(len(keys))] + + return node.Nodes[randomKey], nil +} diff --git a/zordfsdb_test.go b/zordfsdb_test.go index 3761c81..7499d79 100644 --- a/zordfsdb_test.go +++ b/zordfsdb_test.go @@ -199,3 +199,76 @@ func TestCreateList(t *testing.T) { t.Fatal("object.list2.0.newKey4 value wrong") } } + +func TestListLength(t *testing.T) { + copy(t) + + db, err := InitDB("./testdata2") + if err != nil { + t.Fatal(err) + } + + success := db.CreateNode("object.list3") + if !success { + t.Fatal("object.list3 node was not created") + } + + id, _ := db.AddObject("object.list3") + db.Save("object.list3."+id+".key", "value") + id, _ = db.AddObject("object.list3") + db.Save("object.list3."+id+".key", "value") + id, _ = db.AddObject("object.list3") + db.Save("object.list3."+id+".key", "value") + id, _ = db.AddObject("object.list3") + db.Save("object.list3."+id+".key", "value") + + node, _ := db.GetNode("object.list3") + node.FixType() + + fmt.Println(db.GetNode("object.list3")) + + length, err := db.Length("object.list3") + if err != nil { + t.Fatal(err) + } + if length != 4 { + t.Fatal("object.list3 length wrong") + } + + length, err = db.Length("object") + if err == nil { + t.Fatal("Error expected") + } +} + +func TestListRandomNode(t *testing.T) { + copy(t) + + db, err := InitDB("./testdata2") + if err != nil { + t.Fatal(err) + } + + success := db.CreateNode("object.list3") + if !success { + t.Fatal("object.list3 node was not created") + } + + id, _ := db.AddObject("object.list3") + db.Save("object.list3."+id+".key", "value") + id, _ = db.AddObject("object.list3") + db.Save("object.list3."+id+".key", "value") + id, _ = db.AddObject("object.list3") + db.Save("object.list3."+id+".key", "value") + id, _ = db.AddObject("object.list3") + db.Save("object.list3."+id+".key", "value") + + node, _ := db.GetNode("object.list3") + node.FixType() + + node, _ = db.getRandomNode("object.list3") + if node.Nodes["key"].Value != "value" { + fmt.Println(node) + t.Fatal("Random node value wrong") + } +}