Skip to content

Instantly share code, notes, and snippets.

@arnehormann
Last active December 18, 2015 10:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arnehormann/5766351 to your computer and use it in GitHub Desktop.
Save arnehormann/5766351 to your computer and use it in GitHub Desktop.
Hit the dangerous wobbly ground running: Quick&dirty up to speed with go database/sql
type must struct {
db *sql.DB
stmt *sql.Stmt
rows *sql.Rows
err error
closers []io.Closer
}
func Open(dbdriver, dsn string) *must {
m := &must{}
m.db, m.err = sql.Open(dbdriver, dsn)
m.mayPanic(m.db)
return m
}
func (m *must) mayPanic(closer interface{}) {
if m.err != nil {
panic(m.err)
}
if c, ok := closer.(io.Closer); ok {
m.closers = append(m.closers, c)
}
}
func (m *must) Close() {
for i := len(m.closers) - 1; i >= 0; i-- {
_ = m.closers[i].Close()
}
}
func (m *must) Exec(query string, args ...interface{}) sql.Result {
if m.rows != nil {
m.rows, _ = nil, m.rows.Close()
}
var result sql.Result
result, m.err = m.db.Exec(query, args...)
m.mayPanic(nil)
return result
}
func (m *must) QueryColumns(query string, args ...interface{}) (cols []string) {
if m.rows != nil {
m.rows, _ = nil, m.rows.Close()
}
m.rows, m.err = m.db.Query(query, args...)
m.mayPanic(m.rows)
if !m.rows.Next() {
return nil
}
cols, m.err = m.rows.Columns()
m.mayPanic(m.rows)
return cols
}
func (m *must) ScanNext(args ...interface{}) (hasNext bool) {
m.err = m.rows.Scan(args...)
m.mayPanic(nil)
return m.rows.Next()
}
@arnehormann
Copy link
Author

Used like this:

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "io"
    "os"
    "strings"
)

func main() {
    dsn := os.Getenv("MYSQL_DSN")
    if dsn == "" {
        dsn = "root@tcp(localhost:3306)/"
    }
    mysql := Open("mysql", dsn)
    defer mysql.Close()
    cols := mysql.QueryColumns("SHOW SCHEMAS")
    if len(cols) == 0 {
        panic("Can't show schemas")
    }
    receivers := make([]interface{}, len(cols))
    data := make([]string, len(receivers))
    for i := 0; i < len(receivers); i++ {
        receivers[i] = &data[i]
    }
    fmt.Println(strings.Join(cols, "\t|\t"))
    fmt.Println("=====================================")
    for mysql.ScanNext(receivers...) {
        fmt.Println(strings.Join(data, "\t|\t"))
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment