You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
1.3 KiB
83 lines
1.3 KiB
package pgdialect
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"reflect"
|
|
|
|
"github.com/uptrace/bun/schema"
|
|
)
|
|
|
|
func hstoreScanner(typ reflect.Type) schema.ScannerFunc {
|
|
kind := typ.Kind()
|
|
|
|
switch kind {
|
|
case reflect.Ptr:
|
|
if fn := hstoreScanner(typ.Elem()); fn != nil {
|
|
return schema.PtrScanner(fn)
|
|
}
|
|
case reflect.Map:
|
|
// ok:
|
|
default:
|
|
return nil
|
|
}
|
|
|
|
if typ.Key() == stringType && typ.Elem() == stringType {
|
|
return scanMapStringStringValue
|
|
}
|
|
return func(dest reflect.Value, src interface{}) error {
|
|
return fmt.Errorf("bun: Hstore(unsupported %s)", dest.Type())
|
|
}
|
|
}
|
|
|
|
func scanMapStringStringValue(dest reflect.Value, src interface{}) error {
|
|
dest = reflect.Indirect(dest)
|
|
if !dest.CanSet() {
|
|
return fmt.Errorf("bun: Scan(non-settable %s)", dest.Type())
|
|
}
|
|
|
|
m, err := decodeMapStringString(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dest.Set(reflect.ValueOf(m))
|
|
return nil
|
|
}
|
|
|
|
func decodeMapStringString(src interface{}) (map[string]string, error) {
|
|
if src == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
b, err := toBytes(src)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
m := make(map[string]string)
|
|
|
|
p := newHStoreParser(b)
|
|
for {
|
|
key, err := p.NextKey()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
value, err := p.NextValue()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
m[key] = value
|
|
}
|
|
|
|
return m, nil
|
|
}
|