package store import ( "encoding/json" "os" "sync" "git.pengzhan.dev/noteplace-server/internal/models" ) // DB represents the structure of the entire JSON database. type DB struct { Users map[string]models.User `json:"users"` Sessions map[string]models.Session `json:"sessions"` Places map[string]models.Place `json:"places"` Addresses map[string]models.Address `json:"addresses"` Categories map[string]models.Category `json:"categories"` Attributes map[string]models.Attribute `json:"attributes"` Ratings map[string]models.Rating `json:"ratings"` } // Store manages the in-memory data and provides safe access. type Store struct { Mu sync.RWMutex path string Data *DB } // New creates and initializes a new Store. func New(path string) (*Store, error) { s := &Store{ path: path, Data: &DB{}, } if err := s.load(); err != nil { return nil, err } return s, nil } // load reads the database file from disk into the Store. func (s *Store) load() error { s.Mu.Lock() defer s.Mu.Unlock() file, err := os.ReadFile(s.path) if err != nil { // If the file doesn't exist, we can assume an empty database. if os.IsNotExist(err) { s.Data = &DB{ Users: map[string]models.User{}, Sessions: map[string]models.Session{}, Places: map[string]models.Place{}, Addresses: map[string]models.Address{}, Categories: map[string]models.Category{}, Attributes: map[string]models.Attribute{}, Ratings: map[string]models.Rating{}, } return nil } return err } return json.Unmarshal(file, s.Data) } // Save writes the current in-memory data back to the JSON file. func (s *Store) Save() error { s.Mu.RLock() defer s.Mu.RUnlock() data, err := json.MarshalIndent(s.Data, "", " ") if err != nil { return err } return os.WriteFile(s.path, data, 0644) } // CreateSession adds a new session to the store.