7 * A SQL library designed for use with libevent and PostgreSQL's libpq. Provides support for queueing non-transactional
8 * requests, transaction support, parametrized queries and result iteration.
10 * Currently, the API does not expose the underlying libpq data structures, but since it is currently the only
11 * underlying implementation, there is no guarantee that the same API will actually work with other databases' interface
14 * The order of function calls and callbacks goes something like this:
19 * - evsql_trans_abort()
20 * - evsql_trans_error_cb()
21 * - evsql_trans_ready_cb()
23 * - evsql_query(), \ref evsql_param_ + evsql_query_params(), evsql_query_exec()
24 * - evsql_query_abort()
26 * - \ref evsql_result_
27 * - evsql_result_free()
29 * - evsql_trans_commit()
30 * - evsql_trans_done_cb()
39 #include <event2/event.h>
49 * The generic session handle used to manage a single "database connector" with multiple queries/transactions.
58 * Opaque transaction handle returned by evsql_trans() and used for the \ref evsql_query_ functions
60 * @see \ref evsql_trans_
67 * Opaque query handle returned by the \ref evsql_query_ functions and used for evsql_query_abort()
69 * @see \ref evsql_query_
74 * @struct evsql_result
76 * Opaque result handle received by evsql_query_cb(), and used with the \ref evsql_result_ functions
79 * @see \ref evsql_result_
84 * Various transaction isolation levels for conveniance
88 enum evsql_trans_type {
90 EVSQL_TRANS_SERIALIZABLE,
91 EVSQL_TRANS_REPEATABLE_READ,
92 EVSQL_TRANS_READ_COMMITTED,
93 EVSQL_TRANS_READ_UNCOMMITTED,
97 * An item can be in different formats, the classical text-based format (i.e. snprintf "1234") or a more low-level
98 * binary format (i.e uint16_t 0x04F9 in network-byte order).
100 enum evsql_item_format {
101 /** Format values as text strings */
104 /** Type-specific binary encoding */
109 * An item has a specific type, these correspond somewhat to the native database types.
111 enum evsql_item_type {
112 /** End marker, zero */
118 /** A `struct evsql_item_binary` */
121 /** A NUL-terminated char* */
124 /** A uint16_t value */
127 /** A uint32_t value */
130 /** A uint64_t value */
137 * Value for use with EVSQL_TYPE_BINARY, this just a non-NUL-terminated char* and an explicit length
139 struct evsql_item_binary {
140 /** The binary data */
143 /** Number of bytes pointed to by ptr */
148 * Metadata about the format and type of an item, this does not hold any actual value.
150 struct evsql_item_info {
152 enum evsql_item_format format;
155 enum evsql_item_type type;
158 struct evsql_item_flags {
159 /** The value may be NULL @see evsql_result_next */
165 * An union to provide storage for the values of small types
169 union evsql_item_value {
170 /** 16-bit unsigned integer */
173 /** 32-bit unsigned integer */
176 /** 64-bit unsigned integer */
181 * A generic structure containing the type and value of a query parameter or a result field.
183 * @see evsql_query_info
184 * @see evsql_query_params
185 * @see evsql_result_info
188 /** The "header" containing the type and format */
189 struct evsql_item_info info;
192 * Pointer to the raw databytes.
193 * Set to NULL for SQL NULLs, otherwise &value or an external buf
198 * Size of the byte array pointed to by bytes, zero for EVSQL_FMT_TEXT data.
203 * Inline storage for small values
205 union evsql_item_value value;
207 /** Internal flags */
210 * The item has a value stored in `value`
217 * Query meta-info, similar to a prepared statement.
219 * Contains the literal SQL query and the types of the parameters, but no more.
221 * @see evsql_query_exec
223 struct evsql_query_info {
224 /** The SQL query itself */
228 * A variable-length array of the item_info parameters, terminated by an EVSQL_TYPE_INVALID entry.
230 struct evsql_item_info params[];
234 * Contains the query parameter types and their actual values
236 * @see evsql_query_params
238 struct evsql_query_params {
239 /** Requested result format for this query. XXX: move elsewhere */
240 enum evsql_item_format result_format;
243 * A variable-length array of the item parameter-values, terminated by an EVSQL_TYPE_INVALID entry.
245 struct evsql_item list[];
249 * Result layout metadata. This contains the stucture needed to decode result rows.
251 * @see evsql_result_begin
253 struct evsql_result_info {
254 /** XXX: make up something useful to stick here */
258 * A variable-length array of the item_info column types.
260 struct evsql_item_info columns[];
264 * Magic macros for defining param/result info -lists
267 * static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
268 * EVSQL_PARAM( UINT32 ),
275 * @name EVSQL_TYPE/PARAM_*
280 * A `struct evsql_item_info` initializer, using FMT_BINARY and the given EVSQL_TYPE_ -suffix.
282 * @param typenam the suffix of an evsql_item_type name
284 * @see struct evsql_item_info
285 * @see enum evsql_item_type
287 #define EVSQL_TYPE(typenam) { EVSQL_FMT_BINARY, EVSQL_TYPE_ ## typenam }
290 * End marker for a `struct evsql_item_info` array.
292 * @see struct evsql_item_info
294 #define EVSQL_TYPE_END { EVSQL_FMT_BINARY, EVSQL_TYPE_INVALID }
297 * Initializer block for an evsql_query_params struct
299 #define EVSQL_PARAMS(result_fmt) { result_fmt,
302 * An evsql_item initializer
304 #define EVSQL_PARAM(typenam) { EVSQL_TYPE(typenam) }
307 * Include the ending item and terminate the pseudo-block started using #EVSQL_PARAMS
309 #define EVSQL_PARAMS_END { EVSQL_TYPE_END } \
315 * Callback definitions
322 * Callback for handling query results.
324 * The query has completed, either succesfully or unsuccesfully.
326 * Use the \ref evsql_result_ functions to manipulate the results, and call evsql_result_free() (or equivalent) once done.
328 * @param res The result handle that must be result_free'd after use
329 * @param arg The void* passed to \ref evsql_query_
333 typedef void (*evsql_query_cb)(struct evsql_result *res, void *arg);
336 * Callback for handling global-level errors.
338 * The evsql is not useable anymore.
340 * XXX: this is not actually called yet, as no retry logic is implemented, so an evsql itself never fails.
344 typedef void (*evsql_error_cb)(struct evsql *evsql, void *arg);
347 * Callback for handling transaction-level errors. This may be called at any time during a transaction's lifetime,
348 * including from within the \ref evsql_query_ functions (but not always).
350 * The transaction is not useable anymore.
352 * @param trans the transaction in question
353 * @param arg the void* passed to evsql_trans
357 typedef void (*evsql_trans_error_cb)(struct evsql_trans *trans, void *arg);
360 * Callback for handling evsql_trans/evsql_query_abort completion. The transaction is ready for use with \ref evsql_query_.
362 * @param trans the transaction in question
363 * @param arg the void* passed to evsql_trans
366 * @see evsql_query_abort
368 typedef void (*evsql_trans_ready_cb)(struct evsql_trans *trans, void *arg);
371 * Callback for handling evsql_trans_commit completion. The transaction was commited, and should not be used anymore.
373 * @param trans the transaction in question
374 * @param arg the void* passed to evsql_trans
377 * @see evsql_trans_commit
379 typedef void (*evsql_trans_done_cb)(struct evsql_trans *trans, void *arg);
386 * @defgroup evsql_* Session interface
392 * Session creation functions
394 * @defgroup evsql_new_* Session creation interface
400 * Create a new PostgreSQL/libpq (evpq) -based evsql using the given conninfo.
402 * The given \a pq_conninfo pointer must stay valid for the duration of the evsql's lifetime.
404 * See the libpq reference manual for the syntax of pq_conninfo
406 * @param ev_base the libevent base to use
407 * @param pq_conninfo the libpq connection information
408 * @param error_fn XXX: not used, may be NULL
409 * @param cb_arg: XXX: not used, argument for error_fn
410 * @return the evsql context handle for use with other functions
412 struct evsql *evsql_new_pq (struct event_base *ev_base, const char *pq_conninfo,
413 evsql_error_cb error_fn,
420 * Close a connection. Callbacks for waiting queries will not be run.
422 * XXX: not implemented yet.
424 * @param evsql the context handle from \ref evsql_new_
426 void evsql_close (struct evsql *evsql);
433 * @defgroup evsql_query_* Query interface
439 * Queue the given query for execution.
441 * If \a trans is given (i.e. not NULL), then the transaction must be idle, and the query will be executed in that
442 * transaction's context. Otherwise, the query will be executed without a transaction using an idle connection, or
443 * enqueued for later execution.
445 * Once the query is complete (got a result, got an error, the connection failed), then \a query_fn will be called.
446 * The callback can use the \ref evsql_result_ functions to manipulate the query results.
448 * The returned evsql_query handle can be passed to evsql_query_abort at any point before \a query_fn being called.
450 * @param evsql the context handle from \ref evsql_new_
451 * @param trans the optional transaction handle from evsql_trans
452 * @param command the raw SQL command itself
453 * @param query_fn the evsql_query_cb() to call once the query is complete
454 * @param cb_arg the void* passed to the above
455 * @return the evsql_query handle that can be used to abort the query
457 struct evsql_query *evsql_query (struct evsql *evsql, struct evsql_trans *trans, const char *command, evsql_query_cb query_fn, void *cb_arg);
460 * Execute the given SQL query using the list of parameter types/values given via evsql_query_params.
462 * Use the EVSQL_PARAMS macros to declare \a params, and the \ref evsql_param_ functions to populate the values.
464 * See evsql_query() for more info about behaviour.
466 * See the <a href="http://www.postgresql.org/docs/8.3/static/libpq-exec.html#LIBPQ-EXEC-MAIN">libpq PQexecParams tip</a>
467 * for the parameter syntax to use.
469 * @param evsql the context handle from \ref evsql_new_
470 * @param trans the optional transaction handle from evsql_trans
471 * @param command the SQL command to bind the parameters to
472 * @param params the parameter types and values
473 * @param query_fn the evsql_query_cb() to call once the query is complete
474 * @param cb_arg the void* passed to the above
477 struct evsql_query *evsql_query_params (struct evsql *evsql, struct evsql_trans *trans,
478 const char *command, const struct evsql_query_params *params,
479 evsql_query_cb query_fn, void *cb_arg
483 * Execute the given \a query_info's SQL query with the values given as variable arguments, using the \a query_info to
486 * See evsql_query() for more info about behaviour.
488 * @param evsql the context handle from \ref evsql_new_
489 * @param trans the optional transaction handle from evsql_trans
490 * @param query_info the SQL query information
491 * @param query_fn the evsql_query_cb() to call once the query is complete
492 * @param cb_arg the void* passed to the above
495 struct evsql_query *evsql_query_exec (struct evsql *evsql, struct evsql_trans *trans,
496 const struct evsql_query_info *query_info,
497 evsql_query_cb query_fn, void *cb_arg,
502 * Abort a \a query returned by \ref evsql_query_ that has not yet completed (query_fn has not been called yet).
504 * The actual query itself may or may not be aborted (and hence may or may not be executed on the server), but \a query_fn
505 * will not be called anymore, and the query will dispose of itself and any results returned.
507 * If the \a query is part of a transaction, then \a trans must be given, and the query must be the query that is currently
508 * executing on that trans. The transaction's \a ready_fn will be called once the query has been aborted and the
509 * transaction is now idle again.
511 * @param trans if the query is part of a transaction, then it MUST be given here
512 * @param query the in-progress query to abort
514 void evsql_query_abort (struct evsql_trans *trans, struct evsql_query *query);
517 * Print out a textual dump of the given \a sql query and \a params using DEBUG
519 * @param sql the SQL query command
520 * @param params the list of parameter types and values
522 void evsql_query_debug (const char *sql, const struct evsql_query_params *params);
529 * @defgroup evsql_trans_* Transaction interface
535 * Create a new transaction.
537 * A transaction will be allocated its own connection, and the "BEGIN TRANSACTION ..." query will be sent (use the
538 * \a type argument to specify this).
540 * Once the transaction has been opened, the given \a ready_fn will be triggered, and the transaction can then
541 * be used (see \ref evsql_query_).
543 * If, at any point, the transaction-connection fails, any pending query will be forgotten (i.e. the query callback
544 * will NOT be called), and the given \a error_fn will be called. Note that this includes some, but not all,
545 * cases where \ref evsql_query_ returns an error.
547 * Once you are done with the transaction, call either evsql_trans_commit() or evsql_trans_abort().
549 * @param evsql the context handle from \ref evsql_new_
550 * @param type the type of transaction to create
551 * @param error_fn the evsql_trans_error_cb() to call if this transaction fails
552 * @param ready_fn the evsql_trans_ready_cb() to call once this transaction is ready for use
553 * @param done_fn the evsql_trans_done_cb() to call once this transaction has been commmited
554 * @param cb_arg the void* to pass to the above
555 * @return the evsql_trans handle for use with other functions
557 struct evsql_trans *evsql_trans (struct evsql *evsql, enum evsql_trans_type type,
558 evsql_trans_error_cb error_fn,
559 evsql_trans_ready_cb ready_fn,
560 evsql_trans_done_cb done_fn,
565 * Commit a transaction using "COMMIT TRANSACTION".
567 * The transaction must be idle, just like for evsql_query. Once the transaction has been commited, the transaction's
568 * \a done_fn will be called, after which the transaction must not be used anymore.
570 * You cannot abort a COMMIT, calling trans_abort() on trans after a succesful trans_commit is an error.
572 * Note that \a done_fn will never be called directly, always indirectly via the event loop.
574 * @param trans the transaction handle from evsql_trans to commit
577 int evsql_trans_commit (struct evsql_trans *trans);
580 * Abort a transaction, using "ROLLBACK TRANSACTION".
582 * No more transaction callbacks will be called. If there was a query running, it will be aborted, and the transaction
585 * You cannot abort a COMMIT, calling trans_abort on \a trans after a call to trans_commit is an error.
587 * Do not call evsql_trans_abort from within evsql_trans_error_cb()!
589 * @param trans the transaction from evsql_trans to abort
592 void evsql_trans_abort (struct evsql_trans *trans);
595 * Retrieve the transaction-specific error message from the underlying engine.
597 * Intended to be called from evsql_trans_error_cb()
599 const char *evsql_trans_error (struct evsql_trans *trans);
604 * Parameter-building functions.
606 * These manipulate the value of the given parameter index.
608 * @defgroup evsql_param_* Parameter interface
614 * Sets the value of the parameter at the given index
616 * @param params the evsql_query_params struct
617 * @param param the parameter index
618 * @param ptr pointer to the binary data
619 * @param len size of the binary data in bytes
620 * @return zero on success, <0 on error
622 int evsql_param_binary (struct evsql_query_params *params, size_t param, const char *ptr, size_t len);
624 /** @see evsql_param_binary */
625 int evsql_param_string (struct evsql_query_params *params, size_t param, const char *ptr);
627 /** @see evsql_param_binary */
628 int evsql_param_uint16 (struct evsql_query_params *params, size_t param, uint16_t uval);
630 /** @see evsql_param_binary */
631 int evsql_param_uint32 (struct evsql_query_params *params, size_t param, uint32_t uval);
634 * Sets the given parameter to NULL
636 * @param params the evsql_query_params struct
637 * @param param the parameter index
638 * @return zero on success, <0 on error
640 int evsql_param_null (struct evsql_query_params *params, size_t param);
643 * Clears all the parameter values (sets them to NULL)
645 * @param params the evsql_query_params struct
646 * @return zero on success, <0 on error
648 int evsql_params_clear (struct evsql_query_params *params);
653 * Result-handling functions
655 * @defgroup evsql_result_* Result interface
662 * Check the result for errors. Intended for use with non-data queries, i.e. CREATE, etc.
664 * Returns zero if the query was OK, err otherwise. EIO indicates an SQL error, the error message can be retrived
665 * using evsql_result_error.
667 * @param res the result handle passed to evsql_query_cb()
668 * @return zero on success, EIO on SQL error, positive error code otherwise
670 err_t evsql_result_check (struct evsql_result *res);
673 * The iterator-based interface results interface.
675 * Define an evsql_result_info struct that describes the columns returned by the query, and call evsql_result_begin on
676 * the evsql_result. This verifies the query result, and then prepares it for iteration using evsql_result_next.
678 * Call evsql_result_end once you've stopped iteration.
680 * Returns zero if the evsql_result is ready for iteration, err otherwise. EIO indicates an SQL error, the error
681 * message can be retreived using evsql_result_error. The result must be released in both cases.
683 * Note: currently the iterator state is simply stored in evsql_result, so only one iterator at a time per evsql_result.
685 * @param info the metadata to use to handle the result row columns
686 * @param res the result handle passed to evsql_query_cb()
687 * @return zero on success, +err on error
689 err_t evsql_result_begin (struct evsql_result_info *info, struct evsql_result *res);
692 * Reads the next result row from the result prepared using evsql_result_begin. Stores the field values into to given
693 * pointer arguments based on the evsql_result_info given to evsql_result_begin.
695 * If a field is NULL, and the result_info's evsql_item_type has flags.null_ok set, the given pointer is left
696 * untouched, otherwise, an error is returned.
698 * @param res the result handle previous prepared using evsql_result_begin
699 * @param ... a set of pointers corresponding to the evsql_result_info specified using evsql_result_begin
700 * @return >0 when a row was read, zero when there are no more rows left, and -err on error
702 int evsql_result_next (struct evsql_result *res, ...);
705 * Ends the result iteration, releasing any associated resources and the result itself.
707 * The result should not be iterated or accessed anymore.
709 * Note: this does the same thing as evsql_result_free, and works regardless of evsql_result_begin returning
710 * succesfully or not.
712 * @param res the result handle passed to evsql_query_cb()
713 * @see evsql_result_free
715 void evsql_result_end (struct evsql_result *res);
718 * Get the error message associated with the result, intended for use after evsql_result_check/begin return an error
721 * @param res the result handle passed to evsql_query_cb()
722 * @return a char* containing the NUL-terminated error string. Valid until evsql_result_free is called.
724 const char *evsql_result_error (const struct evsql_result *res);
727 * Get the number of data rows returned by the query
729 * @param res the result handle passed to evsql_query_cb()
730 * @return the number of rows, >= 0
732 size_t evsql_result_rows (const struct evsql_result *res);
735 * Get the number of columns in the data results from the query
737 * @param res the result handle passed to evsql_query_cb()
738 * @return the number of columns, presumeably zero if there were no results
740 size_t evsql_result_cols (const struct evsql_result *res);
743 * Get the number of rows affected by an UPDATE/INSERT/etc query.
745 * @param res the result handle passed to evsql_query_cb()
746 * @return the number of rows affected, >= 0
748 size_t evsql_result_affected (const struct evsql_result *res);
751 * Fetch the raw binary value for the given field, returning it via ptr/size.
753 * The given row/col must be within bounds as returned by evsql_result_rows/cols.
755 * *ptr will point to *size bytes of read-only memory allocated internally.
757 * @param res the result handle passed to evsql_query_cb()
758 * @param row the row index to access
759 * @param col the column index to access
760 * @param ptr where to store a pointer to the read-only field data, free'd upon evsql_result_free
761 * @param size updated to the size of the field value pointed to by ptr
762 * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error
763 * @return zero on success, <0 on error
765 int evsql_result_binary (const struct evsql_result *res, size_t row, size_t col, const char **ptr, size_t *size, bool nullok);
768 * Fetch the textual value of the given field, returning it via ptr.
770 * The given row/col must be within bounds as returned by evsql_result_rows/cols.
772 * *ptr will point to a NUL-terminated string allocated internally.
774 * @param res the result handle passed to evsql_query_cb()
775 * @param row the row index to access
776 * @param col the column index to access
777 * @param ptr where to store a pointer to the read-only field data, free'd upon evsql_result_free
778 * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error
779 * @return zero on success, <0 on error
781 int evsql_result_string (const struct evsql_result *res, size_t row, size_t col, const char **ptr, int nullok);
784 * Use evsql_result_binary to read a binary field value, and then convert it using ntoh[slq], storing the value in
787 * The given row/col must be within bounds as returned by evsql_result_rows/cols.
789 * @param res the result handle passed to evsql_query_cb()
790 * @param row the row index to access
791 * @param col the column index to access
792 * @param uval where to store the decoded value
793 * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error
794 * @return zero on success, <0 on error
796 int evsql_result_uint16 (const struct evsql_result *res, size_t row, size_t col, uint16_t *uval, int nullok);
798 /** @see evsql_result_uint16 */
799 int evsql_result_uint32 (const struct evsql_result *res, size_t row, size_t col, uint32_t *uval, int nullok);
801 /** @see evsql_result_uint16 */
802 int evsql_result_uint64 (const struct evsql_result *res, size_t row, size_t col, uint64_t *uval, int nullok);
805 * Every result handle passed to evsql_query_cb() MUST be released by the user, using this function.
807 * @param res the result handle passed to evsql_query_cb()
809 void evsql_result_free (struct evsql_result *res);