2021-08-25 13:34:33 +00:00
|
|
|
package pgdialect
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql/driver"
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/uptrace/bun/dialect"
|
|
|
|
"github.com/uptrace/bun/schema"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2025-01-14 14:23:28 +00:00
|
|
|
driverValuerType = reflect.TypeFor[driver.Valuer]()
|
2021-08-25 13:34:33 +00:00
|
|
|
|
2025-01-14 14:23:28 +00:00
|
|
|
stringType = reflect.TypeFor[string]()
|
|
|
|
sliceStringType = reflect.TypeFor[[]string]()
|
2021-08-25 13:34:33 +00:00
|
|
|
|
2025-01-14 14:23:28 +00:00
|
|
|
intType = reflect.TypeFor[int]()
|
|
|
|
sliceIntType = reflect.TypeFor[[]int]()
|
2021-08-25 13:34:33 +00:00
|
|
|
|
2025-01-14 14:23:28 +00:00
|
|
|
int64Type = reflect.TypeFor[int64]()
|
|
|
|
sliceInt64Type = reflect.TypeFor[[]int64]()
|
2021-08-25 13:34:33 +00:00
|
|
|
|
2025-01-14 14:23:28 +00:00
|
|
|
float64Type = reflect.TypeFor[float64]()
|
|
|
|
sliceFloat64Type = reflect.TypeFor[[]float64]()
|
2023-01-22 11:26:47 +00:00
|
|
|
|
2025-01-14 14:23:28 +00:00
|
|
|
timeType = reflect.TypeFor[time.Time]()
|
|
|
|
sliceTimeType = reflect.TypeFor[[]time.Time]()
|
2021-08-25 13:34:33 +00:00
|
|
|
)
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
func appendTime(buf []byte, tm time.Time) []byte {
|
|
|
|
return tm.UTC().AppendFormat(buf, "2006-01-02 15:04:05.999999-07:00")
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
2022-08-15 10:35:05 +00:00
|
|
|
var mapStringStringType = reflect.TypeOf(map[string]string(nil))
|
|
|
|
|
|
|
|
func (d *Dialect) hstoreAppender(typ reflect.Type) schema.AppenderFunc {
|
|
|
|
kind := typ.Kind()
|
|
|
|
|
|
|
|
switch kind {
|
|
|
|
case reflect.Ptr:
|
|
|
|
if fn := d.hstoreAppender(typ.Elem()); fn != nil {
|
|
|
|
return schema.PtrAppender(fn)
|
|
|
|
}
|
|
|
|
case reflect.Map:
|
|
|
|
// ok:
|
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if typ.Key() == stringType && typ.Elem() == stringType {
|
|
|
|
return appendMapStringStringValue
|
|
|
|
}
|
|
|
|
|
|
|
|
return func(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
|
|
|
err := fmt.Errorf("bun: Hstore(unsupported %s)", v.Type())
|
|
|
|
return dialect.AppendError(b, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func appendMapStringString(b []byte, m map[string]string) []byte {
|
|
|
|
if m == nil {
|
|
|
|
return dialect.AppendNull(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
b = append(b, '\'')
|
|
|
|
|
|
|
|
for key, value := range m {
|
2025-01-14 14:23:28 +00:00
|
|
|
b = appendStringElem(b, key)
|
2022-08-15 10:35:05 +00:00
|
|
|
b = append(b, '=', '>')
|
2025-01-14 14:23:28 +00:00
|
|
|
b = appendStringElem(b, value)
|
2022-08-15 10:35:05 +00:00
|
|
|
b = append(b, ',')
|
|
|
|
}
|
|
|
|
if len(m) > 0 {
|
|
|
|
b = b[:len(b)-1] // Strip trailing comma.
|
|
|
|
}
|
|
|
|
|
|
|
|
b = append(b, '\'')
|
|
|
|
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
func appendMapStringStringValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
|
|
|
m := v.Convert(mapStringStringType).Interface().(map[string]string)
|
|
|
|
return appendMapStringString(b, m)
|
|
|
|
}
|