Skip to content

Instantly share code, notes, and snippets.

@ribrdb
Forked from anonymous/sql.go
Last active September 14, 2017 16:35
Show Gist options
  • Save ribrdb/eedb9e769e88c1313d59fb08746378f0 to your computer and use it in GitHub Desktop.
Save ribrdb/eedb9e769e88c1313d59fb08746378f0 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"database/sql"
)
// JSONScanner scans a column into a map.
type JSONScanner struct {
Key string
Map map[string]interface{}
}
func (s JSONScanner) Scan(src interface{}) error {
s.Map[s.Key] = src
}
func QueryToJSON(db *sql.DB, query string, args ...interface{}) ([]byte, error) {
rows, err := db.Query(query, ...args)
if err != nil {
return nil, err
}
defer rows.Close()
var items []interface{}
// Fetch the column names.
var scanners []*JSONScanner
names, err := rows.Columns()
if err != nil {
return nil, err
}
for _, name := range(names) {
scanners = append(scanners, &JSONScanner{Key: name})
}
// Now convert each row to a map.
for rows.Next() {
// Make a map for this row
item := make(map[string]interface{})
// Make each scanner update this new map.
for _, scanner := range(scanners) {
scanner.Map = item
}
// Read the row.
if err = rows.Scan(...scanners); err != nil {
return nil, err
}
// Save the map
items = append(items, item)
}
if err = row.Err(); err != nil {
return nil, err
}
return json.Marshal(items)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment