package movies import ( "encoding/json" "io/ioutil" "sync" ) type Collection struct { Movies []*Movie mutex sync.RWMutex hasChanged bool movieMap map[string]*Movie } func Import(filename string) (*Collection, error) { b, err := ioutil.ReadFile(filename) if err != nil { return nil, err } var c Collection if err := json.Unmarshal(b, &c); err != nil { return nil, err } c.movieMap = make(map[string]*Movie) for _, m := range c.Movies { m.FillFromOMDB() c.movieMap[m.IMDBID] = m } return &c, nil } func (c *Collection) Export(filename string) error { c.mutex.RLock() defer c.mutex.RUnlock() b, err := json.Marshal(c) if err != nil { return err } err = ioutil.WriteFile(filename, b, 0644) if err != nil { return err } c.hasChanged = false return nil } func (c *Collection) Add(m *Movie) { c.mutex.Lock() defer c.mutex.Unlock() for _, present := range c.Movies { if m.IMDBID == present.IMDBID { return } } c.Movies = append(c.Movies, m) c.movieMap[m.IMDBID] = m c.hasChanged = true } func (c *Collection) HasChanged() bool { return c.hasChanged } func (c *Collection) Get(imdbID string) (*Movie, bool) { c.mutex.RLock() defer c.mutex.RUnlock() m, ok := c.movieMap[imdbID] return m, ok } func (c *Collection) Update(m *Movie) { c.mutex.Lock() defer c.mutex.Unlock() c.movieMap[m.IMDBID] = m found := false for i := range c.Movies { if c.Movies[i].IMDBID == m.IMDBID { c.Movies[i] = m found = true break } } if !found { c.Movies = append(c.Movies, m) } c.hasChanged = true }