Golang generic method to fetch data from database

2.9k views Asked by At

I'm trying to implement the jquery datatables server side processing in Golang. Part of that needs a generic method to select data from DB. I've posted a simplified version of what I've done below.

package main
import (
    "gopkg.in/gorp.v1"
    "database/sql"
  _ "github.com/go-sql-driver/mysql"
)

type User struct {
    TenantId     int     `db:"tenantid"json:"tenantid"`
    Username     string  `db:"username"json:"username"`
    Password     string  `json:"password"`
}


func GenericSelect(database string,  table string, columns []string, result interface{})interface{} {
    dbMap := getDBConnection(database);
    defer dbMap.Db.Close()
    var err error
    query := "SELECT " 

    for index,element := range columns {
      query += element
      if(index+1 != len(columns)){
        query += ","
      }
    }
    query +=  " FROM " + table + " LIMIT 1,100"
    _, err = dbMap.Select(&result, query)
    if err != nil {
        panic(err.Error())  // Just for example purpose.
    }
  return result
}


func getDBConnection(dbname string) *gorp.DbMap {
    var connectionUrl string
    connectionUrl = "root:root@tcp(localhost:3306)/" + dbname

    db, err := sql.Open("mysql", connectionUrl)
    if err != nil {
        panic(err.Error())  // Just for example purpose.
    }
    dbmap := &gorp.DbMap{Db: db, Dialect:gorp.MySQLDialect{"InnoDB", "UTF8"}}
    return dbmap
}


func main(){
        var users []User
        columns := []string{"tenantid", "username", "password"}
        result := GenericSelect("portal","accounting",columns, &users)
        //make result in to a json instead of print
        print(result)
}

Once I run this, it throws the following error,

panic: gorp: Cannot SELECT into this type: *interface {}

goroutine 1 [running]:
main.GenericSelect(0x6b1c30, 0x6, 0x6bd490, 0xa, 0xc208073f60, 0x3, 0x3, 0x5e8e60, 0xc20801e260, 0x0, ...)
    /home/anuruddha/Desktop/go-lang/main.go:30 +0x37f

According to the error, Select() is not accepting interfaces. Is it possible to achieve this level of generality in golang? Appreciate if you can direct me to get this working?

1

There are 1 answers

0
Lucas Jones On BEST ANSWER

In this case result is already a pointer (users is passed as &users), so you don't need to take the address of it again.

Replace the line:

_, err = dbMap.Select(&result, query)

with

_, err = dbMap.Select(result, query)