mercredi 24 octobre 2018

Store information/reference about structure

I am looking for a way to store information which struct a function should use. Each struct corresponds to certain database table.

type Record struct {
   TableName string
   PrimaryKey string
   //XormStruct // how can I store User or Post here?
   XormStruct2 interface{} // see I have tried below
   XormStruct3 reflect.Type // see I have tried below
}

var posts []Post

var ListOfTables [...]Record {
   {"User", "id", User},
   //{"Post", "post_id", Post},
   {"Post", "post_id", posts, reflect.TypeOf([]Post{})},
}

// User is xorm struct
type User struct {
   Id int64
   Name string
}

// Post is xorm struct
type Post struct {
   Post_id int64
   Name string
   Other string
}

I want to be able to dynamically choose struct for table.

for _, rec := range ListOfTables {
    //var entries []rec.XormStruct // this does not work, of course
    //var entries []reflect.TypeOf(rec.XormStruct) // this does not work either
    // xorm is *xorm.Engine
    xorm.Find(&entries)
    //xorm.Find(&rec.XormStruct2) //with interface{}, does not work - produces an empty &[]
    posts3 := reflect.New(rec.XormStruct3).Interface()
    //xorm.Find(&posts3) // same as above, produces empty &[]
    var posts []Post
    xorm.Find(&posts) // produces desired data

    // afterwards I will do same to any table entries, e.g.
    xml.Marshal(entries)
    // so there is really no need to create identical functions for each table
}

Goal DRY (I have about 30 tables, function is the same)

I have tried:

  • to use reflect.TypeOf(), but I do not understand if/how I can use it (reflect.Type) to define a new variable

  • Define Record with XormStruct interface{} and for each ListOfTables entry create a slice e.g. var posts []Post and {"Post", "post_id", posts},

  • Searching SO and godocs

It seems to me, that xorm.Find() is not "happy" about getting an interface{} instead of []Posts even if it does not say so.

UPDATE: I believe the breaking difference is this:

spew.Dump(posts3) //posts3 := reflect.New(rec.XormStruct3).Interface()
// (*[]main.Post)<0x2312312>(<nil>)
spew.Dump(posts) //var posts []Post
// ([]main.Post)<nil>

SOLUTION

posts3 := reflect.New(rec.XormStruct3).Interface()
xorm.Find(posts3) // not &posts3





Aucun commentaire:

Enregistrer un commentaire