go-vise

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

commit 927cb8b75a97c335f16894d3ba1ffe8cefe76e3c
parent 2492d80a6a8448c46fbacb8562a84ceac36d222b
Author: lash <dev@holbrook.no>
Date:   Tue, 14 Jan 2025 19:59:28 +0000

Add fs db dumper

Diffstat:
Mdb/db.go | 1+
Mdb/fs/dump.go | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Adb/fs/dump_test.go | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdb/fs/fs.go | 2++
Mdb/gdbm/dump.go | 1+
5 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/db/db.go b/db/db.go @@ -209,5 +209,6 @@ func(bd *DbBase) ToKey(ctx context.Context, key []byte) (LookupKey, error) { lk.Translation = ToDbKey(db.pfx, b, ln) } } + logg.TraceCtxf(ctx, "made key", "lk", lk.Default, "pfx", db.pfx) return lk, nil } diff --git a/db/fs/dump.go b/db/fs/dump.go @@ -1,12 +1,72 @@ package fs import ( + "bytes" "context" - "errors" + "os" "git.defalsify.org/vise.git/db" ) func(fdb *fsDb) Dump(ctx context.Context, key []byte) (*db.Dumper, error) { - return nil, errors.New("unimplemented") + var err error + key = append([]byte{db.DATATYPE_USERDATA}, key...) + fdb.matchPrefix = key + fdb.elements, err = os.ReadDir(fdb.dir) + if err != nil { + return nil, err + } + + if len(fdb.elements) > 0 { + if len(key) == 0 { + v := fdb.elements[0] + fdb.elements = fdb.elements[1:] + s := v.Name() + k := []byte(s) + k[0] -= 0x30 + vv, err := fdb.Get(ctx, k) + if err != nil { + return nil, err + } + return db.NewDumper(fdb.dumpFunc).WithFirst(k, vv), nil + } + } + for len(fdb.elements) > 0 { + v := fdb.elements[0] + fdb.elements = fdb.elements[1:] + s := v.Name() + k := []byte(s) + if len(key) > len(k) { + continue + } + k[0] -= 0x30 + if bytes.HasPrefix(k, key) { + vv, err := fdb.Get(ctx, k[1:]) + if err != nil { + return nil, err + } + return db.NewDumper(fdb.dumpFunc).WithFirst(k, vv), nil + } + } + return nil, db.NewErrNotFound(key) +} + +func(fdb *fsDb) dumpFunc(ctx context.Context) ([]byte, []byte) { + if len(fdb.elements) == 0 { + return nil, nil + } + v := fdb.elements[0] + fdb.elements = fdb.elements[1:] + s := v.Name() + k := []byte(s) + k[0] -= 0x30 + if bytes.HasPrefix(k, fdb.matchPrefix) { + vv, err := fdb.Get(ctx, k[1:]) + if err != nil { + logg.ErrorCtxf(ctx, "failed to get entry", "key", k) + return nil, nil + } + return k, vv + } + return nil, nil } diff --git a/db/fs/dump_test.go b/db/fs/dump_test.go @@ -0,0 +1,68 @@ +package fs + +import ( + "bytes" + "context" + "io/ioutil" + "testing" + + "git.defalsify.org/vise.git/db" +) + +func TestDumpFs(t *testing.T) { + ctx := context.Background() + + store := NewFsDb() + d, err := ioutil.TempDir("", "vise-db-fs-*") + if err != nil { + t.Fatal(err) + } + err = store.Connect(ctx, d) + if err != nil { + t.Fatal(err) + } + + store.SetPrefix(db.DATATYPE_USERDATA) + err = store.Put(ctx, []byte("bar"), []byte("inky")) + if err != nil { + t.Fatal(err) + } + err = store.Put(ctx, []byte("foobar"), []byte("pinky")) + if err != nil { + t.Fatal(err) + } + err = store.Put(ctx, []byte("foobarbaz"), []byte("blinky")) + if err != nil { + t.Fatal(err) + } + err = store.Put(ctx, []byte("xyzzy"), []byte("clyde")) + if err != nil { + t.Fatal(err) + } + + o, err := store.Dump(ctx, []byte("foo")) + if err != nil { + t.Fatal(err) + } + k, v := o.Next(ctx) + if !bytes.Equal(k, append([]byte{db.DATATYPE_USERDATA}, []byte("foobar")...)) { + t.Fatalf("expected key 'foobar', got %s", k) + } + if !bytes.Equal(v, []byte("pinky")) { + t.Fatalf("expected val 'pinky', got %s", v) + } + k, v = o.Next(ctx) + if !bytes.Equal(k, append([]byte{db.DATATYPE_USERDATA}, []byte("foobarbaz")...)) { + t.Fatalf("expected key 'foobarbaz', got %s", k) + } + if !bytes.Equal(v, []byte("blinky")) { + t.Fatalf("expected val 'blinky', got %s", v) + } + k, v = o.Next(ctx) + if k != nil { + t.Fatalf("expected nil, got %s", k) + } +} +func TestDump(t *testing.T) { + +} diff --git a/db/fs/fs.go b/db/fs/fs.go @@ -21,6 +21,8 @@ type fsLookupKey struct { type fsDb struct { *db.DbBase dir string + elements []os.DirEntry + matchPrefix []byte } diff --git a/db/gdbm/dump.go b/db/gdbm/dump.go @@ -10,6 +10,7 @@ import ( "git.defalsify.org/vise.git/db" ) +// TODO: userdata is hardcoded here, should not be func(gdb *gdbmDb) Dump(ctx context.Context, key []byte) (*db.Dumper, error) { key = append([]byte{db.DATATYPE_USERDATA}, key...) gdb.it = gdb.conn.Iterator()