This is the reference manual for the component named postmodern, which is part of a library of the same name.
Note that this package also exports the database-connection
and database-error
types from CL-postgres, and a few
operators from S-SQL.
query
, execute
, and any other function
that would logically need to communicate with the database will
raise a condition of the type database-error
when something goes wrong. As a special case, errors that break
the connection (socket errors, database shutdowns) will be raised
as subtypes of database-connection-error
,
providing a :reconnect
restart to re-try the
operation that encountered to the error.
Objects of this type represent database connections.
function
connect (database user password host &key (port 5432) pooled-p)
→ database-connection
Create a new database connection for the given
user and database. Port will default to 5432, which is where most
PostgreSQL server are running. If pooled-p
is true, a
connection will be taken from a pool of connections of this type,
if one is available there, and when the connection is disconnected
it will be put back into this pool instead.
method disconnect (database-connection)
Disconnects a normal database connection, or moves a pooled connection into the pool.
function
connected-p (database-connection)
→ boolean
Returns a boolean indicating whether the given connection is still connected to the server.
method reconnect (database-connection)
Reconnect a disconnected database connection. This is not allowed for pooled connections ― after they are disconnected they might be in use by some other process, and should no longer be used.
Special variable holding the current database. Most functions and macros operating on a database assume this contains a connected database.
macro with-connection (spec &body body)
Evaluates the body with *database*
bound to a
connection as specified by spec
, which should be list
that connect
can be applied
to.
macro call-with-connection (spec thunk)
The functional backend to with-connection
and with-connection*
. Binds
*database*
to a new
connection as specified by spec
, which should be a
list that connect
can be
applied to, and runs the zero-argument function given as second
argument in the new environment. When the function returns or
throws, the new connection is disconnected.
function connect-toplevel (database user password host &key (port 5432))
Set *database*
to a new
connection. Use this if you only need one connection, or if you
want a connection for debugging from the REPL.
function disconnect-toplevel ()
Disconnect *database*
.
function clear-connection-pool ()
Disconnect and remove all connections in the connection pools.
Set the maximum amount of connections kept in a
single connection pool, where a pool consists of all the
stored connections with the exact same connect arguments. Defaults
to NIL
, which means there is no maximum.
macro
query (query &rest args/format)
→ result
Execute the given query, which can be either a
string or an S-SQL form (list starting
with a keyword). If the query contains placeholders
($1
, $2
, etc) their values can be given
as extra arguments. If one of these arguments is a keyword
occuring in the table below, it will not be used as a query
argument, but will determine the format in which the results are
returned instead. Any of the following formats can be used, with
the default being :rows
:
:none | Ignore the result values. |
:lists , :rows | Return a list of lists, each list containing the values for a row. |
:list , :row | Return a single row as a list. |
:alists | Return a list of alists which map column names to values,with the names represented as keywords. |
:alist | Return a single row as an alist. |
:str-alists | Like
:alists , but use the original column
names. |
:str-alist | Return a single row as an alist, with strings for names. |
:column | Return a single column as a list. |
:single | Return a single value. |
:single! | Like :single ,
but raise an error when the number of selected rows is not equal
to 1. |
If the database returns information about the amount rows that were effected, such as with updating or deleting queries, this is returned as a second value.
macro execute (query &rest args)
Like query
, but
called with format
:none.
macro doquery (query (&rest names) &body body)
Execute the given query, iterating over the rows
in the result. The body will be executed with the values in the
row bound to the symbols given in names
.
macro
prepare (query &optional (format :rows))
→ function
Creates a function that can be used as the
interface to a prepared statement. The given query (either a
string or an S-SQL form) may contain
placeholders, which look like $1
, $2
,
etc. The resulting function takes one argument for every
placeholder in the query, executes the prepared query, and returns
the result in the format specified (allowed formats are the same
as for query
).
For queries that have to be run very often, especially when they are complex, it may help performance if the server only has to plan them once. See the PostgreSQL manual for details.
In some cases, the server will complain about not
being able to deduce the type of the arguments in a statement. In
that case you should add type declarations (either with the
::
syntax or with S-SQL's :type
construct) to help it
out.
macro defprepared (name query &optional (format :rows))
This is the defun
-style variant of prepare
. It will define a
top-level function for the prepared statement.
macro with-transaction ((&optional name) &body body)
Execute the given body within a database transaction, committing it when the body exits normally, and aborting otherwise. An optional name can be given to the transaction, which can be used to force a commit or abort before the body unwinds.
function commit-transaction (transaction)
Commit the given database transaction.
function abort-transaction (transaction)
Roll back the given database transaction.
macro with-savepoint (name &body body)
Can only be used within a transaction. Establishes
a savepoint with the given name at the start of body
,
and binds the same name to a handle for that savepoint. At the end
of body
, the savepoint is released, unless a
condition is thrown, in which case it is rolled back.
function release-savepoint (savepoint)
Explicitly release the given savepoint.
function rollback-savepoint (transaction)
Roll back the given savepoint.
function
sequence-next (sequence)
→ integer
Get the next value from a sequence. The sequence identifier can be either a string or a symbol, in the latter case it will be converted to a string with S-SQL rules.
function
coalesce (&rest arguments)
→ value
Returns the first non-NIL
, non-null
(as in :null
) argument, or NIL
if none
are present. Useful for providing a fall-back value for the result
of a query, or, when given only one argument, for transforming
:null
s to NIL
.
function
list-tables (&optional strings-p)
→ list
Returns a list of the tables in the current
database. When strings-p
is true, the names will be
given as strings, otherwise as keywords.
function
table-exists-p (name)
→ boolean
Tests whether a table with the given name exists. The name can be either a string or a symbol.
function
table-description (name)
→ list
Returns a list of the fields in the named table. Each field is represented by a list of three elements: the field name, the type, and a boolean indicating whether the field may be null.
function
list-sequences (&optional strings-p)
→ list
Returns a list of the sequences in the current
database. When strings-p
is true, the names will be
given as strings, otherwise as keywords.
function
sequence-exists-p (name)
→ boolean
Tests whether a sequence with the given name exists. The name can be either a string or a symbol.
function
list-views (&optional strings-p)
→ list
Returns a list of the views in the current
database. When strings-p
is true, the names will be
given as strings, otherwise as keywords.
function
view-exists-p (name)
→ boolean
Tests whether a view with the given name exists. The name can be either a string or a symbol.
Postmodern contains a simple system for defining CLOS classes that represent rows in the database. This is not intended as as a full-fledged object-relational magic system ― while serious ORM systems have their place, they are notoriously hard to get right, and are outside of the scope of a humble SQL library like this.
At the heart of Postmodern's DAO system is the
dao-class
metaclass. It allows you to define classes
for your database-access objects as regular CLOS classes. Some of
the slots in these classes will refer to columns in the database.
To specify that a slot refers to a column, give it a
:col-type
option containing an S-SQL type expression (useful if you want to
be able to derive a table definition from the class definition),
or simply a :column
option with value t
.
Such slots can also take a :col-default
option, used
to provide a database-side default value as an S-SQL
expression.
DAO class definitions support two extra class
options: :table-name
to give the name of the table
that the class refers to (defaults to the class name), and
:keys
to provide a set of primary keys for the table.
When no primary keys are defined, operations such as update-dao
and get-dao
will not work.
Simple example:
(defclass user () ((name :col-type string :initarg :name :accessor user-name) (creditcard :col-type (or db-null integer) :initarg :card :col-default :null) (score :col-type bigint :col-default 0 :accessor user-score)) (:metaclass dao-class) (:keys name))
The (or db-null integer)
form is used
to indicate a column can have NULL values.
When inheriting from DAO classes, a subclass' set
of columns also contains all the columns in its superclasses. The
primary key for such a class is the union of its own keys and all
the keys from its superclasses. Classes inheriting from DAO
classes should probably always use the dao-class
metaclass themselves.
When a DAO is created with
make-instance
, it can be passed a
:fetch-defaults
keyword parameter which, when true,
will cause a query to be made to fetch the default values for all
slots that have column default values and were not bound through
initargs. In some cases, such as serial
columns,
which have an implicit default, this will not work. You can work
around this by creating your own sequence and defining a
(:nextval "my_sequence")
default.
method
dao-exists-p (dao)
→ boolean
Test whether a row with the same primary key as
the given DAO exists in the database. Will also return
NIL
when any of the key slots in the object are
unbound.
method
get-dao (type &rest keys)
→ dao
Select the DAO object from the row that has the
given primary key values, or NIL
if no such row
exists. Objects created by this function will have
initialize-instance
called on them (after loading in
the values from the database) without any arguments ― even
:default-initargs
are skipped. The same goes for select-dao
and query-dao
.
macro
select-dao (type &optional (test t) &rest sort)
→ list
Select DAO objects for the rows in the associated table for which the given test (either an S-SQL expression or a string) holds. When sorting arguments are given, which can also be S-SQL forms or strings, these are used to sort the result. (Note that, if you want to sort, you have to pass a test value.)
(select-dao 'user (:> score 10000) name)
function
query-dao (type query)
→ list
Execute the given query (which can be either a string or an S-SQL expression) and return the result as DAOs of the given type. The names of the fields returned by the query must match the slots of the DAO.
Insert the given DAO into the database. When any column slots in the object are unbound, these will be updated with the values they default to in the database. (If they have no defaults, it is an error to insert them.) Note: This feature only works on PostgreSQL 8.2 and up. On older versions, do not insert DAOs with unbound slots.
Update the representation of the given DAO in the database with the values in the object. This is not defined for tables that do not have any non-primary-key columns.
Delete the given DAO from the database.
function
dao-table-name (table)
→ string
Get the table name associated with the given DAO class (or symbol naming such a class).
function
dao-table-definition (table)
→ string
Given a DAO class, or the name of one, this will produce an SQL query string giving the definition of the table. This is just the bare simple definition, so if you need any extra indices or or contraints, you'll have to write your own queries to add them.