Documentation ¶
Index ¶
- Variables
- func Fields(v any) []string
- func Flags(cfg *config.Config) []cli.Flag
- func GetColumnToFieldIndexMap(structType reflect.Type) map[string][]int
- func ParseError(err error) error
- func RegisterConstraint(name, message string)
- func Wildcard(v any) string
- type BatchNode
- type Batcher
- type BatcherResults
- type Database
- type Node
- type SqlNode
- func (n *SqlNode) Addr() string
- func (n *SqlNode) Batch() BatchNode
- func (n *SqlNode) Close()
- func (n *SqlNode) CompareState(state State) bool
- func (n *SqlNode) Exec(ctx context.Context, query string, args ...any) error
- func (n *SqlNode) Get(ctx context.Context, dest interface{}, query string, args ...any) error
- func (n *SqlNode) Select(ctx context.Context, dest interface{}, query string, args ...any) error
- func (n *SqlNode) SetState(state State)
- func (n *SqlNode) State() State
- func (n *SqlNode) Stdlib() *sql.DB
- func (n *SqlNode) String() string
- type State
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrInternal = werror.Internal("internal server error", werror.WithID("dbsql.internal")) ErrNoRows = werror.NotFound("entity does not exists or you do not have enough permissions to perform the operation", werror.WithID("dbsql.query.no_rows")) ErrUniqueViolation = werror.Aborted("invalid input: entity already exists", werror.WithID("dbsql.unique_violation")) ErrForeignKeyViolation = werror.Aborted("invalid input: violates foreign key constraint", werror.WithID("dbsql.foreign_key_violation")) ErrCheckViolation = werror.Aborted("invalid input: violates check constraint", werror.WithID("dbsql.check_violation")) ErrNotNullViolation = werror.Aborted("invalid input: violates not null constraint: column can not be null", werror.WithID("dbsql.not_null_violation")) ErrEntityConflict = werror.Aborted("invalid input: found more then one requested entity", werror.WithID("dbsql.conflict")) )
Functions ¶
func Fields ¶
Fields returns column names for a SQL table that can be queried by a given Go struct. Only use this function to list fields on a struct.
To avoid ambiguity issues, it's important to use the Wildcard function instead of calling strings.Join(pgtools.Field(v), ", ") to generate the query expression.
Example ¶
fmt.Println(strings.Join(Fields(User{}), "\n"))
Output: username full_name email id theme
func GetColumnToFieldIndexMap ¶
GetColumnToFieldIndexMap containing where columns should be mapped.
func ParseError ¶
func RegisterConstraint ¶
func RegisterConstraint(name, message string)
RegisterConstraint register custom database check constraint (like "CHECK balance > 0"). Postgres doesn't define a very useful message for constraint failures (new row for relation "accounts" violates check constraint), so you can define your own.
- name - should be the name of the constraint in the database.
- message - your own custom error message
Panics if you attempt to register two constraints with the same name.
func Wildcard ¶
Wildcard returns an expression that can be used for querying a SQL database.
To make usage simpler in the happy path, Wildcard doesn't return an error. However, this means you should check if the value generated by the function is valid (panic is not used as it would introduce unwanted risk).
The "db" key in the struct field's tag can specify the "json" option when a JSON or JSONB data type is used in PostgreSQL.
It is useful to ensure scany works after adding a field to the database, and for performance reasons too by reducing the number of places where a wildcard (*) is used for convenience in SELECT queries.
Doing this "in the other direction", see https://github.com/golang/pkgsite/blob/2d3ade3c90634f9afed7aa772e53a62bb433447a/internal/database/reflect.go#L20-L46
Example ¶
sql := "SELECT " + Wildcard(User{}) + " WHERE id = $1" fmt.Println(sql)
Output: SELECT "username","full_name","email","id","theme" WHERE id = $1
Types ¶
type BatcherResults ¶
type BatcherResults interface { // Query reads the results from the next query in the batch // as if the query has been sent with Conn.Query. Query() (scanner.Rows, error) // Exec reads the results from the next query in the batch // as if the query has been sent with Conn.Exec. Exec() error // Close closes the batch operation, must be called before the underlying connection // can be used again. Any error that occurred during a batch operation may have made // it impossible to resyncronize the connection with the server. // In this case the underlying connection will have been closed. // Close is safe to call multiple times. If it returns an error subsequent calls // will return the same error. Callback functions will not be rerun Close() error }
type Database ¶
type Database interface { Exec(ctx context.Context, query string, args ...any) (int64, error) Query(ctx context.Context, query string, args ...any) (scanner.Rows, error) Batch() Batcher Stdlib() *sql.DB Close() }
Database is an abstract database interface that can execute queries. This is used to decouple from any particular database library.
type Node ¶
type Node interface { Addr() string State() State SetState(state State) CompareState(state State) bool Close() Stdlib() *sql.DB Select(ctx context.Context, dest interface{}, query string, args ...any) error Get(ctx context.Context, dest interface{}, query string, args ...any) error Exec(ctx context.Context, query string, args ...any) error Batch() BatchNode }
Node of single Cluster