package main import ( "encoding/json" "fmt" "sort" "github.com/peterbourgon/diskv" ) type AlbumDatabase struct { dv *diskv.Diskv sorted bool sortedList []AlbumID } func OpenAlbumDatabase(basepath string) *AlbumDatabase { return &AlbumDatabase{ dv: diskv.New(diskv.Options{ BasePath: basepath, CacheSizeMax: 100 * 1024 * 1024, // 100 MB Compression: diskv.NewGzipCompression(), }), sorted: false, sortedList: make([]AlbumID, 0, 10), } } func (db *AlbumDatabase) AddOrUpdate(a *Album) error { data, err := json.Marshal(a) if err != nil { return err } aInDb, err := db.Get(a.ID) dbNewSorted := false if err == nil { dbNewSorted = (a.PurchaseDate != aInDb.PurchaseDate) } err = db.dv.Write(AlbumIDString(a.ID), data) if err == nil { db.sorted = dbNewSorted } return err } func (db *AlbumDatabase) Delete(ID AlbumID) error { if db.dv.Has(AlbumIDString(ID)) == false { return fmt.Errorf("Album %d not found", ID) } return db.dv.Erase(AlbumIDString(ID)) } func (db *AlbumDatabase) get(ID string) (*Album, error) { res := &Album{} r, err := db.dv.ReadStream(ID, false) if err != nil { return nil, fmt.Errorf("Album %s not found: %s", ID, err) } dec := json.NewDecoder(r) defer closeOrPanic(r, "db record "+ID) return res, dec.Decode(res) } func (db *AlbumDatabase) Get(ID AlbumID) (*Album, error) { return db.get(AlbumIDString(ID)) } func (db *AlbumDatabase) GetJSON(ID AlbumID) ([]byte, error) { return db.dv.Read(AlbumIDString(ID)) } type ListOfAlbum []*Album func (l ListOfAlbum) Len() int { return len(l) } func (l ListOfAlbum) Less(i, j int) bool { return l[i].PurchaseDate.Before(l[j].PurchaseDate) } func (l ListOfAlbum) Swap(i, j int) { l[i], l[j] = l[j], l[i] } func (db *AlbumDatabase) ByPurchaseDate() ([]AlbumID, error) { if db.sorted == false { allAlbums := []*Album{} for aIDStr := range db.dv.Keys(nil) { a, err := db.get(aIDStr) if err != nil { return nil, err } allAlbums = append(allAlbums, a) } sort.Sort(sort.Reverse(ListOfAlbum(allAlbums))) db.sortedList = make([]AlbumID, 0, len(allAlbums)) for _, a := range allAlbums { db.sortedList = append(db.sortedList, a.ID) } db.sorted = true } return db.sortedList, nil }