go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

main.go (3616B)


      1 // 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.
      2 package main
      3 
      4 import (
      5 	"context"
      6 	"flag"
      7 	"fmt"
      8 	"io"
      9 	"io/fs"
     10 	"log"
     11 	"os"
     12 	"path/filepath"
     13 	"path"
     14 	"strings"
     15 
     16 	"git.defalsify.org/vise.git/db"
     17 	fsdb "git.defalsify.org/vise.git/db/fs"
     18 	gdbmdb "git.defalsify.org/vise.git/db/gdbm"
     19 	"git.defalsify.org/vise.git/logging"
     20 )
     21 
     22 var (
     23 	binaryPrefix = ".bin"
     24 	menuPrefix = "menu"
     25 	staticloadPrefix = ".txt"
     26 	templatePrefix = ""
     27 	scan = make(map[string]string)
     28 	logg = logging.NewVanilla()
     29 	dbg = map[uint8]string{
     30 		db.DATATYPE_BIN: "BIN",
     31 		db.DATATYPE_TEMPLATE: "TEMPLATE",
     32 		db.DATATYPE_MENU: "MENU",
     33 		db.DATATYPE_STATICLOAD: "STATICLOAD",
     34 	}
     35 )
     36 
     37 type scanner struct {
     38 	ctx context.Context
     39 	db db.Db
     40 }
     41 
     42 func newScanner(ctx context.Context, db db.Db) (*scanner, error) {
     43 	return &scanner{
     44 		ctx: ctx,
     45 		db: db,
     46 	}, nil
     47 }
     48 
     49 func(sc *scanner) Close() error {
     50 	return sc.db.Close()
     51 }
     52 
     53 func(sc *scanner) Scan(fp string, d fs.DirEntry, err error) error { 
     54 	if err != nil {
     55 		return err
     56 	}
     57 	if d.IsDir() {
     58 		return nil
     59 	}
     60 	fx := path.Ext(fp)
     61 	fb := path.Base(fp)
     62 	if (len(fb) == 0) {
     63 		return nil
     64 	}
     65 	if (fb[0] < 0x61 || fb[0] > 0x7A) {
     66 		return nil
     67 	}
     68 	sc.db.SetPrefix(db.DATATYPE_UNKNOWN)
     69 	switch fx {
     70 		case binaryPrefix:
     71 			sc.db.SetPrefix(db.DATATYPE_BIN)
     72 			//typ = db.DATATYPE_BIN
     73 		case templatePrefix:
     74 			if strings.Contains(fb, "_menu") {
     75 				sc.db.SetPrefix(db.DATATYPE_TEMPLATE)
     76 				//typ = db.DATATYPE_TEMPLATE
     77 			} else {
     78 				sc.db.SetPrefix(db.DATATYPE_MENU)
     79 				//typ = db.DATATYPE_MENU
     80 			}
     81 		case staticloadPrefix:
     82 			sc.db.SetPrefix(db.DATATYPE_STATICLOAD)
     83 		default:
     84 			log.Printf("skip foreign file: %s", fp)
     85 			return nil
     86 	}
     87 	f, err := os.Open(fp)
     88 	defer f.Close()
     89 	if err != nil{
     90 		return err
     91 	}
     92 	v, err := io.ReadAll(f)
     93 	if err != nil{
     94 		return err
     95 	}
     96 
     97 	logg.TraceCtxf(sc.ctx, "put record", "fx", fx, "fb", fb)
     98 	ft := fb[:len(fb)-len(fx)]
     99 	err = sc.db.Put(sc.ctx, []byte(ft), v)
    100 	if err != nil {
    101 		return err
    102 	}
    103 	//k := db.ToDbKey(typ, []byte(ft), nil)
    104 	//err = sc.db.Store(k, v, true)
    105 	//if err != nil {
    106 	//	return err
    107 	//}
    108 	return nil
    109 }
    110 
    111 func main() {
    112 	var store db.Db
    113 	var err error
    114 	var dir string
    115 	var dbPath string
    116 	var dbFile string
    117 	var dbBackend string
    118 	flag.StringVar(&dbPath, "d", "", "output directory")
    119 	flag.StringVar(&dbBackend, "backend", "gdbm", "db backend. valid choices are: gdbm (default), fs")
    120 	flag.Parse()
    121 
    122 	ctx := context.Background()
    123 	switch dbBackend {
    124 	case "gdbm":
    125 		store = gdbmdb.NewGdbmDb()
    126 		dbFile = "vise_resources.gdbm"
    127 	case "fs":
    128 		store = fsdb.NewFsDb()
    129 	}
    130 
    131 	dir = flag.Arg(0)
    132 
    133 	if dbPath == "" {
    134 		dbPath, err = os.MkdirTemp(dir, "vise-dbconvert-*")
    135 	} else {
    136 		err = os.MkdirAll(dir, 0700)
    137 	}
    138 	if err != nil {
    139 		fmt.Fprintf(os.Stderr, "failed to create output dir")
    140 		os.Exit(1)
    141 	}
    142 	if dbFile != "" {
    143 		dbPath = path.Join(dbPath, dbFile)
    144 	}
    145 	if dir == dbPath {
    146 		fmt.Fprintf(os.Stderr, "input and output dir cannot be the same")
    147 	}
    148 
    149 	err = store.Connect(ctx, dbPath)
    150 	if err != nil {
    151 		fmt.Fprintf(os.Stderr, "failed to connect to output db: %s", err)
    152 		os.Exit(1)
    153 	}
    154 	
    155 	store.SetLock(db.DATATYPE_BIN, false)
    156 	store.SetLock(db.DATATYPE_TEMPLATE, false)
    157 	store.SetLock(db.DATATYPE_MENU, false)
    158 	store.SetLock(db.DATATYPE_STATICLOAD, false)
    159 
    160 	o, err := newScanner(ctx, store)
    161 	if err != nil {
    162 		fmt.Fprintf(os.Stderr, "failed to open scanner")
    163 		os.Exit(1)
    164 	}
    165 	err = filepath.WalkDir(dir, o.Scan)
    166 	if err != nil {
    167 		fmt.Fprintf(os.Stderr, "failed to process input: %s", err)
    168 		os.Exit(1)
    169 	}
    170 	fmt.Fprintf(os.Stdout, dbPath)
    171 }