Implement connstr

This commit is contained in:
lash 2025-01-04 09:37:12 +00:00
parent dc1674ec55
commit 2e30739ec9
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
11 changed files with 227 additions and 65 deletions

View File

@ -15,11 +15,10 @@ import (
"git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/urdt/ussd/common"
"git.grassecon.net/urdt/ussd/config"
"git.grassecon.net/urdt/ussd/initializers"
"git.grassecon.net/urdt/ussd/internal/handlers"
httpserver "git.grassecon.net/urdt/ussd/internal/http/at"
at "git.grassecon.net/urdt/ussd/internal/http/at"
"git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/remote"
)

View File

@ -7,6 +7,7 @@ import (
"os"
"os/signal"
"path"
"path/filepath"
"syscall"
"git.defalsify.org/vise.git/engine"
@ -47,24 +48,33 @@ func main() {
config.LoadConfig()
var sessionId string
var dbDir string
var connStr string
var resourceDir string
var size uint
var database string
var engineDebug bool
var host string
var port uint
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&connStr, "c", ".", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host")
flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId)
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "connstr", connStr, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@ -81,18 +91,19 @@ func main() {
cfg.EngineDebug = true
}
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = menuStorageService.EnsureDbDir()
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
userdataStore, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {

View File

@ -8,6 +8,7 @@ import (
"os"
"os/signal"
"path"
"path/filepath"
"strconv"
"syscall"
@ -36,23 +37,31 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var resourceDir string
var size uint
var database string
var engineDebug bool
var host string
var port uint
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
var err error
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host")
flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "connstr", connStr, "resourcedir", resourceDir, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@ -69,14 +78,14 @@ func main() {
cfg.EngineDebug = true
}
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
rs, err := menuStorageService.GetResource(ctx)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = menuStorageService.EnsureDbDir()
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/logging"
@ -30,19 +31,28 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var size uint
var sessionId string
var database string
var engineDebug bool
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", ".", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "outputsize", size)
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "connstr", connStr, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
@ -58,9 +68,9 @@ func main() {
}
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err := menuStorageService.EnsureDbDir()
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)

View File

@ -23,17 +23,19 @@ type StorageServices interface {
GetPersister(ctx context.Context) (*persist.Persister, error)
GetUserdataDb(ctx context.Context) (db.Db, error)
GetResource(ctx context.Context) (resource.Resource, error)
EnsureDbDir() error
SetConn(connStr string) error
}
type StorageService struct {
svc *storage.MenuStorageService
}
func NewStorageService(dbDir string) *StorageService {
return &StorageService{
svc: storage.NewMenuStorageService(dbDir, ""),
func NewStorageService(connStr string) (*StorageService, error) {
svc := &StorageService{
svc: storage.NewMenuStorageService(""),
}
err := svc.SetConn(connStr)
return svc, err
}
func(ss *StorageService) GetPersister(ctx context.Context) (*persist.Persister, error) {
@ -48,6 +50,6 @@ func(ss *StorageService) GetResource(ctx context.Context) (resource.Resource, er
return nil, errors.New("not implemented")
}
func(ss *StorageService) EnsureDbDir() error {
return ss.svc.EnsureDbDir()
func(ss *StorageService) SetConn(connStr string) error {
return ss.svc.SetConn(connStr)
}

View File

@ -7,6 +7,7 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"git.defalsify.org/vise.git/logging"
"git.grassecon.net/urdt/ussd/config"
@ -28,23 +29,38 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var sessionId string
var database string
var engineDebug bool
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", ".", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.Parse()
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "connstr", connStr)
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Database", database)
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connection string error: %v", err)
os.Exit(1)
}
store, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"git.grassecon.net/urdt/ussd/config"
"git.grassecon.net/urdt/ussd/initializers"
@ -28,23 +29,36 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var sessionId string
var database string
var engineDebug bool
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", ".state", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.Parse()
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Database", database)
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connection string error: %v", err)
os.Exit(1)
}
store, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {

View File

@ -1,5 +1,11 @@
package storage
import (
"fmt"
"net/url"
"path"
)
const (
DBTYPE_MEM = iota
DBTYPE_GDBM
@ -11,11 +17,56 @@ type connData struct {
str string
}
func toConnData(s string) connData {
func (cd *connData) DbType() int {
return cd.typ
}
func (cd *connData) String() string {
return cd.str
}
func probePostgres(s string) (string, bool) {
v, err := url.Parse(s)
if err != nil {
return "", false
}
if v.Scheme != "postgres" {
return "", false
}
return s, true
}
func probeGdbm(s string) (string, bool) {
if !path.IsAbs(s) {
return "", false
}
if path.Ext(s) != ".gdbm" {
return "", false
}
s = path.Clean(s)
return s, true
}
func toConnData(connStr string) (connData, error) {
var o connData
if s == "" {
return o
if connStr == "" {
return o, nil
}
return o
v, ok := probePostgres(connStr)
if ok {
o.typ = DBTYPE_POSTGRES
o.str = v
return o, nil
}
v, ok = probeGdbm(connStr)
if ok {
o.typ = DBTYPE_GDBM
o.str = v
return o, nil
}
return o, fmt.Errorf("invalid connection string: %s", connStr)
}

View File

@ -0,0 +1,37 @@
package storage
import (
"testing"
)
func TestParseConnStr(t *testing.T) {
svc := NewMenuStorageService("")
err := svc.SetConn("postgres://foo:bar@localhost:5432/baz")
if err != nil {
t.Fatal(err)
}
err = svc.SetConn("/foo/bar/baz.gdbm")
if err != nil {
t.Fatal(err)
}
err = svc.SetConn("foo/bar/baz.gdbm")
if err == nil {
t.Fatalf("expected error")
}
err = svc.SetConn("http://foo/bar")
if err == nil {
t.Fatalf("expected error")
}
err = svc.SetConn("foo/bar/baz.txt")
if err == nil {
t.Fatalf("expected error")
}
err = svc.SetConn("/foo/bar")
if err == nil {
t.Fatalf("expected error")
}
err = svc.SetConn("foo/bar")
if err == nil {
t.Fatalf("expected error")
}
}

View File

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
"path"
"git.defalsify.org/vise.git/db"
fsdb "git.defalsify.org/vise.git/db/fs"
@ -24,11 +23,12 @@ type StorageService interface {
GetPersister(ctx context.Context) (*persist.Persister, error)
GetUserdataDb(ctx context.Context) db.Db
GetResource(ctx context.Context) (resource.Resource, error)
EnsureDbDir() error
SetConn(connStr string) error
}
type MenuStorageService struct {
dbDir string
//dbDir string
conn connData
resourceDir string
resourceStore db.Db
stateStore db.Db
@ -51,36 +51,47 @@ func buildConnStr() string {
return connString
}
func NewMenuStorageService(dbDir string, resourceDir string) *MenuStorageService {
func NewMenuStorageService(resourceDir string) *MenuStorageService {
return &MenuStorageService{
dbDir: dbDir,
resourceDir: resourceDir,
}
}
func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.Db, fileName string) (db.Db, error) {
database, ok := ctx.Value("Database").(string)
if !ok {
return nil, fmt.Errorf("failed to select the database")
func (ms *MenuStorageService) SetConn(connStr string) error {
o, err := toConnData(connStr)
if err != nil {
return err
}
ms.conn = o
return nil
}
func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.Db, fileName string) (db.Db, error) {
var newDb db.Db
var err error
// database, ok := ctx.Value("Database").(string)
// if !ok {
// return nil, fmt.Errorf("failed to select the database")
// }
if existingDb != nil {
return existingDb, nil
}
var newDb db.Db
var err error
if database == "postgres" {
dbTyp := ms.conn.DbType()
if dbTyp == DBTYPE_POSTGRES {
newDb = postgres.NewPgDb()
connStr := buildConnStr()
err = newDb.Connect(ctx, connStr)
} else {
} else if dbTyp == DBTYPE_GDBM {
err = ms.ensureDbDir()
if err != nil {
return nil, err
}
newDb = gdbmstorage.NewThreadGdbmDb()
storeFile := path.Join(ms.dbDir, fileName)
err = newDb.Connect(ctx, storeFile)
} else {
return nil, fmt.Errorf("unsupported connection string: %s", ms.conn.String())
}
err = newDb.Connect(ctx, ms.conn.String())
if err != nil {
return nil, err
}
@ -137,8 +148,8 @@ func (ms *MenuStorageService) GetStateStore(ctx context.Context) (db.Db, error)
return ms.stateStore, nil
}
func (ms *MenuStorageService) EnsureDbDir() error {
err := os.MkdirAll(ms.dbDir, 0700)
func (ms *MenuStorageService) ensureDbDir() error {
err := os.MkdirAll(ms.conn.String(), 0700)
if err != nil {
return fmt.Errorf("state dir create exited with error: %v\n", err)
}

View File

@ -41,9 +41,11 @@ func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
dbDir := ".test_state"
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
//menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err := menuStorageService.EnsureDbDir()
//err := menuStorageService.EnsureDbDir()
err := menuStorageService.SetConn(dbDir)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)