pgxscan

package
v1.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2020 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package pgxscan allows scanning data into Go structs and other composite types, when working with pgx library native interface.

Essentially, pgxscan is a wrapper around github.com/KirksFletcher/dbscan package. pgxscan connects github.com/jackc/pgx/v4 native interface with dbscan functionality. It contains adapters that are meant to work with pgx.Rows and proxy all calls to dbscan. pgxscan provides all capabilities available in dbscan. It's encouraged to read dbscan docs first to get familiar with all concepts and features: https://pkg.go.dev/github.com/KirksFletcher/dbscan

Querying rows

pgxscan can query rows and work with *pgxpool.Pool, *pgx.Conn or pgx.Tx directly. To support this it has two high-level functions Select and Get, they accept anything that implements Querier interface and query rows from it. This means that they can be used with *pgxpool.Pool, *pgx.Conn or pgx.Tx.

Note about pgx custom types

pgx has a concept of custom types: https://pkg.go.dev/github.com/jackc/pgx/v4?tab=doc#hdr-Custom_Type_Support.

In order to use them with pgxscan you must specify your custom types by value, not by a pointer. Let's take the pgx custom type pgtype.Text as an example:

type User struct {
	ID   string
	Name *pgtype.Text // pgxscan won't be able to scan data into a field defined that way.
	Bio  pgtype.Text // This is a valid use of pgx custom types, pgxscan will handle it easily.
}

This happens because struct fields are always passed to the underlying pgx.Rows.Scan() by pointer, and if the field type is *pgtype.Text, pgx.Rows.Scan() will receive **pgtype.Text type. pgx can't handle **pgtype.Text, since only *pgtype.Text implements pgx custom type interface.

Supported pgx version

pgxscan only works with pgx v4. So the import path of your pgx must be: "github.com/jackc/pgx/v4".

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Get

func Get(ctx context.Context, db Querier, dst interface{}, query string, args ...interface{}) error

Get is a high-level function that queries rows from Querier and calls the ScanOne function. See ScanOne for details.

Example
type User struct {
	ID    string `db:"user_id"`
	Name  string
	Email string
	Age   int
}

db, _ := pgxpool.Connect(ctx, "example-connection-url")

var user User
if err := pgxscan.Get(
	ctx, db, &user, `SELECT user_id, name, email, age FROM users WHERE user_id='bob'`,
); err != nil {
	// Handle query or rows processing error.
}
// user variable now contains data from all rows.
Output:

func Insert added in v1.0.1

func Insert(ctx context.Context, db Querier, data interface{}, table string, additionalQuery string) error

Basic Insert function to allow for inserting structs

func NotFound

func NotFound(err error) bool

NotFound is a helper function to check if an error is `pgx.ErrNoRows`.

func ScanAll

func ScanAll(dst interface{}, rows pgx.Rows) error

ScanAll is a wrapper around the dbscan.ScanAll function. See dbscan.ScanAll for details.

Example
type User struct {
	ID    string `db:"user_id"`
	Name  string
	Email string
	Age   int
}

// 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`)

var users []*User
if err := pgxscan.ScanAll(&users, rows); err != nil {
	// Handle rows processing error.
}
// users variable now contains data from all rows.
Output:

func ScanOne

func ScanOne(dst interface{}, rows pgx.Rows) error

ScanOne is a wrapper around the dbscan.ScanOne function. See dbscan.ScanOne for details. If no rows are found it returns a pgx.ErrNoRows error.

Example
type User struct {
	ID    string `db:"user_id"`
	Name  string
	Email string
	Age   int
}

// 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 WHERE user_id='bob'`)

var user User
if err := pgxscan.ScanOne(&user, rows); err != nil {
	// Handle rows processing error.
}
// user variable now contains data from the single row.
Output:

func ScanRow

func ScanRow(dst interface{}, rows pgx.Rows) error

ScanRow is a wrapper around the dbscan.ScanRow function. See dbscan.ScanRow for details.

Example
type User struct {
	ID    string `db:"user_id"`
	Name  string
	Email string
	Age   int
}

// 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`)
defer rows.Close()
for rows.Next() {

	var user User
	if err := pgxscan.ScanRow(&user, rows); err != nil {
		// Handle row scanning error.
	}
	// user variable now contains data from the current row.

}
if err := rows.Err(); err != nil {
	// Handle rows final error.
}
Output:

func Select

func Select(ctx context.Context, db Querier, dst interface{}, query string, args ...interface{}) error

Select is a high-level function that queries rows from Querier and calls the ScanAll function. See ScanAll for details.

Example
type User struct {
	ID    string `db:"user_id"`
	Name  string
	Email string
	Age   int
}

db, _ := pgxpool.Connect(ctx, "example-connection-url")

var users []*User
if err := pgxscan.Select(
	ctx, db, &users, `SELECT user_id, name, email, age FROM users`,
); err != nil {
	// Handle query or rows processing error.
}
// users variable now contains data from all rows.
Output:

Types

type Querier

type Querier interface {
	Query(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error)
}

Querier is something that pgxscan can query and get the pgx.Rows from. For example, it can be: *pgxpool.Pool, *pgx.Conn or pgx.Tx.

type RowScanner

type RowScanner struct {
	*dbscan.RowScanner
}

RowScanner is a wrapper around the dbscan.RowScanner type. See dbscan.RowScanner for details.

Example
type User struct {
	ID    string `db:"user_id"`
	Name  string
	Email string
	Age   int
}

// 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`)
defer rows.Close()

rs := pgxscan.NewRowScanner(rows)

for rows.Next() {

	var user User
	if err := rs.Scan(&user); err != nil {
		// Handle row scanning error.
	}
	// user variable now contains data from the current row.

}
if err := rows.Err(); err != nil {
	// Handle rows final error.
}
Output:

func NewRowScanner

func NewRowScanner(rows pgx.Rows) *RowScanner

NewRowScanner returns a new RowScanner instance.

type RowsAdapter

type RowsAdapter struct {
	pgx.Rows
}

RowsAdapter makes pgx.Rows compliant with the dbscan.Rows interface. See dbscan.Rows for details.

func NewRowsAdapter

func NewRowsAdapter(rows pgx.Rows) *RowsAdapter

NewRowsAdapter returns a new RowsAdapter instance.

func (RowsAdapter) Close

func (ra RowsAdapter) Close() error

Close implements the dbscan.Rows.Close method.

func (RowsAdapter) Columns

func (ra RowsAdapter) Columns() ([]string, error)

Columns implements the dbscan.Rows.Columns method.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL