status-go/sqlite/fields.go
Samuel Hawksby-Robinson e67592d556
Sync Settings (#2478)
* Sync Settings

* Added valueHandlers and Database singleton

Some issues remain, need a way to comparing incoming sql.DB to check if the connection is to a different file or not. Maybe make singleton instance per filename

* Added functionality to check the sqlite filename

* Refactor of Database.SaveSyncSettings to be used as a handler

* Implemented inteface for setting sync protobuf factories

* Refactored and completed adhoc send setting sync

* Tidying up

* Immutability refactor

* Refactor settings into dedicated package

* Breakout structs

* Tidy up

* Refactor of bulk settings sync

* Bug fixes

* Addressing feedback

* Fix code dropped during rebase

* Fix for db closed

* Fix for node config related crashes

* Provisional fix for type assertion - issue 2

* Adding robust type assertion checks

* Partial fix for null literal db storage and json encoding

* Fix for passively handling nil sql.DB, and checking if elem has len and if len is 0

* Added test for preferred name behaviour

* Adding saved sync settings to MessengerResponse

* Completed granular initial sync and clock from network on save

* add Settings to isEmpty

* Refactor of protobufs, partially done

* Added syncSetting receiver handling, some bug fixes

* Fix for sticker packs

* Implement inactive flag on sync protobuf factory

* Refactor of types and structs

* Added SettingField.CanSync functionality

* Addressing rebase artifact

* Refactor of Setting SELECT queries

* Refactor of string return queries

* VERSION bump and migration index bump

* Deactiveate Sync Settings

* Deactiveated preferred_name and send_status_updates

Co-authored-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
2022-03-23 18:47:00 +00:00

47 lines
970 B
Go

package sqlite
import (
"database/sql/driver"
"encoding/json"
"errors"
"reflect"
)
// JSONBlob type for marshaling/unmarshaling inner type to json.
type JSONBlob struct {
Data interface{}
}
// Scan implements interface.
func (blob *JSONBlob) Scan(value interface{}) error {
dataVal := reflect.ValueOf(blob.Data)
if value == nil || dataVal.Kind() == reflect.Ptr && dataVal.IsNil() {
return nil
}
bytes, ok := value.([]byte)
if !ok {
return errors.New("not a byte slice")
}
if len(bytes) == 0 {
return nil
}
err := json.Unmarshal(bytes, blob.Data)
return err
}
// Value implements interface.
func (blob *JSONBlob) Value() (driver.Value, error) {
dataVal := reflect.ValueOf(blob.Data)
if (blob.Data == nil) || (dataVal.Kind() == reflect.Ptr && dataVal.IsNil()) {
return nil, nil
}
switch dataVal.Kind() {
case reflect.Slice, reflect.Array, reflect.Map:
if dataVal.Len() == 0 {
return nil, nil
}
}
return json.Marshal(blob.Data)
}