Reputation: 81
I have multiple database tables with a concrete struct for each table. I'm using sqlx. My functions for database access work fine for each concrete struct.
Since many of my database operations (e.g., insert a row) are identical across the tables I'd like to DRY them up a bit by having a common set of functions that take an interface and perform the operations.
In a function that takes the interface and calls sqlx functions (e.g., sqlx.Get) I need to pull the concrete struct out of the interface to hand to sqlx. And I'm stumped there.
I've read the Laws of Reflection. I've read the reflect package documentation . I've looked all over and can't seem to put the pieces together properly.
Specific code:
type Persistable interface {
DbFieldNames() []string
DbPrepCreate() error
TableName() string
}
type Session struct {}
implements those methods and is accepted as a Persistable.
This statement works fine (with the concrete struct explicitly created.
// src is the Persistable passed into this function
dest := Session{}
err = stmt.Get(&dest, src)
But using that explicitly created struct in the common function defeats the purpose. What I want to do is this:
dest := SomeFunctionThatExtractsTheConcreteStruct( src )
# such that I can pass that dest into sqlx.
I've used the reflect package to examine the src variable (type, value, kind, ......). I can easily see that src contains a *Session. I can get the real value out. But creating a concrete class from src to pass into sqlx eludes me.
Upvotes: 2
Views: 315
Reputation: 120941
You have the variable named src
with type Persistable
containing a *Session
. Your goal is to get an interface{}
value containing a *Session
to use as the first argument to the Get method.
Because Persistable
is assignable to interface{}
(as are all types), you can simply pass src
to the first argument of the Get method.
err = stmt.Get(src, args...)
Upvotes: 3