mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-10-29 00:55:51 +08:00
124 lines
2.9 KiB
Go
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
|
|
}
|