Simplify encoding extended query arguments
This commit is contained in:
+27
-3
@@ -16,13 +16,37 @@ func (JSONCodec) PreferredFormat() int16 {
|
||||
return TextFormatCode
|
||||
}
|
||||
|
||||
func (JSONCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan {
|
||||
func (c JSONCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
return encodePlanJSONCodecEitherFormatString{}
|
||||
case []byte:
|
||||
return encodePlanJSONCodecEitherFormatByteSlice{}
|
||||
default:
|
||||
return encodePlanJSONCodecEitherFormatMarshal{}
|
||||
}
|
||||
|
||||
// Because anything can be marshalled the normal wrapping in Map.PlanScan doesn't get a chance to run. So try the
|
||||
// appropriate wrappers here.
|
||||
for _, f := range []TryWrapEncodePlanFunc{
|
||||
TryWrapDerefPointerEncodePlan,
|
||||
TryWrapFindUnderlyingTypeEncodePlan,
|
||||
} {
|
||||
if wrapperPlan, nextValue, ok := f(value); ok {
|
||||
if nextPlan := c.PlanEncode(m, oid, format, nextValue); nextPlan != nil {
|
||||
wrapperPlan.SetNext(nextPlan)
|
||||
return wrapperPlan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return encodePlanJSONCodecEitherFormatMarshal{}
|
||||
}
|
||||
|
||||
type encodePlanJSONCodecEitherFormatString struct{}
|
||||
|
||||
func (encodePlanJSONCodecEitherFormatString) Encode(value interface{}, buf []byte) (newBuf []byte, err error) {
|
||||
jsonString := value.(string)
|
||||
buf = append(buf, jsonString...)
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
type encodePlanJSONCodecEitherFormatByteSlice struct{}
|
||||
|
||||
@@ -1155,6 +1155,14 @@ func codecDecodeToTextFormat(codec Codec, m *Map, oid uint32, format int16, src
|
||||
// PlanEncode returns an Encode plan for encoding value into PostgreSQL format for oid and format. If no plan can be
|
||||
// found then nil is returned.
|
||||
func (m *Map) PlanEncode(oid uint32, format int16, value interface{}) EncodePlan {
|
||||
if format == TextFormatCode {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
return encodePlanStringToAnyTextFormat{}
|
||||
case TextValuer:
|
||||
return encodePlanTextValuerToAnyTextFormat{}
|
||||
}
|
||||
}
|
||||
|
||||
var dt *Type
|
||||
|
||||
@@ -1187,6 +1195,27 @@ func (m *Map) PlanEncode(oid uint32, format int16, value interface{}) EncodePlan
|
||||
return nil
|
||||
}
|
||||
|
||||
type encodePlanStringToAnyTextFormat struct{}
|
||||
|
||||
func (encodePlanStringToAnyTextFormat) Encode(value interface{}, buf []byte) (newBuf []byte, err error) {
|
||||
s := value.(string)
|
||||
return append(buf, s...), nil
|
||||
}
|
||||
|
||||
type encodePlanTextValuerToAnyTextFormat struct{}
|
||||
|
||||
func (encodePlanTextValuerToAnyTextFormat) Encode(value interface{}, buf []byte) (newBuf []byte, err error) {
|
||||
t, err := value.(TextValuer).TextValue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !t.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return append(buf, t.String...), nil
|
||||
}
|
||||
|
||||
// TryWrapEncodePlanFunc is a function that tries to create a wrapper plan for value. If successful it returns a plan
|
||||
// that will convert the value passed to Encode and then call the next plan. nextValue is value as it will be converted
|
||||
// by plan. It must be used to find another suitable EncodePlan. When it is found SetNext must be called on plan for it
|
||||
|
||||
Reference in New Issue
Block a user