Created
November 17, 2017 02:20
-
-
Save proprietary/b401b0f7e9fb6c00ed06df553c6a3977 to your computer and use it in GitHub Desktop.
query database in golang into a map/hash table instead of struct
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ( | |
"database/sql" | |
_ "github.com/lib/pq" | |
"log" | |
) | |
// queryMap is used for quickly running a SQL query that returns only one | |
// row. Important: This shouldn't ever return errors and shouldn't ever | |
// be applied on user input. Ideally, you're querying non-nullable | |
// columns using keys you got from some trusted (non-human) | |
// source. Slow(er)? Yes. But this is good for prototyping and relieving | |
// Go-related RSI. Works on Postgres + lib/pq + database/sql. | |
// Usage: | |
// a := queryMap(dbPtr, "select first_name from customers where balance >= $1", 1000) | |
// for _, firstName := range a { | |
// fmt.Println(a["first_name"].(string)) // you must know what type the db driver converts your columns to | |
// } | |
func queryMap(db *sql.DB, sql string, cols ...interface{}) []map[string]interface{} { | |
rows, err := db.Query(sql, cols...) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer rows.Close() | |
ret := make([]map[string]interface{}, 0) | |
for rows.Next() { | |
colVals := make([]interface{}, len(cols)) | |
for i := range colVals { | |
colVals[i] = new(interface{}) | |
} | |
err = rows.Scan(colVals...) | |
if err != nil { | |
log.Fatal(err) | |
} | |
colNames, err := rows.Columns() | |
if err != nil { | |
log.Fatal(err) | |
} | |
these := make(map[string]interface{}) | |
for idx, name := range colNames { | |
these[name] = *colVals[idx].(*interface{}) | |
} | |
ret = append(ret, these) | |
} | |
if err = rows.Err(); err != nil { | |
log.Fatal(err) | |
} | |
return ret | |
} | |
// queryMapOne is queryMap just for one row only. | |
func queryMapOne(db *sql.DB, sql string, cols ...interface{}) map[string]interface{} { | |
xs := queryMap(db, sql, cols...) | |
if len(xs) == 0 { | |
log.Fatalf("Empty result set") | |
return nil | |
} else { | |
return xs[0] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment