Creating a GORM custom data type, how to get context in scan?

Viewed 523

I'm trying to write a Gorm custom data type: https://gorm.io/docs/data_types.html

type MyDataType struct {}

func (f *MyDataType) Scan(value interface{}) error {
    //
}

func (f MyDataType) Value() (driver.Value, error) {
    //
}

For some reasons, I need to access context in Scan or to be able to retrieve field tags.

Is there a way to do this ? Thanks

3 Answers

Value are based on user space which you may need to change the code to be looks like :

type MyDataType struct {}

func (f *MyDataType) Scan(context context.Context, value interface{}) error {
    // proceed the context right there
}

func (f MyDataType) Value() (driver.Value, error) {
    //
}

What context you need to access?

Scan(...) is used to translate the database raw data into your custom fieldtype. You should know the format.

Value() is the other way around, it converts your custom field into whatever should be placed in the database.

You can't change params of func Scan or func Value as trying to do it will break MyDataType's sql.Scanner and sql.Valuer implementation.

It can be done by embedding context.Context inside MyDataType.

type MyDataType struct {
    context.Context
}

func (f *MyDataType) Scan(value interface{}) error {
    ctx := context.Background()
    ctx = context.WithValue(ctx, "key", value)
    f.Context = ctx
    return nil
}

func (f MyDataType) Value() (driver.Value, error) {
    value := f.Context.Value("key")
    return value, nil
}
Related