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/georgysavva/scany/v2/dbscan package. pgxscan connects github.com/jackc/pgx/v5 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/georgysavva/scany/v2/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 Postgres specific types pgtype: https://pkg.go.dev/github.com/jackc/pgx/v5/pgtype In order to use them with pgxscan you must specify your pgtype 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 v2 only works with pgx v5. So the import path of your pgx must be: "github.com/jackc/pgx/v5".
Index ¶
- Variables
- func Get(ctx context.Context, db Querier, dst interface{}, query string, ...) error
- func NewDBScanAPI(opts ...dbscan.APIOption) (*dbscan.API, error)
- func NotFound(err error) bool
- func ScanAll(dst interface{}, rows pgx.Rows) error
- func ScanOne(dst interface{}, rows pgx.Rows) error
- func ScanRow(dst interface{}, rows pgx.Rows) error
- func Select(ctx context.Context, db Querier, dst interface{}, query string, ...) error
- type API
- func (api *API) Get(ctx context.Context, db Querier, dst interface{}, query string, ...) error
- func (api *API) NewRowScanner(rows pgx.Rows) *RowScanner
- func (api *API) ScanAll(dst interface{}, rows pgx.Rows) error
- func (api *API) ScanOne(dst interface{}, rows pgx.Rows) error
- func (api *API) ScanRow(dst interface{}, rows pgx.Rows) error
- func (api *API) Select(ctx context.Context, db Querier, dst interface{}, query string, ...) error
- type Querier
- type RowScanner
- type RowsAdapter
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultAPI = mustNewAPI(mustNewDBScanAPI())
DefaultAPI is the default instance of API with all configuration settings set to default.
Functions ¶
func Get ¶
Get is a package-level helper function that uses the DefaultAPI object. See API.Get for details.
Example ¶
type User struct { ID string `db:"user_id"` FullName string Email string Age int } db, _ := pgxpool.New(ctx, "example-connection-url") var user User if err := pgxscan.Get( ctx, db, &user, `SELECT user_id, full_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 NewDBScanAPI ¶
NewDBScanAPI creates a new dbscan API object with default configuration settings for pgxscan.
func ScanAll ¶
func ScanAll(dst interface{}, rows pgx.Rows) error
ScanAll is a package-level helper function that uses the DefaultAPI object. See API.ScanAll for details.
Example ¶
type User struct { ID string `db:"user_id"` FullName string Email string Age int } // Query pgx.Rows from the database. db, _ := pgxpool.New(ctx, "example-connection-url") rows, _ := db.Query(ctx, `SELECT user_id, full_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 package-level helper function that uses the DefaultAPI object. See API.ScanOne for details.
Example ¶
type User struct { ID string `db:"user_id"` FullName string Email string Age int } // Query pgx.Rows from the database. db, _ := pgxpool.New(ctx, "example-connection-url") rows, _ := db.Query(ctx, `SELECT user_id, full_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 package-level helper function that uses the DefaultAPI object. See API.ScanRow for details.
Example ¶
type User struct { ID string `db:"user_id"` FullName string Email string Age int } // Query pgx.Rows from the database. db, _ := pgxpool.New(ctx, "example-connection-url") rows, _ := db.Query(ctx, `SELECT user_id, full_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 package-level helper function that uses the DefaultAPI object. See API.Select for details.
Example ¶
type User struct { ID string `db:"user_id"` FullName string Email string Age int } db, _ := pgxpool.New(ctx, "example-connection-url") var users []*User if err := pgxscan.Select( ctx, db, &users, `SELECT user_id, full_name, email, age FROM users`, ); err != nil { // Handle query or rows processing error. } // users variable now contains data from all rows.
Output:
Types ¶
type API ¶
type API struct {
// contains filtered or unexported fields
}
API is a wrapper around the dbscan.API type. See dbscan.API for details.
Example ¶
This example shows how to create and use a custom API instance to override default settings.
type User struct { ID string `database:"userid"` FullName string Email string Age int } // Instantiate a custom API with overridden settings. dbscanAPI, err := pgxscan.NewDBScanAPI( dbscan.WithFieldNameMapper(strings.ToLower), dbscan.WithStructTagKey("database"), ) if err != nil { // Handle dbscan API initialization error. } api, err := pgxscan.NewAPI(dbscanAPI) if err != nil { // Handle pgxscan API initialization error. } db, _ := pgxpool.New(ctx, "example-connection-url") var users []*User // Use the custom API instance to access pgxscan functionality. if err := api.Select( ctx, db, &users, `SELECT userid, fullname, email, age FROM users`, ); err != nil { // Handle query or rows processing error. } // users variable now contains data from all rows.
Output:
func (*API) Get ¶
func (api *API) 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.
func (*API) NewRowScanner ¶
func (api *API) NewRowScanner(rows pgx.Rows) *RowScanner
NewRowScanner returns a new RowScanner instance.
func (*API) ScanAll ¶
ScanAll is a wrapper around the dbscan.ScanAll function. See dbscan.ScanAll for details.
func (*API) ScanOne ¶
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.
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"` FullName string Email string Age int } // Query pgx.Rows from the database. db, _ := pgxpool.New(ctx, "example-connection-url") rows, _ := db.Query(ctx, `SELECT user_id, full_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 is a package-level helper function that uses the DefaultAPI object. See API.NewRowScanner for details.
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.
func (RowsAdapter) NextResultSet ¶
func (ra RowsAdapter) NextResultSet() bool
NextResultSet is currently always returning false.