sql_lookup_pass(sql_request);
}
-static void sql_set_credentials_callback(const char *error,
+static void sql_set_credentials_callback(const struct sql_commit_result *sql_result,
struct passdb_sql_request *sql_request)
{
struct passdb_module *_module =
sql_request->auth_request->passdb->passdb;
struct sql_passdb_module *module = (struct sql_passdb_module *)_module;
- if (error != NULL) {
+ if (sql_result->error != NULL) {
if (!module->conn->default_update_query) {
auth_request_log_error(sql_request->auth_request,
AUTH_SUBSYS_DB,
- "Set credentials query failed: %s", error);
+ "Set credentials query failed: %s", sql_result->error);
} else {
auth_request_log_error(sql_request->auth_request,
AUTH_SUBSYS_DB,
"Set credentials query failed: %s"
"(using built-in default update_query: %s)",
- error, module->conn->set.update_query);
+ sql_result->error, module->conn->set.update_query);
}
}
sql_request->callback.
- set_credentials(error == NULL, sql_request->auth_request);
+ set_credentials(sql_result->error == NULL, sql_request->auth_request);
i_free(sql_request);
}
}
static void
-sql_dict_transaction_commit_callback(const char *error,
+sql_dict_transaction_commit_callback(const struct sql_commit_result *sql_result,
struct sql_dict_transaction_context *ctx)
{
struct dict_commit_result result;
memset(&result, 0, sizeof(result));
- if (error == NULL)
+ if (sql_result->error == NULL)
result.ret = sql_dict_transaction_has_nonexistent(ctx) ? 0 : 1;
else {
- result.error = t_strdup_printf("sql dict: commit failed: %s", error);
+ result.error = t_strdup_printf("sql dict: commit failed: %s",
+ sql_result->error);
result.ret = -1;
}
transaction_commit_callback(struct sql_result *result, void *context)
{
struct cassandra_transaction_context *ctx = context;
+ struct sql_commit_result commit_result;
- if (sql_result_next_row(result) < 0)
- ctx->callback(sql_result_get_error(result), ctx->context);
- else
- ctx->callback(NULL, ctx->context);
+ memset(&commit_result, 0, sizeof(commit_result));
+ if (sql_result_next_row(result) < 0) {
+ commit_result.error = sql_result_get_error(result);
+ commit_result.error_type = sql_result_get_error_type(result);
+ }
+ ctx->callback(&commit_result, ctx->context);
driver_cassandra_transaction_unref(&ctx);
}
struct cassandra_transaction_context *ctx =
(struct cassandra_transaction_context *)_ctx;
enum cassandra_query_type query_type;
+ struct sql_commit_result result;
+ memset(&result, 0, sizeof(result));
ctx->callback = callback;
ctx->context = context;
if (ctx->failed || _ctx->head == NULL) {
- callback(ctx->failed ? ctx->error : NULL, context);
+ if (ctx->failed)
+ result.error = ctx->error;
+
+ callback(&result, context);
driver_cassandra_transaction_unref(&ctx);
} else if (_ctx->head->next == NULL) {
/* just a single query, send it */
transaction_commit_callback, ctx);
} else {
/* multiple queries - we don't actually have a transaction though */
- callback("Multiple changes in transaction not supported", context);
+ result.error = "Multiple changes in transaction not supported";
+ callback(&result, context);
}
}
driver_mysql_transaction_commit(struct sql_transaction_context *ctx,
sql_commit_callback_t *callback, void *context)
{
+ struct sql_commit_result result;
const char *error;
+ memset(&result, 0, sizeof(result));
if (sql_transaction_commit_s(&ctx, &error) < 0)
- callback(error, context);
- else
- callback(NULL, context);
+ result.error = error;
+ callback(&result, context);
}
static int ATTR_NULL(3)
transaction_commit_callback(struct sql_result *result,
struct pgsql_transaction_context *ctx)
{
- if (sql_result_next_row(result) < 0)
- ctx->callback(sql_result_get_error(result), ctx->context);
- else
- ctx->callback(NULL, ctx->context);
+ struct sql_commit_result commit_result;
+
+ memset(&commit_result, 0, sizeof(result));
+ if (sql_result_next_row(result) < 0) {
+ commit_result.error = sql_result_get_error(result);
+ commit_result.error_type = sql_result_get_error_type(result);
+ }
+ ctx->callback(&commit_result, ctx->context);
driver_pgsql_transaction_free(ctx);
}
/* kludgy.. */
ctx->ctx.db->state = SQL_DB_STATE_IDLE;
} else if (!SQL_DB_IS_READY(ctx->ctx.db)) {
- ctx->callback("Not connected", ctx->context);
+ struct sql_commit_result commit_result = {
+ .error = "Not connected"
+ };
+ ctx->callback(&commit_result, ctx->context);
return FALSE;
}
return TRUE;
}
+static void
+transaction_commit_error_callback(struct pgsql_transaction_context *ctx,
+ struct sql_result *result)
+{
+ struct sql_commit_result commit_result;
+
+ memset(&commit_result, 0, sizeof(result));
+ commit_result.error = sql_result_get_error(result);
+ commit_result.error_type = sql_result_get_error_type(result);
+
+ ctx->callback(&commit_result, ctx->context);
+}
+
static void
transaction_begin_callback(struct sql_result *result,
struct pgsql_transaction_context *ctx)
i_assert(result->db == ctx->ctx.db);
if (sql_result_next_row(result) < 0) {
- ctx->callback(sql_result_get_error(result), ctx->context);
+ transaction_commit_error_callback(ctx, result);
driver_pgsql_transaction_free(ctx);
return;
}
struct pgsql_db *db = (struct pgsql_db *)result->db;
if (sql_result_next_row(result) < 0) {
- ctx->callback(sql_result_get_error(result), ctx->context);
+ transaction_commit_error_callback(ctx, result);
driver_pgsql_transaction_free(ctx);
return;
}
{
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)query->trans;
+ struct sql_commit_result commit_result;
if (sql_result_next_row(result) < 0) {
- ctx->callback(sql_result_get_error(result), ctx->context);
+ transaction_commit_error_callback(ctx, result);
driver_pgsql_transaction_free(ctx);
return;
}
query->affected_rows) < 0)
i_unreached();
}
- ctx->callback(NULL, ctx->context);
+ memset(&commit_result, 0, sizeof(result));
+ ctx->callback(&commit_result, ctx->context);
driver_pgsql_transaction_free(ctx);
}
{
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)_ctx;
+ struct sql_commit_result result;
+ memset(&result, 0, sizeof(result));
ctx->callback = callback;
ctx->context = context;
if (ctx->failed || _ctx->head == NULL) {
- callback(ctx->failed ? ctx->error : NULL, context);
+ if (ctx->failed)
+ result.error = ctx->error;
+ callback(&result, context);
driver_pgsql_transaction_free(ctx);
} else if (_ctx->head->next == NULL) {
/* just a single query, send it */
struct sqlite_transaction_context *ctx =
(struct sqlite_transaction_context *)_ctx;
struct sqlite_db *db = (struct sqlite_db *)ctx->ctx.db;
- const char *errmsg;
+ struct sql_commit_result commit_result;
if (!ctx->failed) {
sql_exec(_ctx->db, "COMMIT");
ctx->failed = TRUE;
}
+ memset(&commit_result, 0, sizeof(commit_result));
if (ctx->failed) {
- errmsg = sqlite3_errmsg(db->sqlite);
- callback(errmsg, context);
+ commit_result.error = sqlite3_errmsg(db->sqlite);
+ callback(&commit_result, context);
/* also does i_free(ctx) */
driver_sqlite_transaction_rollback(_ctx);
} else {
- callback(NULL, context);
+ callback(&commit_result, context);
i_free(ctx);
}
}
driver_sqlpool_query_callback(struct sql_result *result,
struct sqlpool_request *request);
static void
-driver_sqlpool_commit_callback(const char *error,
+driver_sqlpool_commit_callback(const struct sql_commit_result *result,
struct sqlpool_transaction_context *ctx);
static struct sqlpool_request * ATTR_NULL(2)
}
static void
-driver_sqlpool_commit_callback(const char *error,
+driver_sqlpool_commit_callback(const struct sql_commit_result *result,
struct sqlpool_transaction_context *ctx)
{
- ctx->callback(error, ctx->context);
+ ctx->callback(result, ctx->context);
driver_sqlpool_transaction_free(ctx);
}
struct sql_db;
struct sql_result;
+struct sql_commit_result {
+ const char *error;
+ enum sql_result_error_type error_type;
+};
+
typedef void sql_query_callback_t(struct sql_result *result, void *context);
-typedef void sql_commit_callback_t(const char *error, void *context);
+typedef void sql_commit_callback_t(const struct sql_commit_result *result, void *context);
void sql_drivers_init(void);
void sql_drivers_deinit(void);
#define sql_transaction_commit(ctx, callback, context) \
sql_transaction_commit(ctx + \
CALLBACK_TYPECHECK(callback, void (*)( \
- const char *, typeof(context))), \
+ const struct sql_commit_result *, typeof(context))), \
(sql_commit_callback_t *)callback, context)
/* Synchronous commit. Returns 0 if ok, -1 if error. */
int sql_transaction_commit_s(struct sql_transaction_context **ctx,