I have a typical function that takes a post request from the frontend and decodes the data into a struct in order to put it into a psql database. You can see the code below. My problem is that I want to be able to abstract this function so that I can give it any amount of variables of any type so that for every request I don't have to have a separate write handler.
It looks difficult because I would have to somehow pass in a way to abstract var profitReq profitReq
to work for any struct. If golang had some sort of eval string method I would know how to do this, but someone correct me if I'm wrong, but I don't think that it does.
The other place I need to change is in QueryRow - I have to be able to pass it in a variable number of variables. I could construct the string easily enough, but I'm not sure how to append variables to that QueryRow necessarily. If I append all the variables to an array for example, I can't pass that array into QueryRow as that's not how it's structured. Again, here some sort of eval statement would help.
I'm new to golang, but I've seen a lot of cool things related to interfaces, which I admittedly don't understand very well. Would there be a way to use an interface here that would help?
Thanks to anyone who can help!
func Write_profit_table(profitWriteChannel chan string, profitType string, req *http.Request) {
var profitReq profitReq;
err := json.NewDecoder(req.Body).Decode(&profitReq);
if err!=nil{
log.Panic(err)
}
NotInDB, _ := Search_userinfo_table(profitReq.Email)
if NotInDB == false {
var lastInsertId int
err2 := db.QueryRow("INSERT INTO profit(email, type, dateArray, amount, interest, compounded, recurring, name, description, profitFrom)
VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) returning uid;",
profitReq.Email, profitReq.Type, pq.Array(profitReq.DateArray), profitReq.Profit, profitReq.Interest,
profitReq.Compounded, profitReq.Recurring, profitReq.Name, profitReq.Description, profitReq.ProfitFrom).Scan(&lastInsertId);
if err2!=nil{
log.Panic(err2)
}
}
profitWriteChannel<-"finished writing to profit"
}
The feature you're looking for is called generics.
Generics are not supported by Go 1.x
Luckily for us, there's a proposal for them for Go 2 (called Contracts)
What can you do until then?
Use interfaces
If you know that this method will always query by email, you could create simple interface for that purpose: type Emailer interface { Email() string }
Use empty interface (interface{}
) and reflection to figure out what columns you have.
Write your own generator. A bit like (1), but you don't have to do this yourself.
Here's the gist of it: https://play.golang.org/p/A_2YKWLvmn-