append.go (2256B)
1 package schema 2 3 import ( 4 "fmt" 5 "reflect" 6 "strconv" 7 "time" 8 9 "github.com/uptrace/bun/dialect" 10 ) 11 12 func Append(fmter Formatter, b []byte, v interface{}) []byte { 13 switch v := v.(type) { 14 case nil: 15 return dialect.AppendNull(b) 16 case bool: 17 return dialect.AppendBool(b, v) 18 case int: 19 return strconv.AppendInt(b, int64(v), 10) 20 case int32: 21 return strconv.AppendInt(b, int64(v), 10) 22 case int64: 23 return strconv.AppendInt(b, v, 10) 24 case uint: 25 return strconv.AppendInt(b, int64(v), 10) 26 case uint32: 27 return fmter.Dialect().AppendUint32(b, v) 28 case uint64: 29 return fmter.Dialect().AppendUint64(b, v) 30 case float32: 31 return dialect.AppendFloat32(b, v) 32 case float64: 33 return dialect.AppendFloat64(b, v) 34 case string: 35 return fmter.Dialect().AppendString(b, v) 36 case time.Time: 37 return fmter.Dialect().AppendTime(b, v) 38 case []byte: 39 return fmter.Dialect().AppendBytes(b, v) 40 case QueryAppender: 41 return AppendQueryAppender(fmter, b, v) 42 default: 43 vv := reflect.ValueOf(v) 44 if vv.Kind() == reflect.Ptr && vv.IsNil() { 45 return dialect.AppendNull(b) 46 } 47 appender := Appender(fmter.Dialect(), vv.Type()) 48 return appender(fmter, b, vv) 49 } 50 } 51 52 //------------------------------------------------------------------------------ 53 54 func In(slice interface{}) QueryAppender { 55 v := reflect.ValueOf(slice) 56 if v.Kind() != reflect.Slice { 57 return &inValues{ 58 err: fmt.Errorf("bun: In(non-slice %T)", slice), 59 } 60 } 61 return &inValues{ 62 slice: v, 63 } 64 } 65 66 type inValues struct { 67 slice reflect.Value 68 err error 69 } 70 71 var _ QueryAppender = (*inValues)(nil) 72 73 func (in *inValues) AppendQuery(fmter Formatter, b []byte) (_ []byte, err error) { 74 if in.err != nil { 75 return nil, in.err 76 } 77 return appendIn(fmter, b, in.slice), nil 78 } 79 80 func appendIn(fmter Formatter, b []byte, slice reflect.Value) []byte { 81 sliceLen := slice.Len() 82 83 if sliceLen == 0 { 84 return append(b, "NULL"...) 85 } 86 87 for i := 0; i < sliceLen; i++ { 88 if i > 0 { 89 b = append(b, ", "...) 90 } 91 92 elem := slice.Index(i) 93 if elem.Kind() == reflect.Interface { 94 elem = elem.Elem() 95 } 96 97 if elem.Kind() == reflect.Slice && elem.Type() != bytesType { 98 b = append(b, '(') 99 b = appendIn(fmter, b, elem) 100 b = append(b, ')') 101 } else { 102 b = fmter.AppendValue(b, elem) 103 } 104 } 105 return b 106 }