diff --git a/app/pb.go b/app/pb.go index 855044a..bcd1e56 100644 --- a/app/pb.go +++ b/app/pb.go @@ -3,6 +3,7 @@ package app import ( "database/sql" "fmt" + "sync" "github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels" "github.com/Theodor-Springmann-Stiftung/musenalm/middleware" @@ -26,9 +27,13 @@ type BootFunc = func(e *core.BootstrapEvent) error // INFO: this is the main application that mainly is a pocketbase wrapper type App struct { - PB *pocketbase.PocketBase - MAConfig Config - Pages []pagemodels.IPage + PB *pocketbase.PocketBase + MAConfig Config + Pages []pagemodels.IPage + dataCache map[string]any + dataMutex sync.RWMutex + htmlCache map[string]any + htmlMutex sync.RWMutex } const ( @@ -148,17 +153,60 @@ func (app *App) createEngine() (*templating.Engine, error) { "desc": "Bibliographie deutscher Almanache des 18. und 19. Jahrhunderts", }}) + app.ResetDataCache() engine.AddFunc("data", func(key string) any { - res, err := dbmodels.Data_Key(app.PB.App, key) - if err != nil { - return "{}" + if len(app.dataCache) == 0 { + data, err := dbmodels.Data_All(app.PB.App) + if err != nil { + app.PB.Logger().Error("Failed to fetch data cache: %v", err) + return "{}" + } + app.dataMutex.Lock() + for _, d := range data { + app.dataCache[d.Key()] = d.Value() + } + app.dataMutex.Unlock() } - return res.Value() + app.dataMutex.RLock() + defer app.dataMutex.RUnlock() + return app.dataCache[key] + }) + + app.ResetHtmlCache() + engine.AddFunc("html", func(key string) any { + if len(app.htmlCache) == 0 { + html, err := dbmodels.Html_All(app.PB.App) + if err != nil { + app.PB.Logger().Error("Failed to fetch html cache: %v", err) + return "{}" + } + app.htmlMutex.Lock() + for _, h := range html { + app.htmlCache[h.Key()] = h.HTML() + } + app.htmlMutex.Unlock() + } + app.htmlMutex.RLock() + defer app.htmlMutex.RUnlock() + return app.htmlCache[key] }) return engine, nil } +// BUG: we cant call this from the templates, bc this App struct is not available +func (app *App) ResetDataCache() { + app.dataMutex.Lock() + defer app.dataMutex.Unlock() + app.dataCache = make(map[string]any) +} + +func (app *App) ResetHtmlCache() { + app.htmlMutex.Lock() + defer app.htmlMutex.Unlock() + app.htmlCache = make(map[string]any) +} + func (app *App) setWatchers(engine *templating.Engine) { // INFO: hot reloading for poor people watcher, err := EngineWatcher(engine) diff --git a/dbmodels/html.go b/dbmodels/html.go index d9ab4ff..ad42d7b 100644 --- a/dbmodels/html.go +++ b/dbmodels/html.go @@ -14,8 +14,8 @@ func (h *HTML) SetKey(key string) { h.Set(KEY_FIELD, key) } -func (h *HTML) HTML() string { - return h.GetString(HTML_FIELD) +func (h *HTML) HTML() any { + return h.GetRaw(HTML_FIELD) } func (h *HTML) SetHTML(html string) { diff --git a/dbmodels/queries.go b/dbmodels/queries.go index 21c687e..791f700 100644 --- a/dbmodels/queries.go +++ b/dbmodels/queries.go @@ -149,6 +149,18 @@ func Data_Key(app core.App, key string) (*Data, error) { return &ret, err } +func Data_All(app core.App) ([]*Data, error) { + data := make([]*Data, 0) + err := app.RecordQuery(DATA_TABLE).All(&data) + return data, err +} + +func Html_All(app core.App) ([]*HTML, error) { + html := make([]*HTML, 0) + err := app.RecordQuery(HTML_TABLE).All(&html) + return html, err +} + func AccessTokens_Token(app core.App, token string) (*AccessToken, error) { t := HashStringSHA256(token) return TableByField[*AccessToken](