2021-08-25 14:34:33 +01:00
|
|
|
package schema
|
|
|
|
|
|
|
|
import (
|
2022-04-24 11:26:22 +01:00
|
|
|
"fmt"
|
2021-08-25 14:34:33 +01:00
|
|
|
"reflect"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/uptrace/bun/dialect"
|
|
|
|
)
|
|
|
|
|
2021-10-24 12:14:37 +01:00
|
|
|
func Append(fmter Formatter, b []byte, v interface{}) []byte {
|
2021-08-25 14:34:33 +01:00
|
|
|
switch v := v.(type) {
|
|
|
|
case nil:
|
|
|
|
return dialect.AppendNull(b)
|
|
|
|
case bool:
|
|
|
|
return dialect.AppendBool(b, v)
|
|
|
|
case int:
|
|
|
|
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 uint:
|
2021-10-24 12:14:37 +01:00
|
|
|
return strconv.AppendInt(b, int64(v), 10)
|
2021-08-25 14:34:33 +01:00
|
|
|
case uint32:
|
2021-10-24 12:14:37 +01:00
|
|
|
return fmter.Dialect().AppendUint32(b, v)
|
2021-08-25 14:34:33 +01:00
|
|
|
case uint64:
|
2021-10-24 12:14:37 +01:00
|
|
|
return fmter.Dialect().AppendUint64(b, v)
|
2021-08-25 14:34:33 +01:00
|
|
|
case float32:
|
|
|
|
return dialect.AppendFloat32(b, v)
|
|
|
|
case float64:
|
|
|
|
return dialect.AppendFloat64(b, v)
|
|
|
|
case string:
|
2021-11-13 11:29:08 +00:00
|
|
|
return fmter.Dialect().AppendString(b, v)
|
2021-08-25 14:34:33 +01:00
|
|
|
case time.Time:
|
2021-10-24 12:14:37 +01:00
|
|
|
return fmter.Dialect().AppendTime(b, v)
|
2021-08-25 14:34:33 +01:00
|
|
|
case []byte:
|
2021-10-24 12:14:37 +01:00
|
|
|
return fmter.Dialect().AppendBytes(b, v)
|
2021-08-25 14:34:33 +01:00
|
|
|
case QueryAppender:
|
|
|
|
return AppendQueryAppender(fmter, b, v)
|
|
|
|
default:
|
|
|
|
vv := reflect.ValueOf(v)
|
|
|
|
if vv.Kind() == reflect.Ptr && vv.IsNil() {
|
|
|
|
return dialect.AppendNull(b)
|
|
|
|
}
|
2021-10-24 12:14:37 +01:00
|
|
|
appender := Appender(fmter.Dialect(), vv.Type())
|
2021-08-25 14:34:33 +01:00
|
|
|
return appender(fmter, b, vv)
|
|
|
|
}
|
|
|
|
}
|
2022-04-24 11:26:22 +01:00
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
func In(slice interface{}) QueryAppender {
|
|
|
|
v := reflect.ValueOf(slice)
|
|
|
|
if v.Kind() != reflect.Slice {
|
|
|
|
return &inValues{
|
|
|
|
err: fmt.Errorf("bun: In(non-slice %T)", slice),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &inValues{
|
|
|
|
slice: v,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type inValues struct {
|
|
|
|
slice reflect.Value
|
|
|
|
err error
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ QueryAppender = (*inValues)(nil)
|
|
|
|
|
|
|
|
func (in *inValues) AppendQuery(fmter Formatter, b []byte) (_ []byte, err error) {
|
|
|
|
if in.err != nil {
|
|
|
|
return nil, in.err
|
|
|
|
}
|
|
|
|
return appendIn(fmter, b, in.slice), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func appendIn(fmter Formatter, b []byte, slice reflect.Value) []byte {
|
|
|
|
sliceLen := slice.Len()
|
|
|
|
for i := 0; i < sliceLen; i++ {
|
|
|
|
if i > 0 {
|
|
|
|
b = append(b, ", "...)
|
|
|
|
}
|
|
|
|
|
|
|
|
elem := slice.Index(i)
|
|
|
|
if elem.Kind() == reflect.Interface {
|
|
|
|
elem = elem.Elem()
|
|
|
|
}
|
|
|
|
|
|
|
|
if elem.Kind() == reflect.Slice && elem.Type() != bytesType {
|
|
|
|
b = append(b, '(')
|
|
|
|
b = appendIn(fmter, b, elem)
|
|
|
|
b = append(b, ')')
|
|
|
|
} else {
|
|
|
|
b = fmter.AppendValue(b, elem)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return b
|
|
|
|
}
|