2019-08-20 18:38:40 +03:00
package multiaccounts
import (
2020-11-24 13:13:46 +00:00
"context"
2019-08-20 18:38:40 +03:00
"database/sql"
2020-11-24 13:13:46 +00:00
"github.com/status-im/status-go/images"
2019-08-20 18:38:40 +03:00
"github.com/status-im/status-go/multiaccounts/migrations"
"github.com/status-im/status-go/sqlite"
)
// Account stores public information about account.
type Account struct {
2020-11-24 13:13:46 +00:00
Name string ` json:"name" `
Timestamp int64 ` json:"timestamp" `
KeycardPairing string ` json:"keycard-pairing" `
KeyUID string ` json:"key-uid" `
ImageURIs [ ] string ` json:"image-uris" `
}
type Database struct {
db * sql . DB
2019-08-20 18:38:40 +03:00
}
// InitializeDB creates db file at a given path and applies migrations.
func InitializeDB ( path string ) ( * Database , error ) {
db , err := sqlite . OpenUnecryptedDB ( path )
if err != nil {
return nil , err
}
err = migrations . Migrate ( db )
if err != nil {
return nil , err
}
return & Database { db : db } , nil
}
func ( db * Database ) Close ( ) error {
return db . db . Close ( )
}
func ( db * Database ) GetAccounts ( ) ( [ ] Account , error ) {
2020-11-24 13:13:46 +00:00
rows , err := db . db . Query ( "SELECT name, loginTimestamp, keycardPairing, keyUid from accounts ORDER BY loginTimestamp DESC" )
2019-08-20 18:38:40 +03:00
if err != nil {
return nil , err
}
2020-05-14 06:51:32 -04:00
defer rows . Close ( )
2020-11-24 13:13:46 +00:00
var rst [ ] Account
2019-08-20 18:38:40 +03:00
inthelper := sql . NullInt64 { }
for rows . Next ( ) {
acc := Account { }
2020-11-24 13:13:46 +00:00
err = rows . Scan ( & acc . Name , & inthelper , & acc . KeycardPairing , & acc . KeyUID )
2019-08-20 18:38:40 +03:00
if err != nil {
return nil , err
}
acc . Timestamp = inthelper . Int64
rst = append ( rst , acc )
}
return rst , nil
}
func ( db * Database ) SaveAccount ( account Account ) error {
2020-11-24 13:13:46 +00:00
_ , err := db . db . Exec ( "INSERT OR REPLACE INTO accounts (name, keycardPairing, keyUid) VALUES (?, ?, ?)" , account . Name , account . KeycardPairing , account . KeyUID )
2019-08-20 18:38:40 +03:00
return err
}
func ( db * Database ) UpdateAccount ( account Account ) error {
2020-11-24 13:13:46 +00:00
_ , err := db . db . Exec ( "UPDATE accounts SET name = ?, keycardPairing = ? WHERE keyUid = ?" , account . Name , account . KeycardPairing , account . KeyUID )
2019-08-20 18:38:40 +03:00
return err
}
2019-12-05 10:00:57 +02:00
func ( db * Database ) UpdateAccountTimestamp ( keyUID string , loginTimestamp int64 ) error {
_ , err := db . db . Exec ( "UPDATE accounts SET loginTimestamp = ? WHERE keyUid = ?" , loginTimestamp , keyUID )
2019-08-20 18:38:40 +03:00
return err
}
2019-12-05 10:00:57 +02:00
func ( db * Database ) DeleteAccount ( keyUID string ) error {
_ , err := db . db . Exec ( "DELETE FROM accounts WHERE keyUid = ?" , keyUID )
2019-08-20 18:38:40 +03:00
return err
}
2020-11-24 13:13:46 +00:00
// Account images
2020-11-24 23:16:19 +00:00
func ( db * Database ) GetIdentityImages ( keyUID string ) ( [ ] * images . IdentityImage , error ) {
rows , err := db . db . Query ( ` SELECT key_uid, name, image_payload, width, height, file_size, resize_target FROM identity_images WHERE key_uid = ? ` , keyUID )
2020-11-24 13:13:46 +00:00
if err != nil {
return nil , err
}
defer rows . Close ( )
var iis [ ] * images . IdentityImage
for rows . Next ( ) {
ii := & images . IdentityImage { }
err = rows . Scan ( & ii . KeyUID , & ii . Name , & ii . Payload , & ii . Width , & ii . Height , & ii . FileSize , & ii . ResizeTarget )
if err != nil {
return nil , err
}
iis = append ( iis , ii )
}
return iis , nil
}
2020-11-24 23:16:19 +00:00
func ( db * Database ) GetIdentityImage ( keyUID , it string ) ( * images . IdentityImage , error ) {
rows , err := db . db . Query ( "SELECT key_uid, name, image_payload, width, height, file_size, resize_target FROM identity_images WHERE key_uid = ? AND name = ?" , keyUID , it )
2020-11-24 13:13:46 +00:00
if err != nil {
return nil , err
}
defer rows . Close ( )
var ii images . IdentityImage
for rows . Next ( ) {
2020-11-24 23:16:19 +00:00
err = rows . Scan ( & ii . KeyUID , & ii . Name , & ii . Payload , & ii . Width , & ii . Height , & ii . FileSize , & ii . ResizeTarget )
2020-11-24 13:13:46 +00:00
if err != nil {
return nil , err
}
}
return & ii , nil
}
2020-11-24 23:16:19 +00:00
func ( db * Database ) StoreIdentityImages ( keyUID string , iis [ ] * images . IdentityImage ) error {
2020-11-24 13:13:46 +00:00
// Because SQL INSERTs are triggered in a loop use a tx to ensure a single call to the DB.
tx , err := db . 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 _ , ii := range iis {
if ii == nil {
continue
}
_ , err := tx . Exec (
"INSERT INTO identity_images (key_uid, name, image_payload, width, height, file_size, resize_target) VALUES (?, ?, ?, ?, ?, ?, ?)" ,
2020-11-24 23:16:19 +00:00
keyUID ,
2020-11-24 13:13:46 +00:00
ii . Name ,
ii . Payload ,
ii . Width ,
ii . Height ,
ii . FileSize ,
ii . ResizeTarget ,
)
if err != nil {
return err
}
}
return nil
}
2020-11-24 23:16:19 +00:00
func ( db * Database ) DeleteIdentityImage ( keyUID string ) error {
_ , err := db . db . Exec ( ` DELETE FROM identity_images WHERE key_uid = ? ` , keyUID )
2020-11-24 13:13:46 +00:00
return err
}