dimanche 13 mars 2022

Get pointers to all fields of a struct dynamically using reflection

I'm trying to build a simple orm layer for golang. Which would take a struct and generate the cols [] which can then be passed to sql function rows.Scan(cols...) which takes pointers of fields in the struct corresponding to each of the columns it has found in the result set

Here is my example struct


type ExampleStruct struct {
    ID        int64          `sql:"id"`
    aID    string         `sql:"a_id"`
    UserID    int64          `sql:"user_id"`

And this is my generic ORM function

func GetSqlColumnToFieldMap(model *ExampleStruct) map[string]interface{} {
    
    typeOfModel := reflect.TypeOf(*model)
    ValueOfModel := reflect.ValueOf(*model)
    columnToDataPointerMap := make(map[string]interface{})
    for i := 0; i < ValueOfModel.NumField(); i++ {
        sql_column := typeOfModel.Field(i).Tag.Get("sql")
        structValue := ValueOfModel.Field(i)
        columnToDataPointerMap[sql_column] = structValue.Addr()
    }
    return columnToDataPointerMap
}


Once this method works fine i can use the map it generates to create an ordered list of sql pointers according to the column_names i get in rows() object However i get below error on the .Addr() method call

panic: reflect.Value.Addr of unaddressable value [recovered]
    panic: reflect.Value.Addr of unaddressable value

Is it not possible to do this ? Also in an ideal scenario i would want the method to take an interface instead of *ExampleStruct so that it can be reused across different db models.





Aucun commentaire:

Enregistrer un commentaire