c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef SQL_API_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define SQL_API_H
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
e3a3366eea09eb2ee25ad546cc88dfdee9715dcbTimo Sirainenstruct timespec;
e3a3366eea09eb2ee25ad546cc88dfdee9715dcbTimo Sirainen
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen/* This SQL API is designed to work asynchronously. The underlying drivers
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen however may not. */
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
ccffb125d94adff0ad776de5a96e22f864d6fb0aTimo Sirainenenum sql_db_flags {
ccffb125d94adff0ad776de5a96e22f864d6fb0aTimo Sirainen /* Set if queries are not executed asynchronously */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen SQL_DB_FLAG_BLOCKING = 0x01,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* Set if database wants to use connection pooling */
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen SQL_DB_FLAG_POOLED = 0x02,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen /* Prepared statements are supported by the database. If they aren't,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen the functions can still be used, but they're just internally
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen convered into regular statements. */
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen SQL_DB_FLAG_PREP_STATEMENTS = 0x04,
ccffb125d94adff0ad776de5a96e22f864d6fb0aTimo Sirainen};
ccffb125d94adff0ad776de5a96e22f864d6fb0aTimo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenenum sql_field_type {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen SQL_TYPE_STR,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen SQL_TYPE_UINT,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen SQL_TYPE_ULLONG,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen SQL_TYPE_BOOL
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen};
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenstruct sql_field_def {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen enum sql_field_type type;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen const char *name;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen size_t offset;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen};
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainenenum sql_result_error_type {
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen SQL_RESULT_ERROR_TYPE_UNKNOWN = 0,
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen /* It's unknown whether write succeeded or not. This could be due to
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen a timeout or a disconnection from server. */
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen SQL_RESULT_ERROR_TYPE_WRITE_UNCERTAIN
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen};
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainenenum sql_result_next {
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen /* Row was returned */
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen SQL_RESULT_NEXT_OK = 1,
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen /* There are no more rows */
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen SQL_RESULT_NEXT_LAST = 0,
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen /* Error occurred - see sql_result_get_error*() */
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen SQL_RESULT_NEXT_ERROR = -1,
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen /* There are more results - call sql_result_more() */
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen SQL_RESULT_NEXT_MORE = -99
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen};
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen#define SQL_DEF_STRUCT(name, struct_name, type, c_type) \
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen { (type) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen ((struct struct_name *)0)->name, c_type), \
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen #name, offsetof(struct struct_name, name) }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen#define SQL_DEF_STRUCT_STR(name, struct_name) \
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_STR, const char *)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen#define SQL_DEF_STRUCT_UINT(name, struct_name) \
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_UINT, unsigned int)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen#define SQL_DEF_STRUCT_ULLONG(name, struct_name) \
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_ULLONG, unsigned long long)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen#define SQL_DEF_STRUCT_BOOL(name, struct_name) \
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_BOOL, bool)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstruct sql_db;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstruct sql_result;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
bb2b3656ef7635acc374f7fc19b25aeeb454ae95Timo Sirainenstruct sql_commit_result {
bb2b3656ef7635acc374f7fc19b25aeeb454ae95Timo Sirainen const char *error;
bb2b3656ef7635acc374f7fc19b25aeeb454ae95Timo Sirainen enum sql_result_error_type error_type;
bb2b3656ef7635acc374f7fc19b25aeeb454ae95Timo Sirainen};
bb2b3656ef7635acc374f7fc19b25aeeb454ae95Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainentypedef void sql_query_callback_t(struct sql_result *result, void *context);
bb2b3656ef7635acc374f7fc19b25aeeb454ae95Timo Sirainentypedef void sql_commit_callback_t(const struct sql_commit_result *result, void *context);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_drivers_init(void);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_drivers_deinit(void);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen/* register all built-in SQL drivers */
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_drivers_register_all(void);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_driver_register(const struct sql_db *driver);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_driver_unregister(const struct sql_db *driver);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Initialize database connections. db_driver is the database driver name,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen eg. "mysql" or "pgsql". connect_string is driver-specific. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstruct sql_db *sql_init(const char *db_driver, const char *connect_string);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid sql_deinit(struct sql_db **db);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
ccffb125d94adff0ad776de5a96e22f864d6fb0aTimo Sirainen/* Returns SQL database state flags. */
ccffb125d94adff0ad776de5a96e22f864d6fb0aTimo Sirainenenum sql_db_flags sql_get_flags(struct sql_db *db);
ccffb125d94adff0ad776de5a96e22f864d6fb0aTimo Sirainen
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainen/* Explicitly connect to the database. It's not required to call this function
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainen though. Returns -1 if we're not connected, 0 if we started connecting or
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainen 1 if we are fully connected now. */
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainenint sql_connect(struct sql_db *db);
9349a0afffad990e45d3ad33081e1d2d9e68a753Timo Sirainen/* Explicitly disconnect from database and abort pending auth requests. */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid sql_disconnect(struct sql_db *db);
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainen
24ce0c343cefe54af841871fa39dbc3464028b06Timo Sirainen/* Escape the given string if needed and return it. */
13a8c553f293349248b161ff851743498916e26eTimo Sirainenconst char *sql_escape_string(struct sql_db *db, const char *string);
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen/* Escape the given data as a string. */
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainenconst char *sql_escape_blob(struct sql_db *db,
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen const unsigned char *data, size_t size);
24ce0c343cefe54af841871fa39dbc3464028b06Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Execute SQL query without waiting for results. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenvoid sql_exec(struct sql_db *db, const char *query);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen/* Execute SQL query and return result in callback. If fields list is given,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen the returned fields are validated to be of correct type, and you can use
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen sql_result_next_row_get() */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenvoid sql_query(struct sql_db *db, const char *query,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen sql_query_callback_t *callback, void *context);
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen#define sql_query(db, query, callback, context) \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen sql_query(db, query + \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen CALLBACK_TYPECHECK(callback, void (*)( \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen struct sql_result *, typeof(context))), \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen (sql_query_callback_t *)callback, context)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen/* Execute blocking SQL query and return result. */
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenstruct sql_result *sql_query_s(struct sql_db *db, const char *query);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct sql_prepared_statement *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainensql_prepared_statement_init(struct sql_db *db, const char *query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_prepared_statement_deinit(struct sql_prepared_statement **prep_stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct sql_statement *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainensql_statement_init(struct sql_db *db, const char *query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct sql_statement *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainensql_statement_init_prepared(struct sql_prepared_statement *prep_stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_abort(struct sql_statement **stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_set_timestamp(struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen const struct timespec *ts);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_bind_str(struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int column_idx, const char *value);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_bind_binary(struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int column_idx, const void *value,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen size_t value_size);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_bind_int64(struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int column_idx, int64_t value);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_query(struct sql_statement **stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_query_callback_t *callback, void *context);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen#define sql_statement_query(stmt, callback, context) \
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_statement_query(stmt, \
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen (sql_query_callback_t *)callback, context + \
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen CALLBACK_TYPECHECK(callback, void (*)( \
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_result *, typeof(context))))
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct sql_result *sql_statement_query_s(struct sql_statement **stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenvoid sql_result_setup_fetch(struct sql_result *result,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen const struct sql_field_def *fields,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen void *dest, size_t dest_size);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen/* Go to next row. See enum sql_result_next. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint sql_result_next_row(struct sql_result *result);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen/* If sql_result_next_row() returned SQL_RESULT_NEXT_MORE, this can be called
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen to continue returning more results. The result is freed with this call, so
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen it must not be accesed anymore until the callback is finished. */
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainenvoid sql_result_more(struct sql_result **result,
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen sql_query_callback_t *callback, void *context);
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen#define sql_result_more(result, callback, context) \
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen sql_result_more(result + \
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen CALLBACK_TYPECHECK(callback, void (*)( \
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen struct sql_result *, typeof(context))), \
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen (sql_query_callback_t *)callback, context)
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen/* Synchronous version of sql_result_more(). The result will be replaced with
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen the new result. */
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainenvoid sql_result_more_s(struct sql_result **result);
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainenvoid sql_result_ref(struct sql_result *result);
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen/* Needs to be called only with sql_query_s() or when result has been
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen explicitly referenced. */
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainenvoid sql_result_unref(struct sql_result *result);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Return number of fields in result. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenunsigned int sql_result_get_fields_count(struct sql_result *result);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Return name of the given field index. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *sql_result_get_field_name(struct sql_result *result,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen unsigned int idx);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Return field index for given name, or -1 if not found. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint sql_result_find_field(struct sql_result *result, const char *field_name);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen/* Returns value of given field as string. Note that it can be NULL. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *sql_result_get_field_value(struct sql_result *result,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen unsigned int idx);
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen/* Returns a binary value. Note that a NULL is returned as NULL with size=0,
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen while empty string returns non-NULL with size=0. */
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenconst unsigned char *
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainensql_result_get_field_value_binary(struct sql_result *result,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen unsigned int idx, size_t *size_r);
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen/* Find the field and return its value. NULL return value can mean that either
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen the field didn't exist or that its value is NULL. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *sql_result_find_field_value(struct sql_result *result,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen const char *field_name);
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen/* Return all values of current row. Note that this array is not
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen NULL-terminated - you must use sql_result_get_fields_count() to find out
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen the array's length. It's also possible that some of the values inside the
0b307ab3d0c48074b367f573d239e9db8b76a2caTimo Sirainen array are NULL. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *const *sql_result_get_values(struct sql_result *result);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Return last error message in result. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *sql_result_get_error(struct sql_result *result);
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainenenum sql_result_error_type sql_result_get_error_type(struct sql_result *result);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen/* Begin a new transaction. Currently you're limited to only one open
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen transaction at a time. */
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenstruct sql_transaction_context *sql_transaction_begin(struct sql_db *db);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen/* Commit transaction. */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid sql_transaction_commit(struct sql_transaction_context **ctx,
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen sql_commit_callback_t *callback, void *context);
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen#define sql_transaction_commit(ctx, callback, context) \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen sql_transaction_commit(ctx + \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen CALLBACK_TYPECHECK(callback, void (*)( \
bb2b3656ef7635acc374f7fc19b25aeeb454ae95Timo Sirainen const struct sql_commit_result *, typeof(context))), \
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainen (sql_commit_callback_t *)callback, context)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen/* Synchronous commit. Returns 0 if ok, -1 if error. */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenint sql_transaction_commit_s(struct sql_transaction_context **ctx,
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen const char **error_r);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid sql_transaction_rollback(struct sql_transaction_context **ctx);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen/* Execute query in given transaction. */
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenvoid sql_update(struct sql_transaction_context *ctx, const char *query);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_update_stmt(struct sql_transaction_context *ctx,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement **stmt);
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen/* Save the number of rows updated by this query. The value is set before
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen commit callback is called. */
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainenvoid sql_update_get_rows(struct sql_transaction_context *ctx, const char *query,
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen unsigned int *affected_rows);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_update_stmt_get_rows(struct sql_transaction_context *ctx,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement **stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int *affected_rows);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#endif