package store import "git.tukangketik.id/swanadiva/hostkeeper/v2/internal/model" type HostStore struct { hosts []model.Host } func NewHostStore() *HostStore { s := &HostStore{} mu.RLock() readFile("hosts.json", &s.hosts) mu.RUnlock() if s.hosts == nil { s.hosts = []model.Host{} } return s } func (s *HostStore) All() []model.Host { mu.RLock() defer mu.RUnlock() return s.hosts } func (s *HostStore) Search(q, filter string) []model.Host { mu.RLock() defer mu.RUnlock() var result []model.Host for _, h := range s.hosts { if filter != "" && filter != "all" && h.Status != filter { continue } if q == "" || contains(h.Name, q) || contains(h.IP, q) || contains(h.OS, q) || contains(h.Hostname, q) || contains(h.Username, q) { result = append(result, h) } } if result == nil { return []model.Host{} } return result } func (s *HostStore) Get(id string) (model.Host, bool) { mu.RLock() defer mu.RUnlock() for _, h := range s.hosts { if h.ID == id { return h, true } } return model.Host{}, false } func (s *HostStore) Add(name, ip, os, provider, hostType string) model.Host { return s.AddFull(model.Host{ Name: name, IP: ip, OS: os, Provider: provider, Type: hostType, }) } func (s *HostStore) AddFull(h model.Host) model.Host { mu.Lock() defer mu.Unlock() if h.ID == "" { h.ID = randID() } if h.Status == "" { h.Status = "active" } s.hosts = append(s.hosts, h) writeFile("hosts.json", &s.hosts) return h } func (s *HostStore) Update(h model.Host) bool { mu.Lock() defer mu.Unlock() for i, existing := range s.hosts { if existing.ID == h.ID { s.hosts[i] = h writeFile("hosts.json", &s.hosts) return true } } return false } func (s *HostStore) Delete(id string) { mu.Lock() defer mu.Unlock() for i, h := range s.hosts { if h.ID == id { s.hosts = append(s.hosts[:i], s.hosts[i+1:]...) writeFile("hosts.json", &s.hosts) return } } } func contains(s, q string) bool { if len(s) < len(q) { return false } for i := 0; i <= len(s)-len(q); i++ { match := true for j := 0; j < len(q); j++ { sc, qc := s[i+j], q[j] if sc >= 'A' && sc <= 'Z' { sc += 32 } if qc >= 'A' && qc <= 'Z' { qc += 32 } if sc != qc { match = false break } } if match { return true } } return false }