plugins/coingecko/db.go (view raw)
1package coingecko
2
3import (
4 "bytes"
5 "encoding/gob"
6 "log"
7 "time"
8
9 "git.icyphox.sh/paprika/database"
10 "github.com/dgraph-io/badger/v3"
11)
12
13var (
14 canary = []byte("coin-gecko/list-up-to-date")
15 expire = 72 * time.Hour
16)
17
18func upsertCoinList() error {
19 coins, err := GetCoinList()
20 if err != nil {
21 return err
22 }
23 err = database.DB.DB.Update(func(txn *badger.Txn) error {
24 newCanary := badger.
25 NewEntry(canary, []byte{}).
26 WithTTL(time.Duration(expire))
27 err := txn.SetEntry(newCanary)
28 if err != nil {
29 return err
30 }
31
32 for _, coin := range coins {
33 var buf bytes.Buffer
34 encoder := gob.NewEncoder(&buf)
35 err := encoder.Encode(coin)
36 if err != nil {
37 return err
38 }
39 c := buf.Bytes()
40 err = txn.Set([]byte("coin-gecko/id/"+coin.Id), c)
41 if err != nil {
42 return err
43 }
44 err = txn.Set([]byte("coin-gecko/symbol/"+coin.Symbol), c)
45 if err != nil {
46 return err
47 }
48 }
49 return nil
50 })
51 return err
52}
53
54func GetCoinId(sym string) (string, error) {
55 var ret string
56 err := database.DB.DB.View(func(txn *badger.Txn) error {
57 item, err := txn.Get([]byte("coin-gecko/symbol/" + sym))
58 if err != nil && err != badger.ErrKeyNotFound {
59 return err
60 } else if err != badger.ErrKeyNotFound {
61 err = item.Value(func(val []byte) error {
62 var coinId CoinId
63 decoder := gob.NewDecoder(bytes.NewReader(val))
64 err := decoder.Decode(&coinId)
65 if err != nil {
66 return err
67 } else {
68 ret = coinId.Id
69 return nil
70 }
71 })
72 if err != nil {
73 return err
74 }
75 }
76
77 if ret != "" {
78 return nil
79 }
80
81 item, err = txn.Get([]byte("coin-gecko/id/" + sym))
82 if err != nil && err != badger.ErrKeyNotFound {
83 return err
84 } else if err != badger.ErrKeyNotFound {
85 err = item.Value(func(val []byte) error {
86 var coinId CoinId
87 decoder := gob.NewDecoder(bytes.NewReader(val))
88 err := decoder.Decode(&coinId)
89 if err != nil {
90 return err
91 } else {
92 ret = coinId.Id
93 return nil
94 }
95 })
96 if err != nil {
97 return err
98 }
99 }
100
101 return nil
102 })
103 return ret, err
104}
105
106func CheckUpdateCoinList() error {
107 _, err := database.DB.Get(canary)
108 if err == badger.ErrKeyNotFound {
109 log.Print("Updating Coin Gecko Coin IDs List... ")
110 err = upsertCoinList()
111 log.Println("Done.")
112 } else if err != nil {
113 return err
114 }
115 return err
116}