ksql/attr_serializers.go

67 lines
2.1 KiB
Go

package ksql
import (
"context"
"database/sql/driver"
"fmt"
)
// Here we keep all the registered serializers
var serializers = map[string]AttrSerializer{
"json": jsonSerializer{},
}
// RegisterAttrSerializer allow users to add custom serializers on startup
// it is recommended to do this inside an init() function.
func RegisterAttrSerializer(key string, serializer AttrSerializer) {
_, found := serializers[key]
if found {
panic(fmt.Errorf("KSQL: cannot register serializer '%s' name is already in use", key))
}
serializers[key] = serializer
}
// AttrSerializer describes the two operations required to serialize and deserialize an object from the database.
type AttrSerializer interface {
AttrScan(ctx context.Context, opInfo OpInfo, attrPtr interface{}, dbValue interface{}) error
AttrValue(ctx context.Context, opInfo OpInfo, inputValue interface{}) (outputValue interface{}, _ error)
}
// OpInfo contains information that might be used by a serializer to determine how it should behave.
type OpInfo struct {
// A string version of the name of one of
// the methods of the `ksql.Provider` interface, e.g. `Insert` or `Query`
Method string
// The string representing the current underlying database, e.g.:
// "postgres", "sqlite3", "mysql" or "sqlserver".
DriverName string
}
// attrSerializer is the wrapper that allow us to intercept the Scan and Value processes
// so we can run the serializers instead of allowing the database driver to use
// its default behavior.
//
// For that this struct implements both the `sql.Scanner` and `sql.Valuer` interfaces.
type attrSerializer struct {
ctx context.Context
// When Scanning this value should be a pointer to the attribute
// and when "Valuing" it should just be the actual value
attr interface{}
serializerName string
opInfo OpInfo
}
// Scan implements the sql.Scanner interface
func (a attrSerializer) Scan(dbValue interface{}) error {
return serializers[a.serializerName].AttrScan(a.ctx, a.opInfo, a.attr, dbValue)
}
// Value implements the sql.Valuer interface
func (a attrSerializer) Value() (driver.Value, error) {
return serializers[a.serializerName].AttrValue(a.ctx, a.opInfo, a.attr)
}