-
Notifications
You must be signed in to change notification settings - Fork 251
/
pricefeed.go
123 lines (96 loc) · 3.38 KB
/
pricefeed.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package database
import (
"fmt"
dbtypes "github.com/forbole/bdjuno/v3/database/types"
"github.com/forbole/bdjuno/v3/types"
"github.com/lib/pq"
)
// GetTokensPriceID returns the slice of price ids for all tokens stored in db
func (db *Db) GetTokensPriceID() ([]string, error) {
query := `SELECT * FROM token_unit`
var dbUnits []dbtypes.TokenUnitRow
err := db.Sqlx.Select(&dbUnits, query)
if err != nil {
return nil, err
}
var units []string
for _, unit := range dbUnits {
if unit.PriceID.String != "" {
units = append(units, unit.PriceID.String)
}
}
return units, nil
}
// --------------------------------------------------------------------------------------------------------------------
// SaveToken allows to save the given token details
func (db *Db) SaveToken(token types.Token) error {
query := `INSERT INTO token (name) VALUES ($1) ON CONFLICT DO NOTHING`
_, err := db.Sql.Exec(query, token.Name)
if err != nil {
return err
}
query = `INSERT INTO token_unit (token_name, denom, exponent, aliases, price_id) VALUES `
var params []interface{}
for i, unit := range token.Units {
ui := i * 5
query += fmt.Sprintf("($%d,$%d,$%d,$%d,$%d),", ui+1, ui+2, ui+3, ui+4, ui+5)
params = append(params, token.Name, unit.Denom, unit.Exponent, pq.StringArray(unit.Aliases),
dbtypes.ToNullString(unit.PriceID))
}
query = query[:len(query)-1] // Remove trailing ","
query += " ON CONFLICT DO NOTHING"
_, err = db.Sql.Exec(query, params...)
if err != nil {
return fmt.Errorf("error while saving token: %s", err)
}
return nil
}
// --------------------------------------------------------------------------------------------------------------------
// SaveTokensPrices allows to save the given prices as the most updated ones
func (db *Db) SaveTokensPrices(prices []types.TokenPrice) error {
if len(prices) == 0 {
return nil
}
query := `INSERT INTO token_price (unit_name, price, market_cap, timestamp) VALUES`
var param []interface{}
for i, ticker := range prices {
vi := i * 4
query += fmt.Sprintf("($%d,$%d,$%d,$%d),", vi+1, vi+2, vi+3, vi+4)
param = append(param, ticker.UnitName, ticker.Price, ticker.MarketCap, ticker.Timestamp)
}
query = query[:len(query)-1] // Remove trailing ","
query += `
ON CONFLICT (unit_name) DO UPDATE
SET price = excluded.price,
market_cap = excluded.market_cap,
timestamp = excluded.timestamp
WHERE token_price.timestamp <= excluded.timestamp`
_, err := db.Sql.Exec(query, param...)
if err != nil {
return fmt.Errorf("error while saving tokens prices: %s", err)
}
return nil
}
// SaveTokenPricesHistory stores the given prices as historic ones
func (db *Db) SaveTokenPricesHistory(prices []types.TokenPrice) error {
if len(prices) == 0 {
return nil
}
query := `INSERT INTO token_price_history (unit_name, price, market_cap, timestamp) VALUES`
var param []interface{}
for i, ticker := range prices {
vi := i * 4
query += fmt.Sprintf("($%d,$%d,$%d,$%d),", vi+1, vi+2, vi+3, vi+4)
param = append(param, ticker.UnitName, ticker.Price, ticker.MarketCap, ticker.Timestamp)
}
query = query[:len(query)-1] // Remove trailing ","
query += `
ON CONFLICT ON CONSTRAINT unique_price_for_timestamp DO UPDATE
SET price = excluded.price,
market_cap = excluded.market_cap`
_, err := db.Sql.Exec(query, param...)
if err != nil {
return fmt.Errorf("error while storing tokens price history: %s", err)
}
return nil
}