ksql/attr_modifiers.go

67 lines
2.1 KiB
Go

package ksql
import (
"context"
"database/sql/driver"
"fmt"
)
// Here we keep all the registered modifier
var modifiers = map[string]AttrModifier{
"json": jsonModifier{},
}
// RegisterAttrModifier allow users to add custom modifiers on startup
// it is recommended to do this inside an init() function.
func RegisterAttrModifier(key string, modifier AttrModifier) {
_, found := modifiers[key]
if found {
panic(fmt.Errorf("KSQL: cannot register modifier '%s' name is already in use", key))
}
modifiers[key] = modifier
}
// AttrModifier describes the two operations required to serialize and deserialize an object from the database.
type AttrModifier 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 modifier 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
}
// attrModifier is the wrapper that allow us to intercept the Scan and Value processes
// so we can run the modifiers 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 attrModifier 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{}
modifierName string
opInfo OpInfo
}
// Scan implements the sql.Scanner interface
func (a attrModifier) Scan(dbValue interface{}) error {
return modifiers[a.modifierName].AttrScan(a.ctx, a.opInfo, a.attr, dbValue)
}
// Value implements the sql.Valuer interface
func (a attrModifier) Value() (driver.Value, error) {
return modifiers[a.modifierName].AttrValue(a.ctx, a.opInfo, a.attr)
}