diff options
Diffstat (limited to 'vendor/github.com/uptrace/bun/dialect/pgdialect/append.go')
-rw-r--r-- | vendor/github.com/uptrace/bun/dialect/pgdialect/append.go | 313 |
1 files changed, 2 insertions, 311 deletions
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go index 7e9491abc..c95fa86e7 100644 --- a/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go +++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go @@ -2,12 +2,9 @@ package pgdialect import ( "database/sql/driver" - "encoding/hex" "fmt" "reflect" - "strconv" "time" - "unicode/utf8" "github.com/uptrace/bun/dialect" "github.com/uptrace/bun/schema" @@ -32,316 +29,10 @@ var ( sliceTimeType = reflect.TypeOf([]time.Time(nil)) ) -func arrayAppend(fmter schema.Formatter, b []byte, v interface{}) []byte { - switch v := v.(type) { - case int64: - return strconv.AppendInt(b, v, 10) - case float64: - return dialect.AppendFloat64(b, v) - case bool: - return dialect.AppendBool(b, v) - case []byte: - return arrayAppendBytes(b, v) - case string: - return arrayAppendString(b, v) - case time.Time: - return fmter.Dialect().AppendTime(b, v) - default: - err := fmt.Errorf("pgdialect: can't append %T", v) - return dialect.AppendError(b, err) - } -} - -func arrayAppendStringValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - return arrayAppendString(b, v.String()) -} - -func arrayAppendBytesValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - return arrayAppendBytes(b, v.Bytes()) -} - -func arrayAppendDriverValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - iface, err := v.Interface().(driver.Valuer).Value() - if err != nil { - return dialect.AppendError(b, err) - } - return arrayAppend(fmter, b, iface) -} - -//------------------------------------------------------------------------------ - -func (d *Dialect) arrayAppender(typ reflect.Type) schema.AppenderFunc { - kind := typ.Kind() - - switch kind { - case reflect.Ptr: - if fn := d.arrayAppender(typ.Elem()); fn != nil { - return schema.PtrAppender(fn) - } - case reflect.Slice, reflect.Array: - // ok: - default: - return nil - } - - elemType := typ.Elem() - - if kind == reflect.Slice { - switch elemType { - case stringType: - return appendStringSliceValue - case intType: - return appendIntSliceValue - case int64Type: - return appendInt64SliceValue - case float64Type: - return appendFloat64SliceValue - case timeType: - return appendTimeSliceValue - } - } - - appendElem := d.arrayElemAppender(elemType) - if appendElem == nil { - panic(fmt.Errorf("pgdialect: %s is not supported", typ)) - } - - return func(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - kind := v.Kind() - switch kind { - case reflect.Ptr, reflect.Slice: - if v.IsNil() { - return dialect.AppendNull(b) - } - } - - if kind == reflect.Ptr { - v = v.Elem() - } - - b = append(b, '\'') - - b = append(b, '{') - ln := v.Len() - for i := 0; i < ln; i++ { - elem := v.Index(i) - b = appendElem(fmter, b, elem) - b = append(b, ',') - } - if v.Len() > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - b = append(b, '\'') - - return b - } -} - -func (d *Dialect) arrayElemAppender(typ reflect.Type) schema.AppenderFunc { - if typ.Implements(driverValuerType) { - return arrayAppendDriverValue - } - switch typ.Kind() { - case reflect.String: - return arrayAppendStringValue - case reflect.Slice: - if typ.Elem().Kind() == reflect.Uint8 { - return arrayAppendBytesValue - } - } - return schema.Appender(d, typ) -} - -func appendStringSliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - ss := v.Convert(sliceStringType).Interface().([]string) - return appendStringSlice(b, ss) +func appendTime(buf []byte, tm time.Time) []byte { + return tm.UTC().AppendFormat(buf, "2006-01-02 15:04:05.999999-07:00") } -func appendStringSlice(b []byte, ss []string) []byte { - if ss == nil { - return dialect.AppendNull(b) - } - - b = append(b, '\'') - - b = append(b, '{') - for _, s := range ss { - b = arrayAppendString(b, s) - b = append(b, ',') - } - if len(ss) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - b = append(b, '\'') - - return b -} - -func appendIntSliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - ints := v.Convert(sliceIntType).Interface().([]int) - return appendIntSlice(b, ints) -} - -func appendIntSlice(b []byte, ints []int) []byte { - if ints == nil { - return dialect.AppendNull(b) - } - - b = append(b, '\'') - - b = append(b, '{') - for _, n := range ints { - b = strconv.AppendInt(b, int64(n), 10) - b = append(b, ',') - } - if len(ints) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - b = append(b, '\'') - - return b -} - -func appendInt64SliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - ints := v.Convert(sliceInt64Type).Interface().([]int64) - return appendInt64Slice(b, ints) -} - -func appendInt64Slice(b []byte, ints []int64) []byte { - if ints == nil { - return dialect.AppendNull(b) - } - - b = append(b, '\'') - - b = append(b, '{') - for _, n := range ints { - b = strconv.AppendInt(b, n, 10) - b = append(b, ',') - } - if len(ints) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - b = append(b, '\'') - - return b -} - -func appendFloat64SliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - floats := v.Convert(sliceFloat64Type).Interface().([]float64) - return appendFloat64Slice(b, floats) -} - -func appendFloat64Slice(b []byte, floats []float64) []byte { - if floats == nil { - return dialect.AppendNull(b) - } - - b = append(b, '\'') - - b = append(b, '{') - for _, n := range floats { - b = dialect.AppendFloat64(b, n) - b = append(b, ',') - } - if len(floats) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - b = append(b, '\'') - - return b -} - -//------------------------------------------------------------------------------ - -func arrayAppendBytes(b []byte, bs []byte) []byte { - if bs == nil { - return dialect.AppendNull(b) - } - - b = append(b, `"\\x`...) - - s := len(b) - b = append(b, make([]byte, hex.EncodedLen(len(bs)))...) - hex.Encode(b[s:], bs) - - b = append(b, '"') - - return b -} - -func arrayAppendString(b []byte, s string) []byte { - b = append(b, '"') - for _, r := range s { - switch r { - case 0: - // ignore - case '\'': - b = append(b, "''"...) - case '"': - b = append(b, '\\', '"') - case '\\': - b = append(b, '\\', '\\') - default: - if r < utf8.RuneSelf { - b = append(b, byte(r)) - break - } - l := len(b) - if cap(b)-l < utf8.UTFMax { - b = append(b, make([]byte, utf8.UTFMax)...) - } - n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r) - b = b[:l+n] - } - } - b = append(b, '"') - return b -} - -func appendTimeSliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte { - ts := v.Convert(sliceTimeType).Interface().([]time.Time) - return appendTimeSlice(fmter, b, ts) -} - -func appendTimeSlice(fmter schema.Formatter, b []byte, ts []time.Time) []byte { - if ts == nil { - return dialect.AppendNull(b) - } - b = append(b, '\'') - b = append(b, '{') - for _, t := range ts { - b = append(b, '"') - b = t.UTC().AppendFormat(b, "2006-01-02 15:04:05.999999-07:00") - b = append(b, '"') - b = append(b, ',') - } - if len(ts) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - b = append(b, '\'') - return b -} - -//------------------------------------------------------------------------------ - var mapStringStringType = reflect.TypeOf(map[string]string(nil)) func (d *Dialect) hstoreAppender(typ reflect.Type) schema.AppenderFunc { |