zordfsdb-client/main.go

334 lines
7.2 KiB
Go
Raw Normal View History

2024-08-23 11:19:06 +00:00
package main
import (
"bufio"
"flag"
"fmt"
"os"
"strings"
"g.arns.lt/zordsdavini/zordfsdb"
)
var (
rootDir string
executeCommand string
2024-08-29 15:11:47 +00:00
lastPath string
lastKey string
2024-08-23 11:19:06 +00:00
)
func main() {
flag.StringVar(&rootDir, "d", "./", "database root directory")
flag.StringVar(&executeCommand, "e", "", "execute command")
flag.Parse()
db, err := zordfsdb.InitDB(rootDir)
if err != nil {
panic(err)
}
if len(executeCommand) > 0 {
ExecuteCommand(db, executeCommand)
} else {
reader := bufio.NewReader(os.Stdin)
fmt.Println("ZordFsDB Shell")
fmt.Println("---------------------")
2024-08-29 13:47:24 +00:00
fmt.Println("DB initialized at ", rootDir)
fmt.Println("")
fmt.Println("Copyright (c) 2024 zordsdavini@arns.lt under MIT license")
fmt.Println("")
fmt.Println("Type HELP to get list of commands or QUIT to get out")
fmt.Println("")
2024-08-23 11:19:06 +00:00
for {
2024-08-29 13:47:24 +00:00
fmt.Print("zordfsdb> ")
2024-08-23 11:19:06 +00:00
text, _ := reader.ReadString('\n')
// convert CRLF to LF
text = strings.Replace(text, "\n", "", -1)
2024-08-29 13:47:24 +00:00
if strings.Compare("QUIT", strings.ToUpper(text)) == 0 || strings.Compare("\\Q", strings.ToUpper(text)) == 0 {
fmt.Println("\nBye o/")
2024-08-23 11:19:06 +00:00
break
}
2024-08-29 13:47:24 +00:00
if strings.Compare("HELP", strings.ToUpper(text)) == 0 || strings.Compare("\\H", strings.ToUpper(text)) == 0 {
fmt.Println(`
ZordFsDB shell supported commands:
KEYS [path] - get list of existing properties/objects/lists
GET [path] - get value of property
INC [path] - increase abcex value in property
DEC [path] - decrease abcex value in property
NOW [path] - set value to datetime string in property
DEL [path] - remove property/object/list (no confirmation)
SAVE [path] [value] - set value to property
CREATE [path] - create list/object in path (parent path should exist)
ADD [path] - add abcex indexed object to list. Will return index
2024-08-29 14:04:54 +00:00
INFO [path] - get all info about property/object/list
2024-08-29 14:57:17 +00:00
TREE [path] - draw db part in path with values
2024-08-29 13:47:24 +00:00
HELP - will print this help
QUIT - exit the shell
Last used path can be accessed by _
Last returned index (after ADD command) can be accessed by $
Short commands can be as:
2024-08-29 14:57:17 +00:00
KEYS(\K), GET(\G), INC(\I), DEC(\D), NOW(\N), DEL(\R), SAVE(\S), CREATE(\C), ADD(\A), INFO(\?), TREE(\T), HELP(\H), QUIT(\Q)
2024-08-29 13:47:24 +00:00
`)
continue
}
2024-08-23 11:19:06 +00:00
ExecuteCommand(db, text)
}
}
}
func ExecuteCommand(db zordfsdb.DB, commands string) error {
for _, command := range strings.Split(commands, ";") {
command = strings.Trim(command, " ")
parts := strings.Split(command, " ")
2024-08-29 15:11:47 +00:00
if len(parts) > 1 {
if lastPath != "" {
if parts[1] == "_" {
parts[1] = lastPath
} else {
parts[1] = strings.Replace(parts[1], "_.", lastPath+".", 1)
}
}
if lastKey != "" {
parts[1] = strings.Replace(parts[1], "$", lastKey, 1)
}
lastPath = parts[1]
}
2024-08-23 11:19:06 +00:00
2024-08-29 13:47:24 +00:00
switch strings.ToUpper(parts[0]) {
case "KEYS":
case "\\K":
kpath := "."
if !(len(parts) == 1 || len(parts[1]) == 0) {
kpath = parts[1]
2024-08-23 11:19:06 +00:00
}
2024-08-29 13:47:24 +00:00
fmt.Printf("{%s} KEYS: ", kpath)
fmt.Println(db.Keys(kpath))
fmt.Println("")
2024-08-23 11:19:06 +00:00
break
2024-08-29 14:04:54 +00:00
case "INFO":
case "\\?":
if len(parts) == 1 || len(parts[1]) == 0 {
return fmt.Errorf("err format: INFO [path]\n")
}
node, ok := db.GetNode(parts[1])
if !ok {
fmt.Println("No path found.")
fmt.Println("")
} else {
fmt.Printf("{%s} INFO\n-----------------\n", parts[1])
ntype := "property"
if node.List {
ntype = "list"
} else if node.Object {
ntype = "object"
}
fmt.Println("type:", ntype)
if ntype == "property" {
fmt.Println("value:", node.Value)
} else {
fmt.Println("keys:", db.Keys(parts[1]))
}
fmt.Println("")
}
break
2024-08-29 14:57:17 +00:00
case "TREE":
case "\\T":
if len(parts) == 1 || len(parts[1]) == 0 || parts[1] == "." {
fmt.Printf("TREE\n-----------------\n\\\n")
printNodeTree(&db, 1)
fmt.Println("")
break
}
node, ok := db.GetNode(parts[1])
if !ok {
return fmt.Errorf("err format: TREE [path]\n")
} else {
fmt.Printf("{%s} TREE\n-----------------\n", parts[1])
if !node.List && !node.Object {
fmt.Printf("%s: %s\n\n", node.Key, node.Value)
break
}
fmt.Println(node.Key)
printNodeTree(&node, 1)
}
fmt.Println("")
break
2024-08-29 13:47:24 +00:00
case "GET":
case "\\G":
2024-08-23 11:19:06 +00:00
if len(parts) == 1 || len(parts[1]) == 0 {
2024-08-29 13:47:24 +00:00
return fmt.Errorf("err format: GET [path]\n")
2024-08-23 11:19:06 +00:00
}
value, ok := db.Get(parts[1])
if !ok {
fmt.Println("No value found.")
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
} else {
fmt.Printf("{%s} VALUE: ", parts[1])
fmt.Println(value)
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
}
break
2024-08-29 13:47:24 +00:00
case "INC":
case "\\I":
2024-08-23 11:19:06 +00:00
if len(parts) == 1 || len(parts[1]) == 0 {
2024-08-29 13:47:24 +00:00
return fmt.Errorf("err format: INC [path]\n")
2024-08-23 11:19:06 +00:00
}
ok := db.Inc(parts[1])
if !ok {
fmt.Println("No value found.")
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
} else {
fmt.Printf("{%s} INC OK\n", parts[1])
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
}
break
2024-08-29 13:47:24 +00:00
case "DEC":
case "\\D":
2024-08-23 11:19:06 +00:00
if len(parts) == 1 || len(parts[1]) == 0 {
2024-08-29 13:47:24 +00:00
return fmt.Errorf("err format: DEC [path]\n")
2024-08-23 11:19:06 +00:00
}
ok := db.Dec(parts[1])
if !ok {
fmt.Println("No value found.")
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
} else {
fmt.Printf("{%s} DEC OK\n", parts[1])
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
}
break
2024-08-29 13:47:24 +00:00
case "NOW":
case "\\N":
2024-08-23 11:19:06 +00:00
if len(parts) == 1 || len(parts[1]) == 0 {
2024-08-29 13:47:24 +00:00
return fmt.Errorf("err format: NOW [path]\n")
2024-08-23 11:19:06 +00:00
}
ok := db.Now(parts[1])
if !ok {
fmt.Println("No value found.")
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
} else {
fmt.Printf("{%s} NOW OK\n", parts[1])
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
}
break
2024-08-29 13:47:24 +00:00
case "DEL":
case "\\R":
2024-08-23 11:19:06 +00:00
if len(parts) == 1 || len(parts[1]) == 0 {
2024-08-29 13:47:24 +00:00
return fmt.Errorf("err format: DEL [path]\n")
2024-08-23 11:19:06 +00:00
}
ok := db.Del(parts[1])
if !ok {
fmt.Println("No value/object found.")
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
} else {
fmt.Printf("{%s} DELETED\n", parts[1])
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
}
break
2024-08-29 13:47:24 +00:00
case "SAVE":
case "\\S":
2024-08-23 11:19:06 +00:00
if len(parts) < 3 || len(parts[1]) == 0 {
2024-08-29 13:47:24 +00:00
return fmt.Errorf("err format: SAVE [path] [value|long value]\n")
2024-08-23 11:19:06 +00:00
}
value := strings.Trim(strings.Join(parts[2:], " "), "\"")
ok := db.Save(parts[1], value)
if !ok {
fmt.Println("No value found.")
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
} else {
fmt.Printf("{%s} SAVED\n", parts[1])
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
}
2024-08-29 13:47:24 +00:00
db.Refresh()
2024-08-23 11:19:06 +00:00
break
2024-08-29 13:47:24 +00:00
case "CREATE":
case "\\C":
2024-08-23 11:19:06 +00:00
if len(parts) == 1 || len(parts[1]) == 0 {
2024-08-29 13:47:24 +00:00
return fmt.Errorf("err format: CREATE [path]\n")
2024-08-23 11:19:06 +00:00
}
ok := db.CreateNode(parts[1])
if !ok {
fmt.Println("No path found.")
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
} else {
fmt.Printf("{%s} CREATED\n", parts[1])
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
}
break
2024-08-29 13:47:24 +00:00
case "ADD":
case "\\A":
2024-08-23 11:19:06 +00:00
if len(parts) == 1 || len(parts[1]) == 0 {
2024-08-29 13:47:24 +00:00
return fmt.Errorf("err format: ADD [path]\n")
2024-08-23 11:19:06 +00:00
}
id, err := db.AddObject(parts[1])
if err != nil {
fmt.Println("No path found.")
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-23 11:19:06 +00:00
} else {
fmt.Printf("{%s} ADDED with ID: %s\n", parts[1], id)
2024-08-29 13:47:24 +00:00
fmt.Println("")
2024-08-29 15:11:47 +00:00
lastKey = id
2024-08-23 11:19:06 +00:00
}
break
2024-08-29 13:47:24 +00:00
default:
fmt.Println("err[00] unknown command, try HELP")
2024-08-23 11:19:06 +00:00
}
}
return nil
}
2024-08-29 14:57:17 +00:00
func printNodeTree(node zordfsdb.GetNodes, i int) {
for key, child := range node.GetNodes() {
j := i - 1
for j > 0 {
fmt.Printf("│ ")
j--
}
fmt.Printf("├── %s", key)
if !child.List && !child.Object {
fmt.Printf(": %s\n", child.Value)
} else {
fmt.Println("")
printNodeTree(&child, i+1)
}
}
}