struct mysql_query_list {
struct mysql_query_list *next;
const char *query;
+ unsigned int *affected_rows;
};
extern struct sql_db driver_mysql_db;
const char *query)
{
struct sql_result *result;
+ my_ulonglong rows;
int ret = 0;
if (ctx->failed)
ctx->error = sql_result_get_error(result);
ctx->failed = TRUE;
ret = -1;
+ } else if (ctx->head != NULL && ctx->head->affected_rows != NULL) {
+ struct mysql_result *my_result = (struct mysql_result *)result;
+
+ rows = mysql_affected_rows(my_result->conn->mysql);
+ i_assert(rows != (my_ulonglong)-1);
+ *ctx->head->affected_rows = rows;
}
sql_result_unref(result);
return ret;
}
static void
-driver_mysql_update(struct sql_transaction_context *_ctx, const char *query)
+driver_mysql_update(struct sql_transaction_context *_ctx, const char *query,
+ unsigned int *affected_rows)
{
struct mysql_transaction_context *ctx =
(struct mysql_transaction_context *)_ctx;
list = p_new(ctx->query_pool, struct mysql_query_list, 1);
list->query = p_strdup(ctx->query_pool, query);
+ list->affected_rows = affected_rows;
if (ctx->head == NULL)
ctx->head = list;
struct pgsql_query_list {
struct pgsql_query_list *next;
+ struct pgsql_transaction_context *ctx;
+
const char *query;
+ unsigned int *affected_rows;
};
extern struct sql_db driver_pgsql_db;
extern struct sql_result driver_pgsql_result;
-static void
-transaction_update_callback(struct sql_result *result, void *context);
static void
driver_pgsql_query_full(struct sql_db *db, const char *query,
sql_query_callback_t *callback, void *context,
}
static void
-transaction_commit_callback(struct sql_result *result, void *context)
+transaction_begin_callback(struct sql_result *result,
+ struct pgsql_transaction_context *ctx)
{
- struct pgsql_transaction_context *ctx =
- (struct pgsql_transaction_context *)context;
+ if (sql_result_next_row(result) < 0) {
+ ctx->begin_failed = TRUE;
+ ctx->failed = TRUE;
+ ctx->error = sql_result_get_error(result);
+ } else {
+ ctx->begin_succeeded = TRUE;
+ }
+ driver_pgsql_transaction_unref(ctx);
+}
+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
}
static void
-transaction_update_callback(struct sql_result *result, void *context)
+transaction_update_callback(struct sql_result *result,
+ struct pgsql_query_list *list)
{
- struct pgsql_transaction_context *ctx = context;
+ struct pgsql_transaction_context *ctx = list->ctx;
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;
+ } else if (list->affected_rows != NULL) {
+ struct pgsql_result *pg_result = (struct pgsql_result *)result;
+
+ *list->affected_rows = atoi(PQcmdTuples(pg_result->pgres));
}
driver_pgsql_transaction_unref(ctx);
}
} else {
/* multiple queries, use a transaction */
ctx->refcount++;
- sql_query(_ctx->db, "BEGIN", transaction_update_callback, ctx);
+ sql_query(_ctx->db, "BEGIN", transaction_begin_callback, ctx);
while (ctx->head != NULL) {
ctx->refcount++;
sql_query(_ctx->db, ctx->head->query,
- transaction_update_callback, ctx);
+ transaction_update_callback, ctx->head);
ctx->head = ctx->head->next;
}
sql_query(_ctx->db, "COMMIT", transaction_commit_callback, ctx);
} else {
/* multiple queries, use a transaction */
ctx->refcount++;
- sql_query(_ctx->db, "BEGIN", transaction_update_callback, ctx);
+ sql_query(_ctx->db, "BEGIN", transaction_begin_callback, ctx);
while (ctx->head != NULL) {
ctx->refcount++;
sql_query(_ctx->db, ctx->head->query,
- transaction_update_callback, ctx);
+ transaction_update_callback, ctx->head);
ctx->head = ctx->head->next;
}
if (ctx->refcount > 1) {
else if (result != NULL) {
if (sql_result_next_row(result) < 0)
*error_r = sql_result_get_error(result);
+ else if (ctx->head != NULL &&
+ ctx->head->affected_rows != NULL) {
+ struct pgsql_result *pg_result =
+ (struct pgsql_result *)result;
+
+ *ctx->head->affected_rows =
+ atoi(PQcmdTuples(pg_result->pgres));
+ }
}
if (result != NULL)
sql_result_unref(result);
}
static void
-driver_pgsql_update(struct sql_transaction_context *_ctx, const char *query)
+driver_pgsql_update(struct sql_transaction_context *_ctx, const char *query,
+ unsigned int *affected_rows)
{
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)_ctx;
struct pgsql_query_list *list;
list = p_new(ctx->query_pool, struct pgsql_query_list, 1);
+ list->ctx = ctx;
list->query = p_strdup(ctx->query_pool, query);
+ list->affected_rows = affected_rows;
if (ctx->head == NULL)
ctx->head = list;