Documentation
¶
Overview ¶
Package scan provides functionality for scanning database/sql rows into slices, structs, and primitive types dynamically
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrTooManyColumns indicates that a select query returned multiple columns and // attempted to bind to a slice of a primitive type. For example, trying to bind // `select col1, col2 from mytable` to []string ErrTooManyColumns = errors.New("too many columns returned for primitive slice") // ErrSliceForRow occurs when trying to use Row on a slice ErrSliceForRow = errors.New("cannot scan Row into slice") // AutoClose is true when scan should automatically close Scanner when the scan // is complete. If you set it to false, then you must defer rows.Close() manually AutoClose = true )
Functions ¶
func Columns ¶ added in v1.1.0
Columns scans a struct and returns a list of strings that represent the assumed column names based on the db struct tag, or the field name. Any field or struct tag that matches a string within the excluded list will be excluded from the result
func ColumnsStrict ¶ added in v1.1.0
ColumnsStrict is identical to Columns, but it only searches struct tags and excludes fields not tagged with the db struct tag
func Row ¶
func Row(v interface{}, rows RowsScanner) error
Row scans a single row into a single variable
Example ¶
package main
import (
"database/sql"
"encoding/json"
"os"
"github.com/blockloop/scan"
_ "github.com/mattn/go-sqlite3"
)
func openDB() *sql.DB {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
_, err = db.Exec(`CREATE TABLE persons (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(120) NOT NULL DEFAULT ''
);
INSERT INTO PERSONS (name)
VALUES ('brett'), ('fred');`)
if err != nil {
panic(err)
}
return db
}
func main() {
db := openDB()
rows, err := db.Query("SELECT * FROM persons LIMIT 1")
if err != nil {
panic(err)
}
var person struct {
ID int `db:"id"`
Name string `db:"name"`
}
err = scan.Row(&person, rows)
if err != nil {
panic(err)
}
json.NewEncoder(os.Stdout).Encode(&person)
}
Output: {"ID":1,"Name":"brett"}
Example (Scalar) ¶
package main
import (
"database/sql"
"fmt"
"github.com/blockloop/scan"
_ "github.com/mattn/go-sqlite3"
)
func openDB() *sql.DB {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
_, err = db.Exec(`CREATE TABLE persons (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(120) NOT NULL DEFAULT ''
);
INSERT INTO PERSONS (name)
VALUES ('brett'), ('fred');`)
if err != nil {
panic(err)
}
return db
}
func main() {
db := openDB()
rows, err := db.Query("SELECT name FROM persons LIMIT 1")
if err != nil {
panic(err)
}
var name string
err = scan.Row(&name, rows)
if err != nil {
panic(err)
}
fmt.Printf("%q", name)
}
Output: "brett"
func Rows ¶
func Rows(v interface{}, rows RowsScanner) error
Rows scans sql rows into a slice (v)
Example ¶
package main
import (
"database/sql"
"encoding/json"
"os"
"github.com/blockloop/scan"
_ "github.com/mattn/go-sqlite3"
)
func openDB() *sql.DB {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
_, err = db.Exec(`CREATE TABLE persons (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(120) NOT NULL DEFAULT ''
);
INSERT INTO PERSONS (name)
VALUES ('brett'), ('fred');`)
if err != nil {
panic(err)
}
return db
}
func main() {
db := openDB()
rows, err := db.Query("SELECT * FROM persons ORDER BY name")
if err != nil {
panic(err)
}
var persons []struct {
ID int `db:"id"`
Name string `db:"name"`
}
err = scan.Rows(&persons, rows)
if err != nil {
panic(err)
}
json.NewEncoder(os.Stdout).Encode(&persons)
}
Output: [{"ID":1,"Name":"brett"},{"ID":2,"Name":"fred"}]
Example (Primitive) ¶
package main
import (
"database/sql"
"encoding/json"
"os"
"github.com/blockloop/scan"
_ "github.com/mattn/go-sqlite3"
)
func openDB() *sql.DB {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
_, err = db.Exec(`CREATE TABLE persons (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(120) NOT NULL DEFAULT ''
);
INSERT INTO PERSONS (name)
VALUES ('brett'), ('fred');`)
if err != nil {
panic(err)
}
return db
}
func main() {
db := openDB()
rows, err := db.Query("SELECT name FROM persons ORDER BY name")
if err != nil {
panic(err)
}
var names []string
err = scan.Rows(&names, rows)
if err != nil {
panic(err)
}
json.NewEncoder(os.Stdout).Encode(&names)
}
Output: ["brett","fred"]
Types ¶
type RowsScanner ¶
type RowsScanner interface {
Close() error
Scan(dest ...interface{}) error
Columns() ([]string, error)
ColumnTypes() ([]*sql.ColumnType, error)
Err() error
Next() bool
NextResultSet() bool
}
RowsScanner is a database scanner for many rows. It is most commonly the result of *(database/sql).DB.Query(...) but can be mocked or stubbed