struct pgsql_transaction_context {
struct sql_transaction_context ctx;
+ int refcount;
sql_commit_callback_t *callback;
void *context;
ctx = i_new(struct pgsql_transaction_context, 1);
ctx->ctx.db = db;
+ ctx->refcount = 1;
return &ctx->ctx;
}
+static void
+driver_pgsql_transaction_unref(struct pgsql_transaction_context *ctx)
+{
+ i_assert(ctx->refcount > 0);
+ if (--ctx->refcount > 0)
+ return;
+
+ i_free(ctx->first_update);
+ i_free(ctx);
+}
+
static void
transaction_commit_callback(struct sql_result *result, void *context)
{
callback(ctx->error, context);
if (ctx->opened)
sql_exec(_ctx->db, "ROLLBACK");
- i_free(ctx);
+ driver_pgsql_transaction_unref(ctx);
return;
}
if (!ctx->opened) {
/* nothing done */
ctx->callback(NULL, ctx->context);
+ driver_pgsql_transaction_unref(ctx);
return;
}
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);
sql_result_free(result);
}
- i_free(ctx);
+ driver_pgsql_transaction_unref(ctx);
return *error_r == NULL ? 0 : -1;
}
if (ctx->opened)
sql_exec(_ctx->db, "ROLLBACK");
- i_free(ctx->first_update);
- i_free(ctx);
+ driver_pgsql_transaction_unref(ctx);
}
static void
ctx->failed = TRUE;
ctx->error = sql_result_get_error(result);
}
+ driver_pgsql_transaction_unref(ctx);
}
static void
return;
}
ctx->opened = TRUE;
+ ctx->refcount += 2;
sql_query(_ctx->db, "BEGIN", transaction_update_callback, ctx);
sql_query(_ctx->db, ctx->first_update,
transaction_update_callback, ctx);
i_free_and_null(ctx->first_update);
}
+ ctx->refcount++;
driver_pgsql_query_full(_ctx->db, query,
transaction_update_callback, ctx, FALSE);
}