Compare commits

..

No commits in common. "master" and "lash/dbtx" have entirely different histories.

17 changed files with 124 additions and 200 deletions

View File

@ -9,38 +9,23 @@ import (
) )
var ( var (
logg = logging.NewVanilla().WithDomain("visedriver-config") logg = logging.NewVanilla().WithDomain("visedriver-config")
defaultLanguage = "eng" defaultLanguage = "eng"
languages []string languages []string
DefaultLanguage string DefaultLanguage string
dbConn string dbConn string
dbConnMissing bool dbConnMissing bool
dbConnMode storage.DbMode stateDbConn string
stateDbConn string resourceDbConn string
stateDbConnMode storage.DbMode userDbConn string
resourceDbConn string Languages []string
resourceDbConnMode storage.DbMode
userDbConn string
userDbConnMode storage.DbMode
Languages []string
) )
type Override struct {
DbConn string
DbConnMode storage.DbMode
StateConn string
StateConnMode storage.DbMode
ResourceConn string
ResourceConnMode storage.DbMode
UserConn string
UserConnMode storage.DbMode
}
func setLanguage() error { func setLanguage() error {
defaultLanguage = env.GetEnv("DEFAULT_LANGUAGE", defaultLanguage) defaultLanguage = env.GetEnv("DEFAULT_LANGUAGE", defaultLanguage)
languages = strings.Split(env.GetEnv("LANGUAGES", defaultLanguage), ",") languages = strings.Split(env.GetEnv("LANGUAGES", defaultLanguage), ",")
haveDefaultLanguage := false haveDefaultLanguage := false
for i, v := range languages { for i, v := range(languages) {
languages[i] = strings.ReplaceAll(v, " ", "") languages[i] = strings.ReplaceAll(v, " ", "")
if languages[i] == defaultLanguage { if languages[i] == defaultLanguage {
haveDefaultLanguage = true haveDefaultLanguage = true
@ -62,22 +47,18 @@ func setConn() error {
return nil return nil
} }
func ApplyConn(override *Override) { func ApplyConn(connStr *string, stateConnStr *string, resourceConnStr *string, userConnStr *string) {
if override.DbConn != "?" { if connStr != nil {
dbConn = override.DbConn dbConn = *connStr
stateDbConn = override.StateConn
resourceDbConn = override.ResourceConn
userDbConn = override.UserConn
} }
dbConnMode = override.DbConnMode if stateConnStr != nil {
if override.StateConn != "?" { stateDbConn = *stateConnStr
stateDbConn = override.StateConn
} }
if override.ResourceConn != "?" { if resourceConnStr != nil {
resourceDbConn = override.ResourceConn resourceDbConn = *resourceConnStr
} }
if override.UserConn != "?" { if userConnStr != nil {
userDbConn = override.UserConn userDbConn = *userConnStr
} }
if dbConn == "?" { if dbConn == "?" {
@ -86,45 +67,28 @@ func ApplyConn(override *Override) {
if stateDbConn == "?" { if stateDbConn == "?" {
stateDbConn = dbConn stateDbConn = dbConn
stateDbConnMode = dbConnMode
} }
if resourceDbConn == "?" { if resourceDbConn == "?" {
resourceDbConn = dbConn resourceDbConn = dbConn
resourceDbConnMode = dbConnMode
} }
if userDbConn == "?" { if userDbConn == "?" {
userDbConn = dbConn userDbConn = dbConn
userDbConnMode = dbConnMode
}
logg.Debugf("conns", "conn", dbConn, "user", userDbConn)
if override.DbConnMode != storage.DBMODE_ANY {
dbConnMode = override.DbConnMode
}
if override.StateConnMode != storage.DBMODE_ANY {
stateDbConnMode = override.StateConnMode
}
if override.ResourceConnMode != storage.DBMODE_ANY {
resourceDbConnMode = override.ResourceConnMode
}
if override.UserConnMode != storage.DBMODE_ANY {
userDbConnMode = override.UserConnMode
} }
} }
func GetConns() (storage.Conns, error) { func GetConns() (storage.Conns, error) {
o := storage.NewConns() o := storage.NewConns()
c, err := storage.ToConnDataMode(stateDbConn, stateDbConnMode) c, err := storage.ToConnData(stateDbConn)
if err != nil { if err != nil {
return o, err return o, err
} }
o.Set(c, storage.STORETYPE_STATE) o.Set(c, storage.STORETYPE_STATE)
c, err = storage.ToConnDataMode(resourceDbConn, resourceDbConnMode) c, err = storage.ToConnData(resourceDbConn)
if err != nil { if err != nil {
return o, err return o, err
} }
o.Set(c, storage.STORETYPE_RESOURCE) o.Set(c, storage.STORETYPE_RESOURCE)
c, err = storage.ToConnDataMode(userDbConn, userDbConnMode) c, err = storage.ToConnData(userDbConn)
if err != nil { if err != nil {
return o, err return o, err
} }

View File

@ -2,9 +2,8 @@ package entry
import ( import (
"context" "context"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/persist"
) )
type EntryHandler interface { type EntryHandler interface {

2
go.mod
View File

@ -3,7 +3,7 @@ module git.grassecon.net/grassrootseconomics/visedriver
go 1.23.0 go 1.23.0
require ( require (
git.defalsify.org/vise.git v0.2.3-0.20250204132233-2bffe532f21e git.defalsify.org/vise.git v0.2.3-0.20250119111745-4f69d6fe5939
github.com/jackc/pgx/v5 v5.7.1 github.com/jackc/pgx/v5 v5.7.1
github.com/joho/godotenv v1.5.1 github.com/joho/godotenv v1.5.1
) )

4
go.sum
View File

@ -1,5 +1,5 @@
git.defalsify.org/vise.git v0.2.3-0.20250204132233-2bffe532f21e h1:gtB9OdX6x5gQRM3W824dEurXuuf/YPInqgtv2KAp5Zo= git.defalsify.org/vise.git v0.2.3-0.20250119111745-4f69d6fe5939 h1:DA0gus9TuKpLvZMDmmqCAwAr5Lly+U93jtO2OKtGAeo=
git.defalsify.org/vise.git v0.2.3-0.20250204132233-2bffe532f21e/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= git.defalsify.org/vise.git v0.2.3-0.20250119111745-4f69d6fe5939/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE= github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U= github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@ -7,37 +7,28 @@ import (
"git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/resource"
"git.grassecon.net/grassrootseconomics/visedriver/entry"
"git.grassecon.net/grassrootseconomics/visedriver/errors"
"git.grassecon.net/grassrootseconomics/visedriver/storage" "git.grassecon.net/grassrootseconomics/visedriver/storage"
"git.grassecon.net/grassrootseconomics/visedriver/errors"
"git.grassecon.net/grassrootseconomics/visedriver/entry"
) )
type EngineFunc func(engine.Config, resource.Resource, *persist.Persister) engine.Engine
type BaseRequestHandler struct { type BaseRequestHandler struct {
cfgTemplate engine.Config cfgTemplate engine.Config
rp RequestParser rp RequestParser
rs resource.Resource rs resource.Resource
hn entry.EntryHandler hn entry.EntryHandler
provider storage.StorageProvider provider storage.StorageProvider
engineFunc EngineFunc
} }
//func NewBaseRequestHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, rp request.RequestParser, hn *handlers.Handlers) *BaseRequestHandler {
func NewBaseRequestHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, rp RequestParser, hn entry.EntryHandler) *BaseRequestHandler { func NewBaseRequestHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, rp RequestParser, hn entry.EntryHandler) *BaseRequestHandler {
h := &BaseRequestHandler{ return &BaseRequestHandler{
cfgTemplate: cfg, cfgTemplate: cfg,
rs: rs, rs: rs,
hn: hn, hn: hn,
rp: rp, rp: rp,
provider: storage.NewSimpleStorageProvider(stateDb, userdataDb), provider: storage.NewSimpleStorageProvider(stateDb, userdataDb),
} }
h.engineFunc = h.getDefaultEngine
return h
}
func (f *BaseRequestHandler) WithEngineFunc(fn EngineFunc) *BaseRequestHandler {
f.engineFunc = fn
return f
} }
func (f *BaseRequestHandler) Shutdown(ctx context.Context) { func (f *BaseRequestHandler) Shutdown(ctx context.Context) {
@ -48,22 +39,15 @@ func (f *BaseRequestHandler) Shutdown(ctx context.Context) {
} }
func (f *BaseRequestHandler) GetEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine { func (f *BaseRequestHandler) GetEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine {
return f.engineFunc(cfg, rs, pr)
}
func (f *BaseRequestHandler) getDefaultEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine {
en := engine.NewEngine(cfg, rs) en := engine.NewEngine(cfg, rs)
en = en.WithPersister(pr) en = en.WithPersister(pr)
en = en.WithFirst(f.hn.Init)
if f.cfgTemplate.EngineDebug {
en = en.WithDebug(nil)
}
return en return en
} }
func (f *BaseRequestHandler) Process(rqs RequestSession) (RequestSession, error) { func(f *BaseRequestHandler) Process(rqs RequestSession) (RequestSession, error) {
var r bool var r bool
var err error var err error
var ok bool
logg.InfoCtxf(rqs.Ctx, "new request", "data", rqs) logg.InfoCtxf(rqs.Ctx, "new request", "data", rqs)
@ -73,12 +57,27 @@ func (f *BaseRequestHandler) Process(rqs RequestSession) (RequestSession, error)
return rqs, errors.ErrStorage return rqs, errors.ErrStorage
} }
//f.hn = f.hn.WithPersister(rqs.Storage.Persister)
f.hn.SetPersister(rqs.Storage.Persister) f.hn.SetPersister(rqs.Storage.Persister)
defer func() { defer func() {
f.hn.Exit() f.hn.Exit()
}() }()
eni := f.GetEngine(rqs.Config, f.rs, rqs.Storage.Persister)
en, ok := eni.(*engine.DefaultEngine)
if !ok {
perr := f.provider.Put(rqs.Ctx, rqs.Config.SessionId, rqs.Storage)
rqs.Storage = nil
if perr != nil {
logg.ErrorCtxf(rqs.Ctx, "", "storage put error", perr)
}
return rqs, errors.ErrEngineType
}
en = en.WithFirst(f.hn.Init)
if rqs.Config.EngineDebug {
en = en.WithDebug(nil)
}
rqs.Engine = en
rqs.Engine = f.GetEngine(rqs.Config, f.rs, rqs.Storage.Persister)
r, err = rqs.Engine.Exec(rqs.Ctx, rqs.Input) r, err = rqs.Engine.Exec(rqs.Ctx, rqs.Input)
if err != nil { if err != nil {
perr := f.provider.Put(rqs.Ctx, rqs.Config.SessionId, rqs.Storage) perr := f.provider.Put(rqs.Ctx, rqs.Config.SessionId, rqs.Storage)
@ -93,13 +92,13 @@ func (f *BaseRequestHandler) Process(rqs RequestSession) (RequestSession, error)
return rqs, nil return rqs, nil
} }
func (f *BaseRequestHandler) Output(rqs RequestSession) (RequestSession, error) { func(f *BaseRequestHandler) Output(rqs RequestSession) (RequestSession, error) {
var err error var err error
_, err = rqs.Engine.Flush(rqs.Ctx, rqs.Writer) _, err = rqs.Engine.Flush(rqs.Ctx, rqs.Writer)
return rqs, err return rqs, err
} }
func (f *BaseRequestHandler) Reset(ctx context.Context, rqs RequestSession) (RequestSession, error) { func(f *BaseRequestHandler) Reset(ctx context.Context, rqs RequestSession) (RequestSession, error) {
defer f.provider.Put(ctx, rqs.Config.SessionId, rqs.Storage) defer f.provider.Put(ctx, rqs.Config.SessionId, rqs.Storage)
return rqs, rqs.Engine.Finish(ctx) return rqs, rqs.Engine.Finish(ctx)
} }
@ -108,6 +107,6 @@ func (f *BaseRequestHandler) GetConfig() engine.Config {
return f.cfgTemplate return f.cfgTemplate
} }
func (f *BaseRequestHandler) GetRequestParser() RequestParser { func(f *BaseRequestHandler) GetRequestParser() RequestParser {
return f.rp return f.rp
} }

View File

@ -5,8 +5,8 @@ import (
"strconv" "strconv"
"git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/logging"
"git.grassecon.net/grassrootseconomics/visedriver/errors"
"git.grassecon.net/grassrootseconomics/visedriver/request" "git.grassecon.net/grassrootseconomics/visedriver/request"
"git.grassecon.net/grassrootseconomics/visedriver/errors"
) )
var ( var (

View File

@ -10,8 +10,8 @@ import (
"git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/engine"
viseerrors "git.grassecon.net/grassrootseconomics/visedriver/errors" viseerrors "git.grassecon.net/grassrootseconomics/visedriver/errors"
"git.grassecon.net/grassrootseconomics/visedriver/request"
"git.grassecon.net/grassrootseconomics/visedriver/testutil/mocks/httpmocks" "git.grassecon.net/grassrootseconomics/visedriver/testutil/mocks/httpmocks"
"git.grassecon.net/grassrootseconomics/visedriver/request"
) )
// invalidRequestType is a custom type to test invalid request scenarios // invalidRequestType is a custom type to test invalid request scenarios
@ -165,7 +165,7 @@ func TestDefaultRequestParser_GetSessionId(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
id, err := parser.GetSessionId(context.Background(), tt.request) id, err := parser.GetSessionId(context.Background(),tt.request)
if id != tt.expectedID { if id != tt.expectedID {
t.Errorf("Expected session ID %s, got %s", tt.expectedID, id) t.Errorf("Expected session ID %s, got %s", tt.expectedID, id)

View File

@ -4,10 +4,10 @@ import (
"context" "context"
"io" "io"
"git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/grassrootseconomics/visedriver/storage" "git.grassecon.net/grassrootseconomics/visedriver/storage"
) )
@ -16,12 +16,12 @@ var (
) )
type RequestSession struct { type RequestSession struct {
Ctx context.Context Ctx context.Context
Config engine.Config Config engine.Config
Engine engine.Engine Engine engine.Engine
Input []byte Input []byte
Storage *storage.Storage Storage *storage.Storage
Writer io.Writer Writer io.Writer
Continue bool Continue bool
} }
@ -34,7 +34,7 @@ type RequestParser interface {
type RequestHandler interface { type RequestHandler interface {
GetConfig() engine.Config GetConfig() engine.Config
GetRequestParser() RequestParser GetRequestParser() RequestParser
GetEngine(engine.Config, resource.Resource, *persist.Persister) engine.Engine GetEngine(engine.Config, resource.Resource, *persist.Persister) engine.Engine
Process(RequestSession) (RequestSession, error) Process(RequestSession) (RequestSession, error)
Output(RequestSession) (RequestSession, error) Output(RequestSession) (RequestSession, error)
Reset(context.Context, RequestSession) (RequestSession, error) Reset(context.Context, RequestSession) (RequestSession, error)

View File

@ -5,8 +5,6 @@ import (
"net/url" "net/url"
) )
type DbMode uint8
const ( const (
DBTYPE_NONE = iota DBTYPE_NONE = iota
DBTYPE_MEM DBTYPE_MEM
@ -15,12 +13,6 @@ const (
DBTYPE_POSTGRES DBTYPE_POSTGRES
) )
const (
DBMODE_ANY DbMode = iota
DBMODE_BINARY
DBMODE_TEXT
)
const ( const (
STORETYPE_STATE = iota STORETYPE_STATE = iota
STORETYPE_RESOURCE STORETYPE_RESOURCE
@ -28,12 +20,6 @@ const (
_STORETYPE_MAX _STORETYPE_MAX
) )
var (
DbModeDebug = []string{"ANY", "BIN", "TXT"}
DbTypeDebug = []string{"NONE", "MEM", "FS", "GDBM", "POSTGRES"}
DbStoreDebug = []string{"STATE", "RESOURCE", "USER"}
)
type Conns map[int8]ConnData type Conns map[int8]ConnData
func NewConns() Conns { func NewConns() Conns {
@ -49,50 +35,39 @@ func (c Conns) Set(conn ConnData, typ int8) {
} }
func (c Conns) Have(conn *ConnData) int8 { func (c Conns) Have(conn *ConnData) int8 {
for i := range _STORETYPE_MAX { for i := range(_STORETYPE_MAX) {
ii := int8(i) ii := int8(i)
v, ok := c[ii] v, ok := c[ii]
if !ok { if !ok {
continue continue
} }
if v.Raw() == conn.Raw() { if v.String() == conn.String() {
if v.Mode() == DBMODE_ANY || v.Mode() == conn.Mode() { return ii
return ii
}
} }
} }
return -1 return -1
} }
type ConnData struct { type ConnData struct {
typ int typ int
str string str string
domain string domain string
mode DbMode
} }
func (cd *ConnData) DbType() int { func (cd *ConnData) DbType() int {
return cd.typ return cd.typ
} }
func (cd ConnData) String() string { func (cd *ConnData) String() string {
return fmt.Sprintf("conn: %s, mod %s, typ %s", cd.str, DbModeDebug[uint8(cd.mode)], DbTypeDebug[uint8(cd.typ)]) return cd.str
} }
func (cd *ConnData) Domain() string { func (cd *ConnData) Domain() string {
return cd.domain return cd.domain
} }
func (cd *ConnData) Mode() DbMode {
return cd.mode
}
func (cd *ConnData) Path() string { func (cd *ConnData) Path() string {
v, _ := url.Parse(cd.str) v, _ := url.Parse(cd.str)
v.RawQuery = "" v.RawQuery = ""
return v.String() return v.String()
} }
func (cd *ConnData) Raw() string {
return cd.str
}

View File

@ -18,7 +18,7 @@ var (
) )
type ThreadGdbmDb struct { type ThreadGdbmDb struct {
db db.Db db db.Db
connStr string connStr string
} }
@ -29,7 +29,7 @@ func NewThreadGdbmDb() *ThreadGdbmDb {
return &ThreadGdbmDb{} return &ThreadGdbmDb{}
} }
func (tdb *ThreadGdbmDb) Connect(ctx context.Context, connStr string) error { func(tdb *ThreadGdbmDb) Connect(ctx context.Context, connStr string) error {
var ok bool var ok bool
_, ok = dbC[connStr] _, ok = dbC[connStr]
if ok { if ok {
@ -42,18 +42,18 @@ func (tdb *ThreadGdbmDb) Connect(ctx context.Context, connStr string) error {
return err return err
} }
dbC[connStr] = make(chan db.Db, 1) dbC[connStr] = make(chan db.Db, 1)
dbC[connStr] <- gdb dbC[connStr]<- gdb
tdb.connStr = connStr tdb.connStr = connStr
return nil return nil
} }
func (tdb *ThreadGdbmDb) reserve() { func(tdb *ThreadGdbmDb) reserve() {
if tdb.db == nil { if tdb.db == nil {
tdb.db = <-dbC[tdb.connStr] tdb.db = <-dbC[tdb.connStr]
} }
} }
func (tdb *ThreadGdbmDb) release() { func(tdb *ThreadGdbmDb) release() {
if tdb.db == nil { if tdb.db == nil {
return return
} }
@ -61,57 +61,57 @@ func (tdb *ThreadGdbmDb) release() {
tdb.db = nil tdb.db = nil
} }
func (tdb *ThreadGdbmDb) SetPrefix(pfx uint8) { func(tdb *ThreadGdbmDb) SetPrefix(pfx uint8) {
tdb.reserve() tdb.reserve()
tdb.db.SetPrefix(pfx) tdb.db.SetPrefix(pfx)
} }
func (tdb *ThreadGdbmDb) SetSession(sessionId string) { func(tdb *ThreadGdbmDb) SetSession(sessionId string) {
tdb.reserve() tdb.reserve()
tdb.db.SetSession(sessionId) tdb.db.SetSession(sessionId)
} }
func (tdb *ThreadGdbmDb) SetLanguage(lng *lang.Language) { func(tdb *ThreadGdbmDb) SetLanguage(lng *lang.Language) {
tdb.reserve() tdb.reserve()
tdb.db.SetLanguage(lng) tdb.db.SetLanguage(lng)
} }
func (tdb *ThreadGdbmDb) Safe() bool { func(tdb *ThreadGdbmDb) Safe() bool {
tdb.reserve() tdb.reserve()
v := tdb.db.Safe() v := tdb.db.Safe()
tdb.release() tdb.release()
return v return v
} }
func (tdb *ThreadGdbmDb) Prefix() uint8 { func(tdb *ThreadGdbmDb) Prefix() uint8 {
tdb.reserve() tdb.reserve()
v := tdb.db.Prefix() v := tdb.db.Prefix()
tdb.release() tdb.release()
return v return v
} }
func (tdb *ThreadGdbmDb) SetLock(typ uint8, locked bool) error { func(tdb *ThreadGdbmDb) SetLock(typ uint8, locked bool) error {
tdb.reserve() tdb.reserve()
err := tdb.db.SetLock(typ, locked) err := tdb.db.SetLock(typ, locked)
tdb.release() tdb.release()
return err return err
} }
func (tdb *ThreadGdbmDb) Put(ctx context.Context, key []byte, val []byte) error { func(tdb *ThreadGdbmDb) Put(ctx context.Context, key []byte, val []byte) error {
tdb.reserve() tdb.reserve()
err := tdb.db.Put(ctx, key, val) err := tdb.db.Put(ctx, key, val)
tdb.release() tdb.release()
return err return err
} }
func (tdb *ThreadGdbmDb) Get(ctx context.Context, key []byte) ([]byte, error) { func(tdb *ThreadGdbmDb) Get(ctx context.Context, key []byte) ([]byte, error) {
tdb.reserve() tdb.reserve()
v, err := tdb.db.Get(ctx, key) v, err := tdb.db.Get(ctx, key)
tdb.release() tdb.release()
return v, err return v, err
} }
func (tdb *ThreadGdbmDb) Close(ctx context.Context) error { func(tdb *ThreadGdbmDb) Close(ctx context.Context) error {
tdb.reserve() tdb.reserve()
close(dbC[tdb.connStr]) close(dbC[tdb.connStr])
delete(dbC, tdb.connStr) delete(dbC, tdb.connStr)
@ -120,28 +120,28 @@ func (tdb *ThreadGdbmDb) Close(ctx context.Context) error {
return err return err
} }
func (tdb *ThreadGdbmDb) Dump(ctx context.Context, key []byte) (*db.Dumper, error) { func(tdb *ThreadGdbmDb) Dump(ctx context.Context, key []byte) (*db.Dumper, error) {
tdb.reserve() tdb.reserve()
defer tdb.release() defer tdb.release()
return tdb.db.Dump(ctx, key) return tdb.db.Dump(ctx, key)
} }
func (tdb *ThreadGdbmDb) DecodeKey(ctx context.Context, key []byte) ([]byte, error) { func(tdb *ThreadGdbmDb) DecodeKey(ctx context.Context, key []byte) ([]byte, error) {
return tdb.db.DecodeKey(ctx, key) return tdb.db.DecodeKey(ctx, key)
} }
func (tdb *ThreadGdbmDb) Abort(ctx context.Context) { func(tdb *ThreadGdbmDb) Abort(ctx context.Context) {
tdb.db.Abort(ctx) tdb.db.Abort(ctx)
} }
func (tdb *ThreadGdbmDb) Start(ctx context.Context) error { func(tdb *ThreadGdbmDb) Start(ctx context.Context) error {
return tdb.db.Start(ctx) return tdb.db.Start(ctx)
} }
func (tdb *ThreadGdbmDb) Stop(ctx context.Context) error { func(tdb *ThreadGdbmDb) Stop(ctx context.Context) error {
return tdb.db.Stop(ctx) return tdb.db.Stop(ctx)
} }
func (tdb *ThreadGdbmDb) Connection() string { func(tdb *ThreadGdbmDb) Connection() string {
return tdb.db.Connection() return tdb.db.Connection()
} }

View File

@ -61,15 +61,6 @@ func probeMem(s string) (string, string, bool) {
return "", "", true return "", "", true
} }
func ToConnDataMode(connStr string, mode DbMode) (ConnData, error) {
o, err := ToConnData(connStr)
if err != nil {
return o, err
}
o.mode = mode
return o, nil
}
func ToConnData(connStr string) (ConnData, error) { func ToConnData(connStr string) (ConnData, error) {
var o ConnData var o ConnData

View File

@ -7,28 +7,28 @@ import (
func TestParseConnStr(t *testing.T) { func TestParseConnStr(t *testing.T) {
v, err := ToConnData("postgres://foo:bar@localhost:5432/baz") v, err := ToConnData("postgres://foo:bar@localhost:5432/baz")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if v.DbType() != DBTYPE_POSTGRES { if v.DbType() != DBTYPE_POSTGRES {
t.Fatalf("expected type %v, got %v", DBTYPE_POSTGRES, v.DbType()) t.Fatalf("expected type %v, got %v", DBTYPE_POSTGRES, v.DbType())
} }
v, err = ToConnData("gdbm:///foo/bar") v, err = ToConnData("gdbm:///foo/bar")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if v.DbType() != DBTYPE_GDBM { if v.DbType() != DBTYPE_GDBM {
t.Fatalf("expected type %v, got %v", DBTYPE_GDBM, v.DbType()) t.Fatalf("expected type %v, got %v", DBTYPE_GDBM, v.DbType())
} }
v, err = ToConnData("/foo/bar") v, err = ToConnData("/foo/bar")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if v.DbType() != DBTYPE_FS { if v.DbType() != DBTYPE_FS {
t.Fatalf("expected type %v, got %v", DBTYPE_FS, v.DbType()) t.Fatalf("expected type %v, got %v", DBTYPE_FS, v.DbType())
} }
v, err = ToConnData("/foo/bar/") v, err = ToConnData("/foo/bar/")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if v.DbType() != DBTYPE_FS { if v.DbType() != DBTYPE_FS {
t.Fatalf("expected type %v, got %v", DBTYPE_FS, v.DbType()) t.Fatalf("expected type %v, got %v", DBTYPE_FS, v.DbType())

View File

@ -12,8 +12,8 @@ const (
) )
type Storage struct { type Storage struct {
Persister *persist.Persister Persister *persist.Persister
UserdataDb db.Db UserdataDb db.Db
} }
func (s *Storage) Close(ctx context.Context) error { func (s *Storage) Close(ctx context.Context) error {
@ -35,7 +35,7 @@ func NewSimpleStorageProvider(stateStore db.Db, userdataStore db.Db) StorageProv
pe = pe.WithFlush() pe = pe.WithFlush()
return &SimpleStorageProvider{ return &SimpleStorageProvider{
Storage: &Storage{ Storage: &Storage{
Persister: pe, Persister: pe,
UserdataDb: userdataStore, UserdataDb: userdataStore,
}, },
} }

View File

@ -6,7 +6,8 @@ import (
"fmt" "fmt"
"os" "os"
"path" "path"
"github.com/jackc/pgx/v5/pgxpool"
"git.defalsify.org/vise.git/db" "git.defalsify.org/vise.git/db"
fsdb "git.defalsify.org/vise.git/db/fs" fsdb "git.defalsify.org/vise.git/db/fs"
memdb "git.defalsify.org/vise.git/db/mem" memdb "git.defalsify.org/vise.git/db/mem"
@ -16,7 +17,6 @@ import (
"git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/resource"
gdbmstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db/gdbm" gdbmstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db/gdbm"
"github.com/jackc/pgx/v5/pgxpool"
) )
var ( var (
@ -30,9 +30,9 @@ type StorageService interface {
} }
type MenuStorageService struct { type MenuStorageService struct {
conns Conns conns Conns
poResource resource.Resource poResource resource.Resource
store map[int8]db.Db store map[int8]db.Db
} }
func NewMenuStorageService(conn Conns) *MenuStorageService { func NewMenuStorageService(conn Conns) *MenuStorageService {
@ -55,13 +55,12 @@ func (ms *MenuStorageService) WithDb(store db.Db, typ int8) *MenuStorageService
return ms return ms
} }
func (ms *MenuStorageService) checkDb(ctx context.Context, typ int8) db.Db { func (ms *MenuStorageService) checkDb(ctx context.Context,typ int8) db.Db {
store := ms.store[typ] store := ms.store[typ]
if store != nil { if store != nil {
return store return store
} }
connData := ms.conns[typ] connData := ms.conns[typ]
logg.DebugCtxf(ctx, "db check", "conn", connData, "store", DbStoreDebug[typ])
v := ms.conns.Have(&connData) v := ms.conns.Have(&connData)
if v == -1 { if v == -1 {
return nil return nil
@ -71,7 +70,7 @@ func (ms *MenuStorageService) checkDb(ctx context.Context, typ int8) db.Db {
return nil return nil
} }
ms.store[typ] = ms.store[v] ms.store[typ] = ms.store[v]
logg.DebugCtxf(ctx, "found existing db", "typ", typ, "srctyp", v, "store", ms.store[typ], "srcstore", ms.store[v], "conn", connData) logg.DebugCtxf(ctx, "found existing db", "typ", typ, "srctyp", v, "store", ms.store[typ], "srcstore", ms.store[v])
return ms.store[typ] return ms.store[typ]
} }
@ -85,7 +84,7 @@ func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, section string,
} }
connData := ms.conns[typ] connData := ms.conns[typ]
connStr := connData.Raw() connStr := connData.String()
dbTyp := connData.DbType() dbTyp := connData.DbType()
if dbTyp == DBTYPE_POSTGRES { if dbTyp == DBTYPE_POSTGRES {
// TODO: move to vise // TODO: move to vise
@ -106,16 +105,12 @@ func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, section string,
if err != nil { if err != nil {
return nil, err return nil, err
} }
fsdbInstance := fsdb.NewFsDb() newDb = fsdb.NewFsDb().WithBinary()
if connData.Mode() == DBMODE_BINARY {
fsdbInstance = fsdbInstance.WithBinary()
}
newDb = fsdbInstance
} else if dbTyp == DBTYPE_MEM { } else if dbTyp == DBTYPE_MEM {
logg.WarnCtxf(ctx, "using volatile storage (memdb)") logg.WarnCtxf(ctx, "using volatile storage (memdb)")
newDb = memdb.NewMemDb() newDb = memdb.NewMemDb()
} else { } else {
return nil, fmt.Errorf("unsupported connection string: '%s'\n", connData.Raw()) return nil, fmt.Errorf("unsupported connection string: '%s'\n", connData.String())
} }
logg.InfoCtxf(ctx, "connecting to db", "conn", connData, "typ", typ) logg.InfoCtxf(ctx, "connecting to db", "conn", connData, "typ", typ)
err = newDb.Connect(ctx, connStr) err = newDb.Connect(ctx, connStr)
@ -129,7 +124,7 @@ func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, section string,
// WithGettext triggers use of gettext for translation of templates and menus. // WithGettext triggers use of gettext for translation of templates and menus.
// //
// The first language in `lns` will be used as default language, to resolve node keys to // The first language in `lns` will be used as default language, to resolve node keys to
// language strings. // language strings.
// //
// If `lns` is an empty array, gettext will not be used. // If `lns` is an empty array, gettext will not be used.
@ -140,7 +135,7 @@ func (ms *MenuStorageService) WithGettext(path string, lns []lang.Language) *Men
} }
rs := resource.NewPoResource(lns[0], path) rs := resource.NewPoResource(lns[0], path)
for _, ln := range lns { for _, ln := range(lns) {
rs = rs.WithLanguage(ln) rs = rs.WithLanguage(ln)
} }
@ -169,9 +164,7 @@ func ensureSchemaExists(ctx context.Context, conn ConnData) error {
func applySession(ctx context.Context, store db.Db) error { func applySession(ctx context.Context, store db.Db) error {
sessionId, ok := ctx.Value("SessionId").(string) sessionId, ok := ctx.Value("SessionId").(string)
if !ok { if !ok {
logg.DebugCtxf(ctx, "missing session to apply", "store", store) return fmt.Errorf("missing session to apply to store: %v", store)
return nil
//return fmt.Errorf("missing session to apply to store: %v", store)
} }
store.SetSession(sessionId) store.SetSession(sessionId)
return nil return nil
@ -186,6 +179,7 @@ func (ms *MenuStorageService) GetPersister(ctx context.Context) (*persist.Persis
if err != nil { if err != nil {
return nil, err return nil, err
} }
pr := persist.NewPersister(stateStore) pr := persist.NewPersister(stateStore)
logg.TraceCtxf(ctx, "menu storage service", "persist", pr, "store", stateStore) logg.TraceCtxf(ctx, "menu storage service", "persist", pr, "store", stateStore)
return pr, nil return pr, nil
@ -196,6 +190,7 @@ func (ms *MenuStorageService) GetUserdataDb(ctx context.Context) (db.Db, error)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = applySession(ctx, userStore) err = applySession(ctx, userStore)
if err != nil { if err != nil {
return nil, err return nil, err
@ -233,16 +228,16 @@ func (ms *MenuStorageService) ensureDbDir(path string) error {
func (ms *MenuStorageService) Close(ctx context.Context) error { func (ms *MenuStorageService) Close(ctx context.Context) error {
var errs []error var errs []error
var haveErr bool var haveErr bool
for i := range _STORETYPE_MAX { for i := range(_STORETYPE_MAX) {
err := ms.store[int8(i)].Close(ctx) err := ms.store[int8(i)].Close(ctx)
if err != nil { if err != nil {
haveErr = true haveErr = true
} }
errs = append(errs, err) errs = append(errs, err)
} }
if haveErr { if haveErr {
errStr := "" errStr := ""
for i, err := range errs { for i, err := range(errs) {
errStr += fmt.Sprintf("(%d: %v)", i, err) errStr += fmt.Sprintf("(%d: %v)", i, err)
} }
return errors.New(errStr) return errors.New(errStr)

View File

@ -61,7 +61,7 @@ func TestMenuStorageServiceExplicit(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
ms := NewMenuStorageService(conns) ms := NewMenuStorageService(conns)
ms = ms.WithDb(store, STORETYPE_RESOURCE) ms = ms.WithDb(store, STORETYPE_RESOURCE)
_, err = ms.GetStateStore(ctx) _, err = ms.GetStateStore(ctx)

View File

@ -22,4 +22,4 @@ func (m *MockWriter) Header() http.Header {
return http.Header{} return http.Header{}
} }
func (m *MockWriter) WriteHeader(statusCode int) {} func (m *MockWriter) WriteHeader(statusCode int) {}

View File

@ -5,8 +5,8 @@ import (
"git.defalsify.org/vise.git/db" "git.defalsify.org/vise.git/db"
memdb "git.defalsify.org/vise.git/db/mem" memdb "git.defalsify.org/vise.git/db/mem"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/persist"
) )
type MemStorageService struct { type MemStorageService struct {
@ -39,3 +39,4 @@ func (mss *MemStorageService) GetUserdataDb(ctx context.Context) (db.Db, error)
func (mss *MemStorageService) GetResource(ctx context.Context) (resource.Resource, error) { func (mss *MemStorageService) GetResource(ctx context.Context) (resource.Resource, error) {
return mss.rs, nil return mss.rs, nil
} }