# postgres.connection

> A module of postgres's API.

`postgres.connection` — the connection, its statements and its transactions.

`Connection` is the way in to one libpq `PGconn`.  Everything a caller does
with a database goes through it: `Connection.execute`
for commands, `Connection.query` for rows, `Connection.prepare` for a
server-side statement to run more than once, `Connection.begin` for a
transaction, and `Connection.copy_in`/`Connection.copy_out` for bulk transfer
(the handles those return live in `postgres.copy`).

Values are never interpolated into SQL.  Write ``$1``, ``$2``, ... and pass a
`Params`; libpq sends the values out of band, so there is nothing to escape and
no injection surface:

```mojo
from postgres import Connection, Params

var conn = Connection("postgresql://localhost/app?connect_timeout=5")
_ = conn.execute("CREATE TABLE t (id bigint primary key, name text)")
_ = conn.execute("INSERT INTO t VALUES ($1, $2)",
                 Params().int64(1).text("Alice"))

var res = conn.query("SELECT id, name FROM t WHERE id = $1", Params().int64(1))
for row in res:
    print(row.int64("id"), row.text("name"))
```

**Errors carry their SQLSTATE.**  Every failure the server reports is raised as
a `PostgresError` formatted by `sqlstate.PostgresError.format` --
``postgres [SQLSTATE 23505] duplicate key value ...`` -- so a `try`/`except`
that only has an `Error` in hand can still branch on `sqlstate.sqlstate_of`.
The structured value is also kept in `Connection.last_error`, where the
`is_unique_violation`-style predicates are available without any parsing.

**Transactions are explicit.**  `Connection.begin` issues ``BEGIN`` and hands
back a `Transaction` that rolls itself back if it is destroyed without a
`Transaction.commit` -- so an early return or a raised error cannot leave a
block half-applied:

```mojo
var tx = conn.begin()
_ = tx.execute("UPDATE accounts SET balance = balance - $1 WHERE id = $2",
               Params().numeric("10.00").int64(1))
tx.savepoint("maybe")
_ = tx.execute("INSERT INTO audit VALUES ($1)", Params().int64(1))
tx.commit()
```

**A handle keeps the session open.**  The `PGconn` is owned jointly by the
`Connection` and by every `Statement`, `Transaction`, `copy.CopyIn` and
`copy.CopyOut` made from it, and it is closed when the last of them is
destroyed.  That matters because Mojo destroys a value after its last *use*,
not at the end of the block, so this is the ordinary case rather than an
exotic one:

```mojo
var out = conn.copy_out("COPY t TO STDOUT")   # the last mention of `conn`,
for line in out.rows():                       # and the session is still up
    ...
```

`Connection.close` is the exception, and it is the point of having it: it ends
the session immediately, and every handle still holding the connection then
raises SQLSTATE ``08006`` rather than reaching a freed `PGconn`.

**One connection, one thread.**  libpq's `PGconn` is not safe to use from two
threads at once, and nothing here adds a lock.  Shared ownership is about
lifetime, not concurrency.

**Notices go to stderr.**  A ``NOTICE``/``WARNING`` the server raises -- from a
``RAISE NOTICE``, or from ``CREATE TABLE IF NOT EXISTS`` finding the table
already there -- is printed to standard error by libpq's default notice
processor.  This tin installs none of its own, so those messages are visible
but not capturable; a hook for them is not in v1.

## Structs

### `Statement`

```mojo
struct Statement
```

A statement prepared on the server, ready to run with new parameters.

Created by `Connection.prepare`.  Preparing pays for parsing and planning
once; each `Statement.execute` or `Statement.query` then sends only the
name and the parameter values.

A prepared statement is **session-local**: it lives on the connection it
was prepared on, until that connection closes or `Statement.deallocate`
runs.  Holding a `Statement` **keeps that connection open** -- it shares
ownership of the `PGconn` rather than borrowing it -- so a statement may
safely outlive the `Connection` value it came from, which matters because
Mojo destroys a value after its last *use*:

```mojo
var stmt = conn.prepare("s", "SELECT 1")   # the last mention of `conn`,
var res = stmt.query()                     # and the session is still up
```

An explicit `Connection.close` is the exception: it closes the session
there and then, and every statement on it raises SQLSTATE ``08006``
afterwards.

Example:

```mojo
var stmt = conn.prepare("insert_row", "INSERT INTO t VALUES ($1, $2)")
for i in range(1000):
    _ = stmt.execute(Params().int64(i).text("row"))
```

Note:
Errors raised through a `Statement` *are* recorded in
`Connection.last_error`: the statement holds a share of the same cell
the connection does.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self, cell: ArcPointer[_ConnCell], name: String, sql: String)
```

Record an already-prepared statement.

`Connection.prepare` is the only intended caller: it issues
`PQprepare` and checks the status before constructing this.

Args:

- `cell`: The shared cell of the connection it was prepared on; a
    share of it is kept, so the connection stays open at least as
    long as this statement does.
- `name`: The server-side statement name.
- `sql`: The SQL it was prepared from.

#### `name`

```mojo
def name(self) -> String
```

The server-side statement name.

#### `sql`

```mojo
def sql(self) -> String
```

The SQL this statement was prepared from.

#### `execute`

```mojo
def execute(self, params: Params = Params()) -> Int
```

Run the statement and discard any rows.

Args:

- `params`: The values for ``$1``, ``$2``, ....

Raises: Error: A `sqlstate.PostgresError` if the server rejected the
command.

#### `query`

```mojo
def query(self, params: Params = Params()) -> Result
```

Run the statement and return its rows.

Args:

- `params`: The values for ``$1``, ``$2``, ....

Raises: Error: A `sqlstate.PostgresError` if the server rejected the
command.

#### `deallocate`

```mojo
def deallocate(mut self)
```

Drop the statement from the server session.

Rarely needed -- closing the connection drops every statement it
prepared -- but a long-lived connection that prepares statements
dynamically will otherwise accumulate them.

Raises: Error: A `sqlstate.PostgresError` if ``DEALLOCATE`` failed, which
for an already-deallocated statement is SQLSTATE ``26000``.

### `Connection`

```mojo
struct Connection
```

One connection to a PostgreSQL server.

Opening blocks until the connection succeeds or fails.  **Set
``connect_timeout``** in the conninfo (or on the `ConnectionConfig`, where
it defaults to 10 seconds): without it, a host that silently drops packets
blocks for the operating system's TCP timeout, which can be minutes.

The connection is closed when the last thing holding it is destroyed --
the `Connection` and every `Statement`, `Transaction`, `copy.CopyIn` and
`copy.CopyOut` made from it share ownership of the `PGconn` -- or at once
by `Connection.close`, which invalidates all of them.  Not copyable: a
second `Connection` on one session is what a handle is for.

Example:

```mojo
var conn = Connection("postgresql://user@localhost/app?connect_timeout=5")
var n = conn.execute("DELETE FROM sessions WHERE expires < now()")
print(n, "sessions expired")
```

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self, conninfo: String)
```

Connect using a libpq conninfo string or URI.

Args:

- `conninfo`: Either a URI --
    ``postgresql://user:pass@host:5432/db?sslmode=require`` -- or
    a keyword string -- ``host=localhost dbname=app
    connect_timeout=5``.  libpq parses both through the same entry
    point, and an empty string means "everything from the
    environment" (``PGHOST``, ``PGDATABASE``, ...).

Raises: Error: A `sqlstate.PostgresError` with SQLSTATE
`sqlstate.SQLCLIENT_UNABLE_TO_ESTABLISH` (08001) if the
connection could not be established, carrying libpq's own
explanation.

```mojo
def __init__(out self, config: ConnectionConfig)
```

Connect using a typed `config.ConnectionConfig`.

Args:

- `config`: The connection parameters; rendered with
    `config.ConnectionConfig.to_conninfo`.

Raises: Error: A `sqlstate.PostgresError` with SQLSTATE 08001 if the
connection could not be established.

#### `__deinit__`

```mojo
def __deinit__(deinit self)
```

Drop this share of the connection.

The `PGconn` itself is closed by `_ConnCell`, when the last share of
it goes -- which is this one unless a `Statement`, a `Transaction` or
a COPY handle made from it is still alive, in which case the session
stays up for them.  `Connection.close` is how to end it now.

#### `close`

```mojo
def close(mut self)
```

Close the connection now, whatever else is still holding it. Idempotent.

Every `Result` already handed out stays valid -- their rows were
copied out of libpq's memory.  Everything that reaches the *server*
does not: a `Statement`, `Transaction`, `copy.CopyIn` or
`copy.CopyOut` made from this connection raises SQLSTATE ``08006``
from here on, rather than touching a freed handle.

#### `is_open`

```mojo
def is_open(self) -> Bool
```

Whether the connection is open and usable.

#### `is_alive`

```mojo
def is_alive(self) -> Bool
```

Whether the socket is still there, without asking the server.

Between `Connection.is_open`, which is free but blind, and
`Connection.ping`, which is honest but costs a round trip.  This one
reads whatever the server has *already* sent -- a non-blocking
`PQconsumeInput` -- and then asks `PQstatus`.  Nothing is sent, so
there is no round trip; but a peer that has gone away has sent
something (an ``ErrorResponse``, or just the close), and this is what
collects it.

The difference is not academic.  A backend killed with
``pg_terminate_backend``, a server restarted underneath a long-lived
client, a failover: `Connection.is_open` reports True through all of
them, because libpq's status is a cached opinion that only changes
when a command fails.  This reports False.

Note:
Cheap, not certain.  It cannot see a death whose notification has
not arrived yet, and it cannot see one that has not happened yet;
no local check can.  Use it to *avoid* handing out a connection
already known to be dead -- `pool.ConnectionPool` does exactly
that -- and keep handling the error from the next command anyway.

Only meaningful on an idle connection: mid-``COPY``, or with an
unread result outstanding, the bytes waiting on the socket belong
to whoever is driving that exchange.

#### `backend_pid`

```mojo
def backend_pid(self) -> Int
```

The process ID of the backend serving this connection.

Free -- it was read from the server's startup packet, and no round
trip is involved.  It is the value ``pg_terminate_backend`` takes, and
it changes across a `Connection.reset`, which makes it the way to tell
a recycled session from a reused one.

#### `reset`

```mojo
def reset(mut self) -> Bool
```

Reconnect in place: same handle, same parameters, new session.

Blocks for as long as opening would.  The `PGconn` pointer does not
change, so every `Statement`, `Transaction` and COPY handle sharing
this connection stays valid -- but what they are pointed at is a
*different session*: no prepared statements, no temp tables, no open
transaction, and a different `Connection.backend_pid`.  A `Statement`
that survives a reset will therefore fail with SQLSTATE ``26000``,
which is the honest answer.

`pool.ConnectionPool` uses this to recycle a connection whose backend
died, rather than paying for a fresh `PGconn`.

#### `ping`

```mojo
def ping(mut self) -> Bool
```

Whether the server answers a trivial query right now.

Stronger than `Connection.is_open`, which only reports libpq's cached
view: this actually goes to the server, so it notices a connection
that has died since the last command.

#### `server_version`

```mojo
def server_version(self) -> Int
```

The version of the server on the other end.

Raises: Error: Only if libpq itself could not be reached.

#### `transaction_status`

```mojo
def transaction_status(self) -> Int
```

Whether a transaction block is open on this connection.

Raises: Error: Only if libpq itself could not be reached.

#### `last_error`

```mojo
def last_error(self) -> PostgresError
```

The most recent error raised through this connection.

The structured form of what was raised, so the SQLSTATE predicates are
available without parsing the message back:

```mojo
try:
    _ = conn.execute("INSERT INTO t VALUES (1)")
except:
    if conn.last_error().is_unique_violation():
        ...
```

#### `execute`

```mojo
def execute(mut self, sql: String, params: Params = Params()) -> Int
```

Run a command and discard any rows it returned.

With no parameters this goes through `PQexec`, which accepts
**several statements separated by semicolons** -- handy for a schema
script, and the only reason to prefer it.  The return value is then
the last statement's count, and the first failure aborts the rest.
With parameters it goes through `PQexecParams`, which allows exactly
one statement.

Running a ``SELECT`` here is allowed: the rows are fetched and
dropped, and the count of them is returned.  Use `Connection.query` if
you want the rows themselves.

Args:

- `sql`: The statement text, with ``$1``-style placeholders if
    `params` is non-empty.
- `params`: The parameter values; empty by default.

Raises: Error: A `sqlstate.PostgresError` if the connection is closed or
the server rejected the command.  The SQLSTATE is recoverable
from the message with `sqlstate.sqlstate_of`, and the whole
structured error from `Connection.last_error`.

#### `query`

```mojo
def query(mut self, sql: String, params: Params = Params()) -> Result
```

Run a command and return its rows.

Args:

- `sql`: The statement text, with ``$1``-style placeholders if
    `params` is non-empty.  With parameters libpq allows exactly
    one statement.
- `params`: The parameter values; empty by default.

Raises: Error: A `sqlstate.PostgresError` if the connection is closed or
the server rejected the command.

#### `prepare`

```mojo
def prepare(mut self, name: String, sql: String) -> Statement
```

Prepare `sql` on the server under `name`.

Parameter types are left to the server to infer from the statement --
which is what you want in almost every case, and why there is no OID
argument.  Add a cast (``$1::int``) where the inference would
otherwise land on ``text``.

Args:

- `name`: The statement name.  ``""`` is libpq's unnamed statement,
    which the next `Connection.prepare` on this connection
    replaces.  Any other name persists until the session ends or
    `Statement.deallocate` runs, and re-preparing the same name
    is an error (SQLSTATE ``42P05``).
- `sql`: The statement text, with ``$1``, ``$2``, ... placeholders.

Raises: Error: A `sqlstate.PostgresError` if the statement did not parse
or the name is already taken.

#### `execute_prepared`

```mojo
def execute_prepared(mut self, name: String, params: Params = Params()) -> Int
```

Run the prepared statement `name` and discard any rows.

The method `Statement.execute` is a convenience over; use it directly
when the statement was prepared elsewhere -- by another library, or by
a ``PREPARE`` statement -- and there is no `Statement` value in hand.

Args:

- `name`: The server-side statement name.
- `params`: The values for ``$1``, ``$2``, ....

Raises: Error: A `sqlstate.PostgresError` if the connection is closed, no
such statement is prepared (SQLSTATE ``26000``), or the server
rejected the command.

#### `query_prepared`

```mojo
def query_prepared(mut self, name: String, params: Params = Params()) -> Result
```

Run the prepared statement `name` and return its rows.

Args:

- `name`: The server-side statement name.
- `params`: The values for ``$1``, ``$2``, ....

Raises: Error: A `sqlstate.PostgresError` if the connection is closed, no
such statement is prepared, or the server rejected the
command.

#### `begin`

```mojo
def begin(mut self) -> Transaction
```

Issue ``BEGIN`` and return the guard that ends the block.

The returned `Transaction` rolls back when it is destroyed unless
`Transaction.commit` or `Transaction.rollback` ran first, so the
failure mode of forgetting about it is "nothing happened" rather than
"half of it happened".  Statements inside the block go through the
`Transaction`'s own `Transaction.execute` and `Transaction.query`,
which are the same calls with the same error path.

Raises: Error: A `sqlstate.PostgresError` if the connection is closed, if
``BEGIN`` itself failed, or -- SQLSTATE ``25001`` -- if a
transaction block is **already** open on this connection.
PostgreSQL answers a nested ``BEGIN`` with a warning and
ignores it, which would leave the second guard's ``COMMIT``
ending the first one's block; raising is the only way to keep
the guard's promise.

#### `copy_in`

```mojo
def copy_in(mut self, sql: String) -> CopyIn
```

Start a ``COPY ... FROM STDIN`` and return the handle to write to.

The fast path for bulk loading: one statement, then rows streamed
straight into the table with no per-row parse, plan or round trip.
Encode the rows with `copyfmt.CopyEncoder` and hand them to
`copy.CopyIn.write_rows`, or write already-formatted bytes with
`copy.CopyIn.write`.

Args:

- `sql`: The full ``COPY`` statement, for example ``COPY t (a, b)
    FROM STDIN`` or ``COPY t FROM STDIN (FORMAT csv)``.  It takes
    no parameters -- ``COPY`` never has -- so this goes through
    `PQexec`.

Raises: Error: A `sqlstate.PostgresError` if the connection is closed, the
server rejected the statement (a missing table is ``42P01``),
or -- SQLSTATE ``42809`` -- the statement was valid but did
not start a ``COPY ... FROM STDIN``.

#### `copy_out`

```mojo
def copy_out(mut self, sql: String) -> CopyOut
```

Start a ``COPY ... TO STDOUT`` and return the handle to read from.

Args:

- `sql`: The full ``COPY`` statement, for example ``COPY t TO
    STDOUT`` or ``COPY (SELECT ...) TO STDOUT (FORMAT csv)``.

Raises: Error: A `sqlstate.PostgresError` if the connection is closed, the
server rejected the statement, or -- SQLSTATE ``42809`` -- the
statement did not start a ``COPY ... TO STDOUT``.

### `Transaction`

```mojo
struct Transaction
```

An open transaction block, and the guard that ends it.

Created by `Connection.begin`, which issues ``BEGIN``.  Run the block's
statements through `Transaction.execute` and `Transaction.query` -- the
same calls as the `Connection`'s, with the same parameters and the same
errors -- and finish with `Transaction.commit`:

```mojo
var tx = conn.begin()
_ = tx.execute("INSERT INTO orders VALUES ($1)", Params().int64(1))
_ = tx.execute("INSERT INTO items VALUES ($1, $2)",
               Params().int64(1).int32(3))
tx.commit()
```

**Destruction rolls back.**  If the guard is destroyed without a
`Transaction.commit` -- an early return, a raised error, a forgotten call
-- its destructor issues ``ROLLBACK``.  The failure mode of losing track
of a transaction is therefore "nothing happened", never "half of it
happened".  Since a `with` block ends by destroying the guard, that is
also what makes this shape work:

```mojo
with conn.begin() as tx:
    _ = tx.execute("INSERT INTO orders VALUES ($1)", Params().int64(1))
    tx.commit()          # explicit: leaving the block does NOT commit
```

Leaving that block without the `Transaction.commit` line -- by falling off
the end, by returning, or by raising -- rolls back.  There is no implicit
commit anywhere in this type.

**A failed block cannot be committed.**  PostgreSQL turns a ``COMMIT``
inside a failed transaction into a ``ROLLBACK`` and reports success;
`Transaction.commit` raises SQLSTATE ``25P02`` instead, after issuing the
``ROLLBACK`` itself so the connection is left clean.  Recover from a
failed statement with `Transaction.savepoint` and
`Transaction.rollback_to`.

Like `Statement`, this shares ownership of the connection rather than
borrowing it: the session stays open for as long as the transaction does,
so a `Transaction` may outlive the `Connection` value it came from -- and
it routinely does, since Mojo destroys a value after its last *use*.  An
explicit `Connection.close` is the exception, and ends the block: every
call on the transaction then raises SQLSTATE ``08006``.

Implements: `Movable`

#### `__init__`

```mojo
def __init__(out self, cell: ArcPointer[_ConnCell])
```

Issue ``BEGIN`` on the cell's connection.

`Connection.begin` is the only intended caller: it checks that the
connection is open and that no block is open already.

Args:

- `cell`: The shared cell of the connection to open a transaction on;
    a share of it is kept, so the connection stays open at least
    as long as this transaction does.

Raises: Error: A `sqlstate.PostgresError` if ``BEGIN`` failed.

#### `__deinit__`

```mojo
def __deinit__(deinit self)
```

Roll back unless the block was already committed or rolled back.

Unconditional: a ``ROLLBACK`` is accepted in every transaction state,
including the failed one where nothing else is, and it is the only
statement that leaves the connection idle again.  Errors are swallowed
-- a destructor has nobody to raise to -- and a connection that has
been closed has already lost the transaction, so nothing is sent.

#### `__enter__`

```mojo
def __enter__(deinit self) -> Self
```

Hand the guard to ``with conn.begin() as tx:``.

The guard is transferred into the block rather than borrowed, so it is
destroyed -- and therefore rolled back, unless `Transaction.commit`
ran -- when the block ends, however it ends.

#### `is_open`

```mojo
def is_open(self) -> Bool
```

Whether the block is still open.

#### `execute`

```mojo
def execute(mut self, sql: String, params: Params = Params()) -> Int
```

Run a command inside the block and discard any rows.

`Connection.execute`'s behaviour exactly, including the `PQexec` path
for a parameterless call and the multi-statement strings that allows.

Args:

- `sql`: The statement text, with ``$1``-style placeholders if
    `params` is non-empty.
- `params`: The parameter values; empty by default.

Raises: Error: A `sqlstate.PostgresError` if the transaction is finished
or the server rejected the command.  A rejected statement puts
the block in the failed state, where nothing but a rollback --
whole, or to a savepoint -- will be accepted.

#### `query`

```mojo
def query(mut self, sql: String, params: Params = Params()) -> Result
```

Run a command inside the block and return its rows.

Args:

- `sql`: The statement text, with ``$1``-style placeholders if
    `params` is non-empty.
- `params`: The parameter values; empty by default.

Raises: Error: A `sqlstate.PostgresError` if the transaction is finished
or the server rejected the command.

#### `savepoint`

```mojo
def savepoint(mut self, name: String)
```

Mark a point inside the block to come back to.

The way to survive a *failed* statement without losing the whole
transaction: set a savepoint, try the statement, and
`Transaction.rollback_to` the savepoint if it fails.  The block is
usable again afterwards.

Args:

- `name`: The savepoint name, spliced into the SQL as a quoted
    identifier -- ``SAVEPOINT`` takes an identifier, and
    identifiers cannot be parameters.  Any embedded double quotes
    are doubled, so a name can never end the quoting early.
    Re-using a name is allowed: the newer savepoint hides the
    older one, which is still there after a
    `Transaction.release`.

Raises: Error: A `sqlstate.PostgresError` if the transaction is finished,
or if the block has already failed -- a savepoint cannot be
*set* in the failed state, only rolled back to.

#### `rollback_to`

```mojo
def rollback_to(mut self, name: String)
```

Undo everything after the savepoint `name`, keeping the block open.

Also clears the failed state, which is the point: after this the
transaction accepts statements again and can still be committed.

Args:

- `name`: The savepoint name, quoted as an identifier.

Raises: Error: A `sqlstate.PostgresError` if the transaction is finished,
or if there is no such savepoint (SQLSTATE ``3B001``).

#### `release`

```mojo
def release(mut self, name: String)
```

Forget the savepoint `name`, keeping everything done since it.

The opposite of `Transaction.rollback_to`: the work stays, and the
savepoint -- along with every savepoint set after it -- is gone.

Args:

- `name`: The savepoint name, quoted as an identifier.

Raises: Error: A `sqlstate.PostgresError` if the transaction is finished,
or if there is no such savepoint (SQLSTATE ``3B001``).

#### `commit`

```mojo
def commit(mut self)
```

Commit the block, making everything in it permanent.

The destructor becomes a no-op afterwards, and the `Transaction` is
finished: any further use raises.

Raises: Error: A `sqlstate.PostgresError` if the transaction is already
finished, if ``COMMIT`` itself failed, or -- SQLSTATE
``25P02``, ``transaction is aborted`` -- if a statement inside
the block failed and was not rolled back to a savepoint.
PostgreSQL would answer that ``COMMIT`` with ``ROLLBACK`` and
report success, so a caller who did not check every statement
would believe the block had been committed; the ``ROLLBACK``
is issued here too, leaving the connection idle, but the
outcome is *reported* rather than hidden.

#### `rollback`

```mojo
def rollback(mut self)
```

Roll the block back, discarding everything in it.

Accepted in every state, including the failed one.  The destructor
becomes a no-op afterwards, and the `Transaction` is finished: any
further use raises.

Raises: Error: A `sqlstate.PostgresError` if the transaction is already
finished, or if ``ROLLBACK`` itself failed -- which in
practice means the connection has gone.

## Functions

### `drain_results`

```mojo
def drain_results(conn: Int, cell: ArcPointer[_ConnCell], sql: String) -> Int
```

Collect every outstanding result, then report on the first one.

This is how a ``COPY`` ends.  `LibpqFFI.PQgetResult` must be called until
it returns ``0`` or the connection stays busy and every later command
fails, so the drain happens **first, unconditionally** -- only then is the
first result's status examined and, if it failed, raised.  A malformed
``COPY`` row therefore surfaces as the server's own error (``22P02`` with
its ``DETAIL``/``CONTEXT``) on a connection that is already clean.

Args:

- `conn`: The connection handle.
- `cell`: The connection's shared cell.
- `sql`: The statement text, attached to any error raised.

Raises: Error: A `sqlstate.PostgresError` if the first result reports a
failure.

### `drain_results_quietly`

```mojo
def drain_results_quietly(conn: Int)
```

Collect and discard every outstanding result, reporting nothing.

The destructor's half of `drain_results`: a handle that is dropped rather
than finished still has to leave the connection idle, and a destructor has
nobody to raise to.

Args:

- `conn`: The connection handle.

### `discard_copy_quietly`

```mojo
def discard_copy_quietly(conn: Int, status: Int)
```

End whatever COPY `status` says is in progress, and drain it, silently.

A COPY holds the connection until it is finished one way or another, and
the way out depends on the direction: a ``COPY FROM STDIN`` is ended by
telling libpq the stream failed, while a ``COPY TO STDOUT`` can only be
consumed -- PostgreSQL offers no cancel for it.  This does whichever
applies and then drains the results, so the connection comes back idle.

Used by the COPY destructors, which have nobody to raise to, and by
`Connection.copy_in`/`Connection.copy_out` when the statement started a
COPY in the *other* direction.

Args:

- `conn`: The connection handle.
- `status`: `_ffi.PGRES_COPY_IN`, `_ffi.PGRES_COPY_OUT` or
    `_ffi.PGRES_COPY_BOTH` -- the state the connection is in.  Any
    other value only drains.

## Aliases

### `IN_FAILED_SQL_TRANSACTION`

```mojo
comptime IN_FAILED_SQL_TRANSACTION = StringSpan("25P02")
```

The block has already failed, so ``COMMIT`` would silently roll back.

### `ACTIVE_SQL_TRANSACTION`

```mojo
comptime ACTIVE_SQL_TRANSACTION = StringSpan("25001")
```

A transaction block is already open on this connection.

### `NO_ACTIVE_SQL_TRANSACTION`

```mojo
comptime NO_ACTIVE_SQL_TRANSACTION = StringSpan("25P01")
```

The transaction is over -- committed or rolled back already.

### `WRONG_OBJECT_TYPE`

```mojo
comptime WRONG_OBJECT_TYPE = StringSpan("42809")
```

The statement was not the ``COPY`` the call needed it to be.
