123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- package sqlite
- import (
- "fmt"
- "strings"
- "github.com/spf13/cast"
- "github.com/wecisecode/util/msgpack"
- )
- func BlobMarshal(v interface{}) (s string) {
- bs, e := msgpack.Encode(v)
- if e != nil {
- t, e := cast.ToStringE(v)
- if e != nil {
- s = fmt.Sprintf("%#v", v)
- }
- s = t
- } else {
- s = string(bs)
- }
- return
- }
- func SliceTypeRecognize(tx []interface{}) (v interface{}, t string) {
- t = ""
- for _, a := range tx {
- switch a.(type) {
- case string:
- if t == "" {
- t = "string"
- }
- if t != "string" {
- t = ""
- break
- }
- case int:
- if t == "" {
- t = "int"
- }
- if t != "int" {
- t = ""
- break
- }
- }
- }
- switch t {
- case "string":
- tss := make([]string, len(tx))
- for i, a := range tx {
- tss[i] = cast.ToString(a)
- }
- v = tss
- case "int":
- tis := make([]int, len(tx))
- for i, a := range tx {
- tis[i] = cast.ToInt(a)
- }
- v = tis
- default:
- v = tx
- }
- return
- }
- func MapTypeRecognize(tx map[string]interface{}) (v interface{}, t string) {
- t = ""
- tvs := map[string]interface{}{}
- for k, a := range tx {
- switch ta := a.(type) {
- case []interface{}:
- av, at := SliceTypeRecognize(ta)
- if t == "" {
- t = "[]" + at
- }
- if t != "[]"+at {
- t = ""
- break
- }
- tvs[k] = av
- case []string:
- if t == "" {
- t = "[]string"
- }
- if t != "[]string" {
- t = ""
- break
- }
- tvs[k] = ta
- case []int:
- if t == "" {
- t = "[]int"
- }
- if t != "[]int" {
- t = ""
- break
- }
- tvs[k] = ta
- case string:
- if t == "" {
- t = "string"
- }
- if t != "string" {
- t = ""
- break
- }
- tvs[k] = ta
- case int:
- if t == "" {
- t = "int"
- }
- if t != "int" {
- t = ""
- break
- }
- tvs[k] = ta
- }
- }
- switch t {
- case "[]string":
- tss := make(map[string][]string, len(tx))
- for i, a := range tvs {
- tss[i] = cast.ToStringSlice(a)
- }
- v = tss
- case "[]int":
- tis := make(map[string][]int, len(tx))
- for i, a := range tvs {
- tis[i] = cast.ToIntSlice(a)
- }
- v = tis
- case "string":
- tss := make(map[string]string, len(tx))
- for i, a := range tvs {
- tss[i] = cast.ToString(a)
- }
- v = tss
- case "int":
- tis := make(map[string]int, len(tx))
- for i, a := range tvs {
- tis[i] = cast.ToInt(a)
- }
- v = tis
- default:
- v = tx
- }
- return
- }
- func MapsTypeRecognize(tx []map[string]interface{}) (v interface{}, t string) {
- t = ""
- tvs := []interface{}{}
- for _, x := range tx {
- av, at := MapTypeRecognize(x)
- if t == "" {
- t = at
- }
- if t != at {
- t = ""
- break
- }
- tvs = append(tvs, av)
- }
- switch t {
- case "[]string":
- tss := make([]map[string][]string, len(tx))
- for i, a := range tvs {
- tss[i] = a.(map[string][]string)
- }
- v = tss
- case "[]int":
- tis := make([]map[string][]int, len(tx))
- for i, a := range tvs {
- tis[i] = a.(map[string][]int)
- }
- v = tis
- case "string":
- tss := make([]map[string]string, len(tx))
- for i, a := range tvs {
- tss[i] = a.(map[string]string)
- }
- v = tss
- case "int":
- tis := make([]map[string]int, len(tx))
- for i, a := range tvs {
- tis[i] = a.(map[string]int)
- }
- v = tis
- default:
- v = tx
- }
- return
- }
- func BlobRecognize(x interface{}) (v interface{}, t string) {
- v = x
- switch tx := x.(type) {
- case []map[string]interface{}:
- v, t = MapsTypeRecognize(tx)
- case map[string]interface{}:
- v, t = MapTypeRecognize(tx)
- case []interface{}:
- v, t = SliceTypeRecognize(tx)
- case *interface{}:
- v, t = BlobRecognize(*tx)
- default:
- v = tx
- }
- return
- }
- func BlobUnmarshal(s string, x interface{}) (v interface{}) {
- e := msgpack.Decode([]byte(s), x)
- if e != nil {
- return s
- }
- v = x
- return
- }
- // 从 sqlite 读出的数据 到 go 语言中
- func SQLValueDecode(ftype_sampledata, value interface{}) (v interface{}) {
- v = value
- switch ftype := ftype_sampledata.(type) {
- case string:
- switch ftype {
- case "BOOL", "BOOLEAN":
- v = cast.ToBool(v)
- case "BLOB":
- s := cast.ToString(v)
- var x interface{}
- v = BlobUnmarshal(s, &x)
- v, _ = BlobRecognize(v)
- case "INT", "INTEGER":
- switch tv := v.(type) {
- case int8:
- v = int(tv)
- case int16:
- v = int(tv)
- case int32:
- v = int(tv)
- case int64:
- v = int(tv)
- case uint:
- v = int(tv)
- case uint8:
- v = int(tv)
- case uint16:
- v = int(tv)
- case uint32:
- v = int(tv)
- case uint64:
- v = int(tv)
- }
- case "DATE":
- // 兼容cassandra输出
- v = cast.ToTime(v)
- case "TIME", "DATETIME", "TIMESTAMP":
- v = NSTimeStampValue(v)
- }
- return
- }
- s := cast.ToString(v)
- v = BlobUnmarshal(s, ftype_sampledata)
- return
- }
- // 从 go 语言数据 到 sqlite 数据库中
- func SQLValueEncode(ftype string, v interface{}) interface{} {
- if v == nil {
- return nil
- }
- switch strings.ToLower(ftype) {
- case "int", "integer":
- return cast.ToInt(v)
- case "long", "bigint", "int64":
- return cast.ToInt64(v)
- case "int32":
- return cast.ToInt32(v)
- case "enum", "smallint", "int16":
- return cast.ToInt16(v)
- case "double", "float64":
- return cast.ToFloat64(v)
- case "float", "float32":
- return cast.ToFloat32(v)
- case "bool", "boolean":
- return cast.ToBool(v)
- case "string", "text", "varchar", "clob":
- return cast.ToString(v)
- case "date":
- return MSTimeStampValue(v).Format("2006-01-02")
- case "time", "datetime", "timestamp":
- return MSTimeStampValue(v).UnixNano()
- case "relation":
- sv := BlobMarshal(v)
- if sv == "{}" {
- // 兼容cassandra输入
- sv = "null"
- }
- return sv
- case "blob", "map", "list", "set", "bucket":
- fallthrough
- default:
- return BlobMarshal(v)
- }
- }
|