I have a bunch of very similar structs (A and B in the example) whose instances I want to handle in some function ( f()
in the example) and then insert them into my database. I figured I could handle that with the empty interface somehow, but it seems this is not the solution as I get the error:
i: &{{6 2019-04-03 15:11:37.822100431 +0200 CEST m=+0.001291882} 7} *main.A
2019/04/03 15:11:37 Insert i no table found for type:
exit status 1
I tried to create some minimal but executable example:
package main
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
gorp "gopkg.in/gorp.v2"
"log"
"time"
)
type Meta struct {
Id int
CreatedAt time.Time
}
type A struct {
Meta
Value int
}
type B struct {
Meta
Value string
}
var dbmap *gorp.DbMap
func f(i interface{}) {
fmt.Printf("i: %v %T
", i, i)
err := dbmap.Insert(&i)
checkErr(err, "Insert i")
}
func main() {
Init()
a := A{Meta: Meta{CreatedAt: time.Now()}, Value: 7}
b := B{Meta: Meta{CreatedAt: time.Now()}, Value: "seven"}
err := dbmap.Insert(&a) // works
checkErr(err, "Insert a")
err = dbmap.Insert(&b) // works
checkErr(err, "Insert b")
f(&a) // fails
}
func Init() {
db, err := sql.Open("sqlite3", "/tmp/post_db.bin")
checkErr(err, "sql.Open failed")
dbmap = &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
dbmap.AddTableWithName(A{}, "As").SetKeys(true, "Id")
dbmap.AddTableWithName(B{}, "Bs").SetKeys(true, "Id")
err = dbmap.CreateTablesIfNotExists()
checkErr(err, "Couldn't create tables")
}
func checkErr(err error, msg string) {
if err != nil {
log.Fatalln(msg, err)
}
}
What's the right way to do that? In C++ I'd simply use templates ;)