-
Notifications
You must be signed in to change notification settings - Fork 242
/
persistence.go
119 lines (99 loc) · 3.04 KB
/
persistence.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
package ens
import (
"context"
"database/sql"
"errors"
)
type Persistence struct {
db *sql.DB
}
func NewPersistence(db *sql.DB) *Persistence {
return &Persistence{db: db}
}
func (p *Persistence) GetENSToBeVerified(now uint64) ([]*VerificationRecord, error) {
rows, err := p.db.Query(`SELECT public_key, name, verified, verified_at, clock, verification_retries, next_retry FROM ens_verification_records WHERE NOT(verified) AND verification_retries < ? AND next_retry <= ?`, maxRetries, now)
if err != nil {
return nil, err
}
var records []*VerificationRecord
for rows.Next() {
var record VerificationRecord
err := rows.Scan(&record.PublicKey, &record.Name, &record.Verified, &record.VerifiedAt, &record.Clock, &record.VerificationRetries, &record.NextRetry)
if err != nil {
return nil, err
}
records = append(records, &record)
}
return records, nil
}
func (p *Persistence) UpdateRecords(records []*VerificationRecord) (err error) {
var tx *sql.Tx
tx, err = p.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
for _, record := range records {
var stmt *sql.Stmt
stmt, err = tx.Prepare(`UPDATE ens_verification_records SET verified = ?, verified_at = ?, verification_retries = ?, next_retry = ? WHERE public_key = ?`)
if err != nil {
return err
}
defer stmt.Close()
_, err = stmt.Exec(record.Verified, record.VerifiedAt, record.VerificationRetries, record.NextRetry, record.PublicKey)
if err != nil {
return err
}
}
return nil
}
// AddRecord adds a record or return the latest available if already in the database and
// hasn't changed
func (p *Persistence) AddRecord(record VerificationRecord) (response *VerificationRecord, err error) {
if !record.Valid() {
err = errors.New("invalid ens record")
return
}
var tx *sql.Tx
tx, err = p.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
dbRecord := &VerificationRecord{PublicKey: record.PublicKey}
err = tx.QueryRow(`SELECT name, clock, verified FROM ens_verification_records WHERE public_key = ?`, record.PublicKey).Scan(&dbRecord.Name, &dbRecord.Clock, &dbRecord.Verified)
if err != nil && err != sql.ErrNoRows {
return
}
if dbRecord.Clock >= record.Clock || dbRecord.Name == record.Name {
response = dbRecord
return
}
_, err = tx.Exec(`INSERT INTO ens_verification_records(public_key, name, clock) VALUES (?,?,?)`, record.PublicKey, record.Name, record.Clock)
return
}
func (p *Persistence) GetVerifiedRecord(publicKey string) (*VerificationRecord, error) {
record := &VerificationRecord{}
err := p.db.QueryRow(`SELECT name, clock FROM ens_verification_records WHERE verified AND public_key = ?`, publicKey).Scan(&record.Name, &record.Clock)
switch err {
case sql.ErrNoRows:
return nil, nil
case nil:
return record, nil
}
return nil, err
}