package zordfsdb import ( "os" "path" "strings" "g.arns.lt/zordsdavini/abcex" ) type DB struct { Root string Nodes map[string]Node } type Node struct { Key string Value string Nodes map[string]Node Object bool List bool } func InitDB(root string) (DB, error) { db := DB{Root: root} err := db.Refresh() return db, err } func (db *DB) Refresh() error { db.Nodes = make(map[string]Node) files, err := os.ReadDir(db.Root) if err != nil { return err } for _, file := range files { node := Node{Key: file.Name()} node.Nodes = make(map[string]Node) if file.IsDir() { node, err = readDir(db.Root, node) if err != nil { return err } } else { b, err := os.ReadFile(path.Join(db.Root, file.Name())) if err != nil { return err } node.Value = strings.Trim(string(b), "\n") } db.Nodes[file.Name()] = node } return nil } func readDir(root string, node Node) (Node, error) { newRoot := path.Join(root, node.Key) files, err := os.ReadDir(newRoot) if err != nil { return node, err } for _, file := range files { child := Node{Key: file.Name()} child.Nodes = make(map[string]Node) if file.IsDir() { child, err = readDir(newRoot, child) if err != nil { return node, err } } else { b, err := os.ReadFile(path.Join(newRoot, file.Name())) if err != nil { return node, err } child.Value = strings.Trim(string(b), "\n") } node.Nodes[file.Name()] = child } node.FixType() return node, nil } func (node *Node) FixType() { node.List = false node.Object = false for _, child := range node.Nodes { if child.Object { node.List = true break } node.Object = true break } } func (db *DB) Keys(vpath string) []string { keys := []string{} fullPath := []string{db.Root} fullPath = append(fullPath, strings.Split(vpath, ".")...) root := path.Join(fullPath...) files, err := os.ReadDir(root) if err != nil { return keys } for _, file := range files { keys = append(keys, file.Name()) } return keys } func (db *DB) GetNode(vpath string) (Node, bool) { nodes := db.Nodes current := Node{} STEP_LOOP: for _, step := range strings.Split(vpath, ".") { for _, node := range nodes { if step == node.Key { nodes = node.Nodes current = node continue STEP_LOOP } } return current, false } return current, true } func (db *DB) Get(vpath string) (string, bool) { node, found := db.GetNode(vpath) if !found { return "", false } return node.Value, true } func (db *DB) Inc(vpath string) bool { fullPath := []string{db.Root} fullPath = append(fullPath, strings.Split(vpath, ".")...) val, found := db.Get(vpath) if !found { return false } valAbc := abcex.Decode(val) valAbc++ val = abcex.Encode(valAbc) os.WriteFile(path.Join(fullPath...), []byte(string(val)), 0644) err := db.Refresh() if err != nil { return false } return true } func (db *DB) Dec(vpath string) bool { fullPath := []string{db.Root} fullPath = append(fullPath, strings.Split(vpath, ".")...) val, found := db.Get(vpath) if !found { return false } valAbc := abcex.Decode(val) valAbc-- val = abcex.Encode(valAbc) os.WriteFile(path.Join(fullPath...), []byte(string(val)), 0644) err := db.Refresh() if err != nil { return false } return true }