terom@53: /** terom@53: @mainpage evsql terom@53: @author Tero Marttila terom@53: terom@53: @section Introduction terom@53: Evsql is a C-language SQL library designed for use with libevent, and primarily PostgreSQL's libpq. terom@53: terom@53: Evsql was born as a result of wanting to use a SQL database from within a libevent application, and discovering terom@53: libpq's asynchronous API. Since the libpq API is somewhat cumbersome to use, I wrote a separate interface that terom@53: drives libpq using libevent and makes writing asynchronous SQL clients a lot easier - plus adding some conveniance terom@53: for parametrized queries and such along the way. terom@53: terom@53: The evsql API doesn't expose the underlying database library's API, although since the only currently existing terom@53: implementation is libpq, this should really be thought of as a generically-named PostgreSQL library rather than a terom@53: database-agnostic API... terom@53: terom@53: @section Usage terom@53: Include the top-level evsql.h header, making sure you also have the evpq and lib modules available. terom@53: terom@53: @section Connecting terom@53: Evsql sessions are represented using an opaque struct, called simply evsql. Use the \ref evsql_ evsql_new_ function corresponding to your terom@53: database engine (PostgreSQL -> evsql_new_pq()) to allocate this handle. It is valid for use immediately, although the terom@53: initial connection may not yet be complete. terom@53: terom@53: There is an evsql_close function, but it is currently not implemented. terom@53: terom@53: \ref evsql_ terom@53: terom@53: @section Transactions terom@53: Evsql supports both non-transactional queries and transactional queries. A transaction is allocated its own dedicated terom@53: connection which it can use for its queries without being interfered by other queries/transactions. Evsql takes care of terom@53: sending the initial "BEGIN TRANSACTION" query, and provides evsql_trans_commit()/evsql_trans_abort() functions to send the terom@53: "COMMIT TRANSACTION" and "ROLLBACK TRANSACTION" queries. terom@53: terom@53: Note, however, that transactions can only handle one outstanding query at a time, whereas transactionless queries can terom@53: be enqueued by evsql itself. terom@53: terom@53: \ref evsql_trans_ terom@53: terom@53: @section Querying terom@53: There is a single evsql_query function used for both transactional and non-transactional queries; you can pass NULL terom@53: as the trans argument. terom@53: terom@53: The given callback function is invoked once the query has been processed and the result is available, or the query terom@53: failed. terom@53: terom@53: The important distinction between transactional and non-transactional queries is that transactions only support one terom@53: outstanding query at a time, meaning that you must wait for your callback to be invoked before calling evsql_query terom@53: again for the transaction. Non-transactional queries are sent using an idle connection, and will be enqueued for later terom@53: execution if no idle connections are available. terom@53: terom@53: evsql_query returns a handle that can be passed to evsql_query_abort to abort the query, ensuring that the callback terom@53: given to evsql_query is not invoked, and any associated resources released. terom@53: terom@53: @section Parametrized Queries terom@53: Evsql also provides functions to send parametrized queries, the behaviour of evsql_query explained above applies as terom@53: well. terom@53: terom@53: The first of these is evsql_query_params, which takes the parametrized SQL command and a struct containing the terom@53: parameter types and values as arguments. terom@53: terom@53: The second of these is evsql_query_exec, which takes a evsql_query_info struct containing the parametrized SQL command terom@53: and the parameter types, and the parameter values themselves as a list of variable arguments (of the correct type!). terom@53: terom@53: @section API Reference terom@53: The entire API is defined in the top-level evsql.h header. terom@53: terom@53: */