forked from stellar/go
/
account.go
100 lines (81 loc) · 2.48 KB
/
account.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
package history
import (
sq "github.com/Masterminds/squirrel"
"github.com/stellar/go/services/horizon/internal/db2"
"github.com/stellar/go/xdr"
)
// Accounts provides a helper to filter rows from the `history_accounts` table
// with pre-defined filters. See `AccountsQ` methods for the available filters.
func (q *Q) Accounts() *AccountsQ {
return &AccountsQ{
parent: q,
sql: selectAccount,
}
}
// AccountByAddress loads a row from `history_accounts`, by address
func (q *Q) AccountByAddress(dest interface{}, addy string) error {
sql := selectAccount.Limit(1).Where("ha.address = ?", addy)
return q.Get(dest, sql)
}
// AccountByID loads a row from `history_accounts`, by id
func (q *Q) AccountByID(dest interface{}, id int64) error {
sql := selectAccount.Limit(1).Where("ha.id = ?", id)
return q.Get(dest, sql)
}
// Page specifies the paging constraints for the query being built by `q`.
func (q *AccountsQ) Page(page db2.PageQuery) *AccountsQ {
if q.Err != nil {
return q
}
q.sql, q.Err = page.ApplyTo(q.sql, "ha.id")
return q
}
// Select loads the results of the query specified by `q` into `dest`.
func (q *AccountsQ) Select(dest interface{}) error {
if q.Err != nil {
return q.Err
}
q.Err = q.parent.Select(dest, q.sql)
return q.Err
}
// AccountsByAddresses loads a rows from `history_accounts`, by addresses
func (q *Q) AccountsByAddresses(dest interface{}, addresses []string) error {
sql := selectAccount.Where(map[string]interface{}{
"ha.address": addresses, // ha.address IN (...)
})
return q.Select(dest, sql)
}
// CreateAccounts creates rows for addresses in history_accounts table and
// put
func (q *Q) CreateAccounts(dest interface{}, addresses []string) error {
sql := sq.Insert("history_accounts").Columns("address")
for _, address := range addresses {
sql = sql.Values(address)
}
sql = sql.Suffix("RETURNING *")
return q.Select(dest, sql)
}
// Return id for account. If account doesn't exist, it will be created and the new id returned.
func (q *Q) GetCreateAccountID(
aid xdr.AccountId,
) (result int64, err error) {
var existing Account
err = q.AccountByAddress(&existing, aid.Address())
//account already exists, return id
if err == nil {
result = existing.ID
return
}
// unexpected error
if !q.NoRows(err) {
return
}
//insert account and return id
err = q.GetRaw(
&result,
`INSERT INTO history_accounts (address) VALUES (?) RETURNING id`,
aid.Address(),
)
return
}
var selectAccount = sq.Select("ha.*").From("history_accounts ha")