bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2004-2018 Dovecot authors, see the included COPYING file */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include "lib.h"
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen#include "array.h"
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#include "ioloop.h"
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen#include "str.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include "sql-api-private.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#include <time.h>
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct default_sql_prepared_statement {
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_prepared_statement prep_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen char *query_template;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen};
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
f69bd378b6454dc6498f7d35356ec651123e96a6Timo Sirainenstruct sql_db_module_register sql_db_module_register = { 0 };
8d80659e504ffb34bb0c6a633184fece35751b18Timo SirainenARRAY_TYPE(sql_drivers) sql_drivers;
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_drivers_init(void)
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen{
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen i_array_init(&sql_drivers, 8);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen}
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_drivers_deinit(void)
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen{
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen array_free(&sql_drivers);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen}
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainenstatic const struct sql_db *sql_driver_lookup(const char *name)
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen{
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen const struct sql_db *const *drivers;
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen unsigned int i, count;
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen drivers = array_get(&sql_drivers, &count);
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen for (i = 0; i < count; i++) {
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen if (strcmp(drivers[i]->name, name) == 0)
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen return drivers[i];
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen }
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen return NULL;
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen}
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_driver_register(const struct sql_db *driver)
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen{
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen if (sql_driver_lookup(driver->name) != NULL) {
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen i_fatal("sql_driver_register(%s): Already registered",
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen driver->name);
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen }
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen array_append(&sql_drivers, &driver, 1);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen}
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainenvoid sql_driver_unregister(const struct sql_db *driver)
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen{
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen const struct sql_db *const *drivers;
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen unsigned int i, count;
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen drivers = array_get(&sql_drivers, &count);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen for (i = 0; i < count; i++) {
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen if (drivers[i] == driver) {
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen array_delete(&sql_drivers, i, 1);
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen break;
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen }
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen }
0371406d952fe51367c7be91703e5634b7d9d225Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstruct sql_db *sql_init(const char *db_driver, const char *connect_string)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen const struct sql_db *driver;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen struct sql_db *db;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_assert(connect_string != NULL);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
903507ced4fed650d36782a897e5a56a1978367aTimo Sirainen driver = sql_driver_lookup(db_driver);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (driver == NULL)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_fatal("Unknown database driver '%s'", db_driver);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if ((driver->flags & SQL_DB_FLAG_POOLED) == 0)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen db = driver->v.init(connect_string);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen else
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen db = driver_sqlpool_init(connect_string, driver);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_array_init(&db->module_contexts, 5);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return db;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainenvoid sql_deinit(struct sql_db **_db)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen struct sql_db *db = *_db;
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen *_db = NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&db->to_reconnect);
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen db->v.deinit(db);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainenenum sql_db_flags sql_get_flags(struct sql_db *db)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return db->flags;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainenint sql_connect(struct sql_db *db)
a488bbb7e5d7cc537e7af21d1f651762a2b8bf56Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen time_t now;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen switch (db->state) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen case SQL_DB_STATE_DISCONNECTED:
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen break;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen case SQL_DB_STATE_CONNECTING:
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return 0;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen default:
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return 1;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* don't try reconnecting more than once a second */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen now = time(NULL);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (db->last_connect_try + (time_t)db->connect_delay > now)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return -1;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen db->last_connect_try = now;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen return db->v.connect(db);
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainen}
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid sql_disconnect(struct sql_db *db)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen{
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&db->to_reconnect);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen db->v.disconnect(db);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen}
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
13a8c553f293349248b161ff851743498916e26eTimo Sirainenconst char *sql_escape_string(struct sql_db *db, const char *string)
24ce0c343cefe54af841871fa39dbc3464028b06Timo Sirainen{
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen return db->v.escape_string(db, string);
24ce0c343cefe54af841871fa39dbc3464028b06Timo Sirainen}
24ce0c343cefe54af841871fa39dbc3464028b06Timo Sirainen
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainenconst char *sql_escape_blob(struct sql_db *db,
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen const unsigned char *data, size_t size)
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen{
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen return db->v.escape_blob(db, data, size);
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen}
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainenvoid sql_exec(struct sql_db *db, const char *query)
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainen{
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen db->v.exec(db, query);
a488bbb7e5d7cc537e7af21d1f651762a2b8bf56Timo Sirainen}
a488bbb7e5d7cc537e7af21d1f651762a2b8bf56Timo Sirainen
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen#undef sql_query
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenvoid sql_query(struct sql_db *db, const char *query,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen sql_query_callback_t *callback, void *context)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen db->v.query(db, query, callback, context);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenstruct sql_result *sql_query_s(struct sql_db *db, const char *query)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen{
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen return db->v.query_s(db, query);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstatic struct sql_prepared_statement *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainendefault_sql_prepared_statement_init(struct sql_db *db,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen const char *query_template)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct default_sql_prepared_statement *prep_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen prep_stmt = i_new(struct default_sql_prepared_statement, 1);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen prep_stmt->prep_stmt.db = db;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen prep_stmt->query_template = i_strdup(query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return &prep_stmt->prep_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstatic void
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainendefault_sql_prepared_statement_deinit(struct sql_prepared_statement *_prep_stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct default_sql_prepared_statement *prep_stmt =
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen (struct default_sql_prepared_statement *)_prep_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen i_free(prep_stmt->query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen i_free(prep_stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstatic struct sql_statement *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainendefault_sql_statement_init_prepared(struct sql_prepared_statement *_stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct default_sql_prepared_statement *stmt =
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen (struct default_sql_prepared_statement *)_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return sql_statement_init(_stmt->db, stmt->query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenconst char *sql_statement_get_query(struct sql_statement *stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen string_t *query = t_str_new(128);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen const char *const *args;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int i, args_count, arg_pos = 0;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen args = array_get(&stmt->args, &args_count);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen for (i = 0; stmt->query_template[i] != '\0'; i++) {
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (stmt->query_template[i] == '?') {
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (arg_pos >= args_count ||
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen args[arg_pos] == NULL) {
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen i_panic("lib-sql: Missing bind for arg #%u in statement: %s",
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen arg_pos, stmt->query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen }
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen str_append(query, args[arg_pos++]);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen } else {
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen str_append_c(query, stmt->query_template[i]);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen }
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen }
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (arg_pos != args_count) {
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen i_panic("lib-sql: Too many bind args (%u) for statement: %s",
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen args_count, stmt->query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen }
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return str_c(query);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstatic void
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainendefault_sql_statement_query(struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_query_callback_t *callback, void *context)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_query(stmt->db, sql_statement_get_query(stmt),
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen callback, context);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen pool_unref(&stmt->pool);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstatic struct sql_result *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainendefault_sql_statement_query_s(struct sql_statement *stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_result *result =
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_query_s(stmt->db, sql_statement_get_query(stmt));
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen pool_unref(&stmt->pool);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return result;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstatic void default_sql_update_stmt(struct sql_transaction_context *ctx,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int *affected_rows)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen ctx->db->v.update(ctx, sql_statement_get_query(stmt),
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen affected_rows);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen pool_unref(&stmt->pool);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct sql_prepared_statement *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainensql_prepared_statement_init(struct sql_db *db, const char *query_template)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (db->v.prepared_statement_init != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return db->v.prepared_statement_init(db, query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen else
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return default_sql_prepared_statement_init(db, query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_prepared_statement_deinit(struct sql_prepared_statement **_prep_stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_prepared_statement *prep_stmt = *_prep_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen *_prep_stmt = NULL;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (prep_stmt->db->v.prepared_statement_deinit != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen prep_stmt->db->v.prepared_statement_deinit(prep_stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen else
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen default_sql_prepared_statement_deinit(prep_stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstatic void
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainensql_statement_init_fields(struct sql_statement *stmt, struct sql_db *db)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->db = db;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen p_array_init(&stmt->args, stmt->pool, 8);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct sql_statement *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainensql_statement_init(struct sql_db *db, const char *query_template)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement *stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (db->v.statement_init != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt = db->v.statement_init(db, query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen else {
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen pool_t pool = pool_alloconly_create("sql statement", 1024);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt = p_new(pool, struct sql_statement, 1);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->pool = pool;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen }
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->query_template = p_strdup(stmt->pool, query_template);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_statement_init_fields(stmt, db);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct sql_statement *
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainensql_statement_init_prepared(struct sql_prepared_statement *prep_stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement *stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (prep_stmt->db->v.statement_init_prepared == NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return default_sql_statement_init_prepared(prep_stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt = prep_stmt->db->v.statement_init_prepared(prep_stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_statement_init_fields(stmt, prep_stmt->db);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_abort(struct sql_statement **_stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement *stmt = *_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen *_stmt = NULL;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (stmt->db->v.statement_abort != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->db->v.statement_abort(stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen pool_unref(&stmt->pool);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_set_timestamp(struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen const struct timespec *ts)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (stmt->db->v.statement_set_timestamp != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->db->v.statement_set_timestamp(stmt, ts);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_bind_str(struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int column_idx, const char *value)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen const char *escaped_value =
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen p_strdup_printf(stmt->pool, "'%s'",
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_escape_string(stmt->db, value));
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen array_idx_set(&stmt->args, column_idx, &escaped_value);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (stmt->db->v.statement_bind_str != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->db->v.statement_bind_str(stmt, column_idx, value);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
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 Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen const char *value_str =
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen p_strdup_printf(stmt->pool, "%s",
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_escape_blob(stmt->db, value, value_size));
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen array_idx_set(&stmt->args, column_idx, &value_str);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (stmt->db->v.statement_bind_binary != NULL) {
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->db->v.statement_bind_binary(stmt, column_idx,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen value, value_size);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen }
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_bind_int64(struct sql_statement *stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int column_idx, int64_t value)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen const char *value_str = p_strdup_printf(stmt->pool, "%"PRId64, value);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen array_idx_set(&stmt->args, column_idx, &value_str);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (stmt->db->v.statement_bind_int64 != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->db->v.statement_bind_int64(stmt, column_idx, value);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen#undef sql_statement_query
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_statement_query(struct sql_statement **_stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen sql_query_callback_t *callback, void *context)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement *stmt = *_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen *_stmt = NULL;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (stmt->db->v.statement_query != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen stmt->db->v.statement_query(stmt, callback, context);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen else
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen default_sql_statement_query(stmt, callback, context);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenstruct sql_result *sql_statement_query_s(struct sql_statement **_stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement *stmt = *_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen *_stmt = NULL;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (stmt->db->v.statement_query_s != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return stmt->db->v.statement_query_s(stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen else
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen return default_sql_statement_query_s(stmt);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainenvoid sql_result_ref(struct sql_result *result)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen{
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen result->refcount++;
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen}
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainenvoid sql_result_unref(struct sql_result *result)
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen{
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen i_assert(result->refcount > 0);
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen if (--result->refcount > 0)
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen return;
3656c91dcb8336814bebd4500e81c3dde25233e6Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen i_free(result->map);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->v.free(result);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen}
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenstatic const struct sql_field_def *
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainensql_field_def_find(const struct sql_field_def *fields, const char *name)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen unsigned int i;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen for (i = 0; fields[i].name != NULL; i++) {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen if (strcasecmp(fields[i].name, name) == 0)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return &fields[i];
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return NULL;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen}
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenstatic void
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainensql_result_build_map(struct sql_result *result,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen const struct sql_field_def *fields, size_t dest_size)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen const struct sql_field_def *def;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen const char *name;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen unsigned int i, count, field_size = 0;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen count = sql_result_get_fields_count(result);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->map_size = count;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->map = i_new(struct sql_field_map, result->map_size);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen for (i = 0; i < count; i++) {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen name = sql_result_get_field_name(result, i);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen def = sql_field_def_find(fields, name);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen if (def != NULL) {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->map[i].type = def->type;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->map[i].offset = def->offset;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen switch (def->type) {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen case SQL_TYPE_STR:
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen field_size = sizeof(const char *);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen break;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen case SQL_TYPE_UINT:
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen field_size = sizeof(unsigned int);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen break;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen case SQL_TYPE_ULLONG:
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen field_size = sizeof(unsigned long long);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen break;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen case SQL_TYPE_BOOL:
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen field_size = sizeof(bool);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen break;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen i_assert(def->offset + field_size <= dest_size);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen } else {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->map[i].offset = (size_t)-1;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen}
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo 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{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen if (result->map == NULL)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen sql_result_build_map(result, fields, dest_size);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->fetch_dest = dest;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->fetch_dest_size = dest_size;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen}
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenstatic void sql_result_fetch(struct sql_result *result)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen unsigned int i, count;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen const char *value;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen void *ptr;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen memset(result->fetch_dest, 0, result->fetch_dest_size);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen count = result->map_size;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen for (i = 0; i < count; i++) {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen if (result->map[i].offset == (size_t)-1)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen continue;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen value = sql_result_get_field_value(result, i);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen ptr = STRUCT_MEMBER_P(result->fetch_dest,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen result->map[i].offset);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen switch (result->map[i].type) {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen case SQL_TYPE_STR: {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen *((const char **)ptr) = value;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen break;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen case SQL_TYPE_UINT: {
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (value != NULL &&
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen str_to_uint(value, (unsigned int *)ptr) < 0)
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen i_error("sql: Value not uint: %s", value);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen break;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen case SQL_TYPE_ULLONG: {
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (value != NULL &&
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen str_to_ullong(value, (unsigned long long *)ptr) < 0)
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen i_error("sql: Value not ullong: %s", value);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen break;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen case SQL_TYPE_BOOL: {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen if (value != NULL && (*value == 't' || *value == '1'))
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen *((bool *)ptr) = TRUE;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen break;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen }
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint sql_result_next_row(struct sql_result *result)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen int ret;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen if ((ret = result->v.next_row(result)) <= 0)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return ret;
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen if (result->fetch_dest != NULL)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen sql_result_fetch(result);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return 1;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen#undef sql_result_more
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainenvoid sql_result_more(struct sql_result **result,
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen sql_query_callback_t *callback, void *context)
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen{
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen i_assert((*result)->v.more != NULL);
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen (*result)->v.more(result, TRUE, callback, context);
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen}
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainenstatic void
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainensql_result_more_sync_callback(struct sql_result *result, void *context)
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen{
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen struct sql_result **dest_result = context;
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen *dest_result = result;
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen}
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainenvoid sql_result_more_s(struct sql_result **result)
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen{
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen i_assert((*result)->v.more != NULL);
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen (*result)->v.more(result, FALSE, sql_result_more_sync_callback, result);
065189672f2e741255ac22b158a23207b0ab05a3Timo Sirainen /* the callback must have been called */
065189672f2e741255ac22b158a23207b0ab05a3Timo Sirainen i_assert(*result != NULL);
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen}
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenunsigned int sql_result_get_fields_count(struct sql_result *result)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return result->v.get_fields_count(result);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *sql_result_get_field_name(struct sql_result *result,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen unsigned int idx)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return result->v.get_field_name(result, idx);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint sql_result_find_field(struct sql_result *result, const char *field_name)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return result->v.find_field(result, field_name);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *sql_result_get_field_value(struct sql_result *result,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen unsigned int idx)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return result->v.get_field_value(result, idx);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen}
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenconst unsigned char *
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainensql_result_get_field_value_binary(struct sql_result *result,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen unsigned int idx, size_t *size_r)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return result->v.get_field_value_binary(result, idx, size_r);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *sql_result_find_field_value(struct sql_result *result,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen const char *field_name)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return result->v.find_field_value(result, field_name);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *const *sql_result_get_values(struct sql_result *result)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return result->v.get_values(result);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenconst char *sql_result_get_error(struct sql_result *result)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen return result->v.get_error(result);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainenenum sql_result_error_type sql_result_get_error_type(struct sql_result *result)
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen{
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen return result->error_type;
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen}
1601169d6f6004e0656238ed7691c16f3aab61aaTimo Sirainen
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenstatic void
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainensql_result_not_connected_free(struct sql_result *result ATTR_UNUSED)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen{
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainensql_result_not_connected_next_row(struct sql_result *result ATTR_UNUSED)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen return -1;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic const char *
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainensql_result_not_connected_get_error(struct sql_result *result ATTR_UNUSED)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return SQL_ERRSTR_NOT_CONNECTED;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenstruct sql_transaction_context *sql_transaction_begin(struct sql_db *db)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen{
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen return db->v.transaction_begin(db);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen#undef sql_transaction_commit
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid sql_transaction_commit(struct sql_transaction_context **_ctx,
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen sql_commit_callback_t *callback, void *context)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct sql_transaction_context *ctx = *_ctx;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *_ctx = NULL;
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen ctx->db->v.transaction_commit(ctx, callback, context);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenint sql_transaction_commit_s(struct sql_transaction_context **_ctx,
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen const char **error_r)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct sql_transaction_context *ctx = *_ctx;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *_ctx = NULL;
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen return ctx->db->v.transaction_commit_s(ctx, error_r);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid sql_transaction_rollback(struct sql_transaction_context **_ctx)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct sql_transaction_context *ctx = *_ctx;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *_ctx = NULL;
0ae010139a1bb3b29fbf117c5da1a6a6c6b7b5a0Timo Sirainen ctx->db->v.transaction_rollback(ctx);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenvoid sql_update(struct sql_transaction_context *ctx, const char *query)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen{
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen ctx->db->v.update(ctx, query, NULL);
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen}
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_update_stmt(struct sql_transaction_context *ctx,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement **_stmt)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement *stmt = *_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen *_stmt = NULL;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (ctx->db->v.update_stmt != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen ctx->db->v.update_stmt(ctx, stmt, NULL);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen else
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen default_sql_update_stmt(ctx, stmt, NULL);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainenvoid sql_update_get_rows(struct sql_transaction_context *ctx, const char *query,
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen unsigned int *affected_rows)
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen{
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen ctx->db->v.update(ctx, query, affected_rows);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen}
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainenvoid sql_update_stmt_get_rows(struct sql_transaction_context *ctx,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement **_stmt,
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen unsigned int *affected_rows)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen{
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen struct sql_statement *stmt = *_stmt;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen *_stmt = NULL;
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen if (ctx->db->v.update_stmt != NULL)
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen ctx->db->v.update_stmt(ctx, stmt, affected_rows);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen else
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen default_sql_update_stmt(ctx, stmt, affected_rows);
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen}
9f0fc74e3387d3e496fb0c8f77633e27e48cc1ffTimo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid sql_db_set_state(struct sql_db *db, enum sql_db_state state)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen enum sql_db_state old_state = db->state;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (db->state == state)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen db->state = state;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (db->state_change_callback != NULL) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen db->state_change_callback(db, old_state,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen db->state_change_context);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen}
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid sql_transaction_add_query(struct sql_transaction_context *ctx, pool_t pool,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen const char *query, unsigned int *affected_rows)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen struct sql_transaction_query *tquery;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen tquery = p_new(pool, struct sql_transaction_query, 1);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen tquery->trans = ctx;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen tquery->query = p_strdup(pool, query);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen tquery->affected_rows = affected_rows;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (ctx->head == NULL)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->head = tquery;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen else
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->tail->next = tquery;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->tail = tquery;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen}
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstruct sql_result sql_not_connected_result = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen sql_result_not_connected_free,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen sql_result_not_connected_next_row,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen NULL, NULL, NULL, NULL, NULL, NULL, NULL,
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen sql_result_not_connected_get_error,
402f9bcf48cbccc17fdb5f3ea411a7967aed0fd0Timo Sirainen NULL,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen },
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen .failed_try_retry = TRUE
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen};