From 5d97d87c9b219d1494ac65ab563e3779371748c1 Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Sun, 25 Jun 2023 21:54:04 +0200 Subject: [PATCH] type registery --- app/entry_register.go | 51 ++++++++++++++++++++++++++++++++++ app/repository/interfaces.go | 1 - infra/entry_repository.go | 41 ++++++++++----------------- infra/entry_repository_test.go | 16 +++-------- main.go | 3 +- 5 files changed, 71 insertions(+), 41 deletions(-) create mode 100644 app/entry_register.go diff --git a/app/entry_register.go b/app/entry_register.go new file mode 100644 index 0000000..a6dd53b --- /dev/null +++ b/app/entry_register.go @@ -0,0 +1,51 @@ +package app + +import ( + "errors" + "owl-blogs/domain/model" + "reflect" +) + +type EntryTypeRegistry struct { + types map[string]model.Entry +} + +func NewEntryTypeRegistry() *EntryTypeRegistry { + return &EntryTypeRegistry{types: map[string]model.Entry{}} +} + +func (r *EntryTypeRegistry) entryType(entry model.Entry) string { + return reflect.TypeOf(entry).Elem().Name() +} + +func (r *EntryTypeRegistry) Register(entry model.Entry) error { + t := r.entryType(entry) + if _, ok := r.types[t]; ok { + return errors.New("entry type already registered") + } + r.types[t] = entry + return nil +} + +func (r *EntryTypeRegistry) Types() []model.Entry { + types := []model.Entry{} + for _, t := range r.types { + types = append(types, t) + } + return types +} + +func (r *EntryTypeRegistry) TypeName(entry model.Entry) (string, error) { + t := r.entryType(entry) + if _, ok := r.types[t]; !ok { + return "", errors.New("entry type not registered") + } + return t, nil +} + +func (r *EntryTypeRegistry) Type(name string) (model.Entry, error) { + if _, ok := r.types[name]; !ok { + return nil, errors.New("entry type not registered") + } + return r.types[name], nil +} diff --git a/app/repository/interfaces.go b/app/repository/interfaces.go index 3f97dca..5fb3954 100644 --- a/app/repository/interfaces.go +++ b/app/repository/interfaces.go @@ -3,7 +3,6 @@ package repository import "owl-blogs/domain/model" type EntryRepository interface { - RegisterEntryType(entry model.Entry) error Create(entry model.Entry) error Update(entry model.Entry) error Delete(entry model.Entry) error diff --git a/infra/entry_repository.go b/infra/entry_repository.go index f347347..3e3fa72 100644 --- a/infra/entry_repository.go +++ b/infra/entry_repository.go @@ -3,6 +3,7 @@ package infra import ( "encoding/json" "errors" + "owl-blogs/app" "owl-blogs/app/repository" "owl-blogs/domain/model" "reflect" @@ -22,8 +23,8 @@ type sqlEntry struct { } type DefaultEntryRepo struct { - types map[string]model.Entry - db *sqlx.DB + typeRegistry *app.EntryTypeRegistry + db *sqlx.DB } // Create implements repository.EntryRepository. @@ -33,8 +34,8 @@ func (r *DefaultEntryRepo) Create(entry model.Entry) error { return errors.New("entry already exists") } - t := r.entryType(entry) - if _, ok := r.types[t]; !ok { + t, err := r.typeRegistry.TypeName(entry) + if err != nil { return errors.New("entry type not registered") } @@ -43,7 +44,7 @@ func (r *DefaultEntryRepo) Create(entry model.Entry) error { metaDataJson, _ = json.Marshal(entry.MetaData()) } - _, err := r.db.Exec("INSERT INTO entries (id, type, content, published_at, meta_data) VALUES (?, ?, ?, ?, ?)", entry.ID(), t, entry.Content(), entry.PublishedAt(), metaDataJson) + _, err = r.db.Exec("INSERT INTO entries (id, type, content, published_at, meta_data) VALUES (?, ?, ?, ?, ?)", entry.ID(), t, entry.Content(), entry.PublishedAt(), metaDataJson) return err } @@ -101,16 +102,6 @@ func (r *DefaultEntryRepo) FindById(id string) (model.Entry, error) { return r.sqlEntryToEntry(data) } -// RegisterEntryType implements repository.EntryRepository. -func (r *DefaultEntryRepo) RegisterEntryType(entry model.Entry) error { - t := r.entryType(entry) - if _, ok := r.types[t]; ok { - return errors.New("entry type already registered") - } - r.types[t] = entry - return nil -} - // Update implements repository.EntryRepository. func (r *DefaultEntryRepo) Update(entry model.Entry) error { exEntry, _ := r.FindById(entry.ID()) @@ -118,8 +109,8 @@ func (r *DefaultEntryRepo) Update(entry model.Entry) error { return errors.New("entry not found") } - t := r.entryType(entry) - if _, ok := r.types[t]; !ok { + _, err := r.typeRegistry.TypeName(entry) + if err != nil { return errors.New("entry type not registered") } @@ -128,11 +119,11 @@ func (r *DefaultEntryRepo) Update(entry model.Entry) error { metaDataJson, _ = json.Marshal(entry.MetaData()) } - _, err := r.db.Exec("UPDATE entries SET content = ?, published_at = ?, meta_data = ? WHERE id = ?", entry.Content(), entry.PublishedAt(), metaDataJson, entry.ID()) + _, err = r.db.Exec("UPDATE entries SET content = ?, published_at = ?, meta_data = ? WHERE id = ?", entry.Content(), entry.PublishedAt(), metaDataJson, entry.ID()) return err } -func NewEntryRepository(db Database) repository.EntryRepository { +func NewEntryRepository(db Database, register *app.EntryTypeRegistry) repository.EntryRepository { sqlxdb := db.Get() // Create tables if not exists @@ -147,18 +138,14 @@ func NewEntryRepository(db Database) repository.EntryRepository { `) return &DefaultEntryRepo{ - types: map[string]model.Entry{}, - db: sqlxdb, + db: sqlxdb, + typeRegistry: register, } } -func (r *DefaultEntryRepo) entryType(entry model.Entry) string { - return reflect.TypeOf(entry).Elem().Name() -} - func (r *DefaultEntryRepo) sqlEntryToEntry(entry sqlEntry) (model.Entry, error) { - e, ok := r.types[entry.Type] - if !ok { + e, err := r.typeRegistry.Type(entry.Type) + if err != nil { return nil, errors.New("entry type not registered") } metaData := reflect.New(reflect.TypeOf(e.MetaData()).Elem()).Interface() diff --git a/infra/entry_repository_test.go b/infra/entry_repository_test.go index 95a1373..be62dfd 100644 --- a/infra/entry_repository_test.go +++ b/infra/entry_repository_test.go @@ -1,6 +1,7 @@ package infra_test import ( + "owl-blogs/app" "owl-blogs/app/repository" "owl-blogs/infra" "owl-blogs/test" @@ -12,21 +13,12 @@ import ( func setupRepo() repository.EntryRepository { db := test.NewMockDb() - repo := infra.NewEntryRepository(db) - repo.RegisterEntryType(&test.MockEntry{}) + register := app.NewEntryTypeRegistry() + register.Register(&test.MockEntry{}) + repo := infra.NewEntryRepository(db, register) return repo } -func TestRepoRegister(t *testing.T) { - db := test.NewMockDb() - repo := infra.NewEntryRepository(db) - err := repo.RegisterEntryType(&test.MockEntry{}) - require.NoError(t, err) - - err = repo.RegisterEntryType(&test.MockEntry{}) - require.Error(t, err) -} - func TestRepoCreate(t *testing.T) { repo := setupRepo() diff --git a/main.go b/main.go index 52dd4cd..413dfb7 100644 --- a/main.go +++ b/main.go @@ -8,7 +8,8 @@ import ( func main() { db := infra.NewSqliteDB("owlblogs.db") - repo := infra.NewEntryRepository(db) + registry := app.NewEntryTypeRegistry() + repo := infra.NewEntryRepository(db, registry) entryService := app.NewEntryService(repo) webApp := web.NewWebApp(entryService) webApp.Run()