Mercurial > dovecot > original-hg > dovecot-1.2
changeset 4512:b5d4c1e9a492 HEAD
Delay sending the transaction begin command to server until the first
modification is actually done. If no modifications are done, there's no need
for commit/rollback command either.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 30 Jul 2006 21:13:03 +0300 |
parents | 3f808dd8f568 |
children | f91f3bcb7939 |
files | src/lib-dict/dict-client.c |
diffstat | 1 files changed, 50 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-dict/dict-client.c Sun Jul 30 21:06:09 2006 +0300 +++ b/src/lib-dict/dict-client.c Sun Jul 30 21:13:03 2006 +0300 @@ -43,7 +43,8 @@ unsigned int id; unsigned int connect_counter; - bool failed; + unsigned int failed:1; + unsigned int sent_begin:1; }; static int client_dict_connect(struct client_dict *dict); @@ -158,18 +159,43 @@ } static int +client_dict_transaction_send_begin(struct client_dict_transaction_context *ctx) +{ + struct client_dict *dict = (struct client_dict *)ctx->ctx.dict; + const char *query; + + if (ctx->failed) + return -1; + + t_push(); + query = t_strdup_printf("%c%u\n", DICT_PROTOCOL_CMD_BEGIN, ctx->id); + if (client_dict_send_query(dict, query) < 0) + ctx->failed = TRUE; + else + ctx->connect_counter = dict->connect_counter; + t_pop(); + + return ctx->failed ? -1 : 0; +} + +static int client_dict_send_transaction_query(struct client_dict_transaction_context *ctx, const char *query) { struct client_dict *dict = (struct client_dict *)ctx->ctx.dict; + if (!ctx->sent_begin) { + if (client_dict_transaction_send_begin(ctx) < 0) + return -1; + ctx->sent_begin = TRUE; + } + if (ctx->connect_counter != dict->connect_counter || ctx->failed) return -1; if (dict->output == NULL) { - /* not connected currently */ - if (client_dict_connect(dict) < 0) - return -1; + /* not connected, this'll fail */ + return -1; } if (o_stream_send_str(dict->output, query) < 0 || @@ -405,20 +431,11 @@ { struct client_dict *dict = (struct client_dict *)_dict; struct client_dict_transaction_context *ctx; - const char *query; ctx = i_new(struct client_dict_transaction_context, 1); ctx->ctx.dict = _dict; ctx->id = ++dict->transaction_id_counter; - t_push(); - query = t_strdup_printf("%c%u\n", DICT_PROTOCOL_CMD_BEGIN, ctx->id); - if (client_dict_send_query(dict, query) < 0) - ctx->failed = TRUE; - else - ctx->connect_counter = dict->connect_counter; - t_pop(); - return &ctx->ctx; } @@ -430,22 +447,23 @@ const char *query, *line; int ret = ctx->failed ? -1 : 0; - t_push(); - query = t_strdup_printf("%c%u\n", !ctx->failed ? - DICT_PROTOCOL_CMD_COMMIT : - DICT_PROTOCOL_CMD_ROLLBACK, ctx->id); - if (client_dict_send_transaction_query(ctx, query) < 0) - ret = -1; - else if (ret == 0) { - /* read reply */ - line = client_dict_read_line(dict); - if (line == NULL || *line != DICT_PROTOCOL_REPLY_OK) + if (ctx->sent_begin) { + t_push(); + query = t_strdup_printf("%c%u\n", !ctx->failed ? + DICT_PROTOCOL_CMD_COMMIT : + DICT_PROTOCOL_CMD_ROLLBACK, ctx->id); + if (client_dict_send_transaction_query(ctx, query) < 0) ret = -1; + else if (ret == 0) { + /* read reply */ + line = client_dict_read_line(dict); + if (line == NULL || *line != DICT_PROTOCOL_REPLY_OK) + ret = -1; + } + t_pop(); } - t_pop(); i_free(ctx); - return ret; } @@ -456,10 +474,13 @@ (struct client_dict_transaction_context *)_ctx; const char *query; - t_push(); - query = t_strdup_printf("%c%u\n", DICT_PROTOCOL_CMD_ROLLBACK, ctx->id); - (void)client_dict_send_transaction_query(ctx, query); - t_pop(); + if (ctx->sent_begin) { + t_push(); + query = t_strdup_printf("%c%u\n", DICT_PROTOCOL_CMD_ROLLBACK, + ctx->id); + (void)client_dict_send_transaction_query(ctx, query); + t_pop(); + } i_free(ctx); }