From: Timo Sirainen Date: Sat, 16 Jul 2016 14:31:04 +0000 (-0500) Subject: lib-sql: Added error_type to commit callback. X-Git-Tag: 2.3.0.rc1~3299 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb2b3656ef7635acc374f7fc19b25aeeb454ae95;p=thirdparty%2Fdovecot%2Fcore.git lib-sql: Added error_type to commit callback. --- diff --git a/src/auth/passdb-sql.c b/src/auth/passdb-sql.c index d3f391211a..5048862236 100644 --- a/src/auth/passdb-sql.c +++ b/src/auth/passdb-sql.c @@ -194,29 +194,29 @@ static void sql_lookup_credentials(struct auth_request *request, 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); } diff --git a/src/lib-dict/dict-sql.c b/src/lib-dict/dict-sql.c index aa82408782..35e804a450 100644 --- a/src/lib-dict/dict-sql.c +++ b/src/lib-dict/dict-sql.c @@ -790,16 +790,17 @@ sql_dict_transaction_has_nonexistent(struct sql_dict_transaction_context *ctx) } 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; } diff --git a/src/lib-sql/driver-cassandra.c b/src/lib-sql/driver-cassandra.c index 64c37bbd5c..8eaf10378e 100644 --- a/src/lib-sql/driver-cassandra.c +++ b/src/lib-sql/driver-cassandra.c @@ -1164,11 +1164,14 @@ static void 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); } @@ -1179,12 +1182,17 @@ driver_cassandra_transaction_commit(struct sql_transaction_context *_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 */ @@ -1196,7 +1204,8 @@ driver_cassandra_transaction_commit(struct sql_transaction_context *_ctx, 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); } } diff --git a/src/lib-sql/driver-mysql.c b/src/lib-sql/driver-mysql.c index 21e0f83d70..cafa93b3b0 100644 --- a/src/lib-sql/driver-mysql.c +++ b/src/lib-sql/driver-mysql.c @@ -541,12 +541,13 @@ static void 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) diff --git a/src/lib-sql/driver-pgsql.c b/src/lib-sql/driver-pgsql.c index b65eb128d3..ce95b8152e 100644 --- a/src/lib-sql/driver-pgsql.c +++ b/src/lib-sql/driver-pgsql.c @@ -873,10 +873,14 @@ static void 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); } @@ -890,7 +894,10 @@ static bool transaction_send_next(void *context) /* 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; } @@ -907,6 +914,19 @@ static bool transaction_send_next(void *context) 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) @@ -916,7 +936,7 @@ transaction_begin_callback(struct sql_result *result, 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; } @@ -934,7 +954,7 @@ transaction_update_callback(struct sql_result *result, 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; } @@ -957,9 +977,10 @@ transaction_trans_query_callback(struct sql_result *result, { 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; } @@ -971,7 +992,8 @@ transaction_trans_query_callback(struct sql_result *result, 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); } @@ -981,12 +1003,16 @@ driver_pgsql_transaction_commit(struct sql_transaction_context *_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 */ diff --git a/src/lib-sql/driver-sqlite.c b/src/lib-sql/driver-sqlite.c index a3e16314e1..0f6d82fe73 100644 --- a/src/lib-sql/driver-sqlite.c +++ b/src/lib-sql/driver-sqlite.c @@ -336,7 +336,7 @@ driver_sqlite_transaction_commit(struct sql_transaction_context *_ctx, 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"); @@ -344,13 +344,14 @@ driver_sqlite_transaction_commit(struct sql_transaction_context *_ctx, 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); } } diff --git a/src/lib-sql/driver-sqlpool.c b/src/lib-sql/driver-sqlpool.c index 3f8feb5f40..f8e6adba83 100644 --- a/src/lib-sql/driver-sqlpool.c +++ b/src/lib-sql/driver-sqlpool.c @@ -77,7 +77,7 @@ static void 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) @@ -717,10 +717,10 @@ driver_sqlpool_transaction_free(struct sqlpool_transaction_context *ctx) } 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); } diff --git a/src/lib-sql/sql-api.h b/src/lib-sql/sql-api.h index b0abc3bb02..0ba87b83b2 100644 --- a/src/lib-sql/sql-api.h +++ b/src/lib-sql/sql-api.h @@ -48,8 +48,13 @@ enum sql_result_error_type { 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); @@ -141,7 +146,7 @@ void sql_transaction_commit(struct sql_transaction_context **ctx, #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,