[dovecot-cvs] dovecot/src/lib-sql driver-mysql.c, 1.16.2.5, 1.16.2.6
cras at dovecot.org
cras at dovecot.org
Mon Aug 28 20:06:07 EEST 2006
Update of /var/lib/cvs/dovecot/src/lib-sql
In directory talvi:/tmp/cvs-serv24003
Modified Files:
Tag: branch_1_0
driver-mysql.c
Log Message:
Save queries within transaction in a linked list and send them separately,
instead of using one big string with ';' separator, which didn't work with
everyone..
Index: driver-mysql.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-sql/driver-mysql.c,v
retrieving revision 1.16.2.5
retrieving revision 1.16.2.6
diff -u -d -r1.16.2.5 -r1.16.2.6
--- driver-mysql.c 1 Jul 2006 17:24:11 -0000 1.16.2.5
+++ driver-mysql.c 28 Aug 2006 17:06:05 -0000 1.16.2.6
@@ -65,7 +65,17 @@
struct mysql_transaction_context {
struct sql_transaction_context ctx;
- string_t *queries;
+ pool_t query_pool;
+ struct mysql_query_list *head, *tail;
+
+ const char *error;
+
+ unsigned int failed:1;
+};
+
+struct mysql_query_list {
+ struct mysql_query_list *next;
+ const char *query;
};
extern struct sql_db driver_mysql_db;
@@ -228,12 +238,6 @@
}
t_pop();
-#ifdef CLIENT_MULTI_STATEMENTS
- /* Updates require this because everything is committed in one large
- SQL statement. */
- db->client_flags |= CLIENT_MULTI_STATEMENTS;
-#endif
-
if (array_count(&db->connections) == 0)
i_fatal("mysql: No hosts given in connect string");
}
@@ -550,7 +554,7 @@
ctx = i_new(struct mysql_transaction_context, 1);
ctx->ctx.db = db;
- ctx->queries = str_new(default_pool, 1024);
+ ctx->query_pool = pool_alloconly_create("mysql transaction", 1024);
return &ctx->ctx;
}
@@ -566,26 +570,46 @@
callback(NULL, context);
}
+static int transaction_send_query(struct mysql_transaction_context *ctx,
+ const char *query)
+{
+ struct sql_result *result;
+ int ret = 0;
+
+ if (ctx->failed)
+ return -1;
+
+ result = sql_query_s(ctx->ctx.db, query);
+ if (sql_result_next_row(result) < 0) {
+ ctx->error = sql_result_get_error(result);
+ ctx->failed = TRUE;
+ ret = -1;
+ }
+ sql_result_free(result);
+ return ret;
+}
+
static int
driver_mysql_transaction_commit_s(struct sql_transaction_context *_ctx,
const char **error_r)
{
struct mysql_transaction_context *ctx =
(struct mysql_transaction_context *)_ctx;
- struct sql_result *result;
int ret = 0;
*error_r = NULL;
- if (str_len(ctx->queries) > 0) {
- str_append(ctx->queries, "COMMIT;");
-
- result = sql_query_s(_ctx->db, str_c(ctx->queries));
- if (sql_result_next_row(result) < 0) {
- *error_r = sql_result_get_error(result);
- ret = -1;
+ if (ctx->head != NULL) {
+ /* try to use a transaction in any case,
+ even if it doesn't work. */
+ (void)transaction_send_query(ctx, "BEGIN");
+ while (ctx->head != NULL) {
+ if (transaction_send_query(ctx, ctx->head->query) < 0)
+ break;
+ ctx->head = ctx->head->next;
}
- sql_result_free(result);
+ ret = transaction_send_query(ctx, "COMMIT");
+ *error_r = ctx->error;
}
sql_transaction_rollback(&_ctx);
return ret;
@@ -597,7 +621,7 @@
struct mysql_transaction_context *ctx =
(struct mysql_transaction_context *)_ctx;
- str_free(&ctx->queries);
+ pool_unref(ctx->query_pool);
i_free(ctx);
}
@@ -606,18 +630,20 @@
{
struct mysql_transaction_context *ctx =
(struct mysql_transaction_context *)_ctx;
+ struct mysql_query_list *list;
/* FIXME: with mysql we're just appending everything into one big
- string which gets committed in sql_transaction_commit(). we could
- avoid this if we knew for sure that transactions actually worked,
- but I don't know how to do that.. */
- if (str_len(ctx->queries) == 0) {
- /* try to use a transaction in any case,
- even if it doesn't work. */
- str_append(ctx->queries, "BEGIN;");
- }
- str_append(ctx->queries, query);
- str_append_c(ctx->queries, ';');
+ linked list which gets committed in sql_transaction_commit().
+ we could avoid this if we knew for sure that transactions actually
+ worked, but I don't know how to do that.. */
+ list = p_new(ctx->query_pool, struct mysql_query_list, 1);
+ list->query = p_strdup(ctx->query_pool, query);
+
+ if (ctx->head == NULL)
+ ctx->head = list;
+ else
+ ctx->tail->next = list;
+ ctx->tail = list;
}
struct sql_db driver_mysql_db = {
More information about the dovecot-cvs
mailing list