ussd/internal/storage/storageservice.go

156 lines
3.6 KiB
Go
Raw Normal View History

2024-09-19 14:57:11 +02:00
package storage
import (
"context"
"fmt"
"os"
"path"
"git.defalsify.org/vise.git/db"
fsdb "git.defalsify.org/vise.git/db/fs"
2024-10-19 22:06:58 +02:00
"git.defalsify.org/vise.git/db/postgres"
"git.defalsify.org/vise.git/logging"
2024-09-19 14:57:11 +02:00
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/urdt/ussd/initializers"
2024-09-19 14:57:11 +02:00
)
2024-09-21 22:32:02 +02:00
var (
logg = logging.NewVanilla().WithDomain("storage")
)
2024-09-21 22:32:02 +02:00
2024-09-19 14:57:11 +02:00
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
2024-09-19 14:57:11 +02:00
}
type MenuStorageService struct {
dbDir string
resourceDir string
2024-09-21 22:32:02 +02:00
resourceStore db.Db
stateStore db.Db
2024-09-21 22:32:02 +02:00
userDataStore db.Db
}
2024-09-19 14:57:11 +02:00
func buildConnStr() string {
host := initializers.GetEnv("DB_HOST", "localhost")
user := initializers.GetEnv("DB_USER", "postgres")
password := initializers.GetEnv("DB_PASSWORD", "")
dbName := initializers.GetEnv("DB_NAME", "")
port := initializers.GetEnv("DB_PORT", "5432")
2024-11-19 15:53:06 +01:00
connString := fmt.Sprintf(
"postgres://%s:%s@%s:%s/%s",
user, password, host, port, dbName,
)
2024-11-19 15:53:06 +01:00
logg.Debugf("pg conn string", "conn", connString)
return connString
}
func NewMenuStorageService(dbDir string, resourceDir string) *MenuStorageService {
return &MenuStorageService{
dbDir: dbDir,
resourceDir: resourceDir,
}
}
2024-10-19 14:27:23 +02:00
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")
}
if existingDb != nil {
return existingDb, nil
}
var newDb db.Db
var err error
if database == "postgres" {
2024-10-19 22:06:58 +02:00
newDb = postgres.NewPgDb()
2024-10-19 14:27:23 +02:00
connStr := buildConnStr()
err = newDb.Connect(ctx, connStr)
} else {
newDb = NewThreadGdbmDb()
storeFile := path.Join(ms.dbDir, fileName)
err = newDb.Connect(ctx, storeFile)
}
if err != nil {
return nil, err
}
return newDb, nil
}
func (ms *MenuStorageService) GetPersister(ctx context.Context) (*persist.Persister, error) {
2024-10-19 14:27:23 +02:00
stateStore, err := ms.GetStateStore(ctx)
2024-09-21 22:32:02 +02:00
if err != nil {
return nil, err
}
2024-10-19 14:27:23 +02:00
pr := persist.NewPersister(stateStore)
logg.TraceCtxf(ctx, "menu storage service", "persist", pr, "store", stateStore)
2024-09-19 14:57:11 +02:00
return pr, nil
}
2024-09-21 22:32:02 +02:00
func (ms *MenuStorageService) GetUserdataDb(ctx context.Context) (db.Db, error) {
2024-10-19 14:27:23 +02:00
if ms.userDataStore != nil {
return ms.userDataStore, nil
2024-09-21 22:32:02 +02:00
}
2024-10-19 14:27:23 +02:00
userDataStore, err := ms.getOrCreateDb(ctx, ms.userDataStore, "userdata.gdbm")
if err != nil {
return nil, err
}
2024-10-19 14:27:23 +02:00
ms.userDataStore = userDataStore
2024-09-21 22:32:02 +02:00
return ms.userDataStore, nil
2024-09-19 14:57:11 +02:00
}
func (ms *MenuStorageService) GetResource(ctx context.Context) (resource.Resource, error) {
2024-09-21 22:32:02 +02:00
ms.resourceStore = fsdb.NewFsDb()
err := ms.resourceStore.Connect(ctx, ms.resourceDir)
2024-09-19 14:57:11 +02:00
if err != nil {
return nil, err
}
2024-09-21 22:32:02 +02:00
rfs := resource.NewDbResource(ms.resourceStore)
2024-09-19 14:57:11 +02:00
return rfs, nil
}
func (ms *MenuStorageService) GetStateStore(ctx context.Context) (db.Db, error) {
2024-09-21 22:32:02 +02:00
if ms.stateStore != nil {
2024-10-19 14:27:23 +02:00
return ms.stateStore, nil
2024-09-21 22:32:02 +02:00
}
2024-10-19 14:27:23 +02:00
stateStore, err := ms.getOrCreateDb(ctx, ms.stateStore, "state.gdbm")
2024-09-21 22:32:02 +02:00
if err != nil {
return nil, err
}
2024-10-19 14:27:23 +02:00
ms.stateStore = stateStore
2024-09-21 22:32:02 +02:00
return ms.stateStore, nil
2024-09-19 14:57:11 +02:00
}
func (ms *MenuStorageService) EnsureDbDir() error {
err := os.MkdirAll(ms.dbDir, 0700)
2024-09-19 14:57:11 +02:00
if err != nil {
return fmt.Errorf("state dir create exited with error: %v\n", err)
}
return nil
}
2024-09-21 22:32:02 +02:00
func (ms *MenuStorageService) Close() error {
errA := ms.stateStore.Close()
errB := ms.userDataStore.Close()
errC := ms.resourceStore.Close()
if errA != nil || errB != nil || errC != nil {
return fmt.Errorf("%v %v %v", errA, errB, errC)
}
return nil
}