-
Notifications
You must be signed in to change notification settings - Fork 2
/
query.go
208 lines (189 loc) · 5.77 KB
/
query.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package repository
import (
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
IBCTypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
_ "github.com/lib/pq"
"github.com/synternet/osmosis-publisher/pkg/repository"
)
func (r *Repository) IBCDenom(ibc string) (IBCTypes.DenomTrace, bool) {
var denom IBCDenom
result := r.dbCon.Model(&IBCDenom{}).Limit(1).Find(&denom, "ibc = ?", ibc)
if result.Error != nil {
r.logger.Error("Error fetching IBC Denom from DB:", result.Error)
}
if result.RowsAffected == 0 {
return IBCTypes.DenomTrace{}, false
}
return IBCTypes.DenomTrace{
Path: denom.Path,
BaseDenom: denom.BaseDenom,
}, true
}
func (r *Repository) IBCDenomAll() []IBCTypes.DenomTrace {
var denoms []IBCDenom
result := r.dbCon.Model(&IBCDenom{}).Find(&denoms)
if result.Error != nil {
r.logger.Error("Error fetching all IBC Denoms from DB:", result.Error)
return nil
}
traces := make([]IBCTypes.DenomTrace, len(denoms))
for i, d := range denoms {
traces[i] = IBCTypes.DenomTrace{
Path: d.Path,
BaseDenom: d.BaseDenom,
}
}
return traces
}
func (r *Repository) TokenPrice(timestamp time.Time, denom string) (repository.TokenPrice, bool) {
var token TokenPrice
result := r.dbCon.Model(&TokenPrice{}).Limit(1).Find(&token, "last_updated = ? AND name = ?", timestamp.UnixNano(), denom)
if result.Error != nil {
r.logger.Error("Error fetching TokenPrice from DB:", result.Error)
}
if result.RowsAffected == 0 {
return repository.TokenPrice{}, false
}
return repository.TokenPrice{
LastUpdated: time.Unix(0, token.LastUpdated),
Value: token.Value,
Name: token.Name,
Base: token.Base,
}, true
}
// FIXME
func (r *Repository) NearestTokenPrice(timestamp time.Time, denom string) ([]repository.TokenPrice, bool) {
var tokens []TokenPrice
ts := timestamp.UnixNano()
result := r.dbCon.Raw(
fmt.Sprintf(`
SELECT * FROM token_prices
WHERE name = ? AND (
last_updated = (
SELECT MAX(last_updated) FROM token_prices WHERE last_updated <= ?
) OR last_updated = (
SELECT MIN(last_updated) FROM token_prices WHERE last_updated >= ?
)
)
LIMIT 2
`),
denom, ts, ts).Scan(&tokens)
if result.Error != nil {
r.logger.Error("Error fetching TokenPrices from DB:", result.Error)
}
if result.RowsAffected == 0 {
return nil, false
}
arr := make([]repository.TokenPrice, len(tokens))
for i, token := range tokens {
arr[i] = repository.TokenPrice{
LastUpdated: time.Unix(0, token.LastUpdated),
Value: token.Value,
Name: token.Name,
Base: token.Base,
}
}
return arr, true
}
// LatestTokenPrice will return latest token price.
func (r *Repository) LatestTokenPrice(denom string) (repository.TokenPrice, bool) {
var token TokenPrice
result := r.dbCon.Model(&TokenPrice{}).Order("last_updated DESC").Limit(1).Find(&token, "name = ?", denom)
if result.Error != nil {
r.logger.Error("Error fetching TokenPrice from DB:", result.Error)
}
if result.RowsAffected == 0 {
return repository.TokenPrice{}, false
}
return repository.TokenPrice{
LastUpdated: time.Unix(0, token.LastUpdated),
Value: token.Value,
Name: token.Name,
Base: token.Base,
}, true
}
// LatestPool will return latest pool
func (r *Repository) LatestPool(id uint64) (repository.Pool, bool) {
var pool Pool
result := r.dbCon.Model(&Pool{}).Last(&pool, "pool_id = ?", id)
if result.Error != nil {
r.logger.Error("Error fetching Pool from DB:", result.Error)
return repository.Pool{}, false
}
if result.RowsAffected == 0 {
return repository.Pool{}, false
}
liquidity, err := sdk.ParseCoinsNormalized(pool.Liquidity)
if err != nil {
r.logger.Error("Error parsing pool liquidity from DB", "err", err)
return repository.Pool{}, false
}
volume, err := sdk.ParseCoinsNormalized(pool.Volume)
if err != nil {
r.logger.Error("Error parsing pool volume from DB", "err", err)
return repository.Pool{}, false
}
return repository.Pool{
Height: pool.Height,
PoolId: pool.PoolId,
Liquidity: liquidity,
Volume: volume,
}, true
}
// PoolsRange will return pools from min to max height
func (r *Repository) PoolsRange(min, max, poolId uint64) ([]repository.Pool, error) {
var pools []Pool
query := "height >= ? AND height <= ? AND pool_id = ?"
if poolId == 0 {
query = "height >= ? AND height <= ?"
}
result := r.dbCon.Model(&Pool{}).Find(&pools, query, min, max, poolId)
if result.Error != nil {
r.logger.Error("Error fetching Pools from DB:", result.Error)
return nil, result.Error
}
ret := make([]repository.Pool, len(pools))
for i, p := range pools {
liquidity, err := sdk.ParseCoinsNormalized(p.Liquidity)
if err != nil {
r.logger.Error("Error parsing liquidity from DB", "poolId", p.PoolId, "err", err)
return nil, err
}
volume, err := sdk.ParseCoinsNormalized(p.Volume)
if err != nil {
r.logger.Error("Error parsing volume", "poolId", p.PoolId, "err", err)
return nil, err
}
ret[i] = repository.Pool{
Height: p.Height,
PoolId: p.PoolId,
Liquidity: liquidity,
Volume: volume,
}
}
return ret, nil
}
func (r *Repository) TokenPricesRange(min, max time.Time, denom string) ([]repository.TokenPrice, error) {
var prices []TokenPrice
query := "last_updated >= ? AND last_updated <= ? AND name = ?"
if denom == "" {
query = "last_updated >= ? AND last_updated <= ?"
}
result := r.dbCon.Model(&TokenPrice{}).Find(&prices, query, min.UnixNano(), max.UnixNano(), denom)
if result.Error != nil {
r.logger.Error("Error fetching Token Prices from DB:", result.Error)
return nil, result.Error
}
ret := make([]repository.TokenPrice, len(prices))
for i, p := range prices {
ret[i] = repository.TokenPrice{
LastUpdated: time.Unix(0, p.LastUpdated),
Value: p.Value,
Name: p.Name,
Base: p.Base,
}
}
return ret, nil
}