mirror of
				https://github.com/mickael-kerjean/filestash.git
				synced 2025-10-31 10:07:15 +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
 | |
| }
 | 
