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 }