All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
execute
andexecuteMaybeOne
could returnnull
in some circumstances. They will now return0
when the underlyingrowCount
isnull
. It is possible that they will be changed to returnnumber | null
in a future major version.
- Added an
exports
section to package.json, so you can no longer import internal Possu modules ( e.g.import SqlQuery from "possu/dist/SqlQuery"
). Technically, this should not be a breaking change, since the internal functions are not a part of the public API.
- Exported the
Sql
interface. Thanks @timosaikkonen.
- Drop support for Node 14.x
- Add new
executeOne
andexecuteMaybeOne
functions as the duals ofqueryOne
andqueryMaybeOne
. They will throw aResultError
if the query modifies different than the expected amount of rows.
- Drop support for Node 12.x
- Bump the minimum required version of
pg
and@types/pg
to 8.6.0. - Change
sql`...`.prepare('query-name')
to return a new copy of the query instead of mutating it. - Bump minimum Node.js version to 12.x
- Change the signature of the
shouldRetry
option ofwithTransaction
from(error: Error) => boolean
to(error: unknown) => boolean
. This matches the default error type of catch clauses in TypeScript 4.4. - Catch any errors emitted by the client in
withTransaction
. Apg.Client
is an EventEmitter, which will crash the Node.js process if it emits an error an if there are no error listeners. Possu will now automatically install an error handler that catches any errors emitted by the client during the transaction. Any errors are returned in the promise.
- Added an
sql`...`.prepare('query-name')
method for creating prepared statements. This can sometimes have measurable performance benefits, especially if the query is very complex to parse and plan. - Added a
Connection
type alias forpg.Pool | pg.PoolClient
. It is designed to be used in your query functions as a generic connection type.
import { Connection, query, sql } from 'possu'
export function getUsers(conn: Connection) {
return query(conn, sql`SELECT * FROM users`)
}
- Added
Transaction
type. It is just a regularpg.PoolClient
with a type-level brand, which indicates that the connection has an active transaction. It can be used as additional type safety in functions that must be called within a transaction.
import { Transaction, query, sql } from 'possu'
export async function insertTwoUsers(tx: Transaction) {
await execute(tx, sql`INSERT INTO users (name) VALUES ('Alice')`)
await execute(tx, sql`INSERT INTO users (name) VALUES ('Bob')`)
}
- Changed
withTransaction
to only take a connection pool as the first argument. - Changed
withSavePoint
to take aTransaction
as the first parameter.
- Improve the error message of
queryMaybeOne
in cases where the query returns an unexpected amount of rows. - Make private properties of
SqlQuery
non-enumerable - Improve documentation
- Removed
sql.values
. The existing implementation suffered from problems with the ordering of object keys. In most cases, the use of VALUES lists may be replaced with functions likejsonb_to_recordset
, so I'm removingsql.values
for now. If it proves to be useful in the future, it may come back in some form.
- Added a new
sql.values
query builder for creating VALUES lists. Useful as a data source toINSERT
queries or when writing complex subqueries.
- Added automatic transaction retrying in
withTransaction
for PostgreSQL's40001
(serialization failure) and40P01
(deadlock detected) error codes. - Added an optional options object to
withTransaction
, which can be used to configure the access mode, isolation level and retry logic of a transaction. - The set of queries in
withSavepoint
now receives aPoolClient
as an argument. With the change, one may supply the same function to bothwithTransaction
andwithSavepoint
.
withTransactionMode
andwithTransactionLevel
have been removed, sincewithTransaction
now encompasses their functionality.
- Documentation improvements
- Added a
withSavepoint
function for creating savepoints. Savepoints can be used to simulate nested transactions.
- Added a
sql.json
function for serializing values as JSON in queries. Strictly speaking, this isn't necessary, since it is mostly just equivalent toJSON.stringify
, but I'm including it since it might be more readable. - Added an optional row parser parameter to
query
,queryOne
andqueryMaybeOne
.
- Changed the default type variable in
query
,queryOne
andqueryMaybeOne
fromany
tounknown
. Now the user must explicitly cast the result rows to another type or to use a validating row parser.
- Fixed the
files
andtypes
entries in package.json. With them, the project should actually be usable 🙂.
- Changed
withTransactionLevel
andwithTransactionMode
to take the isolation level and access mode as the first argument. This allows the user to fix them more easily with e.g.Function.prototype.bind
. - Replaced
TooManyRowsReturnedError
andNoRowsReturnedError
with a genericResultError
, which signifies that a query returned an unexpected result.
- Added
withTransactionLevel
andwithTransactionMode
.
- Renamed
transaction
towithTransaction
.
- Initial public release