annotate src/lib-dict/dict-sql.c @ 8654:abb1a50a266d HEAD

pgsql: When doing negative increments, don't even try to use INSERT.
author Timo Sirainen <tss@iki.fi>
date Sun, 18 Jan 2009 21:47:47 -0500
parents cc46e5822b96
children d8a56ea9f408
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8590
b9faf4db2a9f Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents: 8281
diff changeset
1 /* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
3943
cbe5c6772e0d Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
4 #include "array.h"
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "istream.h"
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "str.h"
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "sql-api-private.h"
6480
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
8 #include "sql-pool.h"
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #include "dict-private.h"
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
10 #include "dict-sql-settings.h"
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include "dict-sql.h"
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 #include <unistd.h>
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 #include <fcntl.h>
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15
6480
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
16 #define DICT_SQL_MAX_UNUSED_CONNECTIONS 10
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
17
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
18 enum sql_recurse_type {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
19 SQL_DICT_RECURSE_NONE,
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
20 SQL_DICT_RECURSE_ONE,
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
21 SQL_DICT_RECURSE_FULL
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
22 };
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
23
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 struct sql_dict {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 struct dict dict;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 pool_t pool;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 struct sql_db *db;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
29 const char *username;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
30 const struct dict_sql_settings *set;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
31 unsigned int prev_map_match_idx;
7966
54225d0b6e2b dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just
Timo Sirainen <tss@iki.fi>
parents: 7821
diff changeset
32
54225d0b6e2b dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just
Timo Sirainen <tss@iki.fi>
parents: 7821
diff changeset
33 unsigned int has_on_duplicate_key:1;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 };
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 struct sql_dict_iterate_context {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 struct dict_iterate_context ctx;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
38 enum dict_iterate_flags flags;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
39 char *path;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 struct sql_result *result;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
42 string_t *key;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
43 const struct dict_sql_map *map;
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
44 unsigned int key_prefix_len, pattern_prefix_len, next_map_idx;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 };
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46
3787
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
47 struct sql_dict_transaction_context {
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
48 struct dict_transaction_context ctx;
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
49
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
50 struct sql_transaction_context *sql_ctx;
4511
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
51
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
52 const struct dict_sql_map *prev_inc_map;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
53 char *prev_inc_key;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
54 long long prev_inc_diff;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
55
4511
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
56 unsigned int failed:1;
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
57 unsigned int changed:1;
3787
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
58 };
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
59
6480
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
60 static struct sql_pool *dict_sql_pool;
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
61
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
62 static void sql_dict_prev_inc_flush(struct sql_dict_transaction_context *ctx);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
63
4516
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
64 static struct dict *
4517
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
65 sql_dict_init(struct dict *driver, const char *uri,
6411
6a64e64fa3a3 Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents: 6162
diff changeset
66 enum dict_data_type value_type ATTR_UNUSED,
4516
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
67 const char *username)
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 struct sql_dict *dict;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 pool_t pool;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 pool = pool_alloconly_create("sql dict", 1024);
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 dict = p_new(pool, struct sql_dict, 1);
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 dict->pool = pool;
4517
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
75 dict->dict = *driver;
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
76 dict->username = p_strdup(pool, username);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
77 dict->set = dict_sql_settings_read(pool, uri);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
78 if (dict->set == NULL) {
6428
7cad076906eb pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
79 pool_unref(&pool);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 return NULL;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82
7966
54225d0b6e2b dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just
Timo Sirainen <tss@iki.fi>
parents: 7821
diff changeset
83 /* currently pgsql and sqlite don't support "ON DUPLICATE KEY" */
54225d0b6e2b dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just
Timo Sirainen <tss@iki.fi>
parents: 7821
diff changeset
84 dict->has_on_duplicate_key = strcmp(driver->name, "mysql") == 0;
54225d0b6e2b dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just
Timo Sirainen <tss@iki.fi>
parents: 7821
diff changeset
85
6480
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
86 dict->db = sql_pool_new(dict_sql_pool, driver->name,
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
87 dict->set->connect);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 return &dict->dict;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91 static void sql_dict_deinit(struct dict *_dict)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93 struct sql_dict *dict = (struct sql_dict *)_dict;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
95 sql_deinit(&dict->db);
6428
7cad076906eb pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
96 pool_unref(&dict->pool);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
99 static bool
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
100 dict_sql_map_match(const struct dict_sql_map *map, const char *path,
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
101 ARRAY_TYPE(const_string) *values, unsigned int *pat_len_r,
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
102 unsigned int *path_len_r, bool partial_ok)
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
103 {
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
104 const char *path_start = path;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
105 const char *pat, *field, *p;
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
106 unsigned int len;
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
107
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
108 array_clear(values);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
109 pat = map->pattern;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
110 while (*pat != '\0' && *path != '\0') {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
111 if (*pat == '$') {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
112 /* variable */
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
113 pat++;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
114 if (*pat == '\0') {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
115 /* pattern ended with this variable,
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
116 it'll match the rest of the path */
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
117 len = strlen(path);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
118 if (partial_ok) {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
119 /* iterating - the last field never
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
120 matches fully. if there's a trailing
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
121 '/', drop it. */
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
122 pat--;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
123 if (path[len-1] == '/') {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
124 field = t_strndup(path, len-1);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
125 array_append(values, &field, 1);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
126 } else {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
127 array_append(values, &path, 1);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
128 }
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
129 } else {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
130 array_append(values, &path, 1);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
131 path += len;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
132 }
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
133 *path_len_r = path - path_start;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
134 *pat_len_r = pat - map->pattern;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
135 return TRUE;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
136 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
137 /* pattern matches until the next '/' in path */
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
138 p = strchr(path, '/');
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
139 if (p != NULL) {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
140 field = t_strdup_until(path, p);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
141 array_append(values, &field, 1);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
142 path = p;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
143 } else {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
144 /* no '/' anymore, but it'll still match a
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
145 partial */
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
146 array_append(values, &path, 1);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
147 path += strlen(path);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
148 pat++;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
149 }
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
150 } else if (*pat == *path) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
151 pat++;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
152 path++;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
153 } else {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
154 return FALSE;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
155 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
156 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
157 if (*pat == '\0')
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
158 return *path == '\0';
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
159 else if (!partial_ok)
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
160 return FALSE;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
161 else {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
162 /* partial matches must end with '/' */
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
163 *path_len_r = path - path_start;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
164 *pat_len_r = pat - map->pattern;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
165 return pat == map->pattern || pat[-1] == '/';
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
166 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
167 }
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
168
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
169 static const struct dict_sql_map *
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
170 sql_dict_find_map(struct sql_dict *dict, const char *path,
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
171 ARRAY_TYPE(const_string) *values)
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
172 {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
173 const struct dict_sql_map *maps;
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
174 unsigned int i, idx, count, len;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
175
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
176 t_array_init(values, dict->set->max_field_count);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
177 maps = array_get(&dict->set->maps, &count);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
178 for (i = 0; i < count; i++) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
179 /* start matching from the previously successful match */
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
180 idx = (dict->prev_map_match_idx + i) % count;
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
181 if (dict_sql_map_match(&maps[idx], path, values,
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
182 &len, &len, FALSE)) {
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
183 dict->prev_map_match_idx = idx;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
184 return &maps[idx];
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
185 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
186 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
187 return NULL;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
188 }
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
189
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
190 static void
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
191 sql_dict_where_build(struct sql_dict *dict, const struct dict_sql_map *map,
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
192 const ARRAY_TYPE(const_string) *values_arr,
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
193 char key1, enum sql_recurse_type recurse_type,
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
194 string_t *query)
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
195 {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
196 const char *const *sql_fields, *const *values;
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
197 unsigned int i, count, count2, exact_count;
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
198 bool priv = key1 == DICT_PATH_PRIVATE[0];
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
199
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
200 sql_fields = array_get(&map->sql_fields, &count);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
201 values = array_get(values_arr, &count2);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
202 /* if we came here from iteration code there may be less values */
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
203 i_assert(count2 <= count);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
204
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
205 if (count2 == 0 && !priv) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
206 /* we want everything */
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
207 return;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
208 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
209
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
210 str_append(query, " WHERE");
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
211 exact_count = count == count2 && recurse_type != SQL_DICT_RECURSE_NONE ?
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
212 count2-1 : count2;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
213 for (i = 0; i < exact_count; i++) {
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
214 if (i > 0)
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
215 str_append(query, " AND");
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
216 str_printfa(query, " %s = '%s'", sql_fields[i],
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
217 sql_escape_string(dict->db, values[i]));
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
218 }
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
219 switch (recurse_type) {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
220 case SQL_DICT_RECURSE_NONE:
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
221 break;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
222 case SQL_DICT_RECURSE_ONE:
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
223 if (i > 0)
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
224 str_append(query, " AND");
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
225 if (i < count2) {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
226 str_printfa(query, " %s LIKE '%s/%%' AND "
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
227 "%s NOT LIKE '%s/%%/%%'",
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
228 sql_fields[i],
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
229 sql_escape_string(dict->db, values[i]),
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
230 sql_fields[i],
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
231 sql_escape_string(dict->db, values[i]));
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
232 } else {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
233 str_printfa(query, " %s LIKE '%%' AND "
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
234 "%s NOT LIKE '%%/%%'",
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
235 sql_fields[i], sql_fields[i]);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
236 }
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
237 break;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
238 case SQL_DICT_RECURSE_FULL:
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
239 if (i < count2) {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
240 if (i > 0)
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
241 str_append(query, " AND");
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
242 str_printfa(query, " %s LIKE '%s/%%'", sql_fields[i],
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
243 sql_escape_string(dict->db, values[i]));
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
244 }
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
245 break;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
246 }
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
247 if (priv) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
248 if (count2 > 0)
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
249 str_append(query, " AND");
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
250 str_printfa(query, " %s = '%s'", map->username_field,
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
251 sql_escape_string(dict->db, dict->username));
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
252 }
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
253 }
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
254
3787
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
255 static int sql_dict_lookup(struct dict *_dict, pool_t pool,
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
256 const char *key, const char **value_r)
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
257 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
258 struct sql_dict *dict = (struct sql_dict *)_dict;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
259 const struct dict_sql_map *map;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
260 ARRAY_TYPE(const_string) values;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
261 struct sql_result *result;
3787
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
262 int ret;
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
263
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
264 map = sql_dict_find_map(dict, key, &values);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
265 if (map == NULL) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
266 i_error("sql dict lookup: Invalid/unmapped key: %s", key);
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
267 *value_r = NULL;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
268 return 0;
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
269 }
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
270
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
271 T_BEGIN {
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
272 string_t *query = t_str_new(256);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
273
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
274 str_printfa(query, "SELECT %s FROM %s",
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
275 map->value_field, map->table);
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
276 sql_dict_where_build(dict, map, &values, key[0],
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
277 SQL_DICT_RECURSE_NONE, query);
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
278 result = sql_query_s(dict->db, str_c(query));
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
279 } T_END;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
280
3787
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
281 ret = sql_result_next_row(result);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
282 if (ret <= 0) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
283 if (ret < 0) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
284 i_error("dict sql lookup failed: %s",
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
285 sql_result_get_error(result));
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
286 }
3787
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
287 *value_r = NULL;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
288 } else {
3787
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
289 *value_r =
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
290 p_strdup(pool, sql_result_get_field_value(result, 0));
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
291 }
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
292
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
293 sql_result_free(result);
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
294 return ret;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
295 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
296
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
297 static const struct dict_sql_map *
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
298 sql_dict_iterate_find_next_map(struct sql_dict_iterate_context *ctx,
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
299 ARRAY_TYPE(const_string) *values)
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
300 {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
301 struct sql_dict *dict = (struct sql_dict *)ctx->ctx.dict;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
302 const struct dict_sql_map *maps;
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
303 unsigned int i, count, pat_len, path_len;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
304
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
305 t_array_init(values, dict->set->max_field_count);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
306 maps = array_get(&dict->set->maps, &count);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
307 for (i = ctx->next_map_idx; i < count; i++) {
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
308 if (dict_sql_map_match(&maps[i], ctx->path,
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
309 values, &pat_len, &path_len, TRUE) &&
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
310 ((ctx->flags & DICT_ITERATE_FLAG_RECURSE) != 0 ||
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
311 array_count(values)+1 >= array_count(&maps[i].sql_fields))) {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
312 ctx->key_prefix_len = path_len;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
313 ctx->pattern_prefix_len = pat_len;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
314 ctx->next_map_idx = i + 1;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
315 return &maps[i];
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
316 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
317 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
318 return NULL;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
319 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
320
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
321 static bool sql_dict_iterate_next_query(struct sql_dict_iterate_context *ctx)
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
322 {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
323 struct sql_dict *dict = (struct sql_dict *)ctx->ctx.dict;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
324 const struct dict_sql_map *map;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
325 ARRAY_TYPE(const_string) values;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
326 const char *const *sql_fields;
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
327 enum sql_recurse_type recurse_type;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
328 unsigned int i, count;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
329
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
330 map = sql_dict_iterate_find_next_map(ctx, &values);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
331 if (map == NULL)
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
332 return FALSE;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
333
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
334 T_BEGIN {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
335 string_t *query = t_str_new(256);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
336
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
337 str_printfa(query, "SELECT %s", map->value_field);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
338 /* get all missing fields */
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
339 sql_fields = array_get(&map->sql_fields, &count);
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
340 i = array_count(&values);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
341 if (i == count) {
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
342 /* we always want to know the last field since we're
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
343 iterating its children */
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
344 i_assert(i > 0);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
345 i--;
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
346 }
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
347 for (; i < count; i++)
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
348 str_printfa(query, ",%s", sql_fields[i]);
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
349 str_printfa(query, " FROM %s", map->table);
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
350
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
351 recurse_type = (ctx->flags & DICT_ITERATE_FLAG_RECURSE) == 0 ?
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
352 SQL_DICT_RECURSE_ONE : SQL_DICT_RECURSE_FULL;
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
353 sql_dict_where_build(dict, map, &values, ctx->path[0],
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
354 recurse_type, query);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
355
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
356 if ((ctx->flags & DICT_ITERATE_FLAG_SORT_BY_KEY) != 0) {
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
357 str_append(query, " ORDER BY ");
8281
3e34e1816ac1 dict-sql: Fixed sorting by key.
Timo Sirainen <tss@iki.fi>
parents: 8278
diff changeset
358 for (i = 0; i < count; i++) {
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
359 str_printfa(query, "%s", sql_fields[i]);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
360 if (i < count-1)
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
361 str_append_c(query, ',');
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
362 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
363 } else if ((ctx->flags & DICT_ITERATE_FLAG_SORT_BY_VALUE) != 0)
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
364 str_printfa(query, " ORDER BY %s", map->value_field);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
365 ctx->result = sql_query_s(dict->db, str_c(query));
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
366 } T_END;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
367
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
368 ctx->map = map;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
369 return TRUE;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
370 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
371
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
372 static struct dict_iterate_context *
4516
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
373 sql_dict_iterate_init(struct dict *_dict, const char *path,
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
374 enum dict_iterate_flags flags)
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
375 {
7819
59ec9752c3dd Fixed dict iteration with SQL backend.
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
376 struct sql_dict_iterate_context *ctx;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
377
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
378 ctx = i_new(struct sql_dict_iterate_context, 1);
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
379 ctx->ctx.dict = _dict;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
380 ctx->path = i_strdup(path);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
381 ctx->flags = flags;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
382 ctx->key = str_new(default_pool, 256);
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
383 str_append(ctx->key, ctx->path);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
384
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
385 if (!sql_dict_iterate_next_query(ctx)) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
386 i_error("sql dict iterate: Invalid/unmapped path: %s", path);
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
387 ctx->result = NULL;
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
388 return &ctx->ctx;
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
389 }
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
390 return &ctx->ctx;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
391 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
392
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
393 static int sql_dict_iterate(struct dict_iterate_context *_ctx,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
394 const char **key_r, const char **value_r)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
395 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
396 struct sql_dict_iterate_context *ctx =
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
397 (struct sql_dict_iterate_context *)_ctx;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
398 const char *p;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
399 unsigned int i, count;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
400 int ret;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
401
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
402 if (ctx->result == NULL)
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
403 return -1;
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
404
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
405 while ((ret = sql_result_next_row(ctx->result)) == 0) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
406 /* see if there are more results in the next map */
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
407 if (!sql_dict_iterate_next_query(ctx))
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
408 return 0;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
409 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
410 if (ret < 0) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
411 i_error("dict sql iterate failed: %s",
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
412 sql_result_get_error(ctx->result));
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
413 return ret;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
414 }
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
415
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
416 /* convert fetched row to dict key */
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
417 str_truncate(ctx->key, ctx->key_prefix_len);
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
418 if (ctx->key_prefix_len > 0 &&
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
419 str_c(ctx->key)[ctx->key_prefix_len-1] != '/')
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
420 str_append_c(ctx->key, '/');
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
421
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
422 count = sql_result_get_fields_count(ctx->result);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
423 i = 1;
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
424 for (p = ctx->map->pattern + ctx->pattern_prefix_len; *p != '\0'; p++) {
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
425 if (*p != '$')
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
426 str_append_c(ctx->key, *p);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
427 else {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
428 i_assert(i < count);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
429 str_append(ctx->key,
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
430 sql_result_get_field_value(ctx->result, i));
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
431 i++;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
432 }
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
433 }
7821
654cd4d966be dict sql: Iterated keys need to contain private/shared prefix.
Timo Sirainen <tss@iki.fi>
parents: 7819
diff changeset
434
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
435 *key_r = str_c(ctx->key);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
436 *value_r = sql_result_get_field_value(ctx->result, 0);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
437 return 1;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
438 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
439
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
440 static void sql_dict_iterate_deinit(struct dict_iterate_context *_ctx)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
441 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
442 struct sql_dict_iterate_context *ctx =
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
443 (struct sql_dict_iterate_context *)_ctx;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
444
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
445 if (ctx->result != NULL)
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
446 sql_result_free(ctx->result);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
447 str_free(&ctx->key);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
448 i_free(ctx->path);
3787
40600601502e Added dictinary lookup server and a "proxy" dict implementation to talk to
Timo Sirainen <tss@iki.fi>
parents: 3737
diff changeset
449 i_free(ctx);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
450 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
451
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
452 static struct dict_transaction_context *
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
453 sql_dict_transaction_init(struct dict *_dict)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
454 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
455 struct sql_dict *dict = (struct sql_dict *)_dict;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
456 struct sql_dict_transaction_context *ctx;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
457
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
458 ctx = i_new(struct sql_dict_transaction_context, 1);
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
459 ctx->ctx.dict = _dict;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
460 ctx->sql_ctx = sql_transaction_begin(dict->db);
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
461
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
462 return &ctx->ctx;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
463 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
464
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
465 static int sql_dict_transaction_commit(struct dict_transaction_context *_ctx)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
466 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
467 struct sql_dict_transaction_context *ctx =
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
468 (struct sql_dict_transaction_context *)_ctx;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
469 const char *error;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
470 int ret;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
471
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
472 if (ctx->prev_inc_map != NULL)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
473 sql_dict_prev_inc_flush(ctx);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
474
4511
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
475 if (ctx->failed) {
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
476 sql_transaction_rollback(&ctx->sql_ctx);
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
477 ret = -1;
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
478 } else if (_ctx->changed) {
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
479 ret = sql_transaction_commit_s(&ctx->sql_ctx, &error);
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
480 if (ret < 0)
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
481 i_error("sql dict: commit failed: %s", error);
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
482 } else {
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
483 /* nothing to be done */
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
484 ret = 0;
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
485 }
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
486 i_free(ctx);
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
487 return ret;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
488 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
489
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
490 static void sql_dict_transaction_rollback(struct dict_transaction_context *_ctx)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
491 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
492 struct sql_dict_transaction_context *ctx =
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
493 (struct sql_dict_transaction_context *)_ctx;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
494
4511
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
495 if (_ctx->changed)
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
496 sql_transaction_rollback(&ctx->sql_ctx);
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
497 i_free(ctx->prev_inc_key);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
498 i_free(ctx);
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
499 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
500
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
501 struct dict_sql_build_query_field {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
502 const struct dict_sql_map *map;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
503 const char *value;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
504 };
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
505
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
506 struct dict_sql_build_query {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
507 struct sql_dict *dict;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
508
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
509 ARRAY_DEFINE(fields, struct dict_sql_build_query_field);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
510 const ARRAY_TYPE(const_string) *extra_values;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
511 char key1;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
512 bool inc;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
513 };
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
514
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
515 static const char *sql_dict_set_query(const struct dict_sql_build_query *build)
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
516 {
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
517 struct sql_dict *dict = build->dict;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
518 const struct dict_sql_build_query_field *fields;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
519 const char *const *sql_fields, *const *extra_values;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
520 unsigned int i, field_count, count, count2;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
521 string_t *prefix, *suffix;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
522
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
523 fields = array_get(&build->fields, &field_count);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
524 i_assert(field_count > 0);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
525
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
526 prefix = t_str_new(64);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
527 suffix = t_str_new(256);
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
528 str_printfa(prefix, "INSERT INTO %s (", fields[0].map->table);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
529 str_append(suffix, ") VALUES (");
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
530 for (i = 0; i < field_count; i++) {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
531 if (i > 0) {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
532 str_append_c(prefix, ',');
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
533 str_append_c(suffix, ',');
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
534 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
535 str_append(prefix, fields[i].map->value_field);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
536 if (build->inc)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
537 str_append(suffix, fields[i].value);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
538 else {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
539 str_printfa(suffix, "'%s'",
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
540 sql_escape_string(dict->db, fields[i].value));
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
541 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
542 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
543 if (build->key1 == DICT_PATH_PRIVATE[0]) {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
544 str_printfa(prefix, ",%s", fields[0].map->username_field);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
545 str_printfa(suffix, ",'%s'",
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
546 sql_escape_string(dict->db, dict->username));
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
547 }
7966
54225d0b6e2b dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just
Timo Sirainen <tss@iki.fi>
parents: 7821
diff changeset
548
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
549 /* add the other fields from the key */
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
550 sql_fields = array_get(&fields[0].map->sql_fields, &count);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
551 extra_values = array_get(build->extra_values, &count2);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
552 i_assert(count == count2);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
553 for (i = 0; i < count; i++) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
554 str_printfa(prefix, ",%s", sql_fields[i]);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
555 str_printfa(suffix, ",'%s'",
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
556 sql_escape_string(dict->db, extra_values[i]));
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
557 }
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
558
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
559 str_append_str(prefix, suffix);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
560 str_append_c(prefix, ')');
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
561 if (!dict->has_on_duplicate_key)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
562 return str_c(prefix);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
563
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
564 str_append(prefix, " ON DUPLICATE KEY UPDATE ");
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
565 for (i = 0; i < field_count; i++) {
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
566 if (i > 0)
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
567 str_append_c(prefix, ',');
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
568 str_append(prefix, fields[i].map->value_field);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
569 str_append_c(prefix, '=');
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
570 if (build->inc) {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
571 str_printfa(prefix, "%s+%s",
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
572 fields[i].map->value_field,
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
573 fields[i].value);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
574 } else {
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
575 str_printfa(prefix, "'%s'",
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
576 sql_escape_string(dict->db, fields[i].value));
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
577 }
7966
54225d0b6e2b dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just
Timo Sirainen <tss@iki.fi>
parents: 7821
diff changeset
578 }
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
579 return str_c(prefix);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
580 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
581
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
582 static const char *
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
583 sql_dict_update_query(const struct dict_sql_build_query *build)
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
584 {
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
585 struct sql_dict *dict = build->dict;
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
586 const struct dict_sql_build_query_field *fields;
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
587 unsigned int i, field_count;
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
588 string_t *query;
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
589
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
590 i_assert(build->inc);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
591
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
592 fields = array_get(&build->fields, &field_count);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
593 i_assert(field_count > 0);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
594
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
595 query = t_str_new(64);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
596 str_printfa(query, "UPDATE %s SET ", fields[0].map->table);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
597 for (i = 0; i < field_count; i++) {
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
598 if (i > 0)
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
599 str_append_c(query, ',');
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
600 str_printfa(query, "%s=%s", fields[i].map->value_field,
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
601 fields[i].map->value_field);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
602 if (fields[i].value[0] != '-')
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
603 str_append_c(query, '+');
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
604 else
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
605 str_append(query, fields[i].value);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
606 }
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
607
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
608 sql_dict_where_build(dict, fields[0].map, build->extra_values,
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
609 build->key1, SQL_DICT_RECURSE_NONE, query);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
610 return str_c(query);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
611 }
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
612
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
613 static void sql_dict_set(struct dict_transaction_context *_ctx,
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
614 const char *key, const char *value)
4516
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
615 {
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
616 struct sql_dict_transaction_context *ctx =
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
617 (struct sql_dict_transaction_context *)_ctx;
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
618 struct sql_dict *dict = (struct sql_dict *)_ctx->dict;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
619 const struct dict_sql_map *map;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
620 ARRAY_TYPE(const_string) values;
4516
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
621
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
622 map = sql_dict_find_map(dict, key, &values);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
623 if (map == NULL) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
624 i_error("sql dict set: Invalid/unmapped key: %s", key);
4516
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
625 ctx->failed = TRUE;
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
626 return;
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
627 }
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
628
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
629 if (ctx->prev_inc_map != NULL)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
630 sql_dict_prev_inc_flush(ctx);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
631
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
632 T_BEGIN {
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
633 struct dict_sql_build_query build;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
634 struct dict_sql_build_query_field field;
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
635 const char *query;
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
636
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
637 field.map = map;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
638 field.value = value;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
639
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
640 memset(&build, 0, sizeof(build));
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
641 build.dict = dict;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
642 t_array_init(&build.fields, 1);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
643 array_append(&build.fields, &field, 1);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
644 build.extra_values = &values;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
645 build.key1 = key[0];
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
646
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
647 query = sql_dict_set_query(&build);
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
648 sql_update(ctx->sql_ctx, query);
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
649 } T_END;
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
650 }
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
651
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
652 static void sql_dict_unset(struct dict_transaction_context *_ctx,
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
653 const char *key)
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
654 {
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
655 struct sql_dict_transaction_context *ctx =
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
656 (struct sql_dict_transaction_context *)_ctx;
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
657 struct sql_dict *dict = (struct sql_dict *)_ctx->dict;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
658 const struct dict_sql_map *map;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
659 ARRAY_TYPE(const_string) values;
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
660
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
661 if (ctx->prev_inc_map != NULL)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
662 sql_dict_prev_inc_flush(ctx);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
663
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
664 map = sql_dict_find_map(dict, key, &values);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
665 if (map == NULL) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
666 i_error("sql dict unset: Invalid/unmapped key: %s", key);
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
667 ctx->failed = TRUE;
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
668 return;
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
669 }
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
670
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
671 T_BEGIN {
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
672 string_t *query = t_str_new(256);
7966
54225d0b6e2b dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just
Timo Sirainen <tss@iki.fi>
parents: 7821
diff changeset
673
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
674 str_printfa(query, "DELETE FROM %s", map->table);
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
675 sql_dict_where_build(dict, map, &values, key[0],
8265
72b7277aefb3 dict-sql: Dictionary iteration fixes.
Timo Sirainen <tss@iki.fi>
parents: 8113
diff changeset
676 SQL_DICT_RECURSE_NONE, query);
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
677 sql_update(ctx->sql_ctx, str_c(query));
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
678 } T_END;
4516
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
679 }
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
680
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
681 static void sql_dict_atomic_inc_real(struct sql_dict_transaction_context *ctx,
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
682 const char *key, long long diff)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
683 {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
684 struct sql_dict *dict = (struct sql_dict *)ctx->ctx.dict;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
685 const struct dict_sql_map *map;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
686 ARRAY_TYPE(const_string) values;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
687
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
688 map = sql_dict_find_map(dict, key, &values);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
689 i_assert(map != NULL);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
690
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
691 T_BEGIN {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
692 struct dict_sql_build_query build;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
693 struct dict_sql_build_query_field field;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
694 const char *query;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
695
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
696 field.map = map;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
697 field.value = t_strdup_printf("%lld", diff);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
698
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
699 memset(&build, 0, sizeof(build));
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
700 build.dict = dict;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
701 t_array_init(&build.fields, 1);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
702 array_append(&build.fields, &field, 1);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
703 build.extra_values = &values;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
704 build.key1 = key[0];
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
705 build.inc = TRUE;
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
706
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
707 if (diff >= 0)
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
708 query = sql_dict_set_query(&build);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
709 else {
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
710 /* negative changes can't never be initial values,
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
711 use UPDATE directly. */
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
712 query = sql_dict_update_query(&build);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
713 }
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
714 sql_update(ctx->sql_ctx, query);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
715 } T_END;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
716 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
717
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
718 static void sql_dict_prev_inc_flush(struct sql_dict_transaction_context *ctx)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
719 {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
720 sql_dict_atomic_inc_real(ctx, ctx->prev_inc_key, ctx->prev_inc_diff);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
721 i_free_and_null(ctx->prev_inc_key);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
722 ctx->prev_inc_map = NULL;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
723 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
724
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
725 static bool
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
726 sql_dict_maps_are_mergeable(struct sql_dict *dict,
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
727 const struct dict_sql_map *map1,
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
728 const struct dict_sql_map *map2,
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
729 const char *map1_key, const char *map2_key,
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
730 const ARRAY_TYPE(const_string) *map2_values)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
731 {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
732 const struct dict_sql_map *map3;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
733 ARRAY_TYPE(const_string) map1_values;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
734 const char *const *v1, *const *v2;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
735 unsigned int i, count1, count2;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
736
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
737 if (strcmp(map1->table, map2->table) != 0)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
738 return FALSE;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
739 if (map1_key[0] != map2_key[0])
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
740 return FALSE;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
741 if (map1_key[0] == DICT_PATH_PRIVATE[0]) {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
742 if (strcmp(map1->username_field, map2->username_field) != 0)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
743 return FALSE;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
744 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
745
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
746 map3 = sql_dict_find_map(dict, map1_key, &map1_values);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
747 i_assert(map3 == map1);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
748
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
749 v1 = array_get(&map1_values, &count1);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
750 v2 = array_get(map2_values, &count2);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
751 if (count1 != count2)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
752 return FALSE;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
753
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
754 for (i = 0; i < count1; i++) {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
755 if (strcmp(v1[i], v2[i]) != 0)
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
756 return FALSE;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
757 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
758 return TRUE;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
759 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
760
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
761 static void sql_dict_atomic_inc(struct dict_transaction_context *_ctx,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
762 const char *key, long long diff)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
763 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
764 struct sql_dict_transaction_context *ctx =
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
765 (struct sql_dict_transaction_context *)_ctx;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
766 struct sql_dict *dict = (struct sql_dict *)_ctx->dict;
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
767 const struct dict_sql_map *map;
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
768 ARRAY_TYPE(const_string) values;
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
769
8113
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
770 map = sql_dict_find_map(dict, key, &values);
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
771 if (map == NULL) {
2d3e942a4cde dict sql: Added configuration for mapping dict paths to SQL fields.
Timo Sirainen <tss@iki.fi>
parents: 7966
diff changeset
772 i_error("sql dict atomic inc: Invalid/unmapped key: %s", key);
4511
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
773 ctx->failed = TRUE;
3967
6fabe878c46d Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents: 3943
diff changeset
774 return;
4511
3f808dd8f568 If invalid key is given to dict_set() or dict_atomic_inc() fail the whole
Timo Sirainen <tss@iki.fi>
parents: 4371
diff changeset
775 }
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
776
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
777 if (ctx->prev_inc_map == NULL) {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
778 /* see if we can merge this increment SQL query with the
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
779 next one */
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
780 ctx->prev_inc_map = map;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
781 ctx->prev_inc_key = i_strdup(key);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
782 ctx->prev_inc_diff = diff;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
783 return;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
784 }
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
785 if (!sql_dict_maps_are_mergeable(dict, ctx->prev_inc_map, map,
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
786 ctx->prev_inc_key, key, &values)) {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
787 sql_dict_prev_inc_flush(ctx);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
788 sql_dict_atomic_inc_real(ctx, key, diff);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
789 } else T_BEGIN {
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
790 struct dict_sql_build_query build;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
791 struct dict_sql_build_query_field *field;
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
792 const char *query;
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
793
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
794 memset(&build, 0, sizeof(build));
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
795 build.dict = dict;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
796 t_array_init(&build.fields, 1);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
797 build.extra_values = &values;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
798 build.key1 = key[0];
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
799 build.inc = TRUE;
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
800
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
801 field = array_append_space(&build.fields);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
802 field->map = ctx->prev_inc_map;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
803 field->value = t_strdup_printf("%lld", ctx->prev_inc_diff);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
804 field = array_append_space(&build.fields);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
805 field->map = map;
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
806 field->value = t_strdup_printf("%lld", diff);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
807
8654
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
808 if (diff >= 0)
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
809 query = sql_dict_set_query(&build);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
810 else {
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
811 /* negative changes can't never be initial values,
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
812 use UPDATE directly. */
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
813 query = sql_dict_update_query(&build);
abb1a50a266d pgsql: When doing negative increments, don't even try to use INSERT.
Timo Sirainen <tss@iki.fi>
parents: 8647
diff changeset
814 }
6940
414c9d631a81 Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents: 6480
diff changeset
815 sql_update(ctx->sql_ctx, query);
8647
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
816
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
817 i_free_and_null(ctx->prev_inc_key);
cc46e5822b96 sql dict: Merge two INSERTs together whenever possible (for dict quota).
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
818 ctx->prev_inc_map = NULL;
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
819 } T_END;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
820 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
821
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
822 static struct dict sql_dict = {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
823 MEMBER(name) "sql",
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
824
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
825 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
826 sql_dict_init,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
827 sql_dict_deinit,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
828 sql_dict_lookup,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
829 sql_dict_iterate_init,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
830 sql_dict_iterate,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
831 sql_dict_iterate_deinit,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
832 sql_dict_transaction_init,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
833 sql_dict_transaction_commit,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
834 sql_dict_transaction_rollback,
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
835 sql_dict_set,
4516
aa2f73a4df26 Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4511
diff changeset
836 sql_dict_unset,
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
837 sql_dict_atomic_inc
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
838 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
839 };
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
840
4517
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
841 static struct dict *dict_sql_drivers;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
842
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
843 void dict_sql_register(void)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
844 {
3943
cbe5c6772e0d Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
845 const struct sql_db *const *drivers;
cbe5c6772e0d Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
846 unsigned int i, count;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
847
6480
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
848 dict_sql_pool = sql_pool_init(DICT_SQL_MAX_UNUSED_CONNECTIONS);
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
849
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
850 /* @UNSAFE */
3943
cbe5c6772e0d Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
851 drivers = array_get(&sql_drivers, &count);
4517
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
852 dict_sql_drivers = i_new(struct dict, count + 1);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
853
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
854 for (i = 0; i < count; i++) {
4517
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
855 dict_sql_drivers[i] = sql_dict;
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
856 dict_sql_drivers[i].name = drivers[i]->name;
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
857
4517
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
858 dict_driver_register(&dict_sql_drivers[i]);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
859 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
860 }
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
861
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
862 void dict_sql_unregister(void)
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
863 {
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
864 int i;
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
865
4517
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
866 for (i = 0; dict_sql_drivers[i].name != NULL; i++)
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
867 dict_driver_unregister(&dict_sql_drivers[i]);
e661182eab75 Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents: 4516
diff changeset
868 i_free(dict_sql_drivers);
6480
7596339a9452 Use SQL connection pools.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
869 sql_pool_deinit(&dict_sql_pool);
3737
d67092398377 Added dictionary API and implementation for SQL. It's meant for looking and
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
870 }