v2 #43

Merged
h4kor merged 41 commits from v2 into main 2023-07-19 19:09:19 +00:00
5 changed files with 71 additions and 41 deletions
Showing only changes of commit 5d97d87c9b - Show all commits

51
app/entry_register.go Normal file
View File

@ -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
}

View File

@ -3,7 +3,6 @@ package repository
import "owl-blogs/domain/model" import "owl-blogs/domain/model"
type EntryRepository interface { type EntryRepository interface {
RegisterEntryType(entry model.Entry) error
Create(entry model.Entry) error Create(entry model.Entry) error
Update(entry model.Entry) error Update(entry model.Entry) error
Delete(entry model.Entry) error Delete(entry model.Entry) error

View File

@ -3,6 +3,7 @@ package infra
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"owl-blogs/app"
"owl-blogs/app/repository" "owl-blogs/app/repository"
"owl-blogs/domain/model" "owl-blogs/domain/model"
"reflect" "reflect"
@ -22,7 +23,7 @@ type sqlEntry struct {
} }
type DefaultEntryRepo struct { type DefaultEntryRepo struct {
types map[string]model.Entry typeRegistry *app.EntryTypeRegistry
db *sqlx.DB db *sqlx.DB
} }
@ -33,8 +34,8 @@ func (r *DefaultEntryRepo) Create(entry model.Entry) error {
return errors.New("entry already exists") return errors.New("entry already exists")
} }
t := r.entryType(entry) t, err := r.typeRegistry.TypeName(entry)
if _, ok := r.types[t]; !ok { if err != nil {
return errors.New("entry type not registered") return errors.New("entry type not registered")
} }
@ -43,7 +44,7 @@ func (r *DefaultEntryRepo) Create(entry model.Entry) error {
metaDataJson, _ = json.Marshal(entry.MetaData()) 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 return err
} }
@ -101,16 +102,6 @@ func (r *DefaultEntryRepo) FindById(id string) (model.Entry, error) {
return r.sqlEntryToEntry(data) 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. // Update implements repository.EntryRepository.
func (r *DefaultEntryRepo) Update(entry model.Entry) error { func (r *DefaultEntryRepo) Update(entry model.Entry) error {
exEntry, _ := r.FindById(entry.ID()) exEntry, _ := r.FindById(entry.ID())
@ -118,8 +109,8 @@ func (r *DefaultEntryRepo) Update(entry model.Entry) error {
return errors.New("entry not found") return errors.New("entry not found")
} }
t := r.entryType(entry) _, err := r.typeRegistry.TypeName(entry)
if _, ok := r.types[t]; !ok { if err != nil {
return errors.New("entry type not registered") return errors.New("entry type not registered")
} }
@ -128,11 +119,11 @@ func (r *DefaultEntryRepo) Update(entry model.Entry) error {
metaDataJson, _ = json.Marshal(entry.MetaData()) 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 return err
} }
func NewEntryRepository(db Database) repository.EntryRepository { func NewEntryRepository(db Database, register *app.EntryTypeRegistry) repository.EntryRepository {
sqlxdb := db.Get() sqlxdb := db.Get()
// Create tables if not exists // Create tables if not exists
@ -147,18 +138,14 @@ func NewEntryRepository(db Database) repository.EntryRepository {
`) `)
return &DefaultEntryRepo{ 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) { func (r *DefaultEntryRepo) sqlEntryToEntry(entry sqlEntry) (model.Entry, error) {
e, ok := r.types[entry.Type] e, err := r.typeRegistry.Type(entry.Type)
if !ok { if err != nil {
return nil, errors.New("entry type not registered") return nil, errors.New("entry type not registered")
} }
metaData := reflect.New(reflect.TypeOf(e.MetaData()).Elem()).Interface() metaData := reflect.New(reflect.TypeOf(e.MetaData()).Elem()).Interface()

View File

@ -1,6 +1,7 @@
package infra_test package infra_test
import ( import (
"owl-blogs/app"
"owl-blogs/app/repository" "owl-blogs/app/repository"
"owl-blogs/infra" "owl-blogs/infra"
"owl-blogs/test" "owl-blogs/test"
@ -12,21 +13,12 @@ import (
func setupRepo() repository.EntryRepository { func setupRepo() repository.EntryRepository {
db := test.NewMockDb() db := test.NewMockDb()
repo := infra.NewEntryRepository(db) register := app.NewEntryTypeRegistry()
repo.RegisterEntryType(&test.MockEntry{}) register.Register(&test.MockEntry{})
repo := infra.NewEntryRepository(db, register)
return repo 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) { func TestRepoCreate(t *testing.T) {
repo := setupRepo() repo := setupRepo()

View File

@ -8,7 +8,8 @@ import (
func main() { func main() {
db := infra.NewSqliteDB("owlblogs.db") db := infra.NewSqliteDB("owlblogs.db")
repo := infra.NewEntryRepository(db) registry := app.NewEntryTypeRegistry()
repo := infra.NewEntryRepository(db, registry)
entryService := app.NewEntryService(repo) entryService := app.NewEntryService(repo)
webApp := web.NewWebApp(entryService) webApp := web.NewWebApp(entryService)
webApp.Run() webApp.Run()