const char *error;
unsigned int opened:1;
+ unsigned int begin_succeeded:1;
+ unsigned int begin_failed:1;
unsigned int failed:1;
};
if (ctx->failed) {
callback(ctx->error, context);
- if (ctx->opened)
+ if (!ctx->begin_failed)
sql_exec(_ctx->db, "ROLLBACK");
driver_pgsql_transaction_unref(ctx);
return;
}
- if (!ctx->opened) {
+ ctx->callback = callback;
+ ctx->context = context;
+
+ if (ctx->first_update != NULL) {
+ sql_query(_ctx->db, ctx->first_update,
+ transaction_commit_callback, ctx);
+ i_free_and_null(ctx->first_update);
+ } else if (ctx->opened) {
+ driver_pgsql_query_full(_ctx->db, "COMMIT",
+ transaction_commit_callback, ctx,
+ FALSE);
+ } else {
/* nothing done */
ctx->callback(NULL, ctx->context);
driver_pgsql_transaction_unref(ctx);
- return;
}
-
- ctx->callback = callback;
- ctx->context = context;
-
- driver_pgsql_query_full(_ctx->db, "COMMIT",
- transaction_commit_callback, ctx, FALSE);
}
static int
(struct pgsql_transaction_context *)_ctx;
struct sql_result *result;
- if (ctx->first_update != NULL) {
- ctx->refcount++;
- sql_query(_ctx->db, ctx->first_update,
- transaction_update_callback, ctx);
- i_free_and_null(ctx->first_update);
- }
-
if (ctx->failed) {
*error_r = ctx->error;
- if (ctx->opened)
+ if (!ctx->begin_failed)
sql_exec(_ctx->db, "ROLLBACK");
- } else if (!ctx->opened)
+ } else if (ctx->first_update != NULL) {
+ result = sql_query_s(_ctx->db, ctx->first_update);
+ if (sql_result_next_row(result) < 0)
+ *error_r = sql_result_get_error(result);
+ else
+ *error_r = NULL;
+ i_free_and_null(ctx->first_update);
+ sql_result_free(result);
+ } else if (!ctx->opened) {
*error_r = NULL;
- else {
+ } else {
result = sql_query_s(_ctx->db, "COMMIT");
if (ctx->failed)
*error_r = ctx->error;
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)_ctx;
- if (ctx->opened)
+ if (!ctx->begin_failed)
sql_exec(_ctx->db, "ROLLBACK");
driver_pgsql_transaction_unref(ctx);
}
struct pgsql_transaction_context *ctx = context;
if (sql_result_next_row(result) < 0) {
+ if (!ctx->begin_succeeded)
+ ctx->begin_failed = TRUE;
ctx->failed = TRUE;
ctx->error = sql_result_get_error(result);
+ } else {
+ ctx->begin_succeeded = TRUE;
}
driver_pgsql_transaction_unref(ctx);
}