Files
2025-08-26 14:04:45 +10:00

124 lines
2.9 KiB
Go

package plg_metadata_sqlite
import (
"database/sql"
"encoding/json"
"fmt"
"os"
"strings"
. "github.com/mickael-kerjean/filestash/server/common"
_ "modernc.org/sqlite"
)
func init() {
db, err := sql.Open("sqlite", GetAbsolutePath(DB_PATH, "metadata.sql"))
if err != nil {
Log.Error("plg_metadata_sqlite - cannot open sqlite metadata db: %s", err.Error())
os.Exit(1)
return
}
db.Exec(`CREATE TABLE IF NOT EXISTS metadata (
tenantID TEXT NOT NULL,
path TEXT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (tenantID, path)
)`)
Hooks.Register.Metadata(MetaImpl{db: db})
}
type MetaImpl struct {
db *sql.DB
}
func (this MetaImpl) Get(ctx *App, path string) ([]FormElement, error) {
tenantID := GenerateID(ctx.Session)
forms := []FormElement{}
var blob string
err := this.db.QueryRowContext(ctx.Context, "SELECT value FROM metadata WHERE tenantID=? AND path = ?", tenantID, path).Scan(&blob)
if err == sql.ErrNoRows {
return forms, nil
} else if err != nil {
return forms, err
}
err = json.Unmarshal([]byte(blob), &forms)
return forms, err
}
func (this MetaImpl) Set(ctx *App, path string, value []FormElement) error {
tenantID := GenerateID(ctx.Session)
if len(value) == 0 {
_, err := this.db.Exec("DELETE FROM metadata WHERE tenantID=? AND path=?", tenantID, path)
return err
}
blob, err := json.Marshal(value)
if err != nil {
return err
}
_, err = this.db.Exec(`
INSERT INTO metadata (tenantID, path, value) VALUES (?, ?, ?)
ON CONFLICT(tenantID, path) DO UPDATE SET value=excluded.value
`, tenantID, path, string(blob))
return err
}
func (this MetaImpl) Search(ctx *App, path string, facets map[string]any) (map[string][]FormElement, error) {
tenantID := GenerateID(ctx.Session)
rows, err := this.db.QueryContext(ctx.Context, `
SELECT path, value FROM metadata WHERE
tenantID=? AND
path LIKE ?
ORDER BY path
`, tenantID, path+"%")
if err != nil {
return nil, err
}
out := make(map[string][]FormElement)
for rows.Next() {
var (
metapath string
metavalue []byte
metaforms []FormElement
)
if err = rows.Scan(&metapath, &metavalue); err != nil {
break
}
if err = json.Unmarshal(metavalue, &metaforms); err != nil {
break
}
isResult := false
for _, form := range metaforms {
if form.Id == "" || facets[form.Id] == "" {
continue
}
facetValues, ok := facets[form.Id].([]any)
if !ok {
continue
}
formValue := fmt.Sprintf("%s", form.Value)
isOK := true
for _, facetValue := range facetValues {
if strings.Contains(formValue, fmt.Sprintf("%s", facetValue)) == false {
isOK = false
break
}
}
if isOK {
isResult = true
}
}
if isResult {
chroot := ctx.Session["path"]
if key := strings.TrimPrefix(metapath, chroot); key != "" {
if !strings.HasPrefix(key, "/") {
key = "/" + key
}
out[key] = metaforms
}
}
}
rows.Close()
return out, nil
}