112 lines
2.1 KiB
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
|
|
}
|