github.com/status-im/status-go@v1.1.0/sqlite/fields.go (about)

     1  package sqlite
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"math"
     9  	"math/big"
    10  	"reflect"
    11  )
    12  
    13  // JSONBlob type for marshaling/unmarshaling inner type to json.
    14  type JSONBlob struct {
    15  	Data  interface{}
    16  	Valid bool
    17  }
    18  
    19  // Scan implements interface.
    20  func (blob *JSONBlob) Scan(value interface{}) error {
    21  	dataVal := reflect.ValueOf(blob.Data)
    22  	blob.Valid = false
    23  	if value == nil || dataVal.Kind() == reflect.Ptr && dataVal.IsNil() {
    24  		return nil
    25  	}
    26  
    27  	var bytes []byte
    28  	ok := true
    29  	switch v := value.(type) {
    30  	case []byte:
    31  		bytes, ok = value.([]byte)
    32  	case string:
    33  		bytes = []byte(v)
    34  	default:
    35  		ok = false
    36  	}
    37  	if !ok {
    38  		return errors.New("not a byte slice or string")
    39  	}
    40  	if len(bytes) == 0 {
    41  		return nil
    42  	}
    43  	err := json.Unmarshal(bytes, blob.Data)
    44  	blob.Valid = err == nil
    45  	return err
    46  }
    47  
    48  // Value implements interface.
    49  func (blob *JSONBlob) Value() (driver.Value, error) {
    50  	dataVal := reflect.ValueOf(blob.Data)
    51  	if (blob.Data == nil) || (dataVal.Kind() == reflect.Ptr && dataVal.IsNil()) {
    52  		return nil, nil
    53  	}
    54  
    55  	switch dataVal.Kind() {
    56  	case reflect.Slice, reflect.Array, reflect.Map:
    57  		if dataVal.Len() == 0 {
    58  			return nil, nil
    59  		}
    60  	}
    61  
    62  	return json.Marshal(blob.Data)
    63  }
    64  
    65  func BigIntToClampedInt64(val *big.Int) *int64 {
    66  	if val == nil {
    67  		return nil
    68  	}
    69  	var v int64
    70  	if val.IsInt64() {
    71  		v = val.Int64()
    72  	} else {
    73  		v = math.MaxInt64
    74  	}
    75  	return &v
    76  }
    77  
    78  // BigIntToPadded128BitsStr converts a big.Int to a string, padding it with 0 to account for 128 bits size
    79  // Returns nil if input val is nil
    80  // This should work to sort and compare big.Ints values in SQLite
    81  func BigIntToPadded128BitsStr(val *big.Int) *string {
    82  	if val == nil {
    83  		return nil
    84  	}
    85  	hexStr := val.Text(16)
    86  	res := new(string)
    87  	*res = fmt.Sprintf("%032s", hexStr)
    88  	return res
    89  }
    90  
    91  func Int64ToPadded128BitsStr(val int64) *string {
    92  	res := fmt.Sprintf("%032x", val)
    93  	return &res
    94  }