evsql: documentation improvements, fix consts, use bools new-evsql
authorTero Marttila <terom@fixme.fi>
Sat, 13 Dec 2008 04:20:56 +0200
branchnew-evsql
changeset 51 c65d0f4c3bff
parent 50 881de320e483
child 52 f5037572c326
evsql: documentation improvements, fix consts, use bools
src/evsql.h
src/evsql/result.c
src/evsql/util.c
--- a/src/evsql.h	Sat Nov 29 01:50:32 2008 +0200
+++ b/src/evsql.h	Sat Dec 13 04:20:56 2008 +0200
@@ -1,38 +1,46 @@
 #ifndef EVSQL_H
 #define EVSQL_H
 
-/*
- * An event-based (Postgre)SQL client API using libevent
+/**
+ * A SQL library designed for use with libevent and PostgreSQL's libpq. Provides support for queueing non-transactional
+ * requests, transaction support, parametrized queries and result iteration.
+ *
+ * Currently, the API does not expose the underlying libpq data structures, but since it is currently the only
+ * underlying implementation, there is no garuntee that the same API will actually work with other databases' interface
+ * libraries...
  */
 
 #include <stdint.h>
+#include <stdbool.h>
 #include <event2/event.h>
 
+/**
+ * For err_t.
+ */
 #include "lib/err.h"
 
-/*
- * The generic context handle
+/**
+ * The generic context handle used to manage a single "database connector" with multiple queries/transactions.
  */
 struct evsql;
 
-/*
- * Transaction handle
+/**
+ * Opaque transaction handle
  */
 struct evsql_trans;
 
-/*
- * A query handle
+/**
+ * Opaque query handle
  */
 struct evsql_query;
 
-/*
- * A result handle
+/**
+ * Opaque result handle
  */
 struct evsql_result;
 
-
-/*
- * Transaction type
+/**
+ * Various transaction isolation levels for conveniance
  */
 enum evsql_trans_type {
     EVSQL_TRANS_DEFAULT,
@@ -42,49 +50,76 @@
     EVSQL_TRANS_READ_UNCOMMITTED,
 };
 
-/*
- * Parameters and Result fields are both items
+/**
+ * An item can be in different formats, the classical text-based format (i.e. snprintf "1234") or a more low-level
+ * binary format (i.e uint16_t 0x04F9 in network-byte order).
  */
 enum evsql_item_format {
+    /** Format values as text strings */
     EVSQL_FMT_TEXT,
+
+    /** Type-specific binary encoding */
     EVSQL_FMT_BINARY,
 };
 
+/**
+ * An item has a specific type, these correspond somewhat to the native database types.
+ */
 enum evsql_item_type {
+    /** End marker, zero */
     EVSQL_TYPE_INVALID,
-
+    
+    /** A SQL NULL */
     EVSQL_TYPE_NULL_,
     
+    /** A `struct evsql_item_binary` */
     EVSQL_TYPE_BINARY,
+
+    /** A NUL-terminated char* */
     EVSQL_TYPE_STRING,
+
+    /** A uint16_t value */
     EVSQL_TYPE_UINT16,
+
+    /** A uint32_t value */
     EVSQL_TYPE_UINT32,
+
+    /** A uint64_t value */
     EVSQL_TYPE_UINT64,
+
+    EVSQL_TYPE_MAX
 };
 
+/**
+ * Value for use with EVSQL_TYPE_BINARY, this just a non-NUL-terminated char* and an explicit length
+ */
 struct evsql_item_binary {
     const char *ptr;
     size_t len;
 };
 
-/*
- * Metadata about the type of an item
+/**
+ * Metadata about the format and type of an item, this does not hold any actual value.
  */
 struct evsql_item_info {
-    // format
+    /** The format */
     enum evsql_item_format format;
     
-    // type
+    /** The type type */
     enum evsql_item_type type;
 
-    // flags
+    /** Various flags */
     struct evsql_item_flags {
-        uint8_t null_ok : 1;
+        /**
+         * The value may be NULL; behaviour varies for query and result 
+         * XXX: document
+         */
+        bool null_ok : 1;
     } flags;
 };
 
-/*
- * Storage for various scalar values
+/**
+ * An union to provide storage for the values of small types
  */
 union evsql_item_value {
     uint16_t uint16;
@@ -92,137 +127,215 @@
     uint64_t uint64;
 };
 
-/*
- * The type and value of an item
+/**
+ * A generic structure containing the type and value of a query parameter or a result field.
  */
 struct evsql_item {
-    // "header"
+    /** The "header" containing the type and format */
     struct evsql_item_info info;
 
-    // pointer to the raw databytes. Set to NULL to indicate SQL-NULL, &value, or an external buf
+    /**
+     * Pointer to the raw databytes. 
+     * Set to NULL for SQL NULLs, otherwise &value or an external buf 
+     */
     const char *bytes;
 
-    // size of byte array pointed to by bytes, zero for text
+    /**
+     * Size of the byte array pointed to by bytes, zero for EVSQL_FMT_TEXT data.
+     */
     size_t length;
 
-    // the decoded value
+    /**
+     * Inline storage for small values
+     */
     union evsql_item_value value;
     
-    // (internal) flags
+    /** Internal flags */
     struct {
-        uint8_t has_value : 1;
+        /**
+         * The item has a value stored in `value`
+         */
+        bool has_value : 1;
     } flags;
 };
 
-/*
- * Query info, similar to prepared statements
+/**
+ * Query meta-info, similar to a prepared statement.
  *
- * Contains the literal SQL query and the types of the arguments
+ * Contains the literal SQL query and the types of the parameters, but no more.
  */
 struct evsql_query_info {
-    // the SQL query itself
+    /** The SQL query itself */
     const char *sql;
 
-    // the list of items
+    /** 
+     * A variable-length array of the item_info parameters, terminated by an EVSQL_TYPE_INVALID entry.
+     */
     struct evsql_item_info params[];
 };
 
-/*
- * Contains the query parameter types and their values
+/**
+ * Contains the query parameter types and their actual values
  */
 struct evsql_query_params {
-    // result format
+    /** Requested result format for this query. XXX: move elsewhere */
     enum evsql_item_format result_format;
     
-    // list of params
+    /**
+     * A variable-length array of the item parameter-values, terminated by an EVSQL_TYPE_INVALID entry.
+     */
     struct evsql_item list[];
 };
 
-/*
- * Result info
- *
- * Contains the types of the result columns
+/**
+ * Result layout metadata. This contains the stucture needed to decode result rows.
  */
 struct evsql_result_info {
-    // XXX: put something useful here?
+    // XXX: make up something useful to stick here
     int _unused;
 
-    // the list of fields
+    /**
+     * A variable-length array of the item_info column types.
+     */
     struct evsql_item_info columns[];
 };
 
-/*
- * Macros for defining param/result infos/lists
+/**
+ * Magic macros for defining param/result info -lists
+ */
+
+/**
+ * A `struct evsql_item_info` initializer, using FMT_BINARY and the given EVSQL_TYPE_ -suffix.
+ *
+ * @see struct evsql_item_info
+ * @see enum evsql_item_type
+ */
+#define EVSQL_TYPE(typenam)                     { EVSQL_FMT_BINARY, EVSQL_TYPE_ ## typenam  }
+
+/**
+ * End marker for a `struct evsql_item_info` array.
+ *
+ * @see struct evsql_item_info
+ */
+#define EVSQL_TYPE_END                          { EVSQL_FMT_BINARY, EVSQL_TYPE_INVALID      }
+
+/**
+ * Initializer block for a `struct evsql_query_params` struct. EVSQL_PARAMS/EVSQL_PARAMS_END should be used as a
+ * pseudo-block with the following layout:
+ *
+ *  static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
+ *      EVSQL_PARAM(...),
+ *      ...,
+ *
+ *      EVSQL_PARAMS_END
+ *  };
  */
 #define EVSQL_PARAMS(result_fmt)            { result_fmt, 
 #define EVSQL_PARAM(typenam)                    { EVSQL_TYPE(typenam) }
 #define EVSQL_PARAMS_END                        { EVSQL_TYPE_END } \
                                               } // <<<
 
-#define EVSQL_TYPE(typenam)                     { EVSQL_FMT_BINARY, EVSQL_TYPE_ ## typenam  }
-#define EVSQL_TYPE_END                          { EVSQL_FMT_BINARY, EVSQL_TYPE_INVALID      }
 
-
-/*
+/**
  * Callback for handling query results.
  *
  * The query has completed, either succesfully or unsuccesfully.
  *
  * Use the evsql_result_* functions to manipulate the results, and call evsql_result_free (or equivalent) once done.
+ *
+ * @param res The result handle that must be result_free'd after use
+ * @param arg The void* passed to evsql_query_*
+ *
+ * @see evsql_query
  */
 typedef void (*evsql_query_cb)(struct evsql_result *res, void *arg);
 
-/*
+/**
  * Callback for handling global-level errors.
  *
  * The evsql is not useable anymore.
  *
- * XXX: this is not actually called yet, no retry logic implemented.
+ * XXX: this is not actually called yet, as no retry logic is implemented, so an evsql itself never fails.
+ *
+ * @see evsql_new_pq
  */
 typedef void (*evsql_error_cb)(struct evsql *evsql, void *arg);
 
-/*
+/**
  * Callback for handling transaction-level errors. This may be called at any time during a transaction's lifetime,
- * including from within the evsql_query_* functions.
+ * including from within the evsql_query_* functions (but not always).
  *
  * The transaction is not useable anymore.
+ *
+ * @param trans the transaction in question
+ * @param arg the void* passed to evsql_trans
+ *
+ * @see evsql_trans
  */
 typedef void (*evsql_trans_error_cb)(struct evsql_trans *trans, void *arg);
 
-/*
+/**
  * Callback for handling evsql_trans/evsql_query_abort completion. The transaction is ready for use with evsql_query_*.
+ *
+ * @param trans the transaction in question
+ * @param arg the void* passed to evsql_trans
+ *
+ * @see evsql_trans
+ * @see evsql_query_abort
  */
 typedef void (*evsql_trans_ready_cb)(struct evsql_trans *trans, void *arg);
 
-/*
+/**
  * Callback for handling evsql_trans_commit completion. The transaction was commited, and should not be used anymore.
+ *
+ * @param trans the transaction in question
+ * @param arg the void* passed to evsql_trans
+ *
+ * @see evsql_trans
+ * @see evsql_trans_commit
  */
 typedef void (*evsql_trans_done_cb)(struct evsql_trans *trans, void *arg);
 
-/*
- * Create a new PostgreSQL/libpq(evpq) -based evsql using the given conninfo.
+/**
+ * Create a new PostgreSQL/libpq (evpq) -based evsql using the given conninfo.
  *
  * The given conninfo must stay valid for the duration of the evsql's lifetime.
+ *
+ * See the libpq reference manual for the syntax of pq_conninfo
+ *
+ * @param ev_base the libevent base to use
+ * @param pq_conninfo the libpq connection information
+ * @param error_fn XXX: not used, may be NULL
+ * @param cb_arg: XXX: not used, argument for error_fn
+ * @return the evsql context handle for use with other functions
  */
 struct evsql *evsql_new_pq (struct event_base *ev_base, const char *pq_conninfo, 
     evsql_error_cb error_fn, 
     void *cb_arg
 );
 
-/*
+/**
  * Create a new transaction.
  *
  * A transaction will be allocated its own connection, and the "BEGIN TRANSACTION ..." query will be sent (use the
- * evsql_trans_type argument to specify this). 
+ * trans_type argument to specify this). 
  *
- * Once the transaction has been opened, the given evsql_trans_ready_cb will be triggered, and the transaction can then
+ * Once the transaction has been opened, the given trans_ready_cb will be triggered, and the transaction can then
  * be used (see evsql_query_*).
  *
- * If, at any point, the transaction-connection fails, and pending query will be forgotten (i.e. the query callback
- * will NOT be called), and the given evsql_trans_error_cb will be called. Note that this includes some, but not all,
+ * If, at any point, the transaction-connection fails, any pending query will be forgotten (i.e. the query callback
+ * will NOT be called), and the given trans_error_cb will be called. Note that this includes some, but not all,
  * cases where evsql_query_* returns an error.
  *
  * Once you are done with the transaction, call either evsql_trans_commit or evsql_trans_abort.
+ *
+ * @param evsql the context handle from evsql_new_*
+ * @param type the type of transaction to create
+ * @param error_fn the trans_error_cb to call if this transaction fails
+ * @param ready_fn the trans_ready_cb to call once this transaction is ready for use
+ * @param done_fn the trans_done_cb to call once this transaction has been commmited
+ * @param cb_arg the void* to pass to the above
+ * @return the evsql_trans handle for use with other functions
  */
 struct evsql_trans *evsql_trans (struct evsql *evsql, enum evsql_trans_type type, 
     evsql_trans_error_cb error_fn, 
@@ -231,36 +344,53 @@
     void *cb_arg
 );
 
-/*
+/**
  * Queue the given query for execution.
  *
- * If trans is specified (not NULL), then the transaction must be idle, and the query will be executed in that
+ * If a trans is given (i.e. not NULL), then the transaction must be idle, and the query will be executed in that
  * transaction's context. Otherwise, the query will be executed without a transaction using an idle connection, or
  * enqueued for later execution.
  *
  * Once the query is complete (got a result, got an error, the connection failed), then the query_cb will be called.
- * The callback can used the evsql_result_* functions to manipulate it.
+ * The callback can use the evsql_result_* functions to manipulate it.
  *
  * The returned evsql_query handle can be passed to evsql_query_abort at any point before query_fn being called. 
  *
+ * @param evsql the context handle from evsql_new_*
+ * @param trans the optional transaction handle from evsql_trans
+ * @param command the raw SQL command itself
+ * @param query_fn the query_cb to call once the query is complete
+ * @param cb_arg the void* passed to the above
+ * @return the evsql_query handle that can be used to abort the query
  */
 struct evsql_query *evsql_query (struct evsql *evsql, struct evsql_trans *trans, const char *command, evsql_query_cb query_fn, void *cb_arg);
 
-/*
+/**
  * Execute the given SQL query using the list of parameter types/values given via evsql_query_params.
  *
+ * Use the EVSQL_PARAMS macros to declare the struct, and the evsql_param_* functions to populate the values.
+ *
  * See evsql_query for more info about behaviour.
+ *
+ * XXX: explain SQL param syntax...
+ *
+ * @param command the SQL command to bind the parameters to
+ * @param params the parameter types and values
+ * @see evsql_query
  */
 struct evsql_query *evsql_query_params (struct evsql *evsql, struct evsql_trans *trans, 
     const char *command, const struct evsql_query_params *params, 
     evsql_query_cb query_fn, void *cb_arg
 );
 
-/*
- * Execute the given query_info's SQL query using the values given as variable arguments, using the evsql_query_info to
+/**
+ * Execute the given query_info's SQL query with the values given as variable arguments, using the evsql_query_info to
  * resolve the types.
  *
  * See evsql_query for more info about behaviour.
+ *
+ * @param query_info the SQL query information
+ * @see evsql_query
  */
 struct evsql_query *evsql_query_exec (struct evsql *evsql, struct evsql_trans *trans, 
     const struct evsql_query_info *query_info,
@@ -268,7 +398,7 @@
     ...
 );
 
-/*
+/**
  * Abort a query returned by evsql_query_* that has not yet completed (query_fn has not been called yet).
  *
  * The actual query itself may or may not be aborted (and hence may or may not be executed on the server), but query_fn
@@ -277,42 +407,61 @@
  * If the query is part of a transaction, then trans must be given, and the query must be the query that is currently
  * executing on that trans. The transaction's ready_fn will be called once the query has been aborted and the
  * transaction is now idle again.
+ *
+ * @param trans if the query is part of a transaction, then it MUST be given here
+ * @param query the in-progress query to abort
  */
 void evsql_query_abort (struct evsql_trans *trans, struct evsql_query *query);
 
-/*
+/**
  * Commit a transaction using "COMMIT TRANSACTION".
  *
  * The transaction must be idle, just like for evsql_query. Once the transaction has been commited, the transaction's
- * done_fn will be called, after which the transaction must not be used.
+ * done_fn will be called, after which the transaction must not be used anymore.
  *
- * You cannot abort a COMMIT, calling trans_abort on trans after a succesful trans_commit is a FATAL error.
+ * You cannot abort a COMMIT, calling trans_abort on trans after a succesful trans_commit is an error.
  *
  * Note that done_fn will never be called directly, always indirectly via the event loop.
+ *
+ * @param trans the transaction handle from evsql_trans to commit
+ * @see evsql_trans
  */
 int evsql_trans_commit (struct evsql_trans *trans);
 
-/*
+/**
  * Abort a transaction, using "ROLLBACK TRANSACTION".
  *
- * No more transaction callbacks will be called, if there was a query running, it will be aborted, and the transaction
+ * No more transaction callbacks will be called. If there was a query running, it will be aborted, and the transaction
  * then rollback'd.
  *
- * You cannot abort a COMMIT, calling trans_abort on trans after a succesful trans_commit is a FATAL error.
+ * You cannot abort a COMMIT, calling trans_abort on trans after a call to trans_commit is an error.
  * 
  * Do not call evsql_trans_abort from within evsql_trans_error_cb!
+ *
+ * @param trans the transaction from evsql_trans to abort
+ * @see evsql_trans
  */
 void evsql_trans_abort (struct evsql_trans *trans);
 
-/*
+// @{
+/**
  * Transaction-handling functions
  */
 
-// error string, meant to be called from evsql_trans_error_cb
+/** 
+ * Retrieve the transaction-specific error message from the underlying engine.
+ *
+ * Intended to be called from trans_error_cb
+ */
 const char *evsql_trans_error (struct evsql_trans *trans);
 
-/*
- * Param-building functions
+// @}
+
+// @{
+/**
+ * Parameter-building functions.
+ *
+ * These manipulate the value of the given parameter index.
  */
 int evsql_param_binary (struct evsql_query_params *params, size_t param, const char *ptr, size_t len);
 int evsql_param_string (struct evsql_query_params *params, size_t param, const char *ptr);
@@ -321,26 +470,37 @@
 int evsql_param_null   (struct evsql_query_params *params, size_t param);
 int evsql_params_clear (struct evsql_query_params *params);
 
-/*
+// @}
+
+// @{
+/**
  * Query-handling functions
  */
 
-// print out a textual repr of the given query/params via DEBUG
+/**
+ * Print out a textual dump of the given query and parameters using DEBUG
+ */
 void evsql_query_debug (const char *sql, const struct evsql_query_params *params);
 
-/*
+// @}
+
+// @{
+/**
  * Result-handling functions
  */
 
-/*
+/**
  * Check the result for errors. Intended for use with non-data queries, i.e. CREATE, etc.
  *
  * Returns zero if the query was OK, err otherwise. EIO indicates an SQL error, the error message can be retrived
  * using evsql_result_error.
+ *
+ * @param res the result handle passed to query_cb
+ * @return zero on success, EIO on SQL error, positive error code otherwise
  */
 err_t evsql_result_check (struct evsql_result *res);
 
-/*
+/**
  * The iterator-based interface results interface.
  *
  * Define an evsql_result_info struct that describes the columns returned by the query, and call evsql_result_begin on
@@ -349,60 +509,140 @@
  * Call evsql_result_end once you've stopped iteration.
  *
  * Returns zero if the evsql_result is ready for iteration, err otherwise. EIO indicates an SQL error, the error
- * message can be retreived using evsql_result_error.
+ * message can be retreived using evsql_result_error. The result must be released in both cases.
  *
  * Note: currently the iterator state is simply stored in evsql_result, so only one iterator at a time per evsql_result.
+ *
+ * @param info the metadata to use to handle the result row columns
+ * @param res the result handle passed to query_cb
+ * @return zero on success, +err on error
  */
 err_t evsql_result_begin (struct evsql_result_info *info, struct evsql_result *res);
 
-/*
- * Reads the next result row, storing the field values into the pointer arguments given. The types are resolved using
- * the evsql_result_info given to evsql_result_begin.
+/**
+ * Reads the next result row from the result prepared using evsql_result_begin. Stores the field values into to given
+ * pointer arguments based on the evsql_result_info given to evsql_result_begin.
  *
- * Returns >0 when a row was read, 0 when there are no more rows, and -err if there was an error.
+ * @param res the result handle previous prepared using evsql_result_begin
+ * @param ... a set of pointers corresponding to the evsql_result_info specified using evsql_result_begin
+ * @return >0 when a row was read, zero when there are no more rows left, and -err on error
  */
 int evsql_result_next (struct evsql_result *res, ...);
 
-/*
+/**
  * Ends the result iteration, releasing any associated resources and the result itself.
  *
  * The result should not be iterated or accessed anymore.
  *
  * Note: this does the same thing as evsql_result_free, and works regardless of evsql_result_begin returning
  * succesfully or not.
+ *
+ * @param res the result handle passed to query_cb
+ * @see evsql_result_free
  */
 void evsql_result_end (struct evsql_result *res);
 
-
-// get error message associated with function
+/**
+ * Get the error message associated with the result, intended for use after evsql_result_check/begin return an error
+ * code.
+ * 
+ * @param res the result handle passed to query_cb
+ * @return a char* containing the NUL-terminated error string. Valid until evsql_result_free is called.
+ */
 const char *evsql_result_error (const struct evsql_result *res);
 
-// number of rows in the result
+/**
+ * Get the number of data rows returned by the query
+ *
+ * @param res the result handle passed to query_cb
+ * @return the number of rows, >= 0
+ */
 size_t evsql_result_rows (const struct evsql_result *res);
 
-// number of columns in the result
+/**
+ * Get the number of columns in the data results from the query
+ *
+ * @param res the result handle passed to query_cb
+ * @return the number of columns. XXX: zero if no data?
+ */
 size_t evsql_result_cols (const struct evsql_result *res);
 
-// number of affected rows for UPDATE/INSERT
+/**
+ * Get the number of rows affected by an UPDATE/INSERT/etc query.
+ *
+ * @param res the result handle passed to query_cb
+ * @return the number of rows affected, >= 0
+ */
 size_t evsql_result_affected (const struct evsql_result *res);
 
-// fetch the raw binary value from a result set, and return it via ptr
-// if size is nonzero, check that the size of the field data matches
-int evsql_result_binary (const struct evsql_result *res, size_t row, size_t col, const char **ptr, size_t *size, int nullok);
+/**
+ * Fetch the raw binary value for the given field, returning it via ptr/size.
+ *
+ * The given row/col must be within bounds as returned by evsql_result_rows/cols.
+ *
+ * *ptr will point to *size bytes of read-only memory allocated internally.
+ *
+ * @param res the result handle passed to query_cb
+ * @param row the row index to access
+ * @param col the column index to access
+ * @param ptr where to store a pointer to the read-only field data, free'd upon evsql_result_free
+ * @param size updated to the size of the field value pointed to by ptr
+ * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error
+ * @return zero on success, <0 on error
+ */
+int evsql_result_binary (const struct evsql_result *res, size_t row, size_t col, const char **ptr, size_t *size, bool nullok);
+
+/**
+ * Fetch the textual value of the given field, returning it via ptr.
+ *
+ * The given row/col must be within bounds as returned by evsql_result_rows/cols.
+ *
+ * *ptr will point to a NUL-terminated string allocated internally.
+ *
+ * @param res the result handle passed to query_cb
+ * @param row the row index to access
+ * @param col the column index to access
+ * @param ptr where to store a pointer to the read-only field data, free'd upon evsql_result_free
+ * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error
+ * @return zero on success, <0 on error
+ */
 int evsql_result_string (const struct evsql_result *res, size_t row, size_t col, const char **ptr, int nullok);
 
-// fetch certain kinds of values from a binary result set
+// @{
+/**
+ * Use evsql_result_binary to read a binary field value, and then convert it using ntoh[slq], storing the value in
+ * *val.
+ *
+ * The given row/col must be within bounds as returned by evsql_result_rows/cols.
+ *
+ * @param res the result handle passed to query_cb
+ * @param row the row index to access
+ * @param col the column index to access
+ * @param val where to store the decoded value
+ * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error
+ * @return zero on success, <0 on error
+ */
 int evsql_result_uint16 (const struct evsql_result *res, size_t row, size_t col, uint16_t *uval, int nullok);
 int evsql_result_uint32 (const struct evsql_result *res, size_t row, size_t col, uint32_t *uval, int nullok);
 int evsql_result_uint64 (const struct evsql_result *res, size_t row, size_t col, uint64_t *uval, int nullok);
 
-// release the result set, freeing its memory
+// @}
+
+/**
+ * Every result handle passed to query_cb MUST be released by the user, using this function.
+ *
+ * @param res the result handle passed to query_cb
+ */
 void evsql_result_free (struct evsql_result *res);
 
-/*
+// @}
+
+/**
  * Close a connection. Callbacks for waiting queries will not be run.
  *
  * XXX: not implemented yet.
+ *
+ * @param evsql the context handle from evsql_new_*
  */
 void evsql_close (struct evsql *evsql);
 
--- a/src/evsql/result.c	Sat Nov 29 01:50:32 2008 +0200
+++ b/src/evsql/result.c	Sat Dec 13 04:20:56 2008 +0200
@@ -65,7 +65,7 @@
     }
 }
 
-int evsql_result_field (const struct evsql_result *res, size_t row, size_t col, char ** const ptr, size_t *size) {
+int evsql_result_field (const struct evsql_result *res, size_t row, size_t col, const char **ptr, size_t *size) {
     *ptr = NULL;
 
     switch (res->evsql->type) {
@@ -147,7 +147,7 @@
     va_start(vargs, res);
 
     for (col = res->info->columns, col_idx = 0; col->type; col++, col_idx++) {
-        char *value = NULL;
+        const char *value = NULL;
         size_t length = 0;
         
         // check for NULLs, then try and get the field value
@@ -172,7 +172,7 @@
             } break;
 
             case EVSQL_TYPE_STRING: {
-                char **str_ptr = va_arg(vargs, char **);
+                const char **str_ptr = va_arg(vargs, const char **);
 
                 if (value) {
                     *str_ptr = value;
--- a/src/evsql/util.c	Sat Nov 29 01:50:32 2008 +0200
+++ b/src/evsql/util.c	Sat Dec 13 04:20:56 2008 +0200
@@ -125,7 +125,7 @@
     }
 }
 
-int evsql_result_binary (const struct evsql_result *res, size_t row, size_t col, const char **ptr, size_t *size, int nullok) {
+int evsql_result_binary (const struct evsql_result *res, size_t row, size_t col, const char **ptr, size_t *size, bool nullok) {
     *ptr = NULL;
 
     switch (res->evsql->type) {