Search code examples
mysqlgogorp

Passing a variadic parameter for select query


I'm trying to build a query as follows, here I'm using gorp.

func GetAgregatedDownloadsFromTo(constrains Constrains) [] dao.NameValue {
    dbMap := utils.GetDBConnection("radsummary");
    defer dbMap.Db.Close()
    var totalDailyDownloads[] NameValue
    query := "SELECT SUM(outputoctets) as value ,date as name FROM dailyacct where date >= ? AND date < ? "

    if len(constrains.LocationGroups) > 0 {
        query = query + " AND calledstationid=? "
        for i := 1; i< len(constrains.LocationGroups); i++ {
            query = query + " OR calledstationid=? "
        }
        query = query + " group by date"
        print(query)
        _, err := dbMap.Select(&totalDailyDownloads, query, constrains.From, constrains.To, constrains.LocationGroups...)
        if err != nil {
            panic(err.Error()) // proper error handling instead of panic
        }
    }
    return totalDailyDownloads
}

type Constrains struct {
    From string `json:"from"`
    To string   `json:"to"`
    LocationGroups []string    `json:"locationgroups"`
}

Query construction happens based on the length of constrains.LocationGroups. Trouble I'm having is passing the variable number of args to the Select query once I give constrains.LocationGroups... as select query parameters it throws a compiler error too many arguments in call to dbMap.Select

Is it possible to achieve this kind of requirement?. Appreciate your input.


Solution

  • Found an answer based on Pass string slice to variadic empty interface parameter

    Below is the updated code to achieve the task

    func GetAgregatedDownloadsFromTo(constrains dao.Constrains) [] dao.NameValue {
        dbMap := utils.GetDBConnection("radsummary");
        defer dbMap.Db.Close()
        var totalDailyDownloads[] dao.NameValue
        query := "SELECT SUM(outputoctets) as value ,date as name FROM dailyacct where date >= ? AND date < ? "
    
        if len(constrains.LocationGroups) > 0 {
            args := make([]interface{}, len(constrains.LocationGroups)+2)
            args[0] = constrains.From
            args[1] = constrains.To
            for index, value := range constrains.LocationGroups { args[index+2] = value }
    
            query = query + " AND calledstationid=? "
            for i := 1; i< len(constrains.LocationGroups); i++ {
                query = query + " OR calledstationid=? "
            }
            query = query + " group by date"
            print(query)
            _, err := dbMap.Select(&totalDailyDownloads, query, args...)
            if err != nil {
                panic(err.Error()) // proper error handling instead of panic
            }
        }
        return totalDailyDownloads
    }
    

    Here I had to convert the string slice to an interface slice.