Making the ExecuteQuery function generic to return a map of rows instead of a struct

This will help us to execute arbitrary queries and map them to results at a later stage.
This commit is contained in:
Arpit Mohan 2019-02-26 23:49:20 +05:30
parent acbb5a55e0
commit 4016562f09
2 changed files with 36 additions and 16 deletions

View File

@ -3,7 +3,6 @@ package storage
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"internal-tools-server/models"
"log" "log"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
@ -15,7 +14,7 @@ var StorageEngine DataStore
// DataStore defines the interface that all db implementations must implement. // DataStore defines the interface that all db implementations must implement.
type DataStore interface { type DataStore interface {
ExecuteQuery(query string) ([]models.Component, error) ExecuteQuery(query string) ([]map[string]interface{}, error)
GetDatastore() *gorm.DB GetDatastore() *gorm.DB
} }

View File

@ -2,7 +2,6 @@ package storage
import ( import (
"fmt" "fmt"
"internal-tools-server/models"
"log" "log"
"os" "os"
@ -88,25 +87,47 @@ func (d *PostgresDataStore) dbConfig() {
} }
// ExecuteQuery executes the query on the DB // ExecuteQuery executes the query on the DB
func (d *PostgresDataStore) ExecuteQuery(query string) ([]models.Component, error) { func (d *PostgresDataStore) ExecuteQuery(query string) ([]map[string]interface{}, error) {
rows, err := d.DB.Raw(query).Rows() rows, err := d.DB.Raw(query).Rows()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer rows.Close() cols, err := rows.Columns()
components := []models.Component{} if err != nil {
return nil, err
for rows.Next() {
component := models.Component{}
err = rows.Scan(
&component.ID,
&component.Name,
&component.Type,
)
components = append(components, component)
} }
return components, nil defer rows.Close()
values := make([]map[string]interface{}, 0)
for rows.Next() {
// Create a slice of interface{}'s to represent each column,
// and a second slice to contain pointers to each item in the columns slice.
columns := make([]interface{}, len(cols))
columnPointers := make([]interface{}, len(cols))
for i := range columns {
columnPointers[i] = &columns[i]
}
// Scan the result into the column pointers...
if err := rows.Scan(columnPointers...); err != nil {
return nil, err
}
// Create our map, and retrieve the value for each column from the pointers slice,
// storing it in the map with the name of the column as the key.
m := make(map[string]interface{})
for i, colName := range cols {
val := columnPointers[i].(*interface{})
m[colName] = *val
}
// Outputs: map[columnName:value columnName2:value2 columnName3:value3 ...]
fmt.Println(m)
values = append(values, m)
}
return values, nil
} }
func (d *PostgresDataStore) GetDatastore() *gorm.DB { func (d *PostgresDataStore) GetDatastore() *gorm.DB {