commit bd9758bd774b87abd39cf659e767d3c814af73c9
parent 36092536755abdefb0ad5f1f5644c656a282528e
Author: lash <dev@holbrook.no>
Date: Sun, 1 Sep 2024 21:46:06 +0100
Rename dev/gdbm to dbconvert and implement with db.Db
Diffstat:
3 files changed, 172 insertions(+), 122 deletions(-)
diff --git a/db/gdbm/gdbm.go b/db/gdbm/gdbm.go
@@ -33,7 +33,7 @@ func(gdb *gdbmDb) Connect(ctx context.Context, connStr string) error {
var db *gdbm.Database
_, err := os.Stat(connStr)
if err != nil {
- if !errors.Is(os.ErrNotExist, err) {
+ if !errors.Is(err.(*os.PathError).Unwrap(), os.ErrNotExist) {
return err
}
db, err = gdbm.Open(connStr, gdbm.ModeWrcreat)
diff --git a/dev/dbconvert/main.go b/dev/dbconvert/main.go
@@ -0,0 +1,171 @@
+// Executable dbconvert processes a given directory recursively and inserts all legacy template files, menu files and bytecode files into corresponding db.Db entries of the chosen backend.
+package main
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "io"
+ "io/fs"
+ "log"
+ "os"
+ "path/filepath"
+ "path"
+ "strings"
+
+ "git.defalsify.org/vise.git/db"
+ fsdb "git.defalsify.org/vise.git/db/fs"
+ gdbmdb "git.defalsify.org/vise.git/db/gdbm"
+ "git.defalsify.org/vise.git/logging"
+)
+
+var (
+ binaryPrefix = ".bin"
+ menuPrefix = "menu"
+ staticloadPrefix = ".txt"
+ templatePrefix = ""
+ scan = make(map[string]string)
+ logg = logging.NewVanilla()
+ dbg = map[uint8]string{
+ db.DATATYPE_BIN: "BIN",
+ db.DATATYPE_TEMPLATE: "TEMPLATE",
+ db.DATATYPE_MENU: "MENU",
+ db.DATATYPE_STATICLOAD: "STATICLOAD",
+ }
+)
+
+type scanner struct {
+ ctx context.Context
+ db db.Db
+}
+
+func newScanner(ctx context.Context, db db.Db) (*scanner, error) {
+ return &scanner{
+ ctx: ctx,
+ db: db,
+ }, nil
+}
+
+func(sc *scanner) Close() error {
+ return sc.db.Close()
+}
+
+func(sc *scanner) Scan(fp string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if d.IsDir() {
+ return nil
+ }
+ fx := path.Ext(fp)
+ fb := path.Base(fp)
+ if (len(fb) == 0) {
+ return nil
+ }
+ if (fb[0] < 0x61 || fb[0] > 0x7A) {
+ return nil
+ }
+ sc.db.SetPrefix(db.DATATYPE_UNKNOWN)
+ switch fx {
+ case binaryPrefix:
+ sc.db.SetPrefix(db.DATATYPE_BIN)
+ //typ = db.DATATYPE_BIN
+ case templatePrefix:
+ if strings.Contains(fb, "_menu") {
+ sc.db.SetPrefix(db.DATATYPE_TEMPLATE)
+ //typ = db.DATATYPE_TEMPLATE
+ } else {
+ sc.db.SetPrefix(db.DATATYPE_MENU)
+ //typ = db.DATATYPE_MENU
+ }
+ case staticloadPrefix:
+ sc.db.SetPrefix(db.DATATYPE_STATICLOAD)
+ default:
+ log.Printf("skip foreign file: %s", fp)
+ return nil
+ }
+ f, err := os.Open(fp)
+ defer f.Close()
+ if err != nil{
+ return err
+ }
+ v, err := io.ReadAll(f)
+ if err != nil{
+ return err
+ }
+
+ logg.TraceCtxf(sc.ctx, "put record", "fx", fx, "fb", fb)
+ ft := fb[:len(fb)-len(fx)]
+ err = sc.db.Put(sc.ctx, []byte(ft), v)
+ if err != nil {
+ return err
+ }
+ //k := db.ToDbKey(typ, []byte(ft), nil)
+ //err = sc.db.Store(k, v, true)
+ //if err != nil {
+ // return err
+ //}
+ return nil
+}
+
+func main() {
+ var store db.Db
+ var err error
+ var dir string
+ var dbPath string
+ var dbFile string
+ var dbBackend string
+ flag.StringVar(&dbPath, "d", "", "output directory")
+ flag.StringVar(&dbBackend, "backend", "gdbm", "db backend. valid choices are: gdbm (default), fs")
+ flag.Parse()
+
+ ctx := context.Background()
+ switch dbBackend {
+ case "gdbm":
+ store = gdbmdb.NewGdbmDb()
+ dbFile = "vise_resources.gdbm"
+ case "fs":
+ store = fsdb.NewFsDb()
+ }
+
+ dir = flag.Arg(0)
+
+ if dbPath == "" {
+ dbPath, err = os.MkdirTemp(dir, "vise-dbconvert-*")
+ } else {
+ err = os.MkdirAll(dir, 0700)
+ }
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to create output dir")
+ os.Exit(1)
+ }
+ if dbFile != "" {
+ dbPath = path.Join(dbPath, dbFile)
+ }
+ if dir == dbPath {
+ fmt.Fprintf(os.Stderr, "input and output dir cannot be the same")
+ }
+
+ err = store.Connect(ctx, dbPath)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to connect to output db: %s", err)
+ os.Exit(1)
+ }
+
+ store.SetLock(db.DATATYPE_BIN, false)
+ store.SetLock(db.DATATYPE_TEMPLATE, false)
+ store.SetLock(db.DATATYPE_MENU, false)
+ store.SetLock(db.DATATYPE_STATICLOAD, false)
+
+ o, err := newScanner(ctx, store)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to open scanner")
+ os.Exit(1)
+ }
+ err = filepath.WalkDir(dir, o.Scan)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to process input: %s", err)
+ os.Exit(1)
+ }
+ fmt.Fprintf(os.Stdout, dbPath)
+}
diff --git a/dev/gdbm/main.go b/dev/gdbm/main.go
@@ -1,121 +0,0 @@
-// Executable gdbm processes a given directory recursively and inserts all template files, menu files and bytecode files into corresponding db.Db entries backed by a gdbm backend.
-//
-// TODO: Implement with db/gdbm
-package main
-
-import (
- "flag"
- "fmt"
- "io"
- "io/fs"
- "log"
- "os"
- "path/filepath"
- "path"
- "strings"
-
- gdbm "github.com/graygnuorg/go-gdbm"
-
- "git.defalsify.org/vise.git/db"
-)
-
-var (
- binaryPrefix = ".bin"
- menuPrefix = "menu"
- templatePrefix = ""
- scan = make(map[string]string)
- dbg = map[uint8]string{
- db.DATATYPE_BIN: "BIN",
- db.DATATYPE_TEMPLATE: "TEMPLATE",
- db.DATATYPE_MENU: "MENU",
- }
-)
-
-type scanner struct {
- db *gdbm.Database
-}
-
-func newScanner(fp string) (*scanner, error) {
- db, err := gdbm.Open(fp, gdbm.ModeNewdb)
- if err != nil {
- return nil, err
- }
- return &scanner{
- db: db,
- }, nil
-}
-
-func(sc *scanner) Close() error {
- return sc.db.Close()
-}
-
-func(sc *scanner) Scan(fp string, d fs.DirEntry, err error) error {
- var typ uint8
- if err != nil {
- return err
- }
- typ = db.DATATYPE_UNKNOWN
- if d.IsDir() {
- return nil
- }
- fx := path.Ext(fp)
- fb := path.Base(fp)
- if (len(fb) == 0) {
- return nil
- }
- if (fb[0] < 0x61 || fb[0] > 0x7A) {
- return nil
- }
- switch fx {
- case binaryPrefix:
- typ = db.DATATYPE_BIN
- case templatePrefix:
- if strings.Contains(fb, "_menu") {
- typ = db.DATATYPE_TEMPLATE
- } else {
- typ = db.DATATYPE_MENU
- }
- default:
- log.Printf("skip foreign file: %s", fp)
- return nil
- }
- f, err := os.Open(fp)
- defer f.Close()
- if err != nil{
- return err
- }
- v, err := io.ReadAll(f)
- if err != nil{
- return err
- }
-
- log.Printf("fx fb %s %s", fx, fb)
- ft := fb[:len(fb)-len(fx)]
- k := db.ToDbKey(typ, []byte(ft), nil)
- err = sc.db.Store(k, v, true)
- if err != nil {
- return err
- }
- log.Printf("stored key [%s] %x for %s (%s)", dbg[typ], k, fp, ft)
- return nil
-}
-
-func main() {
- var dir string
- var dbPath string
- flag.StringVar(&dbPath, "d", "vise.gdbm", "database file path")
- flag.Parse()
-
- dir = flag.Arg(0)
-
- o, err := newScanner(dbPath)
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to open scanner")
- os.Exit(1)
- }
- err = filepath.WalkDir(dir, o.Scan)
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to open scanner")
- os.Exit(1)
- }
-}