github.com/status-im/status-go@v1.1.0/multiaccounts/settings_wallet/database.go (about) 1 package walletsettings 2 3 import ( 4 "database/sql" 5 "errors" 6 ) 7 8 type TokenPreferences struct { 9 Key string `json:"key"` 10 Position int `json:"position"` 11 GroupPosition int `json:"groupPosition"` 12 Visible bool `json:"visible"` 13 CommunityID string `json:"communityId"` 14 } 15 16 type CollectiblePreferencesType int 17 18 const ( 19 CollectiblePreferencesTypeNonCommunityCollectible CollectiblePreferencesType = iota + 1 20 CollectiblePreferencesTypeCommunityCollectible 21 CollectiblePreferencesTypeCollection 22 CollectiblePreferencesTypeCommunity 23 ) 24 25 type CollectiblePreferences struct { 26 Type CollectiblePreferencesType `json:"type"` 27 Key string `json:"key"` 28 Position int `json:"position"` 29 Visible bool `json:"visible"` 30 } 31 32 type WalletSettings struct { 33 db *sql.DB 34 } 35 36 func NewWalletSettings(db *sql.DB) *WalletSettings { 37 return &WalletSettings{ 38 db: db, 39 } 40 } 41 42 // This function should not be used directly, it is called from the functions which update token preferences. 43 func (ws *WalletSettings) setClockOfLastTokenPreferencesChange(tx *sql.Tx, clock uint64) error { 44 if tx == nil { 45 return errors.New("database transaction is nil") 46 } 47 _, err := tx.Exec("UPDATE settings SET wallet_token_preferences_change_clock = ? WHERE synthetic_id = 'id'", clock) 48 return err 49 } 50 51 func (ws *WalletSettings) GetClockOfLastTokenPreferencesChange() (result uint64, err error) { 52 query := "SELECT wallet_token_preferences_change_clock FROM settings WHERE synthetic_id = 'id'" 53 err = ws.db.QueryRow(query).Scan(&result) 54 if err != nil { 55 return 0, err 56 } 57 return result, err 58 } 59 60 func (ws *WalletSettings) UpdateTokenPreferences(preferences []TokenPreferences, groupByCommunity bool, testNetworksEnabled bool, clock uint64) error { 61 if len(preferences) == 0 { 62 return errors.New("tokens: trying to create custom order with empty list") 63 } 64 65 tx, err := ws.db.Begin() 66 if err != nil { 67 return err 68 } 69 70 var mainError error = nil 71 72 defer func() { 73 if mainError == nil { 74 err = tx.Commit() 75 return 76 } 77 _ = tx.Rollback() 78 }() 79 80 _, mainError = tx.Exec("DELETE FROM token_preferences WHERE testnet = ?", testNetworksEnabled) 81 if mainError != nil { 82 return mainError 83 } 84 85 for _, p := range preferences { 86 if p.Position < 0 { 87 mainError = errors.New("tokens: trying to create custom order with negative position") 88 return mainError 89 } 90 _, err := tx.Exec("INSERT INTO token_preferences (key, position, group_position, visible, community_id, testnet) VALUES (?, ?, ?, ?, ?, ?)", p.Key, p.Position, p.GroupPosition, p.Visible, p.CommunityID, testNetworksEnabled) 91 if err != nil { 92 mainError = err 93 return err 94 } 95 } 96 97 if groupByCommunity { 98 // Find community tokens without group position 99 // Group position can be -1 if it wasn't created yet. Values must be consitstent across all tokens 100 rows, err := tx.Query(`SELECT COUNT(*) FROM token_preferences WHERE testnet = ? AND group_position = -1 AND community_id != '' AND visible GROUP BY community_id HAVING COUNT(*) > 0`, testNetworksEnabled) 101 if err != nil { 102 mainError = err 103 return err 104 } 105 if rows.Next() { 106 mainError = errors.New("tokens: not all community tokens have assigned the group position") 107 return mainError 108 } 109 } 110 111 mainError = ws.setClockOfLastTokenPreferencesChange(tx, clock) 112 if mainError != nil { 113 return mainError 114 } 115 return nil 116 } 117 118 func (ws *WalletSettings) GetTokenPreferences(testNetworksEnabled bool) ([]TokenPreferences, error) { 119 rows, err := ws.db.Query("SELECT key, position, group_position, visible, community_id FROM token_preferences WHERE testnet = ?", testNetworksEnabled) 120 if err != nil { 121 return nil, err 122 } 123 defer rows.Close() 124 125 var result []TokenPreferences 126 127 for rows.Next() { 128 token := TokenPreferences{} 129 err := rows.Scan(&token.Key, &token.Position, &token.GroupPosition, &token.Visible, &token.CommunityID) 130 if err != nil { 131 return nil, err 132 } 133 134 result = append(result, token) 135 } 136 137 if err := rows.Err(); err != nil { 138 return nil, err 139 } 140 141 return result, nil 142 } 143 144 func (ws *WalletSettings) setClockOfLastCollectiblePreferencesChange(tx *sql.Tx, clock uint64) error { 145 if tx == nil { 146 return errors.New("database transaction is nil") 147 } 148 _, err := tx.Exec("UPDATE settings SET wallet_collectible_preferences_change_clock = ? WHERE synthetic_id = 'id'", clock) 149 return err 150 } 151 152 func (ws *WalletSettings) GetClockOfLastCollectiblePreferencesChange() (result uint64, err error) { 153 query := "SELECT wallet_collectible_preferences_change_clock FROM settings WHERE synthetic_id = 'id'" 154 err = ws.db.QueryRow(query).Scan(&result) 155 if err != nil { 156 return 0, err 157 } 158 return result, err 159 } 160 161 func (ws *WalletSettings) UpdateCollectiblePreferences(preferences []CollectiblePreferences, groupByCommunity bool, groupByCollection bool, testNetworksEnabled bool, clock uint64) error { 162 if len(preferences) == 0 { 163 return errors.New("collectibles: trying to create custom order with empty list") 164 } 165 166 tx, err := ws.db.Begin() 167 if err != nil { 168 return err 169 } 170 171 var mainError error = nil 172 173 defer func() { 174 if mainError == nil { 175 err = tx.Commit() 176 return 177 } 178 _ = tx.Rollback() 179 }() 180 181 _, mainError = tx.Exec("DELETE FROM collectible_preferences WHERE testnet = ?", testNetworksEnabled) 182 if mainError != nil { 183 return mainError 184 } 185 186 for _, p := range preferences { 187 if p.Position < 0 { 188 mainError = errors.New("collectibles: trying to create custom order with negative position") 189 return mainError 190 } 191 _, err := tx.Exec("INSERT INTO collectible_preferences (type, key, position, visible, testnet) VALUES (?, ?, ?, ?, ?)", p.Type, p.Key, p.Position, p.Visible, testNetworksEnabled) 192 if err != nil { 193 mainError = err 194 return err 195 } 196 } 197 198 mainError = ws.setClockOfLastCollectiblePreferencesChange(tx, clock) 199 if mainError != nil { 200 return mainError 201 } 202 return nil 203 } 204 205 func (ws *WalletSettings) GetCollectiblePreferences(testNetworksEnabled bool) ([]CollectiblePreferences, error) { 206 rows, err := ws.db.Query("SELECT type, key, position, visible FROM collectible_preferences WHERE testnet = ?", testNetworksEnabled) 207 if err != nil { 208 return nil, err 209 } 210 defer rows.Close() 211 212 var result []CollectiblePreferences 213 214 for rows.Next() { 215 p := CollectiblePreferences{} 216 err := rows.Scan(&p.Type, &p.Key, &p.Position, &p.Visible) 217 if err != nil { 218 return nil, err 219 } 220 221 result = append(result, p) 222 } 223 224 if err := rows.Err(); err != nil { 225 return nil, err 226 } 227 228 return result, nil 229 }