✨ Improve Store
Still need to fill out SQLite bootstrap Also setup plug-in system mechanism
This commit is contained in:
parent
c4513aa94b
commit
e7b88bcc09
10 changed files with 154 additions and 6 deletions
1
app.go
1
app.go
|
|
@ -6,6 +6,7 @@ import (
|
|||
"time"
|
||||
|
||||
"codeberg.org/danjones000/lenore/config"
|
||||
_ "codeberg.org/danjones000/lenore/imports"
|
||||
"codeberg.org/danjones000/lenore/store"
|
||||
vocab "github.com/go-ap/activitypub"
|
||||
"github.com/go-ap/client"
|
||||
|
|
|
|||
|
|
@ -7,14 +7,19 @@ import (
|
|||
|
||||
"codeberg.org/danjones000/lenore"
|
||||
"codeberg.org/danjones000/lenore/config"
|
||||
"github.com/go-ap/storage-sqlite"
|
||||
"codeberg.org/danjones000/lenore/store"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conf := config.Config{BaseURL: "http://localhost:4523/"}
|
||||
sqlConf := sqlite.Config{Path: "storage"}
|
||||
conf := config.Config{
|
||||
BaseURL: "http://localhost:4523/",
|
||||
Conn: config.ConnSettings{
|
||||
Store: "sqlite",
|
||||
DSN: "storage",
|
||||
},
|
||||
}
|
||||
|
||||
db, err := sqlite.New(sqlConf)
|
||||
db, err := store.MakeStore(conf.Conn.Store, conf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@ type Config struct {
|
|||
Name string
|
||||
Env Env
|
||||
BaseURL string
|
||||
Conn ConnSettings
|
||||
}
|
||||
|
||||
type ConnSettings struct {
|
||||
Store string
|
||||
DSN string
|
||||
AdditionalSettings map[string]any
|
||||
}
|
||||
|
||||
func (c Config) Environment() Env {
|
||||
|
|
|
|||
3
imports/.gitignore
vendored
Normal file
3
imports/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
*
|
||||
!default.go
|
||||
!.gitignore
|
||||
5
imports/default.go
Normal file
5
imports/default.go
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
package imports
|
||||
|
||||
import (
|
||||
_ "codeberg.org/danjones000/lenore/store/sqlite"
|
||||
)
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
package testmocks
|
||||
|
||||
import (
|
||||
"codeberg.org/danjones000/lenore/store"
|
||||
"codeberg.org/danjones000/lenore/config"
|
||||
vocab "github.com/go-ap/activitypub"
|
||||
"github.com/go-ap/filters"
|
||||
)
|
||||
|
||||
type st struct{}
|
||||
|
||||
func (s *st) Bootstrap(config.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *st) Load(iri vocab.IRI, filters ...filters.Check) (vocab.Item, error) {
|
||||
i := vocab.ActorNew(iri, vocab.ActorType)
|
||||
return i, nil
|
||||
|
|
@ -36,6 +40,6 @@ func (s *st) RemoveFrom(col vocab.IRI, it vocab.Item) error {
|
|||
func (s *st) Close() {
|
||||
}
|
||||
|
||||
func GetStore() store.Store {
|
||||
func GetStore() *st {
|
||||
return &st{}
|
||||
}
|
||||
|
|
|
|||
34
store/factory.go
Normal file
34
store/factory.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"codeberg.org/danjones000/lenore/config"
|
||||
)
|
||||
|
||||
var ErrNoFactory = errors.New("unknown factory")
|
||||
|
||||
type StoreFactory func(config.Config) (Store, error)
|
||||
|
||||
var factories map[string]StoreFactory
|
||||
|
||||
func init() {
|
||||
factories = make(map[string]StoreFactory)
|
||||
}
|
||||
|
||||
func AddFactory(name string, f StoreFactory) {
|
||||
factories[name] = f
|
||||
}
|
||||
|
||||
func GetFactory(name string) StoreFactory {
|
||||
return factories[name]
|
||||
}
|
||||
|
||||
func MakeStore(name string, conf config.Config) (Store, error) {
|
||||
f, ok := factories[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", ErrNoFactory, name)
|
||||
}
|
||||
return f(conf)
|
||||
}
|
||||
47
store/factory_test.go
Normal file
47
store/factory_test.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"codeberg.org/danjones000/lenore/config"
|
||||
"codeberg.org/danjones000/lenore/internal/testmocks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var f StoreFactory = func(config.Config) (Store, error) {
|
||||
return testmocks.GetStore(), nil
|
||||
}
|
||||
|
||||
func TestAddFactory(t *testing.T) {
|
||||
AddFactory("mock", f)
|
||||
defer delete(factories, "mock")
|
||||
_, ok := factories["mock"]
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
||||
func TestGetFactoryNil(t *testing.T) {
|
||||
f := GetFactory("mock")
|
||||
assert.Nil(t, f)
|
||||
}
|
||||
|
||||
func TestGetFactoryNotNil(t *testing.T) {
|
||||
AddFactory("mock", f)
|
||||
defer delete(factories, "mock")
|
||||
f := GetFactory("mock")
|
||||
assert.NotNil(t, f)
|
||||
}
|
||||
|
||||
func TestMakeStoreError(t *testing.T) {
|
||||
s, e := MakeStore("mock", config.Config{})
|
||||
assert.Nil(t, s)
|
||||
assert.ErrorIs(t, e, ErrNoFactory)
|
||||
assert.ErrorContains(t, e, ErrNoFactory.Error()+": mock")
|
||||
}
|
||||
|
||||
func TestMakeStoreNoError(t *testing.T) {
|
||||
AddFactory("mock", f)
|
||||
defer delete(factories, "mock")
|
||||
s, e := MakeStore("mock", config.Config{})
|
||||
assert.NotNil(t, s)
|
||||
assert.NoError(t, e)
|
||||
}
|
||||
29
store/sqlite/repo.go
Normal file
29
store/sqlite/repo.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package sqlite
|
||||
|
||||
import (
|
||||
"codeberg.org/danjones000/lenore/config"
|
||||
"codeberg.org/danjones000/lenore/store"
|
||||
"github.com/go-ap/storage-sqlite"
|
||||
)
|
||||
|
||||
func init() {
|
||||
store.AddFactory("sqlite", MakeStore)
|
||||
}
|
||||
|
||||
func MakeStore(conf config.Config) (store.Store, error) {
|
||||
sqlConf := sqlite.Config{Path: conf.Conn.DSN}
|
||||
db, err := sqlite.New(sqlConf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Repo{db}, nil
|
||||
}
|
||||
|
||||
type Repo struct {
|
||||
store.PartStore
|
||||
}
|
||||
|
||||
func (r Repo) Bootstrap(config.Config) error {
|
||||
// @todo
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"codeberg.org/danjones000/lenore/config"
|
||||
st "github.com/go-ap/fedbox/storage"
|
||||
proc "github.com/go-ap/processing"
|
||||
"github.com/openshift/osin"
|
||||
|
|
@ -21,7 +22,19 @@ type ClientLister interface {
|
|||
GetClient(id string) (osin.Client, error)
|
||||
}
|
||||
|
||||
type Bootstrapper interface {
|
||||
// Bootstrap should initialize the data store so that it can be used.
|
||||
// This will be called every time the application starts, so it MUST be idempotent and doesn't delete existing data.
|
||||
// An option is to run migrations in this method.
|
||||
Bootstrap(config.Config) error
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
Bootstrapper
|
||||
PartStore
|
||||
}
|
||||
|
||||
type PartStore interface {
|
||||
ClientSaver
|
||||
ClientLister
|
||||
proc.Store
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue