-
Notifications
You must be signed in to change notification settings - Fork 242
/
database.go
143 lines (121 loc) · 2.81 KB
/
database.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
package sociallinkssettings
import (
"context"
"database/sql"
"errors"
"github.com/status-im/status-go/protocol/identity"
)
const (
MaxNumOfSocialLinks = 20
)
var (
ErrNilSocialLinkProvided = errors.New("social links, nil object provided")
ErrOlderSocialLinksProvided = errors.New("older social links provided")
)
type SocialLinksSettings struct {
db *sql.DB
}
func NewSocialLinksSettings(db *sql.DB) *SocialLinksSettings {
return &SocialLinksSettings{
db: db,
}
}
func (s *SocialLinksSettings) getSocialLinksClock(tx *sql.Tx) (result uint64, err error) {
query := "SELECT social_links FROM settings_sync_clock WHERE synthetic_id = 'id'"
if tx == nil {
err = s.db.QueryRow(query).Scan(&result)
} else {
err = tx.QueryRow(query).Scan(&result)
}
return result, err
}
func (s *SocialLinksSettings) getSocialLinks(tx *sql.Tx) (identity.SocialLinks, error) {
var (
rows *sql.Rows
err error
)
query := "SELECT text, url FROM profile_social_links ORDER BY position ASC"
if tx == nil {
rows, err = s.db.Query(query)
} else {
rows, err = tx.Query(query)
}
if err != nil {
return nil, err
}
defer rows.Close()
var socialLinks identity.SocialLinks
for rows.Next() {
socialLink := &identity.SocialLink{}
err := rows.Scan(&socialLink.Text, &socialLink.URL)
if err != nil {
return nil, err
}
socialLinks = append(socialLinks, socialLink)
}
err = rows.Err()
if err != nil {
return nil, err
}
return socialLinks, nil
}
func (s *SocialLinksSettings) GetSocialLinks() (identity.SocialLinks, error) {
return s.getSocialLinks(nil)
}
func (s *SocialLinksSettings) GetSocialLinksClock() (result uint64, err error) {
return s.getSocialLinksClock(nil)
}
func (s *SocialLinksSettings) AddOrReplaceSocialLinksIfNewer(links identity.SocialLinks, clock uint64) error {
tx, err := s.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
dbClock, err := s.getSocialLinksClock(tx)
if err != nil {
return err
}
if dbClock > clock {
return ErrOlderSocialLinksProvided
}
dbLinks, err := s.getSocialLinks(tx)
if err != nil {
return err
}
if len(dbLinks) > 0 {
_, err = tx.Exec("DELETE from profile_social_links")
if err != nil {
return err
}
}
stmt, err := tx.Prepare("INSERT INTO profile_social_links (text, url, position) VALUES (?, ?, ?)")
if err != nil {
return err
}
defer stmt.Close()
for position, link := range links {
if link == nil {
return ErrNilSocialLinkProvided
}
_, err = stmt.Exec(
link.Text,
link.URL,
position,
)
if err != nil {
return err
}
}
stmt, err = tx.Prepare("UPDATE settings_sync_clock SET social_links = ? WHERE synthetic_id = 'id'")
if err != nil {
return err
}
_, err = stmt.Exec(clock)
return err
}