From 696f7fe087e4b0adbbd399f4939e4f8682a39d79 Mon Sep 17 00:00:00 2001 From: Simon Martens Date: Mon, 12 Jan 2026 15:16:11 +0100 Subject: [PATCH] +general tables --- dbmodels/data.go | 27 +++ dbmodels/db_data.go | 18 ++ dbmodels/file.go | 31 ++++ dbmodels/html.go | 23 +++ dbmodels/image.go | 47 +++++ dbmodels/page.go | 59 +++++++ migrations/01_tables.go | 160 ++++++++++++++++++ migrations/1747983000_migrate_abkuerzungen.go | 56 ++++++ scratchpad.md | 65 +++++++ 9 files changed, 486 insertions(+) create mode 100644 dbmodels/data.go create mode 100644 dbmodels/file.go create mode 100644 dbmodels/html.go create mode 100644 dbmodels/image.go create mode 100644 dbmodels/page.go create mode 100644 migrations/1747983000_migrate_abkuerzungen.go diff --git a/dbmodels/data.go b/dbmodels/data.go new file mode 100644 index 0000000..74e06d6 --- /dev/null +++ b/dbmodels/data.go @@ -0,0 +1,27 @@ +package dbmodels + +import "github.com/pocketbase/pocketbase/core" + +type Data struct { + core.BaseRecordProxy +} + +func (d *Data) Key() string { + return d.GetString(KEY_FIELD) +} + +func (d *Data) SetKey(key string) { + d.Set(KEY_FIELD, key) +} + +func (d *Data) Value() map[string]interface{} { + val := d.Get(VALUE_FIELD) + if val == nil { + return nil + } + return val.(map[string]interface{}) +} + +func (d *Data) SetValue(value map[string]interface{}) { + d.Set(VALUE_FIELD, value) +} diff --git a/dbmodels/db_data.go b/dbmodels/db_data.go index 0f4ef77..51a4918 100644 --- a/dbmodels/db_data.go +++ b/dbmodels/db_data.go @@ -441,6 +441,11 @@ const ( ITEMS_TABLE = "items" SESSIONS_TABLE = "sessions" ACCESS_TOKENS_TABLE = "access_tokens" + DATA_TABLE = "data" + IMAGES_TABLE = "images" + FILES_TABLE = "files" + HTML_TABLE = "html" + PAGES_TABLE = "pages" ID_FIELD = "id" CREATED_FIELD = "created" @@ -538,5 +543,18 @@ const ( ACCESS_TOKENS_LAST_ACCESS_FIELD = "accessed" ACCESS_TOKENS_STATUS_FIELD = "status" + KEY_FIELD = "key" + VALUE_FIELD = "value" + TITLE_FIELD = "title" + DESCRIPTION_FIELD = "description" + PREVIEW_FIELD = "preview" + IMAGE_FIELD = "image" + FILE_FIELD = "file" + HTML_FIELD = "html" + DATA_FIELD = "data" + TEMPLATE_FIELD = "template" + LAYOUT_FIELD = "layout" + TYPE_FIELD = "type" + SESSION_COOKIE_NAME = "sid" ) diff --git a/dbmodels/file.go b/dbmodels/file.go new file mode 100644 index 0000000..7be5079 --- /dev/null +++ b/dbmodels/file.go @@ -0,0 +1,31 @@ +package dbmodels + +import "github.com/pocketbase/pocketbase/core" + +type File struct { + core.BaseRecordProxy +} + +func (f *File) Key() string { + return f.GetString(KEY_FIELD) +} + +func (f *File) SetKey(key string) { + f.Set(KEY_FIELD, key) +} + +func (f *File) Description() string { + return f.GetString(DESCRIPTION_FIELD) +} + +func (f *File) SetDescription(description string) { + f.Set(DESCRIPTION_FIELD, description) +} + +func (f *File) FileField() string { + return f.GetString(FILE_FIELD) +} + +func (f *File) SetFileField(file string) { + f.Set(FILE_FIELD, file) +} diff --git a/dbmodels/html.go b/dbmodels/html.go new file mode 100644 index 0000000..d9ab4ff --- /dev/null +++ b/dbmodels/html.go @@ -0,0 +1,23 @@ +package dbmodels + +import "github.com/pocketbase/pocketbase/core" + +type HTML struct { + core.BaseRecordProxy +} + +func (h *HTML) Key() string { + return h.GetString(KEY_FIELD) +} + +func (h *HTML) SetKey(key string) { + h.Set(KEY_FIELD, key) +} + +func (h *HTML) HTML() string { + return h.GetString(HTML_FIELD) +} + +func (h *HTML) SetHTML(html string) { + h.Set(HTML_FIELD, html) +} diff --git a/dbmodels/image.go b/dbmodels/image.go new file mode 100644 index 0000000..1a5f6c3 --- /dev/null +++ b/dbmodels/image.go @@ -0,0 +1,47 @@ +package dbmodels + +import "github.com/pocketbase/pocketbase/core" + +type Image struct { + core.BaseRecordProxy +} + +func (i *Image) Key() string { + return i.GetString(KEY_FIELD) +} + +func (i *Image) SetKey(key string) { + i.Set(KEY_FIELD, key) +} + +func (i *Image) Title() string { + return i.GetString(TITLE_FIELD) +} + +func (i *Image) SetTitle(title string) { + i.Set(TITLE_FIELD, title) +} + +func (i *Image) Description() string { + return i.GetString(DESCRIPTION_FIELD) +} + +func (i *Image) SetDescription(description string) { + i.Set(DESCRIPTION_FIELD, description) +} + +func (i *Image) Preview() string { + return i.GetString(PREVIEW_FIELD) +} + +func (i *Image) SetPreview(preview string) { + i.Set(PREVIEW_FIELD, preview) +} + +func (i *Image) ImageFile() string { + return i.GetString(IMAGE_FIELD) +} + +func (i *Image) SetImageFile(image string) { + i.Set(IMAGE_FIELD, image) +} diff --git a/dbmodels/page.go b/dbmodels/page.go new file mode 100644 index 0000000..7d2e20c --- /dev/null +++ b/dbmodels/page.go @@ -0,0 +1,59 @@ +package dbmodels + +import "github.com/pocketbase/pocketbase/core" + +type Page struct { + core.BaseRecordProxy +} + +func (p *Page) Key() string { + return p.GetString(KEY_FIELD) +} + +func (p *Page) SetKey(key string) { + p.Set(KEY_FIELD, key) +} + +func (p *Page) URL() string { + return p.GetString(URL_FIELD) +} + +func (p *Page) SetURL(url string) { + p.Set(URL_FIELD, url) +} + +func (p *Page) Template() string { + return p.GetString(TEMPLATE_FIELD) +} + +func (p *Page) SetTemplate(template string) { + p.Set(TEMPLATE_FIELD, template) +} + +func (p *Page) Layout() string { + return p.GetString(LAYOUT_FIELD) +} + +func (p *Page) SetLayout(layout string) { + p.Set(LAYOUT_FIELD, layout) +} + +func (p *Page) Type() string { + return p.GetString(TYPE_FIELD) +} + +func (p *Page) SetType(pageType string) { + p.Set(TYPE_FIELD, pageType) +} + +func (p *Page) Data() map[string]interface{} { + val := p.Get(DATA_FIELD) + if val == nil { + return nil + } + return val.(map[string]interface{}) +} + +func (p *Page) SetData(data map[string]interface{}) { + p.Set(DATA_FIELD, data) +} diff --git a/migrations/01_tables.go b/migrations/01_tables.go index 12addf3..cc27233 100644 --- a/migrations/01_tables.go +++ b/migrations/01_tables.go @@ -72,6 +72,31 @@ func init() { return err } + err = app.Save(dataTable()) + if err != nil { + return err + } + + err = app.Save(imagesTable()) + if err != nil { + return err + } + + err = app.Save(filesTable()) + if err != nil { + return err + } + + err = app.Save(htmlTable()) + if err != nil { + return err + } + + err = app.Save(pagesTable()) + if err != nil { + return err + } + return nil }, func(app core.App) error { places, err := app.FindCollectionByNameOrId(dbmodels.PLACES_TABLE) @@ -436,3 +461,138 @@ func contentsIndexes(collection *core.Collection) { dbmodels.AddIndex(collection, dbmodels.YEAR_FIELD, false) dbmodels.AddIndexNoCollate(collection, dbmodels.ENTRIES_TABLE, false) } + +func dataTable() *core.Collection { + collection := core.NewBaseCollection(dbmodels.DATA_TABLE) + dbmodels.SetBasicPublicRules(collection) + collection.Fields = dataTableFields() + dataTableIndexes(collection) + return collection +} + +func dataTableFields() core.FieldsList { + fields := core.NewFieldsList( + &core.TextField{Name: dbmodels.KEY_FIELD, Required: true, Presentable: true}, + &core.JSONField{Name: dbmodels.VALUE_FIELD, Required: false}, + ) + dbmodels.SetCreatedUpdatedFields(&fields) + return fields +} + +func dataTableIndexes(collection *core.Collection) { + dbmodels.AddIndex(collection, dbmodels.KEY_FIELD, false) +} + +func imagesTable() *core.Collection { + collection := core.NewBaseCollection(dbmodels.IMAGES_TABLE) + dbmodels.SetBasicPublicRules(collection) + collection.Fields = imagesTableFields() + imagesTableIndexes(collection) + return collection +} + +func imagesTableFields() core.FieldsList { + fields := core.NewFieldsList( + &core.TextField{Name: dbmodels.KEY_FIELD, Required: true, Presentable: true}, + &core.TextField{Name: dbmodels.TITLE_FIELD, Required: false}, + &core.TextField{Name: dbmodels.DESCRIPTION_FIELD, Required: false}, + &core.FileField{ + Name: dbmodels.PREVIEW_FIELD, + Required: false, + MaxSize: 100 * 1024 * 1024, + MaxSelect: 1, + MimeTypes: dbmodels.MUSENALM_MIME_TYPES, + Thumbs: []string{"0x300", "0x500", "0x1000", "300x0", "500x0", "1000x0"}, + }, + &core.FileField{ + Name: dbmodels.IMAGE_FIELD, + Required: false, + MaxSize: 100 * 1024 * 1024, + MaxSelect: 1, + MimeTypes: dbmodels.MUSENALM_MIME_TYPES, + Thumbs: []string{"0x300", "0x500", "0x1000", "300x0", "500x0", "1000x0"}, + }, + ) + dbmodels.SetCreatedUpdatedFields(&fields) + return fields +} + +func imagesTableIndexes(collection *core.Collection) { + dbmodels.AddIndex(collection, dbmodels.KEY_FIELD, false) + dbmodels.AddIndex(collection, dbmodels.TITLE_FIELD, false) +} + +func filesTable() *core.Collection { + collection := core.NewBaseCollection(dbmodels.FILES_TABLE) + dbmodels.SetBasicPublicRules(collection) + collection.Fields = filesTableFields() + filesTableIndexes(collection) + return collection +} + +func filesTableFields() core.FieldsList { + fields := core.NewFieldsList( + &core.TextField{Name: dbmodels.KEY_FIELD, Required: true, Presentable: true}, + &core.TextField{Name: dbmodels.DESCRIPTION_FIELD, Required: false}, + &core.FileField{ + Name: dbmodels.FILE_FIELD, + Required: false, + MaxSize: 100 * 1024 * 1024, + MaxSelect: 1, + MimeTypes: dbmodels.MUSENALM_MIME_TYPES, + }, + ) + dbmodels.SetCreatedUpdatedFields(&fields) + return fields +} + +func filesTableIndexes(collection *core.Collection) { + dbmodels.AddIndex(collection, dbmodels.KEY_FIELD, false) +} + +func htmlTable() *core.Collection { + collection := core.NewBaseCollection(dbmodels.HTML_TABLE) + dbmodels.SetBasicPublicRules(collection) + collection.Fields = htmlTableFields() + htmlTableIndexes(collection) + return collection +} + +func htmlTableFields() core.FieldsList { + fields := core.NewFieldsList( + &core.TextField{Name: dbmodels.KEY_FIELD, Required: true, Presentable: true}, + &core.EditorField{Name: dbmodels.HTML_FIELD, Required: false, ConvertURLs: false}, + ) + dbmodels.SetCreatedUpdatedFields(&fields) + return fields +} + +func htmlTableIndexes(collection *core.Collection) { + dbmodels.AddIndex(collection, dbmodels.KEY_FIELD, false) +} + +func pagesTable() *core.Collection { + collection := core.NewBaseCollection(dbmodels.PAGES_TABLE) + dbmodels.SetBasicPublicRules(collection) + collection.Fields = pagesTableFields() + pagesTableIndexes(collection) + return collection +} + +func pagesTableFields() core.FieldsList { + fields := core.NewFieldsList( + &core.TextField{Name: dbmodels.KEY_FIELD, Required: true, Presentable: true}, + &core.TextField{Name: dbmodels.URL_FIELD, Required: false}, + &core.TextField{Name: dbmodels.TEMPLATE_FIELD, Required: false}, + &core.TextField{Name: dbmodels.LAYOUT_FIELD, Required: false}, + &core.TextField{Name: dbmodels.TYPE_FIELD, Required: false}, + &core.JSONField{Name: dbmodels.DATA_FIELD, Required: false}, + ) + dbmodels.SetCreatedUpdatedFields(&fields) + return fields +} + +func pagesTableIndexes(collection *core.Collection) { + dbmodels.AddIndex(collection, dbmodels.KEY_FIELD, false) + dbmodels.AddIndex(collection, dbmodels.URL_FIELD, false) +} diff --git a/migrations/1747983000_migrate_abkuerzungen.go b/migrations/1747983000_migrate_abkuerzungen.go new file mode 100644 index 0000000..a39447c --- /dev/null +++ b/migrations/1747983000_migrate_abkuerzungen.go @@ -0,0 +1,56 @@ +package migrations + +import ( + "github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels" + "github.com/pocketbase/pocketbase/core" + m "github.com/pocketbase/pocketbase/migrations" +) + +func init() { + m.Register(func(app core.App) error { + // Find source collection + abkColl, err := app.FindCollectionByNameOrId("page_benutzerhinweise_abkuerzungen") + if err != nil { + return err + } + + // Query all abbreviations + var records []*core.Record + err = app.RecordQuery(abkColl.Name).All(&records) + if err != nil { + return err + } + + // Convert to JSON map + abkMap := make(map[string]string) + for _, r := range records { + abkMap[r.GetString("Abkuerzung")] = r.GetString("Bedeutung") + } + + // Find data collection + dataColl, err := app.FindCollectionByNameOrId(dbmodels.DATA_TABLE) + if err != nil { + return err + } + + // Create new record in data table + record := core.NewRecord(dataColl) + record.Set(dbmodels.KEY_FIELD, "abkuerzungen") + record.Set(dbmodels.VALUE_FIELD, abkMap) + + return app.Save(record) + }, func(app core.App) error { + // Rollback: delete from data table + dataColl, err := app.FindCollectionByNameOrId(dbmodels.DATA_TABLE) + if err != nil { + return err + } + + record, err := app.FindFirstRecordByFilter(dataColl.Name, dbmodels.KEY_FIELD+" = 'abkuerzungen'") + if err != nil { + return nil // Already deleted + } + + return app.Delete(record) + }) +} diff --git a/scratchpad.md b/scratchpad.md index caf1988..c251cff 100644 --- a/scratchpad.md +++ b/scratchpad.md @@ -17,3 +17,68 @@ BUGS: - DI: Schriftgröße edit-Screen - MO: doppelte Einträge Reihen-Liste - S. Abendstunden +- Löschen v. Personen syncronisiert nicht den Suchindex + + + +Scrap that. I'd like more general tables: files, images, data, HTML + +Data has two main and two metadata fields: +Key (string, indexed) +Value (JSON) +Updated (date) +Created (date) + +Images has five main fields: +Key (string, indexed) +Title (string, indexed) +Description (string) +Preview (file) +Image (image, file) +Updated (date) +Created (date) + +Files has three main fields: +Key (string, indexed) +Description (string) +File (file) +Updated (date) +Created (date) + +HTML has two main fields: +Key (string, indexed) +HTML (editor) +Updated (date) +Created (date) + +I'd like to have a table for each of these. + +The following changes will be made to the db + migrations: +- Index images become a part of the more generic images table (their index starts with index-) so we can find them quickly +- Abkürzungen will be stored as an object in the data table +- All the text for the websites will be mmoved to the HTML table with the keys being the names. + +Help about the fields will also be stored in the data table as a JSON object: +[ +tablename: { + description: string, + private_description: string, + private: boolean, + fieldname: { + type: string, + firendly_name: string, + description: string, + private_description: string, + required: boolean, + private: boolean, + default: string, + options: array + } +}, +tablename: { +... ] + +1. Create the migrations for these three newtables in tables.go migration -- I will reapply all the migrations later +2. Move the existing abkürzungen to the data table +3. Move the existing index images to the images table +4. Move the existing websites to the HTML table (istead of each website having its own table)