Skip to content

Commit

Permalink
feat(util/gconv): add basic types conversion support for function Scan (
Browse files Browse the repository at this point in the history
  • Loading branch information
gqcn authored Dec 18, 2024
1 parent 233295b commit a5c8b96
Show file tree
Hide file tree
Showing 13 changed files with 977 additions and 472 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ jobs:
# ClickHouse backend server.
# docker run -d --name clickhouse \
# -p 9000:9000 -p 8123:8123 -p 9001:9001 \
# loads/clickhouse-server:22.1.3.7
# clickhouse/clickhouse-server:24.11.1.2557-alpine
clickhouse-server:
image: loads/clickhouse-server:22.1.3.7
image: clickhouse/clickhouse-server:24.11.1.2557-alpine
ports:
- 9000:9000
- 8123:8123
Expand Down
13 changes: 11 additions & 2 deletions contrib/drivers/clickhouse/clickhouse_z_unit_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,18 @@ func Test_DB_Delete(t *testing.T) {
defer dropTable(table)

gtest.C(t, func(t *gtest.T) {
_, err := db.Delete(ctx, table, "id>3")
t.AssertNE(err, nil)
//db.SetDebug(true)
count, err := db.Model(table).Ctx(ctx).Count()
t.AssertNil(err)
t.Assert(count, 10)

result, err := db.Delete(ctx, table, "id>3")
t.AssertNil(err)
t.AssertNil(result)

count, err = db.Model(table).Ctx(ctx).Count()
t.AssertNil(err)
t.Assert(count, 3)
})
}

Expand Down
9 changes: 3 additions & 6 deletions contrib/rpc/grpcx/grpcx_unit_z_grpc_server_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,10 @@ func Test_Grpcx_Grpc_Server_Config_Logger(t *testing.T) {
time.Sleep(time.Millisecond * 100)
defer s.Stop()

var (
logFilePath = fmt.Sprintf("/tmp/log/%s.log", gtime.Now().Format("Y-m-d"))
logFileContent = gfile.GetContents(logFilePath)
)
defer gfile.Remove(logFilePath)
var logFilePath = fmt.Sprintf("/tmp/log/%s.log", gtime.Now().Format("Y-m-d"))
defer gfile.RemoveFile(logFilePath)
t.Assert(gfile.Exists(logFilePath), true)
t.Assert(gstr.Contains(logFileContent, "TestLogger "), true)
t.Assert(s.Logger().GetConfig().Prefix, "TestLogger")
})

}
275 changes: 0 additions & 275 deletions util/gconv/gconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,6 @@
package gconv

import (
"context"
"fmt"
"math"
"reflect"
"strconv"
"strings"
"time"

"github.com/gogf/gf/v2/encoding/gbinary"
"github.com/gogf/gf/v2/internal/intlog"
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/internal/reflection"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
"github.com/gogf/gf/v2/util/gconv/internal/structcache"
)
Expand Down Expand Up @@ -56,265 +43,3 @@ func init() {
Bool: Bool,
})
}

// Byte converts `any` to byte.
func Byte(any interface{}) byte {
if v, ok := any.(byte); ok {
return v
}
return Uint8(any)
}

// Bytes converts `any` to []byte.
func Bytes(any interface{}) []byte {
if any == nil {
return nil
}
switch value := any.(type) {
case string:
return []byte(value)

case []byte:
return value

default:
if f, ok := value.(localinterface.IBytes); ok {
return f.Bytes()
}
originValueAndKind := reflection.OriginValueAndKind(any)
switch originValueAndKind.OriginKind {
case reflect.Map:
bytes, err := json.Marshal(any)
if err != nil {
intlog.Errorf(context.TODO(), `%+v`, err)
}
return bytes

case reflect.Array, reflect.Slice:
var (
ok = true
bytes = make([]byte, originValueAndKind.OriginValue.Len())
)
for i := range bytes {
int32Value := Int32(originValueAndKind.OriginValue.Index(i).Interface())
if int32Value < 0 || int32Value > math.MaxUint8 {
ok = false
break
}
bytes[i] = byte(int32Value)
}
if ok {
return bytes
}
}
return gbinary.Encode(any)
}
}

// Rune converts `any` to rune.
func Rune(any interface{}) rune {
if v, ok := any.(rune); ok {
return v
}
return Int32(any)
}

// Runes converts `any` to []rune.
func Runes(any interface{}) []rune {
if v, ok := any.([]rune); ok {
return v
}
return []rune(String(any))
}

// String converts `any` to string.
// It's most commonly used converting function.
func String(any interface{}) string {
if any == nil {
return ""
}
switch value := any.(type) {
case int:
return strconv.Itoa(value)
case int8:
return strconv.Itoa(int(value))
case int16:
return strconv.Itoa(int(value))
case int32:
return strconv.Itoa(int(value))
case int64:
return strconv.FormatInt(value, 10)
case uint:
return strconv.FormatUint(uint64(value), 10)
case uint8:
return strconv.FormatUint(uint64(value), 10)
case uint16:
return strconv.FormatUint(uint64(value), 10)
case uint32:
return strconv.FormatUint(uint64(value), 10)
case uint64:
return strconv.FormatUint(value, 10)
case float32:
return strconv.FormatFloat(float64(value), 'f', -1, 32)
case float64:
return strconv.FormatFloat(value, 'f', -1, 64)
case bool:
return strconv.FormatBool(value)
case string:
return value
case []byte:
return string(value)
case time.Time:
if value.IsZero() {
return ""
}
return value.String()
case *time.Time:
if value == nil {
return ""
}
return value.String()
case gtime.Time:
if value.IsZero() {
return ""
}
return value.String()
case *gtime.Time:
if value == nil {
return ""
}
return value.String()
default:
if f, ok := value.(localinterface.IString); ok {
// If the variable implements the String() interface,
// then use that interface to perform the conversion
return f.String()
}
if f, ok := value.(localinterface.IError); ok {
// If the variable implements the Error() interface,
// then use that interface to perform the conversion
return f.Error()
}
// Reflect checks.
var (
rv = reflect.ValueOf(value)
kind = rv.Kind()
)
switch kind {
case
reflect.Chan,
reflect.Map,
reflect.Slice,
reflect.Func,
reflect.Interface,
reflect.UnsafePointer:
if rv.IsNil() {
return ""
}
case reflect.String:
return rv.String()
case reflect.Ptr:
if rv.IsNil() {
return ""
}
return String(rv.Elem().Interface())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.FormatInt(rv.Int(), 10)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return strconv.FormatUint(rv.Uint(), 10)
case reflect.Uintptr:
return strconv.FormatUint(rv.Uint(), 10)
case reflect.Float32, reflect.Float64:
return strconv.FormatFloat(rv.Float(), 'f', -1, 64)
case reflect.Bool:
return strconv.FormatBool(rv.Bool())
}
// Finally, we use json.Marshal to convert.
if jsonContent, err := json.Marshal(value); err != nil {
return fmt.Sprint(value)
} else {
return string(jsonContent)
}
}
}

// Bool converts `any` to bool.
// It returns false if `any` is: false, "", 0, "false", "off", "no", empty slice/map.
func Bool(any interface{}) bool {
if any == nil {
return false
}
switch value := any.(type) {
case bool:
return value
case []byte:
if _, ok := emptyStringMap[strings.ToLower(string(value))]; ok {
return false
}
return true
case string:
if _, ok := emptyStringMap[strings.ToLower(value)]; ok {
return false
}
return true
default:
if f, ok := value.(localinterface.IBool); ok {
return f.Bool()
}
rv := reflect.ValueOf(any)
switch rv.Kind() {
case reflect.Ptr:
if rv.IsNil() {
return false
}
if rv.Type().Elem().Kind() == reflect.Bool {
return rv.Elem().Bool()
}
return Bool(rv.Elem().Interface())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return rv.Int() != 0
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return rv.Uint() != 0
case reflect.Float32, reflect.Float64:
return rv.Float() != 0
case reflect.Bool:
return rv.Bool()
// TODO:(Map,Array,Slice,Struct) It might panic here for these types.
case reflect.Map, reflect.Array:
fallthrough
case reflect.Slice:
return rv.Len() != 0
case reflect.Struct:
return true
default:
s := strings.ToLower(String(any))
if _, ok := emptyStringMap[s]; ok {
return false
}
return true
}
}
}

// checkJsonAndUnmarshalUseNumber checks if given `any` is JSON formatted string value and does converting using `json.UnmarshalUseNumber`.
func checkJsonAndUnmarshalUseNumber(any interface{}, target interface{}) bool {
switch r := any.(type) {
case []byte:
if json.Valid(r) {
if err := json.UnmarshalUseNumber(r, &target); err != nil {
return false
}
return true
}

case string:
anyAsBytes := []byte(r)
if json.Valid(anyAsBytes) {
if err := json.UnmarshalUseNumber(anyAsBytes, &target); err != nil {
return false
}
return true
}
}
return false
}
Loading

0 comments on commit a5c8b96

Please sign in to comment.