chore: ⬆️ updated deps
This commit is contained in:
+83
-15
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
)
|
||||
|
||||
// QueuedQuery is a query that has been queued for execution via a Batch.
|
||||
// QueuedQuery is a query that has been queued for execution via a [Batch].
|
||||
type QueuedQuery struct {
|
||||
SQL string
|
||||
Arguments []any
|
||||
@@ -46,7 +46,7 @@ func (qq *QueuedQuery) QueryRow(fn func(row Row) error) {
|
||||
//
|
||||
// Note: for simple batch insert uses where it is not required to handle
|
||||
// each potential error individually, it's sufficient to not set any callbacks,
|
||||
// and just handle the return value of BatchResults.Close.
|
||||
// and just handle the return value of [BatchResults.Close].
|
||||
func (qq *QueuedQuery) Exec(fn func(ct pgconn.CommandTag) error) {
|
||||
qq.Fn = func(br BatchResults) error {
|
||||
ct, err := br.Exec()
|
||||
@@ -65,12 +65,13 @@ type Batch struct {
|
||||
}
|
||||
|
||||
// Queue queues a query to batch b. query can be an SQL query or the name of a prepared statement. The only pgx option
|
||||
// argument that is supported is QueryRewriter. Queries are executed using the connection's DefaultQueryExecMode.
|
||||
// argument that is supported is [QueryRewriter]. Queries are executed using the connection's DefaultQueryExecMode
|
||||
// (see [ConnConfig.DefaultQueryExecMode]).
|
||||
//
|
||||
// While query can contain multiple statements if the connection's DefaultQueryExecMode is QueryModeSimple, this should
|
||||
// be avoided. QueuedQuery.Fn must not be set as it will only be called for the first query. That is, QueuedQuery.Query,
|
||||
// QueuedQuery.QueryRow, and QueuedQuery.Exec must not be called. In addition, any error messages or tracing that
|
||||
// include the current query may reference the wrong query.
|
||||
// While query can contain multiple statements if the connection's DefaultQueryExecMode is [QueryExecModeSimpleProtocol],
|
||||
// this should be avoided. QueuedQuery.Fn must not be set as it will only be called for the first query. That is,
|
||||
// [QueuedQuery.Query], [QueuedQuery.QueryRow], and [QueuedQuery.Exec] must not be called. In addition, any error
|
||||
// messages or tracing that include the current query may reference the wrong query.
|
||||
func (b *Batch) Queue(query string, arguments ...any) *QueuedQuery {
|
||||
qq := &QueuedQuery{
|
||||
SQL: query,
|
||||
@@ -86,20 +87,20 @@ func (b *Batch) Len() int {
|
||||
}
|
||||
|
||||
type BatchResults interface {
|
||||
// Exec reads the results from the next query in the batch as if the query has been sent with Conn.Exec. Prefer
|
||||
// Exec reads the results from the next query in the batch as if the query has been sent with [Conn.Exec]. Prefer
|
||||
// calling Exec on the QueuedQuery, or just calling Close.
|
||||
Exec() (pgconn.CommandTag, error)
|
||||
|
||||
// Query reads the results from the next query in the batch as if the query has been sent with Conn.Query. Prefer
|
||||
// calling Query on the QueuedQuery.
|
||||
// Query reads the results from the next query in the batch as if the query has been sent with [Conn.Query]. Prefer
|
||||
// calling [QueuedQuery.Query].
|
||||
Query() (Rows, error)
|
||||
|
||||
// QueryRow reads the results from the next query in the batch as if the query has been sent with Conn.QueryRow.
|
||||
// Prefer calling QueryRow on the QueuedQuery.
|
||||
// QueryRow reads the results from the next query in the batch as if the query has been sent with [Conn.QueryRow].
|
||||
// Prefer calling [QueuedQuery.QueryRow].
|
||||
QueryRow() Row
|
||||
|
||||
// Close closes the batch operation. All unread results are read and any callback functions registered with
|
||||
// QueuedQuery.Query, QueuedQuery.QueryRow, or QueuedQuery.Exec will be called. If a callback function returns an
|
||||
// [QueuedQuery.Query], [QueuedQuery.QueryRow], or [QueuedQuery.Exec] will be called. If a callback function returns an
|
||||
// error or the batch encounters an error subsequent callback functions will not be called.
|
||||
//
|
||||
// For simple batch inserts inside a transaction or similar queries, it's sufficient to not set any callbacks,
|
||||
@@ -272,7 +273,7 @@ func (br *batchResults) nextQueryAndArgs() (query string, args []any, ok bool) {
|
||||
ok = true
|
||||
br.qqIdx++
|
||||
}
|
||||
return
|
||||
return query, args, ok
|
||||
}
|
||||
|
||||
type pipelineBatchResults struct {
|
||||
@@ -296,6 +297,7 @@ func (br *pipelineBatchResults) Exec() (pgconn.CommandTag, error) {
|
||||
return pgconn.CommandTag{}, fmt.Errorf("batch already closed")
|
||||
}
|
||||
if br.lastRows != nil && br.lastRows.err != nil {
|
||||
br.err = br.lastRows.err
|
||||
return pgconn.CommandTag{}, br.err
|
||||
}
|
||||
|
||||
@@ -404,7 +406,6 @@ func (br *pipelineBatchResults) Close() error {
|
||||
|
||||
if br.err == nil && br.lastRows != nil && br.lastRows.err != nil {
|
||||
br.err = br.lastRows.err
|
||||
return br.err
|
||||
}
|
||||
|
||||
if br.closed {
|
||||
@@ -451,6 +452,45 @@ func (br *pipelineBatchResults) nextQueryAndArgs() (query string, args []any, er
|
||||
return bi.SQL, bi.Arguments, nil
|
||||
}
|
||||
|
||||
type emptyBatchResults struct {
|
||||
conn *Conn
|
||||
closed bool
|
||||
}
|
||||
|
||||
// Exec reads the results from the next query in the batch as if the query has been sent with Exec.
|
||||
func (br *emptyBatchResults) Exec() (pgconn.CommandTag, error) {
|
||||
if br.closed {
|
||||
return pgconn.CommandTag{}, fmt.Errorf("batch already closed")
|
||||
}
|
||||
return pgconn.CommandTag{}, errors.New("no more results in batch")
|
||||
}
|
||||
|
||||
// Query reads the results from the next query in the batch as if the query has been sent with Query.
|
||||
func (br *emptyBatchResults) Query() (Rows, error) {
|
||||
if br.closed {
|
||||
alreadyClosedErr := fmt.Errorf("batch already closed")
|
||||
return &baseRows{err: alreadyClosedErr, closed: true}, alreadyClosedErr
|
||||
}
|
||||
|
||||
rows := br.conn.getRows(context.Background(), "", nil)
|
||||
rows.err = errors.New("no more results in batch")
|
||||
rows.closed = true
|
||||
return rows, rows.err
|
||||
}
|
||||
|
||||
// QueryRow reads the results from the next query in the batch as if the query has been sent with QueryRow.
|
||||
func (br *emptyBatchResults) QueryRow() Row {
|
||||
rows, _ := br.Query()
|
||||
return (*connRow)(rows.(*baseRows))
|
||||
}
|
||||
|
||||
// Close closes the batch operation. 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.
|
||||
func (br *emptyBatchResults) Close() error {
|
||||
br.closed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// invalidates statement and description caches on batch results error
|
||||
func invalidateCachesOnBatchResultsError(conn *Conn, b *Batch, err error) {
|
||||
if err != nil && conn != nil && b != nil {
|
||||
@@ -467,3 +507,31 @@ func invalidateCachesOnBatchResultsError(conn *Conn, b *Batch, err error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ErrPreprocessingBatch occurs when an error is encountered while preprocessing a batch.
|
||||
// The two preprocessing steps are "prepare" (server-side SQL parse/plan) and
|
||||
// "build" (client-side argument encoding).
|
||||
type ErrPreprocessingBatch struct {
|
||||
step string // "prepare" or "build"
|
||||
sql string
|
||||
err error
|
||||
}
|
||||
|
||||
func newErrPreprocessingBatch(step, sql string, err error) ErrPreprocessingBatch {
|
||||
return ErrPreprocessingBatch{step: step, sql: sql, err: err}
|
||||
}
|
||||
|
||||
func (e ErrPreprocessingBatch) Error() string {
|
||||
// intentionally not including the SQL query in the error message
|
||||
// to avoid leaking potentially sensitive information into logs.
|
||||
// If the user wants the SQL, they can call SQL().
|
||||
return fmt.Sprintf("error preprocessing batch (%s): %v", e.step, e.err)
|
||||
}
|
||||
|
||||
func (e ErrPreprocessingBatch) Unwrap() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
func (e ErrPreprocessingBatch) SQL() string {
|
||||
return e.sql
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user