Statistics
| Branch: | Tag: | Revision:

root / lib / filter-kvs-sqlite.c @ fd8e2542

History | View | Annotate | Download (5.8 kB)

1
/* SylFilter - a message filter
2
 *
3
 * Copyright (C) 2011 Hiroyuki Yamamoto
4
 * Copyright (C) 2011 Sylpheed Development Team
5
 */
6
7
#include "config.h"
8
9
#ifdef USE_SQLITE
10
11
#include <sqlite3.h>
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <glib.h>
15
16
#include "filter-kvs.h"
17
#include "filter-kvs-sqlite.h"
18
19
static XFilterKVS *sqlite_open(const char *dbfile);
20
static int sqlite_close(XFilterKVS *kvs);
21
static int sqlite_insert(XFilterKVS *kvs, const char *key, void *value, int size);
22
static int sqlite_delete(XFilterKVS *kvs, const char *key);
23
static int sqlite_update(XFilterKVS *kvs, const char *key, void *value, int size);
24
static int sqlite_fetch(XFilterKVS *kvs, const char *key, void *vbuf, int vsize);
25
static int sqlite_begin(XFilterKVS *kvs);
26
static int sqlite_end(XFilterKVS *kvs);
27
static int sqlite_size(XFilterKVS *kvs);
28
static int sqlite_foreach(XFilterKVS *kvs, XFilterKVSForeachFunc func, void *data);
29
30
31
int xfilter_kvs_sqlite_set_engine(void)
32
{
33
        XFilterKVSEngine engine = {
34
                sqlite_open,
35
                sqlite_close,
36
                sqlite_insert,
37
                sqlite_delete,
38
                sqlite_update,
39
                sqlite_fetch,
40
                sqlite_begin,
41
                sqlite_end,
42
                sqlite_size,
43
                sqlite_foreach
44
        };
45
46
        return xfilter_kvs_set_engine(&engine);
47
}
48
49
static XFilterKVS *sqlite_open(const char *dbfile)
50
{
51
        sqlite3 *dbhandle = NULL;
52
        int ret;
53
54
        if (sqlite3_open(dbfile, &dbhandle) != SQLITE_OK) {
55
                sqlite3_close(dbhandle);
56
                return NULL;
57
        }
58
        if ((ret = sqlite3_exec(dbhandle, "CREATE TABLE kvs (key TEXT PRIMARY KEY, value INTEGER NOT NULL)", NULL, NULL, NULL)) != SQLITE_OK)
59
                printf("sqlite3_exec: returned %d\n", ret);
60
        return xfilter_kvs_new(dbfile, (void *)dbhandle);
61
}
62
63
static int sqlite_close(XFilterKVS *kvs)
64
{
65
        if (sqlite3_close((sqlite3 *)xfilter_kvs_get_handle(kvs)) != SQLITE_OK)
66
                return -1;
67
        return 0;
68
}
69
70
static int sqlite_insert(XFilterKVS *kvs, const char *key, void *value, int size)
71
{
72
        sqlite3 *db;
73
        char buf[1024];
74
        int ival;
75
        int ret;
76
77
        if (size != 4)
78
                return -1;
79
80
        ival = *((int *)value);
81
82
        db = (sqlite3 *)xfilter_kvs_get_handle(kvs);
83
        sqlite3_snprintf(sizeof(buf), buf,
84
                         "INSERT INTO kvs VALUES ('%q', %d)", key, ival);
85
        //g_print("%s\n", buf);
86
        if ((ret = sqlite3_exec(db, buf, NULL, NULL, NULL)) != SQLITE_OK) {
87
                printf("sqlite3_exec: insert: returned %d\n", ret);
88
                return -1;
89
        }
90
        return 0;
91
}
92
93
static int sqlite_delete(XFilterKVS *kvs, const char *key)
94
{
95
        sqlite3 *db;
96
        char buf[1024];
97
        int ret;
98
99
        db = (sqlite3 *)xfilter_kvs_get_handle(kvs);
100
        sqlite3_snprintf(sizeof(buf), buf,
101
                         "DELETE FROM kvs WHERE key = '%q'", key);
102
        g_print("%s\n", buf);
103
        if ((ret = sqlite3_exec(db, buf, NULL, NULL, NULL)) != SQLITE_OK) {
104
                printf("sqlite3_exec: delete: returned %d\n", ret);
105
                return -1;
106
        }
107
        return 0;
108
}
109
110
static int sqlite_update(XFilterKVS *kvs, const char *key, void *value, int size)
111
{
112
        sqlite3 *db;
113
        char buf[1024];
114
        int ival;
115
        int ret;
116
117
        if (size != 4)
118
                return -1;
119
120
        ival = *((int *)value);
121
122
        db = (sqlite3 *)xfilter_kvs_get_handle(kvs);
123
        sqlite3_snprintf(sizeof(buf), buf,
124
                         "UPDATE kvs SET value = %d WHERE key = '%q'", ival, key);
125
        //g_print("%s\n", buf);
126
        if ((ret = sqlite3_exec(db, buf, NULL, NULL, NULL)) != SQLITE_OK) {
127
                printf("sqlite3_exec: update: returned %d\n", ret);
128
                return -1;
129
        }
130
        return 0;
131
}
132
133
static int fetch_cb(void *data, int count, char **cols, char **names)
134
{
135
        char *val;
136
137
        val = cols[0];
138
        *((int *)data) = atoi(val);
139
        return 0;
140
}
141
142
static int sqlite_fetch(XFilterKVS *kvs, const char *key, void *vbuf, int vsize)
143
{
144
        sqlite3 *db;
145
        char buf[1024];
146
        int ival = -1;
147
        int ret;
148
149
        if (vsize != 4)
150
                return -1;
151
152
        db = (sqlite3 *)xfilter_kvs_get_handle(kvs);
153
        sqlite3_snprintf(sizeof(buf), buf,
154
                         "SELECT value FROM kvs WHERE key = '%q'", key);
155
        //g_print("%s\n", buf);
156
        if ((ret = sqlite3_exec(db, buf, fetch_cb, &ival, NULL)) != SQLITE_OK) {
157
                printf("sqlite3_exec: update: returned %d\n", ret);
158
                return -1;
159
        }
160
161
        if (ival == -1)
162
                return -1;
163
164
        *((int *)vbuf) = ival;
165
166
        return sizeof(ival);
167
}
168
169
static int sqlite_begin(XFilterKVS *kvs)
170
{
171
        sqlite3 *db;
172
        int ret;
173
174
        db = (sqlite3 *)xfilter_kvs_get_handle(kvs);
175
        if ((ret = sqlite3_exec(db, "BEGIN", NULL, NULL, NULL)) != SQLITE_OK) {
176
                printf("sqlite3_exec: begin: returned %d\n", ret);
177
                return -1;
178
        }
179
180
        return 0;
181
}
182
183
static int sqlite_end(XFilterKVS *kvs)
184
{
185
        sqlite3 *db;
186
        int ret;
187
188
        db = (sqlite3 *)xfilter_kvs_get_handle(kvs);
189
        if ((ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL)) != SQLITE_OK) {
190
                printf("sqlite3_exec: commit: returned %d\n", ret);
191
                return -1;
192
        }
193
194
        return 0;
195
}
196
197
static int size_cb(void *data, int count, char **cols, char **names)
198
{
199
        char *val;
200
201
        val = cols[0];
202
        *((int *)data) = atoi(val);
203
        return 0;
204
}
205
206
static int sqlite_size(XFilterKVS *kvs)
207
{
208
        sqlite3 *db;
209
        char buf[1024];
210
        int ival = 0;
211
        int ret;
212
213
        db = (sqlite3 *)xfilter_kvs_get_handle(kvs);
214
        sqlite3_snprintf(sizeof(buf), buf, "SELECT count(key) FROM kvs");
215
        g_print("%s\n", buf);
216
        if ((ret = sqlite3_exec(db, buf, size_cb, &ival, NULL)) != SQLITE_OK) {
217
                printf("sqlite3_exec: update: returned %d\n", ret);
218
                return -1;
219
        }
220
221
        return ival;
222
}
223
224
struct cbdata
225
{
226
        XFilterKVS *kvs;
227
        XFilterKVSForeachFunc func;
228
        void *data;
229
};
230
231
static int foreach_cb(void *data, int count, char **cols, char **names)
232
{
233
        const char *key;
234
        const char *val;
235
        int ival;
236
        int r;
237
        struct cbdata *cbdata;
238
239
        cbdata = (struct cbdata *)data;
240
        key = cols[0];
241
        val = cols[1];
242
        ival = atoi(val);
243
        r = cbdata->func(cbdata->kvs, key, &ival, sizeof(ival), cbdata->data);
244
        if (r < 0)
245
                return -1;
246
        return 0;
247
}
248
249
static int sqlite_foreach(XFilterKVS *kvs, XFilterKVSForeachFunc func, void *data)
250
{
251
        sqlite3 *db;
252
        char buf[1024];
253
        int ret;
254
        struct cbdata cbdata;
255
256
        cbdata.func = func;
257
        cbdata.data = data;
258
        db = (sqlite3 *)xfilter_kvs_get_handle(kvs);
259
        sqlite3_snprintf(sizeof(buf), buf, "SELECT key, value FROM kvs");
260
        if ((ret = sqlite3_exec(db, buf, foreach_cb, &cbdata, NULL)) != SQLITE_OK) {
261
                printf("sqlite3_exec: update: returned %d\n", ret);
262
                if (ret != SQLITE_ABORT)
263
                        return -1;
264
        }
265
266
        return 0;
267
}
268
269
#endif /* USE_SQLITE */