| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package sqlchemy
- import (
- "database/sql"
- "fmt"
- "reflect"
- "strconv"
- "strings"
- "time"
- "yunion.io/x/jsonutils"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/gotypes"
- "yunion.io/x/pkg/tristate"
- "yunion.io/x/pkg/util/timeutils"
- )
- func getQuoteStringValue(dat interface{}) string {
- value := reflect.ValueOf(dat)
- switch value.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return fmt.Sprintf("%d", value.Int())
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return fmt.Sprintf("%d", value.Uint())
- case reflect.Float32, reflect.Float64:
- return fmt.Sprintf("%f", value.Float())
- }
- strVal := GetStringValue(dat)
- strVal = strings.ReplaceAll(strVal, "'", "\\'")
- return "'" + strVal + "'"
- }
- func GetStringValue(dat interface{}) string {
- switch g := dat.(type) {
- case tristate.TriState:
- return g.String()
- case time.Time:
- return timeutils.MysqlTime(g)
- case []byte:
- return string(g)
- }
- value := reflect.Indirect(reflect.ValueOf(dat))
- switch value.Kind() {
- case reflect.Bool:
- if value.Bool() {
- return "true"
- }
- return "false"
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return fmt.Sprintf("%d", value.Int())
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return fmt.Sprintf("%d", value.Uint())
- case reflect.Float32, reflect.Float64:
- return fmt.Sprintf("%v", value.Float())
- case reflect.String:
- return value.String()
- }
- serializable, ok := value.Interface().(gotypes.ISerializable)
- if ok {
- return serializable.String()
- } else {
- return jsonutils.Marshal(value.Interface()).String()
- }
- }
- func setValueBySQLString(value reflect.Value, val string) error {
- if !value.CanSet() {
- return errors.Wrap(ErrReadOnly, "value is not settable")
- }
- switch value.Type() {
- case tristate.TriStateType:
- if val == "1" {
- value.Set(tristate.TriStateTrueValue)
- } else if val == "0" {
- value.Set(tristate.TriStateFalseValue)
- } else {
- value.Set(tristate.TriStateNoneValue)
- }
- return nil
- case gotypes.TimeType:
- if val != "0000-00-00 00:00:00" {
- tm, err := timeutils.ParseTimeStr(val)
- if err != nil {
- return errors.Wrap(err, "ParseTimeStr")
- }
- value.Set(reflect.ValueOf(tm))
- }
- return nil
- }
- switch value.Kind() {
- case reflect.Bool:
- if val == "0" {
- value.SetBool(false)
- } else {
- value.SetBool(true)
- }
- return nil
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- valInt, err := strconv.ParseInt(val, 10, 64)
- if err != nil {
- return errors.Wrap(err, "ParseInt")
- }
- value.SetInt(valInt)
- return nil
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- valUint, err := strconv.ParseUint(val, 10, 64)
- if err != nil {
- return errors.Wrap(err, "ParseUint")
- }
- value.SetUint(valUint)
- return nil
- case reflect.Float32, reflect.Float64:
- valFloat, err := strconv.ParseFloat(val, 64)
- if err != nil {
- return errors.Wrap(err, "ParseFloat")
- }
- value.SetFloat(valFloat)
- return nil
- case reflect.String:
- value.SetString(val)
- return nil
- case reflect.Slice:
- jsonV, err := jsonutils.ParseString(val)
- if err != nil {
- return errors.Wrapf(err, "jsonutils.ParseString %s", val)
- }
- if jsonV == jsonutils.JSONNull {
- return nil
- }
- jsonA, err := jsonV.GetArray()
- if err != nil {
- return errors.Wrap(err, "jsonV.GetArray")
- }
- sliceValue := reflect.MakeSlice(value.Type(), 0, len(jsonA))
- value.Set(sliceValue)
- for i := range jsonA {
- elemValue := reflect.New(value.Type().Elem()).Elem()
- jsonStr, _ := jsonA[i].GetString()
- err := setValueBySQLString(elemValue, jsonStr)
- if err != nil {
- return errors.Wrapf(err, "TestSetValueBySQLString %s", jsonA[i].String())
- }
- value.Set(reflect.Append(value, elemValue))
- }
- return nil
- case reflect.Map:
- jsonV, err := jsonutils.ParseString(val)
- if err != nil {
- return errors.Wrapf(err, "jsonutils.ParseString %s", val)
- }
- if jsonV == jsonutils.JSONNull {
- return nil
- }
- mapValue := reflect.MakeMap(value.Type())
- value.Set(mapValue)
- err = jsonV.Unmarshal(mapValue.Interface())
- if err != nil {
- return errors.Wrapf(err, "jsonV.Unmarshal")
- }
- return nil
- default:
- if valueType := value.Type(); valueType.Implements(gotypes.ISerializableType) {
- serializable, err := jsonutils.JSONDeserialize(valueType, val)
- if err != nil {
- return err
- }
- value.Set(reflect.ValueOf(serializable))
- return nil
- } else if value.Kind() == reflect.Ptr {
- if value.IsNil() {
- value.Set(reflect.New(value.Type().Elem()))
- }
- return setValueBySQLString(value.Elem(), val)
- } else {
- jsonV, err := jsonutils.ParseString(val)
- if err != nil {
- return errors.Wrapf(err, "%s not a json string: %s", val, err)
- }
- if jsonV == jsonutils.JSONNull {
- return nil
- }
- newVal := reflect.New(value.Type())
- err = jsonV.Unmarshal(newVal.Interface())
- if err != nil {
- return errors.Wrap(err, "Unmarshal fail")
- }
- value.Set(reflect.Indirect(newVal))
- return nil
- }
- }
- }
- func ConvertValueToTime(val interface{}) time.Time {
- switch v := val.(type) {
- case string:
- tm, _ := timeutils.ParseTimeStr(v)
- return tm
- case time.Time:
- return v
- case int:
- return time.Unix(int64(v), 0)
- case int32:
- return time.Unix(int64(v), 0)
- case int64:
- return time.Unix(int64(v), 0)
- case uint:
- return time.Unix(int64(v), 0)
- case uint32:
- return time.Unix(int64(v), 0)
- case uint64:
- return time.Unix(int64(v), 0)
- case float32:
- return time.Unix(int64(v), int64((v-float32(int64(v)))*1000000000))
- case float64:
- return time.Unix(int64(v), int64((v-float64(int64(v)))*1000000000))
- case *string:
- tm, _ := timeutils.ParseTimeStr(*v)
- return tm
- case *time.Time:
- return *v
- case *int:
- return time.Unix(int64(*v), 0)
- case *int32:
- return time.Unix(int64(*v), 0)
- case *int64:
- return time.Unix(int64(*v), 0)
- case *uint:
- return time.Unix(int64(*v), 0)
- case *uint32:
- return time.Unix(int64(*v), 0)
- case *uint64:
- return time.Unix(int64(*v), 0)
- case *float32:
- return time.Unix(int64(*v), int64((*v-float32(int64(*v)))*1000000000))
- case *float64:
- return time.Unix(int64(*v), int64((*v-float64(int64(*v)))*1000000000))
- }
- return time.Time{}
- }
- func ConvertValueToInteger(val interface{}) int64 {
- switch v := val.(type) {
- case string:
- intv, _ := strconv.ParseInt(v, 10, 64)
- return intv
- case int:
- return int64(v)
- case int32:
- return int64(v)
- case int64:
- return v
- case uint:
- return int64(v)
- case uint32:
- return int64(v)
- case uint64:
- return int64(v)
- case float32:
- return int64(v)
- case float64:
- return int64(v)
- case time.Time:
- return v.Unix()
- case *string:
- intv, _ := strconv.ParseInt(*v, 10, 64)
- return intv
- case *int:
- return int64(*v)
- case *int32:
- return int64(*v)
- case *int64:
- return *v
- case *uint:
- return int64(*v)
- case *uint32:
- return int64(*v)
- case *uint64:
- return int64(*v)
- case *float32:
- return int64(*v)
- case *float64:
- return int64(*v)
- case *time.Time:
- return v.Unix()
- }
- return 0
- }
- func ConvertValueToFloat(val interface{}) float64 {
- switch v := val.(type) {
- case string:
- intv, _ := strconv.ParseFloat(v, 64)
- return intv
- case int:
- return float64(v)
- case int32:
- return float64(v)
- case int64:
- return float64(v)
- case uint:
- return float64(v)
- case uint32:
- return float64(v)
- case uint64:
- return float64(v)
- case float32:
- return float64(v)
- case float64:
- return v
- case time.Time:
- return float64(v.Unix())
- case *string:
- intv, _ := strconv.ParseFloat(*v, 64)
- return intv
- case *int:
- return float64(*v)
- case *int32:
- return float64(*v)
- case *int64:
- return float64(*v)
- case *uint:
- return float64(*v)
- case *uint32:
- return float64(*v)
- case *uint64:
- return float64(*v)
- case *float32:
- return float64(*v)
- case *float64:
- return *v
- case *time.Time:
- return float64(v.Unix())
- }
- return 0
- }
- func ConvertValueToBool(val interface{}) bool {
- switch v := val.(type) {
- case string:
- v = strings.ToLower(v)
- return v == "1" || v == "true" || v == "ok" || v == "yes" || v == "on"
- case bool:
- return v
- case tristate.TriState:
- return v == tristate.True
- case int8:
- return v > 0
- case int16:
- return v > 0
- case int:
- return v > 0
- case int32:
- return v > 0
- case int64:
- return v > 0
- case uint8:
- return v > 0
- case uint16:
- return v > 0
- case uint:
- return v > 0
- case uint32:
- return v > 0
- case uint64:
- return v > 0
- case float32:
- return v > 0
- case float64:
- return v > 0
- case *string:
- if gotypes.IsNil(v) {
- return false
- }
- nv := strings.ToLower(*v)
- return nv == "1" || nv == "true" || nv == "ok" || nv == "yes" || nv == "on"
- case *bool:
- if gotypes.IsNil(v) {
- return false
- }
- return *v
- case *tristate.TriState:
- if gotypes.IsNil(v) {
- return false
- }
- return *v == tristate.True
- case *int8:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *int16:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *int:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *int32:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *int64:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *uint8:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *uint16:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *uint:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *uint32:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *uint64:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *float32:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- case *float64:
- if gotypes.IsNil(v) {
- return false
- }
- return *v > 0
- }
- return false
- }
- func ConvertValueToTriState(val interface{}) tristate.TriState {
- switch v := val.(type) {
- case tristate.TriState:
- return v
- case string:
- switch strings.ToLower(v) {
- case "true", "yes", "on", "ok", "1":
- return tristate.True
- case "none", "null", "unknown":
- return tristate.None
- default:
- return tristate.False
- }
- case bool:
- if v {
- return tristate.True
- } else {
- return tristate.False
- }
- case sql.NullInt32:
- if v.Valid {
- return ConvertValueToTriState(v.Int32)
- }
- return tristate.None
- case int8:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case int16:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case int:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case int32:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case int64:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case uint8:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case uint16:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case uint:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case uint32:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case uint64:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case float32:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case float64:
- switch {
- case v > 0:
- return tristate.True
- default:
- return tristate.False
- }
- case *string:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- switch strings.ToLower(*v) {
- case "true", "yes", "on", "ok", "1":
- return tristate.True
- case "none", "null", "unknown":
- return tristate.None
- default:
- return tristate.False
- }
- case *bool:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v {
- return tristate.True
- } else {
- return tristate.False
- }
- case *tristate.TriState:
- return *v
- case *int8:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *int16:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *int:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *int32:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *int64:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *uint8:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *uint16:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *uint:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *uint32:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *uint64:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *float32:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- case *float64:
- if gotypes.IsNil(v) {
- return tristate.None
- }
- if *v > 0 {
- return tristate.True
- } else {
- return tristate.False
- }
- }
- return tristate.None
- }
- func ConvertValueToString(val interface{}) string {
- if gotypes.IsNil(val) {
- return ""
- }
- switch v := val.(type) {
- case string:
- return v
- case int8, int16, int, int32, int64, uint8, uint16, uint, uint32, uint64:
- return fmt.Sprintf("%d", v)
- case float32, float64:
- return fmt.Sprintf("%f", v)
- case bool:
- return fmt.Sprintf("%v", v)
- case time.Time:
- return timeutils.IsoTime(v)
- case *string:
- return *v
- case *int8:
- return fmt.Sprintf("%d", *v)
- case *int16:
- return fmt.Sprintf("%d", *v)
- case *int:
- return fmt.Sprintf("%d", *v)
- case *int32:
- return fmt.Sprintf("%d", *v)
- case *int64:
- return fmt.Sprintf("%d", *v)
- case *uint8:
- return fmt.Sprintf("%d", *v)
- case *uint16:
- return fmt.Sprintf("%d", *v)
- case *uint:
- return fmt.Sprintf("%d", *v)
- case *uint32:
- return fmt.Sprintf("%d", *v)
- case *uint64:
- return fmt.Sprintf("%d", *v)
- case *float32:
- return fmt.Sprintf("%f", *v)
- case *float64:
- return fmt.Sprintf("%f", *v)
- case *time.Time:
- return timeutils.IsoTime(*v)
- case tristate.TriState:
- return v.String()
- case *tristate.TriState:
- return (*v).String()
- }
- if reflect.ValueOf(val).Kind() == reflect.String {
- return val.(string)
- }
- return jsonutils.Marshal(val).String()
- }
- func getFloatValue(val interface{}) (float64, error) {
- switch v := val.(type) {
- case float32:
- return float64(v), nil
- case float64:
- return v, nil
- case int:
- return float64(v), nil
- case int8:
- return float64(v), nil
- case int16:
- return float64(v), nil
- case int32:
- return float64(v), nil
- case int64:
- return float64(v), nil
- case uint:
- return float64(v), nil
- case uint8:
- return float64(v), nil
- case uint16:
- return float64(v), nil
- case uint32:
- return float64(v), nil
- case uint64:
- return float64(v), nil
- case *float32:
- return float64(*v), nil
- case *float64:
- return *v, nil
- case *int:
- return float64(*v), nil
- case *int8:
- return float64(*v), nil
- case *int16:
- return float64(*v), nil
- case *int32:
- return float64(*v), nil
- case *int64:
- return float64(*v), nil
- case *uint:
- return float64(*v), nil
- case *uint8:
- return float64(*v), nil
- case *uint16:
- return float64(*v), nil
- case *uint32:
- return float64(*v), nil
- case *uint64:
- return float64(*v), nil
- case string:
- return strconv.ParseFloat(v, 64)
- case *string:
- return strconv.ParseFloat(*v, 64)
- }
- return 0, errors.ErrInvalidFormat
- }
- func getTimeValue(val interface{}) (time.Time, error) {
- switch v := val.(type) {
- case time.Time:
- return v, nil
- case *time.Time:
- return *v, nil
- case string:
- return timeutils.ParseTimeStr(v)
- case *string:
- return timeutils.ParseTimeStr(*v)
- }
- return time.Time{}, errors.ErrInvalidFormat
- }
- const MIN_FLOAT_EQUAL_DIFF = float64(0.000001)
- func floatEqual(of, nf float64) bool {
- if of > nf {
- return of < MIN_FLOAT_EQUAL_DIFF+nf
- } else if of < nf {
- return of+MIN_FLOAT_EQUAL_DIFF > nf
- } else {
- return true
- }
- }
- const MIN_MICRO_SECOND_EQUAL_DIFF = 1000000
- func timeEqual(of, nf time.Time) bool {
- ofUnix := of.UnixMicro()
- nfUnix := nf.UnixMicro()
- if ofUnix == nfUnix {
- return true
- }
- if ofUnix > nfUnix {
- return ofUnix < MIN_MICRO_SECOND_EQUAL_DIFF+nfUnix
- } else {
- return ofUnix+MIN_MICRO_SECOND_EQUAL_DIFF > nfUnix
- }
- }
- func EqualsGrossValue(of, nf interface{}) bool {
- ofFloat, ofErr := getFloatValue(of)
- nfFloat, nfErr := getFloatValue(nf)
- if ofErr == nil && nfErr == nil {
- return floatEqual(ofFloat, nfFloat)
- }
- ofTime, ofErr := getTimeValue(of)
- nfTime, nfErr := getTimeValue(nf)
- if ofErr == nil && nfErr == nil {
- return timeEqual(ofTime, nfTime)
- }
- return false
- }
|