Skip to content

Commit

Permalink
Improve dbscan.ScanAll comment.
Browse files Browse the repository at this point in the history
  • Loading branch information
georgysavva committed Jun 28, 2020
1 parent 28b66d9 commit fa97c22
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 21 deletions.
16 changes: 9 additions & 7 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
// Package dbscan allows scanning data from database rows into complex Go types.
/*
dbscan works with abstract `Rows` and doesn't depend on any specific database or library.
dbscan works with abstract Rows and doesn't depend on any specific database or library.
If a type implements Rows interface it can leverage full functional of this package.
Subpackages sqlscan and pgxscan are wrappers around this package
they contain functions and adapters tailored to database/sql and
github.com/jackc/pgx/v4 libraries correspondingly. sqlscan and pgxscan proxy all calls to dbscan internally.
dbscan does all the logic, but generally, it shouldn't be imported by the application code directly.
If you are working with database/sql - use sqlscan subpackage.
If you are working with pgx - use pgxscan subpackage.
Scanning into struct
dbscan provides ability to scan row data into struct.
The main feature of dbscan is ability to scan row data into struct.
type User struct {
ID string `db:"user_id"`
Expand All @@ -27,7 +29,7 @@ dbscan provides ability to scan row data into struct.
By default, to get the corresponding column dbscan translates field name to snake case.
In order to override this behaviour, specify column name in the `db` field tag.
In the example above `User` struct is mapped to the following columns: "user_id", "first_name", "email".
In the example above User struct is mapped to the following columns: "user_id", "first_name", "email".
Struct can contain embedded structs as well. It allows to reuse models in different queries.
Note that non-embedded structs aren't allowed, this decision was made due to simplicity.
Expand Down Expand Up @@ -73,25 +75,25 @@ dbscan won't be able to make the chose to which field to assign and return an er
Post
}
`Row` struct is invalid since both User.ID and Post.ID are mapped to the "id" column.
Row struct is invalid since both User.ID and Post.ID are mapped to the "id" column.
Other destination types
Scanning into map
Apart from scanning into structs, dbscan can handle maps,
in that case it uses column name as the map key and column data as the map value. For example:
var results []map[string]interface{}
if err := dbscan.ScanAll(&result, rows); err != nil {
// Handle rows processing error
}
// results variable now contains data from the row.
Note that map type isn't limited to map[string]interface{},
it can be any map with string key, e.g. map[string]string or map[string]int,
if all column values have the same specific type.
Scanning into other types
If the destination isn't a struct nor a map, dbscan handles it as single column scan,
it ensures that rows contain exactly one column and scans destination from the column, for example:
Expand Down
12 changes: 6 additions & 6 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"github.com/georgysavva/dbscan"
)

var rows dbscan.Rows

func ExampleScanAll() {
type User struct {
ID string
Expand All @@ -15,6 +13,7 @@ func ExampleScanAll() {
}

// Query rows from the database that implement dbscan.Rows interface.
var rows dbscan.Rows

var users []*User
if err := dbscan.ScanAll(&users, rows); err != nil {
Expand All @@ -32,6 +31,7 @@ func ExampleScanOne() {
}

// Query rows from the database that implement dbscan.Rows interface.
var rows dbscan.Rows

var user User
if err := dbscan.ScanOne(&user, rows); err != nil {
Expand All @@ -49,10 +49,10 @@ func ExampleRowScanner() {
}

// Query rows from the database that implement dbscan.Rows interface.
var rows dbscan.Rows

// Make sure rows are closed.
// Make sure rows are always closed.
defer rows.Close()

rs := dbscan.NewRowScanner(rows)
for rows.Next() {
var user User
Expand All @@ -78,10 +78,10 @@ func ExampleRowScan() {
}

// Query rows from the database that implement dbscan.Rows interface.
var rows dbscan.Rows

// Make sure rows are closed.
// Make sure rows are always closed.
defer rows.Close()

for rows.Next() {
var user User
if err := dbscan.ScanRow(&user, rows); err != nil {
Expand Down
8 changes: 4 additions & 4 deletions pgxscan/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ func ExampleRowScanner() {
// Query pgx.Rows from the database.
db, _ := pgxpool.Connect(ctx, "example-connection-url")
rows, _ := db.Query(ctx, `SELECT user_id, name, email, age from users`)
// Make sure rows are closed.
defer rows.Close()

// Make sure rows are always closed.
defer rows.Close()
rs := pgxscan.NewRowScanner(rows)
for rows.Next() {
var user User
Expand All @@ -119,9 +119,9 @@ func ExampleRowScan() {
// Query pgx.Rows from the database.
db, _ := pgxpool.Connect(ctx, "example-connection-url")
rows, _ := db.Query(ctx, `SELECT user_id, name, email, age from users`)
// Make sure rows are closed.
defer rows.Close()

// Make sure rows are always closed.
defer rows.Close()
for rows.Next() {
var user User
if err := pgxscan.ScanRow(&user, rows); err != nil {
Expand Down
8 changes: 4 additions & 4 deletions sqlscan/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ func ExampleRowScanner() {
// Query *sql.Rows from the database.
db, _ := sql.Open("pgx", "example-connection-url")
rows, _ := db.Query(`SELECT user_id, name, email, age from users`)
// Make sure rows are closed.
defer rows.Close()

// Make sure rows are always closed.
defer rows.Close()
rs := sqlscan.NewRowScanner(rows)
for rows.Next() {
var user User
Expand Down Expand Up @@ -123,9 +123,9 @@ func ExampleRowScan() {
// Query *sql.Rows from the database.
db, _ := sql.Open("pgx", "example-connection-url")
rows, _ := db.Query(`SELECT user_id, name, email, age from users`)
// Make sure rows are closed.
defer rows.Close()

// Make sure rows are always closed.
defer rows.Close()
for rows.Next() {
var user User
if err := sqlscan.ScanRow(&user, rows); err != nil {
Expand Down

0 comments on commit fa97c22

Please sign in to comment.