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 { buf := bytes.NewBuffer([]byte{}) enc := gob.NewEncoder(buf) dec := gob.NewDecoder(buf) 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 { buf.Reset() if _, err := buf.Read(val); err != nil { return err } if err := dec.Decode(&bids); err != nil { return err } return nil }) } // append bid bids = append(bids, bid) // encode new list buf.Reset() 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) buf := bytes.NewBuffer([]byte{}) dec := gob.NewDecoder(buf) 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 { buf.Reset() if _, err := buf.Read(val); err != nil { return err } // panic(len(val)) var bids []*types.Bid 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 }