130 lines
2.2 KiB
Go
130 lines
2.2 KiB
Go
package ejs
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
type Store struct {
|
|
path string
|
|
}
|
|
|
|
type Search interface {
|
|
match([]byte) bool
|
|
}
|
|
|
|
func NewStore(path string) (Store, error) {
|
|
s := Store{}
|
|
s.path = path
|
|
|
|
err := s.createFolderIfNeeded(path)
|
|
if err != nil {
|
|
return Store{}, err
|
|
}
|
|
|
|
return s, nil
|
|
}
|
|
|
|
func (s Store) Save(dataset, id string, data any) error {
|
|
err := s.createFolderIfNeeded(fmt.Sprintf("%v/%v", s.path, dataset))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
jsonData, err := json.Marshal(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
os.WriteFile(fmt.Sprintf("%v/%v/%v.json", s.path, dataset, id), jsonData, 0600)
|
|
return nil
|
|
}
|
|
|
|
func (s Store) List(dataset string) ([]string, error) {
|
|
entries, err := os.ReadDir(fmt.Sprintf("%v/%v/", s.path, dataset))
|
|
if err != nil {
|
|
return []string{}, err
|
|
}
|
|
|
|
var entrylist []string
|
|
for _, e := range entries {
|
|
name := e.Name()
|
|
name = strings.TrimRight(name, ".json")
|
|
entrylist = append(entrylist, name)
|
|
}
|
|
|
|
return entrylist, nil
|
|
}
|
|
|
|
func (s Store) Get(dataset, id string, data any) error {
|
|
content, err := os.ReadFile(fmt.Sprintf("%v/%v/%v.json", s.path, dataset, id))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = json.Unmarshal(content, data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s Store) Scan(dataset string, cbFunc func(id string)) error {
|
|
ids, err := s.List(dataset)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, id := range ids {
|
|
cbFunc(id)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s Store) Search(dataset string, searchFilter ...Search) ([]string, error) {
|
|
ids, err := s.List(dataset)
|
|
if err != nil {
|
|
return []string{}, err
|
|
}
|
|
|
|
found := []string{}
|
|
|
|
for _, id := range ids {
|
|
content, err := os.ReadFile(fmt.Sprintf("%v/%v/%v.json", s.path, dataset, id))
|
|
if err != nil {
|
|
return []string{}, err
|
|
}
|
|
|
|
match := true
|
|
for _, search := range searchFilter {
|
|
if !search.match(content) {
|
|
match = false
|
|
}
|
|
}
|
|
|
|
if match {
|
|
found = append(found, id)
|
|
}
|
|
}
|
|
|
|
return found, nil
|
|
}
|
|
|
|
func (s Store) createFolderIfNeeded(path string) error {
|
|
_, err := os.Stat(path)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
if !os.IsNotExist(err) {
|
|
return err
|
|
}
|
|
|
|
err = os.Mkdir(path, 0700)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|