v2 #43
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
3
main.go
3
main.go
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue