/* currently pgsql and sqlite don't support "ON DUPLICATE KEY" */
dict->has_on_duplicate_key = strcmp(driver->name, "mysql") == 0;
- /* only Cassandra CQL supports "USING TIMESTAMP" */
- dict->has_using_timestamp = strcmp(driver->name, "cassandra") == 0;
dict->db = sql_db_cache_new(dict_sql_db_cache, driver->name,
dict->set->connect);
sql_dict_transaction_free(ctx);
}
-static void
-sql_dict_transaction_add_timestamp(struct sql_dict_transaction_context *ctx,
- string_t *query)
+static struct sql_statement *
+sql_dict_transaction_stmt_init(struct sql_dict_transaction_context *ctx,
+ const char *query)
{
struct sql_dict *dict = (struct sql_dict *)ctx->ctx.dict;
- unsigned long long timestamp_usecs;
-
- if (ctx->ctx.timestamp.tv_sec == 0 || !dict->has_using_timestamp)
- return;
+ struct sql_statement *stmt = sql_statement_init(dict->db, query);
- timestamp_usecs = ctx->ctx.timestamp.tv_sec * 1000000ULL +
- ctx->ctx.timestamp.tv_nsec / 1000;
- str_printfa(query, " USING TIMESTAMP %llu", timestamp_usecs);
+ if (ctx->ctx.timestamp.tv_sec != 0)
+ sql_statement_set_timestamp(stmt, &ctx->ctx.timestamp);
+ return stmt;
}
struct dict_sql_build_query_field {
char key1;
};
-static int sql_dict_set_query(struct sql_dict_transaction_context *ctx,
- const struct dict_sql_build_query *build,
+static int sql_dict_set_query(const struct dict_sql_build_query *build,
const char **query_r, const char **error_r)
{
struct sql_dict *dict = build->dict;
str_append_str(prefix, suffix);
str_append_c(prefix, ')');
- sql_dict_transaction_add_timestamp(ctx, prefix);
if (!dict->has_on_duplicate_key) {
*query_r = str_c(prefix);
return 0;
}
static int
-sql_dict_update_query(struct sql_dict_transaction_context *ctx,
- const struct dict_sql_build_query *build,
+sql_dict_update_query(const struct dict_sql_build_query *build,
const char **query_r, const char **error_r)
{
struct sql_dict *dict = build->dict;
i_assert(field_count > 0);
query = t_str_new(64);
- str_printfa(query, "UPDATE %s", fields[0].map->table);
- sql_dict_transaction_add_timestamp(ctx, query);
- str_append(query, " SET ");
+ str_printfa(query, "UPDATE %s SET ", fields[0].map->table);
for (i = 0; i < field_count; i++) {
const char *first_value_field =
t_strcut(fields[i].map->value_field, ',');
build.extra_values = &values;
build.key1 = key[0];
- if (sql_dict_set_query(ctx, &build, &query, &error) < 0) {
+ if (sql_dict_set_query(&build, &query, &error) < 0) {
ctx->error = i_strdup_printf("dict-sql: Failed to set %s=%s: %s",
key, value, error);
} else {
struct sql_statement *stmt =
- sql_statement_init(dict->db, query);
+ sql_dict_transaction_stmt_init(ctx, query);
sql_update_stmt(ctx->sql_ctx, &stmt);
}
}
}
str_printfa(query, "DELETE FROM %s", map->table);
- sql_dict_transaction_add_timestamp(ctx, query);
if (sql_dict_where_build(dict, map, &values, key[0],
SQL_DICT_RECURSE_NONE, query, &error) < 0) {
ctx->error = i_strdup_printf(
"dict-sql: Failed to delete %s: %s", key, error);
} else {
struct sql_statement *stmt =
- sql_statement_init(dict->db, str_c(query));
+ sql_dict_transaction_stmt_init(ctx, str_c(query));
sql_update_stmt(ctx->sql_ctx, &stmt);
}
}
build.extra_values = &values;
build.key1 = key[0];
- if (sql_dict_update_query(ctx, &build, &query, &error) < 0) {
+ if (sql_dict_update_query(&build, &query, &error) < 0) {
ctx->error = i_strdup_printf(
"dict-sql: Failed to increase %s: %s", key, error);
} else {
struct sql_statement *stmt =
- sql_statement_init(dict->db, query);
+ sql_dict_transaction_stmt_init(ctx, query);
sql_update_stmt_get_rows(ctx->sql_ctx, &stmt,
sql_dict_next_inc_row(ctx));
}
field->map = map;
field->value = value;
- if (sql_dict_set_query(ctx, &build, &query, &error) < 0) {
+ if (sql_dict_set_query(&build, &query, &error) < 0) {
ctx->error = i_strdup_printf(
"dict-sql: Failed to set %s: %s", key, error);
} else {
struct sql_statement *stmt =
- sql_statement_init(dict->db, query);
+ sql_dict_transaction_stmt_init(ctx, query);
sql_update_stmt(ctx->sql_ctx, &stmt);
}
i_free_and_null(ctx->prev_set_value);
field->map = map;
field->value = t_strdup_printf("%lld", diff);
- if (sql_dict_update_query(ctx, &build, &query, &error) < 0) {
+ if (sql_dict_update_query(&build, &query, &error) < 0) {
ctx->error = i_strdup_printf(
"dict-sql: Failed to increase %s: %s", key, error);
} else {
struct sql_statement *stmt =
- sql_statement_init(dict->db, query);
+ sql_dict_transaction_stmt_init(ctx, query);
sql_update_stmt_get_rows(ctx->sql_ctx, &stmt,
sql_dict_next_inc_row(ctx));
}