Compare commits
No commits in common. "master" and "lash/dbtx" have entirely different histories.
@ -1,48 +1,31 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/env"
|
"git.grassecon.net/grassrootseconomics/visedriver/env"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
slogging "github.com/grassrootseconomics/go-vise/slog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logg = slogging.Get().With("component", "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
|
|
||||||
configManager *Config
|
|
||||||
)
|
)
|
||||||
|
|
||||||
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
|
||||||
@ -64,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 == "?" {
|
||||||
@ -88,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
|
||||||
}
|
}
|
||||||
@ -136,17 +98,6 @@ func GetConns() (storage.Conns, error) {
|
|||||||
|
|
||||||
// LoadConfig initializes the configuration values after environment variables are loaded.
|
// LoadConfig initializes the configuration values after environment variables are loaded.
|
||||||
func LoadConfig() error {
|
func LoadConfig() error {
|
||||||
configManager = NewConfig()
|
|
||||||
|
|
||||||
// Add configuration keys with validation
|
|
||||||
configManager.AddKey("HOST", "127.0.0.1", false, nil)
|
|
||||||
configManager.AddKey("PORT", "7123", false, func(v string) error {
|
|
||||||
_, err := strconv.Atoi(v)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
configManager.AddKey("DB_CONN", "", true, nil)
|
|
||||||
// ... add other keys ? or is enough :/ ...
|
|
||||||
|
|
||||||
err := setConn()
|
err := setConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -158,7 +109,5 @@ func LoadConfig() error {
|
|||||||
DefaultLanguage = defaultLanguage
|
DefaultLanguage = defaultLanguage
|
||||||
Languages = languages
|
Languages = languages
|
||||||
|
|
||||||
// Report configuration
|
|
||||||
configManager.Report("INFO")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
//go:build configreport
|
|
||||||
// +build configreport
|
|
||||||
|
|
||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
slogging "github.com/grassrootseconomics/go-vise/slog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// go test -tags configreport ./config/... ---> run with tag
|
|
||||||
func TestConfig(t *testing.T) {
|
|
||||||
logger := slogging.Get().With("component", "test")
|
|
||||||
cfg := NewConfig(logger)
|
|
||||||
|
|
||||||
t.Run("Default Values", func(t *testing.T) {
|
|
||||||
cfg.AddKey("TEST_KEY", "default", false, nil)
|
|
||||||
value, err := cfg.GetValue("TEST_KEY")
|
|
||||||
t.Logf("Got value: %q, error: %v", value, err)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
if value != "default" {
|
|
||||||
t.Errorf("expected 'default', got '%s'", value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Environment Override", func(t *testing.T) {
|
|
||||||
os.Setenv("TEST_ENV_KEY", "override")
|
|
||||||
defer os.Unsetenv("TEST_ENV_KEY")
|
|
||||||
|
|
||||||
cfg.AddKey("TEST_ENV_KEY", "default", false, nil)
|
|
||||||
value, err := cfg.GetValue("TEST_ENV_KEY")
|
|
||||||
t.Logf("Got value: %q, error: %v", value, err)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
if value != "override" {
|
|
||||||
t.Errorf("expected 'override', got '%s'", value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Validation", func(t *testing.T) {
|
|
||||||
validator := func(v string) error {
|
|
||||||
if v != "valid" {
|
|
||||||
return fmt.Errorf("invalid value")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.AddKey("VALIDATED_KEY", "valid", false, validator)
|
|
||||||
os.Setenv("VALIDATED_KEY", "invalid")
|
|
||||||
defer os.Unsetenv("VALIDATED_KEY")
|
|
||||||
|
|
||||||
value, err := cfg.GetValue("VALIDATED_KEY")
|
|
||||||
t.Logf("Got value: %q, error: %v", value, err)
|
|
||||||
if err == nil {
|
|
||||||
t.Error("expected validation error, got nil")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
//go:build configreport
|
|
||||||
|
|
||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/env"
|
|
||||||
slogging "github.com/grassrootseconomics/go-vise/slog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ConfigValue represents a configuration key-value pair
|
|
||||||
type ConfigValue struct {
|
|
||||||
Key string
|
|
||||||
Default string
|
|
||||||
Validator func(string) error
|
|
||||||
Sensitive bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config handles configuration management and reporting
|
|
||||||
type Config struct {
|
|
||||||
values map[string]ConfigValue
|
|
||||||
logger *slogging.Slog
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewConfig(logging interface{}) *Config {
|
|
||||||
return &Config{
|
|
||||||
values: make(map[string]ConfigValue),
|
|
||||||
logger: slogging.Get().With("component", "visedriver-config-reporter"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddKey registers a new configuration key with optional validation
|
|
||||||
func (c *Config) AddKey(key string, defaultValue string, sensitive bool, validator func(string) error) {
|
|
||||||
c.values[key] = ConfigValue{
|
|
||||||
Key: key,
|
|
||||||
Default: defaultValue,
|
|
||||||
Validator: validator,
|
|
||||||
Sensitive: sensitive,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the value for a given key, applying environment override if present
|
|
||||||
func (c *Config) GetValue(key string) (string, error) {
|
|
||||||
// Find config value by key
|
|
||||||
var cv ConfigValue
|
|
||||||
for _, v := range c.values {
|
|
||||||
if v.Key == key {
|
|
||||||
cv = v
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if cv.Key == "" {
|
|
||||||
return "", fmt.Errorf("configuration key not found: %s", key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get value from environment or default
|
|
||||||
value := env.GetEnv(key, cv.Default)
|
|
||||||
|
|
||||||
// Validate if validator exists
|
|
||||||
if cv.Validator != nil && cv.Validator(value) != nil {
|
|
||||||
return "", fmt.Errorf("invalid value for key %s", key)
|
|
||||||
}
|
|
||||||
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Report outputs all configuration values at the specified log level
|
|
||||||
func (c *Config) Report(level string) {
|
|
||||||
for _, cv := range c.values {
|
|
||||||
value, err := c.GetValue(cv.Key)
|
|
||||||
if err != nil {
|
|
||||||
c.logger.Errorf("Error getting value for %s: %v", cv.Key, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if cv.Sensitive {
|
|
||||||
value = "****"
|
|
||||||
}
|
|
||||||
|
|
||||||
c.logger.Debugf("config set", cv.Key, value)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
//go:build !configreport
|
|
||||||
|
|
||||||
package config
|
|
||||||
|
|
||||||
type Config struct{}
|
|
||||||
|
|
||||||
func NewConfig() *Config {
|
|
||||||
return &Config{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) AddKey(key string, defaultValue string, sensitive bool, validator func(string) error) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) GetValue(key string) (string, error) {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) Report(level string) {}
|
|
@ -10,7 +10,7 @@ This document describes component versions:
|
|||||||
|
|
||||||
## User profile data
|
## User profile data
|
||||||
|
|
||||||
All user profile items are stored under keys matching the user's session id, prefixed with the 8-bit value `github.com/grassrootseconomics/go-vise/db.DATATYPE_USERDATA` (32), and followed with a 16-big big-endian value subprefix.
|
All user profile items are stored under keys matching the user's session id, prefixed with the 8-bit value `git.defalsify.org/vise.git/db.DATATYPE_USERDATA` (32), and followed with a 16-big big-endian value subprefix.
|
||||||
|
|
||||||
For example, given the sessionId `+254123` and the key `git.grassecon.net/urdt-ussd/common.DATA_PUBLIC_KEY` (2) will be stored under the key:
|
For example, given the sessionId `+254123` and the key `git.grassecon.net/urdt-ussd/common.DATA_PUBLIC_KEY` (2) will be stored under the key:
|
||||||
|
|
||||||
|
@ -2,9 +2,8 @@ package entry
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"git.defalsify.org/vise.git/resource"
|
||||||
"github.com/grassrootseconomics/go-vise/persist"
|
"git.defalsify.org/vise.git/persist"
|
||||||
"github.com/grassrootseconomics/go-vise/resource"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type EntryHandler interface {
|
type EntryHandler interface {
|
||||||
|
20
go.mod
20
go.mod
@ -1,27 +1,27 @@
|
|||||||
module git.grassecon.net/grassrootseconomics/visedriver
|
module git.grassecon.net/grassrootseconomics/visedriver
|
||||||
|
|
||||||
go 1.24
|
go 1.23.0
|
||||||
|
|
||||||
toolchain go1.24.6
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/grassrootseconomics/go-vise v0.5.0
|
git.defalsify.org/vise.git v0.2.3-0.20250119111745-4f69d6fe5939
|
||||||
github.com/jackc/pgx/v5 v5.7.5
|
github.com/jackc/pgx/v5 v5.7.1
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // indirect
|
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
|
||||||
|
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
github.com/leonelquinteros/gotext v1.7.2 // indirect
|
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/stretchr/testify v1.9.0 // indirect
|
github.com/stretchr/testify v1.9.0 // indirect
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
golang.org/x/crypto v0.40.0 // indirect
|
golang.org/x/crypto v0.27.0 // indirect
|
||||||
golang.org/x/sync v0.16.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/text v0.27.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
|
gopkg.in/leonelquinteros/gotext.v1 v1.3.1 // indirect
|
||||||
)
|
)
|
||||||
|
38
go.sum
38
go.sum
@ -1,28 +1,28 @@
|
|||||||
|
git.defalsify.org/vise.git v0.2.3-0.20250119111745-4f69d6fe5939 h1:DA0gus9TuKpLvZMDmmqCAwAr5Lly+U93jtO2OKtGAeo=
|
||||||
|
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=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||||
github.com/grassrootseconomics/go-vise v0.5.0 h1:FRg2de55Eb5SisrgTBeFWfWX+sXwp5q9r7YWtKWDwsk=
|
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo=
|
||||||
github.com/grassrootseconomics/go-vise v0.5.0/go.mod h1:b2/q4jfTu2i1wyUwYUu7FYq4m2f1AZv8MpiDM3ZcoGo=
|
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y=
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
|
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||||
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/leonelquinteros/gotext v1.7.2 h1:bDPndU8nt+/kRo1m4l/1OXiiy2v7Z7dfPQ9+YP7G1Mc=
|
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM+j0jiCe8WKPQHoRgQiRTnfcLY=
|
||||||
github.com/leonelquinteros/gotext v1.7.2/go.mod h1:9/haCkm5P7Jay1sxKDGJ5WIg4zkz8oZKw4ekNpALob8=
|
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk=
|
||||||
github.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w=
|
github.com/pashagolub/pgxmock/v4 v4.3.0 h1:DqT7fk0OCK6H0GvqtcMsLpv8cIwWqdxWgfZNLeHCb/s=
|
||||||
github.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
|
github.com/pashagolub/pgxmock/v4 v4.3.0/go.mod h1:9VoVHXwS3XR/yPtKGzwQvwZX1kzGB9sM8SviDcHDa3A=
|
||||||
github.com/pashagolub/pgxmock/v4 v4.7.0 h1:de2ORuFYyjwOQR7NBm57+321RnZxpYiuUjsmqRiqgh8=
|
|
||||||
github.com/pashagolub/pgxmock/v4 v4.7.0/go.mod h1:9L57pC193h2aKRHVyiiE817avasIPZnPwPlw3JczWvM=
|
|
||||||
github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I=
|
github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I=
|
||||||
github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U=
|
github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
@ -35,13 +35,15 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
|
|||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/leonelquinteros/gotext.v1 v1.3.1 h1:8d9/fdTG0kn/B7NNGV1BsEyvektXFAbkMsTZS2sFSCc=
|
||||||
|
gopkg.in/leonelquinteros/gotext.v1 v1.3.1/go.mod h1:X1WlGDeAFIYsW6GjgMm4VwUwZ2XjI7Zan2InxSUQWrU=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
@ -3,41 +3,32 @@ package request
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/grassrootseconomics/go-vise/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"github.com/grassrootseconomics/go-vise/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
"github.com/grassrootseconomics/go-vise/persist"
|
"git.defalsify.org/vise.git/persist"
|
||||||
"github.com/grassrootseconomics/go-vise/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
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/errors"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
slogging "github.com/grassrootseconomics/go-vise/slog"
|
"git.grassecon.net/grassrootseconomics/visedriver/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logg = slogging.Get().With("component", "visedriver.http.session")
|
logg = logging.NewVanilla().WithDomain("visedriver.http.session")
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTPRequestHandler implements the session handler for HTTP
|
// HTTPRequestHandler implements the session handler for HTTP
|
||||||
|
@ -8,10 +8,10 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grassrootseconomics/go-vise/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)
|
||||||
|
@ -4,24 +4,24 @@ 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/logging"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
"github.com/grassrootseconomics/go-vise/engine"
|
|
||||||
"github.com/grassrootseconomics/go-vise/persist"
|
|
||||||
"github.com/grassrootseconomics/go-vise/resource"
|
|
||||||
slogging "github.com/grassrootseconomics/go-vise/slog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logg = slogging.Get().With("component", "visedriver.request")
|
logg = logging.NewVanilla().WithDomain("visedriver.request")
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
|
147
storage/db/gdbm/gdbm.go
Normal file
147
storage/db/gdbm/gdbm.go
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.defalsify.org/vise.git/db"
|
||||||
|
gdbmdb "git.defalsify.org/vise.git/db/gdbm"
|
||||||
|
"git.defalsify.org/vise.git/lang"
|
||||||
|
"git.defalsify.org/vise.git/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
logg = logging.NewVanilla().WithDomain("gdbmstorage")
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
dbC map[string]chan db.Db
|
||||||
|
)
|
||||||
|
|
||||||
|
type ThreadGdbmDb struct {
|
||||||
|
db db.Db
|
||||||
|
connStr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewThreadGdbmDb() *ThreadGdbmDb {
|
||||||
|
if dbC == nil {
|
||||||
|
dbC = make(map[string]chan db.Db)
|
||||||
|
}
|
||||||
|
return &ThreadGdbmDb{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Connect(ctx context.Context, connStr string) error {
|
||||||
|
var ok bool
|
||||||
|
_, ok = dbC[connStr]
|
||||||
|
if ok {
|
||||||
|
logg.WarnCtxf(ctx, "already registered thread gdbm, skipping", "connStr", connStr)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
gdb := gdbmdb.NewGdbmDb()
|
||||||
|
err := gdb.Connect(ctx, connStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dbC[connStr] = make(chan db.Db, 1)
|
||||||
|
dbC[connStr]<- gdb
|
||||||
|
tdb.connStr = connStr
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) reserve() {
|
||||||
|
if tdb.db == nil {
|
||||||
|
tdb.db = <-dbC[tdb.connStr]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) release() {
|
||||||
|
if tdb.db == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dbC[tdb.connStr] <- tdb.db
|
||||||
|
tdb.db = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) SetPrefix(pfx uint8) {
|
||||||
|
tdb.reserve()
|
||||||
|
tdb.db.SetPrefix(pfx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) SetSession(sessionId string) {
|
||||||
|
tdb.reserve()
|
||||||
|
tdb.db.SetSession(sessionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) SetLanguage(lng *lang.Language) {
|
||||||
|
tdb.reserve()
|
||||||
|
tdb.db.SetLanguage(lng)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Safe() bool {
|
||||||
|
tdb.reserve()
|
||||||
|
v := tdb.db.Safe()
|
||||||
|
tdb.release()
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Prefix() uint8 {
|
||||||
|
tdb.reserve()
|
||||||
|
v := tdb.db.Prefix()
|
||||||
|
tdb.release()
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) SetLock(typ uint8, locked bool) error {
|
||||||
|
tdb.reserve()
|
||||||
|
err := tdb.db.SetLock(typ, locked)
|
||||||
|
tdb.release()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Put(ctx context.Context, key []byte, val []byte) error {
|
||||||
|
tdb.reserve()
|
||||||
|
err := tdb.db.Put(ctx, key, val)
|
||||||
|
tdb.release()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Get(ctx context.Context, key []byte) ([]byte, error) {
|
||||||
|
tdb.reserve()
|
||||||
|
v, err := tdb.db.Get(ctx, key)
|
||||||
|
tdb.release()
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Close(ctx context.Context) error {
|
||||||
|
tdb.reserve()
|
||||||
|
close(dbC[tdb.connStr])
|
||||||
|
delete(dbC, tdb.connStr)
|
||||||
|
err := tdb.db.Close(ctx)
|
||||||
|
tdb.db = nil
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Dump(ctx context.Context, key []byte) (*db.Dumper, error) {
|
||||||
|
tdb.reserve()
|
||||||
|
defer tdb.release()
|
||||||
|
return tdb.db.Dump(ctx, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) DecodeKey(ctx context.Context, key []byte) ([]byte, error) {
|
||||||
|
return tdb.db.DecodeKey(ctx, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Abort(ctx context.Context) {
|
||||||
|
tdb.db.Abort(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Start(ctx context.Context) error {
|
||||||
|
return tdb.db.Start(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Stop(ctx context.Context) error {
|
||||||
|
return tdb.db.Stop(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(tdb *ThreadGdbmDb) Connection() string {
|
||||||
|
return tdb.db.Connection()
|
||||||
|
}
|
@ -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
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -3,8 +3,8 @@ package storage
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/grassrootseconomics/go-vise/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"github.com/grassrootseconomics/go-vise/persist"
|
"git.defalsify.org/vise.git/persist"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,22 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"github.com/grassrootseconomics/go-vise/db"
|
|
||||||
fsdb "github.com/grassrootseconomics/go-vise/db/fs"
|
|
||||||
memdb "github.com/grassrootseconomics/go-vise/db/mem"
|
|
||||||
"github.com/grassrootseconomics/go-vise/db/postgres"
|
|
||||||
"github.com/grassrootseconomics/go-vise/lang"
|
|
||||||
"github.com/grassrootseconomics/go-vise/persist"
|
|
||||||
"github.com/grassrootseconomics/go-vise/resource"
|
|
||||||
slogging "github.com/grassrootseconomics/go-vise/slog"
|
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
"git.defalsify.org/vise.git/db"
|
||||||
|
fsdb "git.defalsify.org/vise.git/db/fs"
|
||||||
|
memdb "git.defalsify.org/vise.git/db/mem"
|
||||||
|
"git.defalsify.org/vise.git/db/postgres"
|
||||||
|
"git.defalsify.org/vise.git/lang"
|
||||||
|
"git.defalsify.org/vise.git/logging"
|
||||||
|
"git.defalsify.org/vise.git/persist"
|
||||||
|
"git.defalsify.org/vise.git/resource"
|
||||||
|
gdbmstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db/gdbm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logg = slogging.Get().With("component", "storage")
|
logg = logging.NewVanilla().WithDomain("storage")
|
||||||
)
|
)
|
||||||
|
|
||||||
type StorageService interface {
|
type StorageService interface {
|
||||||
@ -28,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 {
|
||||||
@ -53,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
|
||||||
@ -69,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]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,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
|
||||||
@ -92,22 +93,24 @@ func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, section string,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newDb = postgres.NewPgDb().WithSchema(connData.Domain())
|
newDb = postgres.NewPgDb().WithSchema(connData.Domain())
|
||||||
|
} else if dbTyp == DBTYPE_GDBM {
|
||||||
|
err = ms.ensureDbDir(connStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
connStr = path.Join(connStr, section)
|
||||||
|
newDb = gdbmstorage.NewThreadGdbmDb()
|
||||||
} else if dbTyp == DBTYPE_FS {
|
} else if dbTyp == DBTYPE_FS {
|
||||||
err = ms.ensureDbDir(connStr)
|
err = ms.ensureDbDir(connStr)
|
||||||
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)
|
||||||
@ -121,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.
|
||||||
@ -132,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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,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
|
||||||
@ -178,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
|
||||||
@ -188,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
|
||||||
@ -225,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)
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
fsdb "github.com/grassrootseconomics/go-vise/db/fs"
|
fsdb "git.defalsify.org/vise.git/db/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMenuStorageServiceOneSet(t *testing.T) {
|
func TestMenuStorageServiceOneSet(t *testing.T) {
|
||||||
@ -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)
|
||||||
|
@ -3,10 +3,10 @@ package httpmocks
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"git.defalsify.org/vise.git/engine"
|
||||||
|
"git.defalsify.org/vise.git/persist"
|
||||||
|
"git.defalsify.org/vise.git/resource"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
"github.com/grassrootseconomics/go-vise/engine"
|
|
||||||
"github.com/grassrootseconomics/go-vise/persist"
|
|
||||||
"github.com/grassrootseconomics/go-vise/resource"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockRequestHandler implements request.RequestHandler interface for testing
|
// MockRequestHandler implements request.RequestHandler interface for testing
|
||||||
|
@ -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) {}
|
@ -3,10 +3,10 @@ package mocks
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/grassrootseconomics/go-vise/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
memdb "github.com/grassrootseconomics/go-vise/db/mem"
|
memdb "git.defalsify.org/vise.git/db/mem"
|
||||||
"github.com/grassrootseconomics/go-vise/persist"
|
"git.defalsify.org/vise.git/resource"
|
||||||
"github.com/grassrootseconomics/go-vise/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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user