✨ 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