package memdb import ( "bytes" "cosmos-test/x/cosmostest/types" "encoding/gob" "log" "math/big" "github.com/dgraph-io/badger/v3" ) type bidDB struct { db *badger.DB } var BidDB bidDB // Mount Db & initialize encoder/decoder func (b *bidDB) Mount() { db, err := badger.Open(badger.DefaultOptions("").WithInMemory(true)) if err != nil { // must force crash here, since db is absolutely required log.Fatalf("Failed to mount in-memory db: %s", err) } b.db = db // initialize encode/decode stuff gob.Register([]types.Bid{}) } // Add a bid to the bid list under specified auction key. func (b *bidDB) AddBid(auctionId string, bid *types.Bid) error { k := []byte(auctionId) err := b.db.Update(func(txn *badger.Txn) error { var bids []*types.Bid bidsOld, err := txn.Get(k) if err == badger.ErrKeyNotFound { // key not found -> just create a new Bid array bids = []*types.Bid{} } else { if err != nil { return err } // key found -> decode contents to bids bidsOld.Value(func(val []byte) error { dec := gob.NewDecoder(bytes.NewReader(val)) if err := dec.Decode(&bids); err != nil { return err } return nil }) } // append bid bids = append(bids, bid) // encode new list buf := bytes.NewBuffer(nil) enc := gob.NewEncoder(buf) if err := enc.Encode(&bids); err != nil { return err } // set under auction key in db if err := txn.Set(k, buf.Bytes()); err != nil { return err } return nil }) return err } // Get the highest bid in the list under specified auction key. func (b *bidDB) GetHighestBid(auctionId string) (*types.Bid, error) { k := []byte(auctionId) var bid *types.Bid err := b.db.View(func(txn *badger.Txn) error { bidData, err := txn.Get(k) if err != nil { return err } err = bidData.Value(func(val []byte) error { var bids []*types.Bid dec := gob.NewDecoder(bytes.NewReader(val)) if err := dec.Decode(&bids); err != nil { return err } amt := big.NewInt(0) rAmt := big.NewInt(0) for _, rBid := range bids { if bid == nil { bid = rBid amt.SetString(rBid.Amount, 10) } else { rAmt.SetString(rBid.Amount, 10) if rAmt.Cmp(amt) == 1 { bid = rBid } } } return nil }) return err }) return bid, err } func (b *bidDB) ClearAuction(auctionId string) error { k := []byte(auctionId) err := b.db.Update(func(txn *badger.Txn) error { return txn.Delete(k) }) return err }