go-vise

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

commit 7ea16f9137b46ff746f6ba40d3afc7b305d98f87
parent 5769abf3366f78392dd9ad59607fde3bfe3e63b3
Author: lash <dev@holbrook.no>
Date:   Sun, 22 Sep 2024 16:21:36 +0100

Add read only modifier to database

Diffstat:
Mdb/gdbm/gdbm.go | 36+++++++++++++++++++++++++++++++-----
Mengine/db.go | 2+-
Mstate/state.go | 6+++++-
3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/db/gdbm/gdbm.go b/db/gdbm/gdbm.go @@ -3,6 +3,7 @@ package gdbm import ( "context" "errors" + "fmt" "os" gdbm "github.com/graygnuorg/go-gdbm" @@ -14,6 +15,7 @@ import ( type gdbmDb struct { *db.DbBase conn *gdbm.Database + readOnly bool prefix uint8 } @@ -25,6 +27,18 @@ func NewGdbmDb() *gdbmDb { return db } +// WithReadOnly sets database as read only. +// +// There may exist more than one instance of read-only +// databases to the same file at the same time. +// However, only one single write database. +// +// Readonly cannot be set when creating a new database. +func(gdb *gdbmDb) WithReadOnly() *gdbmDb { + gdb.readOnly = true + return gdb +} + // String implements the string interface. func(gdb *gdbmDb) String() string { fn, err := gdb.conn.FileName() @@ -41,18 +55,30 @@ func(gdb *gdbmDb) Connect(ctx context.Context, connStr string) error { return nil } var db *gdbm.Database + cfg := gdbm.DatabaseConfig{ + FileName: connStr, + Flags: gdbm.OF_NOLOCK | gdbm.OF_PREREAD, + FileMode: 0600, + } + _, err := os.Stat(connStr) if err != nil { if !errors.Is(err.(*os.PathError).Unwrap(), os.ErrNotExist) { - return err + return fmt.Errorf("db path lookup err: %v", err) } - db, err = gdbm.Open(connStr, gdbm.ModeWrcreat) + if gdb.readOnly { + return fmt.Errorf("cannot open new database readonly") + } + cfg.Mode = gdbm.ModeReader | gdbm.ModeWrcreat } else { - db, err = gdbm.Open(connStr, gdbm.ModeWriter | gdbm.ModeReader) + cfg.Mode = gdbm.ModeReader + if !gdb.readOnly { + cfg.Mode |= gdbm.ModeWriter + } } - + db, err = gdbm.OpenConfig(cfg) if err != nil { - return err + return fmt.Errorf("db open err: %v", err) } logg.DebugCtxf(ctx, "gdbm connected", "connstr", connStr) gdb.conn = db diff --git a/engine/db.go b/engine/db.go @@ -244,7 +244,7 @@ func(en *DefaultEngine) ensurePersist() error { } else { en.ca = cac } - logg.Tracef("set persister", "st", st, "cac", cac) + logg.Tracef("set persister", "st", st, "cac", cac, "session", en.cfg.SessionId) en.pe = en.pe.WithContent(st, cac) err := en.pe.Load(en.cfg.SessionId) if err != nil { diff --git a/state/state.go b/state/state.go @@ -7,6 +7,10 @@ import ( "git.defalsify.org/vise.git/lang" ) +const ( + INPUT_LIMIT = 255 +) + var ( IndexError = fmt.Errorf("already at first index") MaxLevel = 128 @@ -347,7 +351,7 @@ func(st *State) GetInput() ([]byte, error) { // SetInput is used to record the latest client input. func(st *State) SetInput(input []byte) error { l := len(input) - if l > 255 { + if l > INPUT_LIMIT { return fmt.Errorf("input size %v too large (limit %v)", l, 255) } st.input = input