Documentation ¶
Overview ¶
Package scan provides functionality for scanning database/sql rows into slices, structs, and primitive types dynamically
Index ¶
- Variables
- func Columns(v interface{}, excluded ...string) []string
- func ColumnsStrict(v interface{}, excluded ...string) []string
- func Row(v interface{}, rows RowsScanner) error
- func Rows(v interface{}, rows RowsScanner) error
- func Values(cols []string, v interface{}) []interface{}
- type RowsScanner
- type Scanner
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"]
func Values ¶ added in v1.2.0
func Values(cols []string, v interface{}) []interface{}
Values scans a struct and returns the values associated with the columns provided.
Example:
var cols = scan.Columns(&models.User{}) func insertUser(u *models.User) { vals := scan.Values(cols, u) sq.Insert("users"). Columns(cols). Values(vals). RunWith(db).ExecContext(ctx) }
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