1
0
mirror of https://github.com/uptrace/go-clickhouse.git synced 2025-06-08 23:26:11 +02:00
2022-09-03 09:38:20 +03:00

129 lines
2.6 KiB
Go

package chschema
import (
"database/sql/driver"
"encoding/hex"
"fmt"
"math"
"strconv"
"time"
)
func Append(fmter Formatter, b []byte, v any) []byte {
switch v := v.(type) {
case nil:
return AppendNull(b)
case bool:
return AppendBool(b, v)
case int8:
return strconv.AppendInt(b, int64(v), 10)
case int16:
return strconv.AppendInt(b, int64(v), 10)
case int32:
return strconv.AppendInt(b, int64(v), 10)
case int64:
return strconv.AppendInt(b, v, 10)
case int:
return strconv.AppendInt(b, int64(v), 10)
case uint8:
return strconv.AppendUint(b, uint64(v), 10)
case uint16:
return strconv.AppendUint(b, uint64(v), 10)
case uint32:
return strconv.AppendUint(b, uint64(v), 10)
case uint64:
return strconv.AppendUint(b, v, 10)
case uint:
return strconv.AppendUint(b, uint64(v), 10)
case float32:
return appendFloat(b, float64(v), 32)
case float64:
return appendFloat(b, v, 64)
case string:
return AppendString(b, v)
case time.Time:
return AppendTime(b, v)
case []byte:
return AppendBytes(b, v)
case QueryAppender:
return AppendQueryAppender(fmter, b, v)
case driver.Valuer:
return appendDriverValue(fmter, b, v)
default:
return AppendError(b, fmt.Errorf("ch: can't append %T", v))
}
}
func AppendError(b []byte, err error) []byte {
b = append(b, "?!("...)
b = append(b, err.Error()...)
b = append(b, ')')
return b
}
func AppendNull(b []byte) []byte {
return append(b, "NULL"...)
}
func AppendBool(dst []byte, v bool) []byte {
var c byte
if v {
c = 1
}
return append(dst, c)
}
func AppendFloat(dst []byte, v float64) []byte {
return appendFloat(dst, v, 64)
}
func appendFloat(dst []byte, v float64, bitSize int) []byte {
switch {
case math.IsNaN(v):
return append(dst, "nan"...)
case math.IsInf(v, 1):
return append(dst, "inf"...)
case math.IsInf(v, -1):
return append(dst, "-inf"...)
default:
return strconv.AppendFloat(dst, v, 'f', -1, bitSize)
}
}
func AppendString(b []byte, s string) []byte {
b = append(b, '\'')
for i := 0; i < len(s); i++ {
c := s[i]
if c == '\'' {
b = append(b, '\\', '\'')
} else {
b = append(b, c)
}
}
b = append(b, '\'')
return b
}
func AppendTime(b []byte, tm time.Time) []byte {
b = append(b, "toDateTime('"...)
b = tm.UTC().AppendFormat(b, "2006-01-02 15:04:05")
b = append(b, "', 'UTC')"...)
return b
}
func AppendBytes(b []byte, bytes []byte) []byte {
if bytes == nil {
return AppendNull(b)
}
tmp := make([]byte, hex.EncodedLen(len(bytes)))
hex.Encode(tmp, bytes)
b = append(b, "unhex('"...)
b = append(b, tmp...)
b = append(b, "')"...)
return b
}