315 lines
5.3 KiB
Go
315 lines
5.3 KiB
Go
package zordfsdb
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
|
|
"g.arns.lt/zordsdavini/abcex"
|
|
)
|
|
|
|
type GetNodes interface {
|
|
GetNodes() map[string]Node
|
|
}
|
|
|
|
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 (db *DB) GetNodes() map[string]Node {
|
|
return db.Nodes
|
|
}
|
|
|
|
func (node *Node) GetNodes() map[string]Node {
|
|
return node.Nodes
|
|
}
|
|
|
|
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 {
|
|
val = "0"
|
|
}
|
|
|
|
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 {
|
|
val = "0"
|
|
}
|
|
|
|
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) Now(vpath string) bool {
|
|
fullPath := []string{db.Root}
|
|
fullPath = append(fullPath, strings.Split(vpath, ".")...)
|
|
|
|
now := time.Now()
|
|
formatted := now.Format(time.RFC3339)
|
|
|
|
os.WriteFile(path.Join(fullPath...), []byte(formatted), 0644)
|
|
|
|
err := db.Refresh()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (db *DB) Save(vpath string, value string) bool {
|
|
fullPath := []string{db.Root}
|
|
fullPath = append(fullPath, strings.Split(vpath, ".")...)
|
|
|
|
err := os.WriteFile(path.Join(fullPath...), []byte(value), 0644)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
err = db.Refresh()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (db *DB) Del(vpath string) bool {
|
|
fullPath := []string{db.Root}
|
|
fullPath = append(fullPath, strings.Split(vpath, ".")...)
|
|
|
|
os.RemoveAll(path.Join(fullPath...))
|
|
|
|
err := db.Refresh()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (db *DB) CreateNode(vpath string) bool {
|
|
fullPath := []string{db.Root}
|
|
fullPath = append(fullPath, strings.Split(vpath, ".")...)
|
|
|
|
err := os.Mkdir(path.Join(fullPath...), 0750)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
err = db.Refresh()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (db *DB) AddObject(vpath string) (string, error) {
|
|
fullPath := []string{db.Root}
|
|
fullPath = append(fullPath, strings.Split(vpath, ".")...)
|
|
root := path.Join(fullPath...)
|
|
ids, err := os.ReadDir(root)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
maxId := int64(0)
|
|
notEmpty := false
|
|
for _, id := range ids {
|
|
idInt := abcex.Decode(id.Name())
|
|
if maxId <= idInt {
|
|
maxId = idInt
|
|
notEmpty = true
|
|
}
|
|
}
|
|
|
|
if notEmpty {
|
|
maxId++
|
|
}
|
|
|
|
fullPath = append(fullPath, abcex.Encode(maxId))
|
|
fmt.Println(fullPath, maxId, abcex.Encode(maxId))
|
|
|
|
err = os.Mkdir(path.Join(fullPath...), 0750)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
err = db.Refresh()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return abcex.Encode(maxId), nil
|
|
}
|