commit df0eec0f9617c615c85175de10694fdc2bf4346e
parent c18958992e9fefba6a1f269b4f0e4b86318173b6
Author: lash <dev@holbrook.no>
Date: Wed, 28 Aug 2024 01:55:11 +0100
Add gdbm example
Diffstat:
3 files changed, 115 insertions(+), 12 deletions(-)
diff --git a/dev/gdbm/main.go b/dev/gdbm/main.go
@@ -11,6 +11,8 @@ import (
"path"
gdbm "github.com/graygnuorg/go-gdbm"
+
+ "git.defalsify.org/vise.git/resource"
)
var (
@@ -19,11 +21,6 @@ var (
scan = make(map[string]string)
)
-const (
- RESOURCETYPE_UNKNOWN = iota
- RESOURCETYPE_BIN
- RESOURCETYPE_TEMPLATE
-)
type scanner struct {
db *gdbm.Database
@@ -44,10 +41,11 @@ func(sc *scanner) Close() error {
}
func(sc *scanner) Scan(fp string, d fs.DirEntry, err error) error {
+ var typ uint8
if err != nil {
return err
}
- typ := RESOURCETYPE_UNKNOWN
+ typ = resource.FSRESOURCETYPE_UNKNOWN
if d.IsDir() {
return nil
}
@@ -55,9 +53,9 @@ func(sc *scanner) Scan(fp string, d fs.DirEntry, err error) error {
fb := path.Base(fp)
switch fx {
case binaryPrefix:
- typ = RESOURCETYPE_BIN
+ typ = resource.FSRESOURCETYPE_BIN
case templatePrefix:
- typ = RESOURCETYPE_TEMPLATE
+ typ = resource.FSRESOURCETYPE_TEMPLATE
default:
log.Printf("skip foreign file: %s", fp)
return nil
@@ -72,10 +70,15 @@ func(sc *scanner) Scan(fp string, d fs.DirEntry, err error) error {
return err
}
- ft := path.Base(fb)
- k := []byte{uint8(typ)}
- k = append(k, []byte(ft)...)
- return sc.db.Store(k, v, true)
+ log.Printf("fx fb %s %s", fx, fb)
+ ft := fb[:len(fb)-len(fx)]
+ k := resource.ToDbKey(typ, ft, nil)
+ err = sc.db.Store(k, v, true)
+ if err != nil {
+ return err
+ }
+ log.Printf("stored key %x for %s (%s)", k, fp, ft)
+ return nil
}
func main() {
diff --git a/resource/fs.go b/resource/fs.go
@@ -13,6 +13,12 @@ import (
"git.defalsify.org/vise.git/lang"
)
+const (
+ FSRESOURCETYPE_UNKNOWN = iota
+ FSRESOURCETYPE_BIN
+ FSRESOURCETYPE_TEMPLATE
+)
+
type FsResource struct {
MenuResource
Path string
diff --git a/resource/gdbm.go b/resource/gdbm.go
@@ -0,0 +1,94 @@
+package resource
+
+import (
+ "context"
+ "fmt"
+ "log"
+
+ gdbm "github.com/graygnuorg/go-gdbm"
+ "git.defalsify.org/vise.git/lang"
+)
+
+
+type gdbmResource struct {
+ db *gdbm.Database
+ fns map[string]EntryFunc
+}
+
+func NewGdbmResource(fp string) *gdbmResource {
+ db, err := gdbm.Open(fp, gdbm.ModeReader)
+ if err != nil {
+ panic(err)
+ }
+ return &gdbmResource{
+ db: db,
+ }
+}
+
+func ToDbKey(typ uint8, s string, l *lang.Language) []byte {
+ k := []byte{typ}
+ if l != nil && l.Code != "" {
+ s += "_" + l.Code
+ }
+ return append(k, []byte(s)...)
+}
+
+
+func(dbr *gdbmResource) GetTemplate(ctx context.Context, sym string) (string, error) {
+ var ln lang.Language
+ v := ctx.Value("Language")
+ if v != nil {
+ ln = v.(lang.Language)
+ }
+ k := ToDbKey(FSRESOURCETYPE_TEMPLATE, sym, &ln)
+ log.Printf("db fetch %x for %s", k, sym)
+ r, err := dbr.db.Fetch(k)
+ if err != nil {
+ return "", err
+ }
+ return string(r), nil
+}
+
+func(dbr *gdbmResource) GetCode(sym string) ([]byte, error) {
+ k := ToDbKey(FSRESOURCETYPE_BIN, sym, nil)
+ return dbr.db.Fetch(k)
+}
+
+func(dbr *gdbmResource) GetMenu(ctx context.Context, sym string) (string, error) {
+ msym := sym + "_menu"
+ var ln lang.Language
+ v := ctx.Value("Language")
+ if v != nil {
+ ln = v.(lang.Language)
+ }
+ k := ToDbKey(FSRESOURCETYPE_TEMPLATE, msym, &ln)
+ r, err := dbr.db.Fetch(k)
+ if err != nil {
+ log.Printf("fetch %x", k)
+ if err.(*gdbm.GdbmError).Is(gdbm.ErrItemNotFound) {
+ return sym, nil
+ }
+ return "", err
+ }
+ return string(r), nil
+
+}
+
+func(dbr gdbmResource) FuncFor(sym string) (EntryFunc, error) {
+ fn, ok := dbr.fns[sym]
+ if !ok {
+ return nil, fmt.Errorf("function %s not found", sym)
+ }
+ return fn, nil
+}
+
+func(dbr *gdbmResource) AddLocalFunc(sym string, fn EntryFunc) {
+ if dbr.fns == nil {
+ dbr.fns = make(map[string]EntryFunc)
+ }
+ dbr.fns[sym] = fn
+}
+
+func(dbr *gdbmResource) String() string {
+ return fmt.Sprintf("gdbm: %v", dbr.db)
+}