Reputation: 2062
I want to make a generic model struct to embed in structs that will use gorp
(https://github.com/coopernurse/gorp) to persist objects in my MySQL database. It's my understanding that this kind of composition is how one accomplishes things in Go that are done with inheritance in strongly OO languages.
I haven't been having good luck, however, as I want to define all of the CRUD methods on the GorpModel
struct, to avoid repeating them in each model, but this causes gorp
(as I'm using it right now) to assume that the table I want to interact with is called GorpModel
due to the reflection that gorp
uses. Which causes errors, naturally, as I have no such table in my database.
Is there any way to figure out / use which type I'm in (the superclass which GorpModel
is embedded in) to make the below code work, or am I barking up the wrong tree altogether?
package models
import (
"fmt"
"reflect"
"github.com/coopernurse/gorp"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
type GorpModel struct {
New bool `db:"-"`
}
var dbm *gorp.DbMap = nil
func (gm *GorpModel) DbInit() {
gm.New = true
if dbm == nil {
db, err := sql.Open("mysql", "username:password@my_db")
if err != nil {
panic(err)
}
dbm = &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}
dbm.AddTable(User{}).SetKeys(true, "Id")
dbm.CreateTables()
}
}
func (gm *GorpModel) Create() {
err := dbm.Insert(gm)
if err != nil {
panic(err)
}
}
func (gm *GorpModel) Delete() int64 {
nrows, err := dbm.Delete(gm)
if err != nil {
panic(err)
}
return nrows
}
func (gm *GorpModel) Update() {
_, err := dbm.Update(gm)
if err != nil {
panic(err)
}
}
The New
property of the GorpModel
struct is used to keep track of whether it is a newly created model, and whether we should call Update
or Insert
on Save
(which is defined in the child User
struct at the moment).
Upvotes: 2
Views: 2972
Reputation: 9645
Is there any way to figure out / use which type I'm in (the superclass which GorpModel is embedded in)
No.
I don't know the best way to structure your solution, but with respect to the CRUD you're trying to implement in some kind of base class, just write them as functions. ie.
func Create(gm interface{}) { // or whatever the signature should be
err := dbm.Insert(gm)
if err != nil {
panic(err)
}
}
Upvotes: 2