sql-api.h revision b87761f9bbef949f31dae297e619ac3f5e9c2b2e
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody#ifndef SQL_API_H
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen#define SQL_API_H
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* This SQL API is designed to work asynchronously. The underlying drivers
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen however may not. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenenum sql_db_flags {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* Set if queries are not executed asynchronously */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen SQL_DB_FLAG_BLOCKING = 0x01,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* Set if database wants to use connection pooling */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen SQL_DB_FLAG_POOLED = 0x02
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen};
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenenum sql_field_type {
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen SQL_TYPE_STR,
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen SQL_TYPE_UINT,
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen SQL_TYPE_ULLONG,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen SQL_TYPE_BOOL
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen};
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstruct sql_field_def {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen enum sql_field_type type;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen const char *name;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen size_t offset;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen};
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#define SQL_DEF_STRUCT(name, struct_name, type, c_type) \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen { (type) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen ((struct struct_name *)0)->name, c_type), \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen #name, offsetof(struct struct_name, name) }
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#define SQL_DEF_STRUCT_STR(name, struct_name) \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_STR, const char *)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#define SQL_DEF_STRUCT_UINT(name, struct_name) \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_UINT, unsigned int)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#define SQL_DEF_STRUCT_ULLONG(name, struct_name) \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_ULLONG, unsigned long long)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#define SQL_DEF_STRUCT_BOOL(name, struct_name) \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_BOOL, bool)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenstruct sql_db;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenstruct sql_result;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainentypedef void sql_query_callback_t(struct sql_result *result, void *context);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainentypedef void sql_commit_callback_t(const char *error, void *context);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenvoid sql_drivers_init(void);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenvoid sql_drivers_deinit(void);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen/* register all built-in SQL drivers */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_drivers_register_all(void);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_driver_register(const struct sql_db *driver);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_driver_unregister(const struct sql_db *driver);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Initialize database connections. db_driver is the database driver name,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen eg. "mysql" or "pgsql". connect_string is driver-specific. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstruct sql_db *sql_init(const char *db_driver, const char *connect_string);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_deinit(struct sql_db **db);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Returns SQL database state flags. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenenum sql_db_flags sql_get_flags(struct sql_db *db);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Explicitly connect to the database. It's not required to call this function
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen though. Returns -1 if we're not connected, 0 if we started connecting or
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen 1 if we are fully connected now. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenint sql_connect(struct sql_db *db);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Explicitly disconnect from database and abort pending auth requests. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_disconnect(struct sql_db *db);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Escape the given string if needed and return it. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenconst char *sql_escape_string(struct sql_db *db, const char *string);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Escape the given data as a string. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenconst char *sql_escape_blob(struct sql_db *db,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const unsigned char *data, size_t size);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Execute SQL query without waiting for results. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_exec(struct sql_db *db, const char *query);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Execute SQL query and return result in callback. If fields list is given,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen the returned fields are validated to be of correct type, and you can use
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen sql_result_next_row_get() */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_query(struct sql_db *db, const char *query,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen sql_query_callback_t *callback, void *context);
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen#define sql_query(db, query, callback, context) \
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen sql_query(db, query + \
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen CALLBACK_TYPECHECK(callback, void (*)( \
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen struct sql_result *, typeof(context))), \
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen (sql_query_callback_t *)callback, context)
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen/* Execute blocking SQL query and return result. */
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainenstruct sql_result *sql_query_s(struct sql_db *db, const char *query);
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainenvoid sql_result_setup_fetch(struct sql_result *result,
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen const struct sql_field_def *fields,
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen void *dest, size_t dest_size);
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Go to next row, returns 1 if ok, 0 if this was the last row or -1 if error
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen occurred. This needs to be the first call for result. */
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainenint sql_result_next_row(struct sql_result *result);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_result_ref(struct sql_result *result);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Needs to be called only with sql_query_s() or when result has been
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen explicitly referenced. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid sql_result_unref(struct sql_result *result);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Return number of fields in result. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenunsigned int sql_result_get_fields_count(struct sql_result *result);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Return name of the given field index. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenconst char *sql_result_get_field_name(struct sql_result *result,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen unsigned int idx);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Return field index for given name, or -1 if not found. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenint sql_result_find_field(struct sql_result *result, const char *field_name);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Returns value of given field as string. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenconst char *sql_result_get_field_value(struct sql_result *result,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen unsigned int idx);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenconst unsigned char *
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainensql_result_get_field_value_binary(struct sql_result *result,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen unsigned int idx, size_t *size_r);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenconst char *sql_result_find_field_value(struct sql_result *result,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const char *field_name);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Return all values of current row. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenconst char *const *sql_result_get_values(struct sql_result *result);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Return last error message in result. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenconst char *sql_result_get_error(struct sql_result *result);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Begin a new transaction. Currently you're limited to only one open
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen transaction at a time. */
b8864211b88ed7521e9af514590639344af38910Timo Sirainenstruct sql_transaction_context *sql_transaction_begin(struct sql_db *db);
b8864211b88ed7521e9af514590639344af38910Timo Sirainen/* Commit transaction. */
c3cb859d93a77d52d6af054d358b55d45b4a5188Timo Sirainenvoid sql_transaction_commit(struct sql_transaction_context **ctx,
b8864211b88ed7521e9af514590639344af38910Timo Sirainen sql_commit_callback_t *callback, void *context);
c3cb859d93a77d52d6af054d358b55d45b4a5188Timo Sirainen#define sql_transaction_commit(ctx, callback, context) \
c3cb859d93a77d52d6af054d358b55d45b4a5188Timo Sirainen sql_transaction_commit(ctx + \
c3cb859d93a77d52d6af054d358b55d45b4a5188Timo Sirainen CALLBACK_TYPECHECK(callback, void (*)( \
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const char *, typeof(context))), \
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen (sql_commit_callback_t *)callback, context)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen/* Synchronous commit. Returns 0 if ok, -1 if error. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenint sql_transaction_commit_s(struct sql_transaction_context **ctx,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const char **error_r);
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainenvoid sql_transaction_rollback(struct sql_transaction_context **ctx);
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen/* Execute query in given transaction. */
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainenvoid sql_update(struct sql_transaction_context *ctx, const char *query);
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen/* Save the number of rows updated by this query. The value is set before
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen commit callback is called. */
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainenvoid sql_update_get_rows(struct sql_transaction_context *ctx, const char *query,
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen unsigned int *affected_rows);
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen#endif
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen