Nigiri/collection.go

112 lines
2.1 KiB
Go

package nigiri
import (
"fmt"
"os"
"path/filepath"
"sync"
)
type StoreManager interface {
LoadData(path string) error
SaveData(path string) error
Clear()
EntityExists(id int) bool
SetValidator(validator any)
}
type Collection struct {
baseDir string
stores map[string]StoreManager
mu sync.RWMutex
}
func NewCollection(baseDir string) *Collection {
return &Collection{
baseDir: baseDir,
stores: make(map[string]StoreManager),
}
}
// Add registers store and auto-loads if file exists
func (c *Collection) Add(name string, store StoreManager) error {
c.mu.Lock()
defer c.mu.Unlock()
c.stores[name] = store
store.SetValidator(c)
// Auto-load if file exists
path := filepath.Join(c.baseDir, name+".json")
if _, err := os.Stat(path); err == nil {
return store.LoadData(path)
}
return nil
}
// Get returns typed store
func Get[T any](c *Collection, name string) *BaseStore[T] {
c.mu.RLock()
defer c.mu.RUnlock()
if store, exists := c.stores[name]; exists {
if typed, ok := store.(*BaseStore[T]); ok {
return typed
}
}
return nil
}
// Load loads all stores
func (c *Collection) Load() error {
c.mu.RLock()
defer c.mu.RUnlock()
os.MkdirAll(c.baseDir, 0755)
for name, store := range c.stores {
path := filepath.Join(c.baseDir, name+".json")
if err := store.LoadData(path); err != nil {
return fmt.Errorf("load %s: %w", name, err)
}
}
return nil
}
// Save saves all stores
func (c *Collection) Save() error {
c.mu.RLock()
defer c.mu.RUnlock()
os.MkdirAll(c.baseDir, 0755)
for name, store := range c.stores {
path := filepath.Join(c.baseDir, name+".json")
if err := store.SaveData(path); err != nil {
return fmt.Errorf("save %s: %w", name, err)
}
}
return nil
}
// Clear clears all stores
func (c *Collection) Clear() {
c.mu.RLock()
defer c.mu.RUnlock()
for _, store := range c.stores {
store.Clear()
}
}
// EntityExists implements relationship validation
func (c *Collection) EntityExists(entityName string, id int) bool {
c.mu.RLock()
defer c.mu.RUnlock()
if store, exists := c.stores[entityName]; exists {
return store.EntityExists(id)
}
return false
}