mirror of
https://github.com/uptrace/go-clickhouse.git
synced 2025-06-08 23:26:11 +02:00
122 lines
2.5 KiB
Go
122 lines
2.5 KiB
Go
package chschema
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"fmt"
|
|
"math"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/uptrace/go-clickhouse/ch/internal"
|
|
)
|
|
|
|
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)
|
|
}
|
|
return AppendString(b, internal.String(bytes))
|
|
}
|