diff options
Diffstat (limited to 'src/namestore/plugin_namestore_sqlite.c')
-rw-r--r-- | src/namestore/plugin_namestore_sqlite.c | 260 |
1 files changed, 81 insertions, 179 deletions
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index f62be1e18..34e548613 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c | |||
@@ -106,72 +106,6 @@ struct Plugin | |||
106 | 106 | ||
107 | 107 | ||
108 | /** | 108 | /** |
109 | * @brief Prepare a SQL statement | ||
110 | * | ||
111 | * @param dbh handle to the database | ||
112 | * @param zSql SQL statement, UTF-8 encoded | ||
113 | * @param ppStmt set to the prepared statement | ||
114 | * @return 0 on success | ||
115 | */ | ||
116 | static int | ||
117 | sq_prepare (sqlite3 *dbh, | ||
118 | const char *zSql, | ||
119 | sqlite3_stmt **ppStmt) | ||
120 | { | ||
121 | char *dummy; | ||
122 | int result; | ||
123 | |||
124 | result = | ||
125 | sqlite3_prepare_v2 (dbh, | ||
126 | zSql, | ||
127 | strlen (zSql), | ||
128 | ppStmt, | ||
129 | (const char **) &dummy); | ||
130 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
131 | "Prepared `%s' / %p: %d\n", | ||
132 | zSql, | ||
133 | *ppStmt, | ||
134 | result); | ||
135 | return result; | ||
136 | } | ||
137 | |||
138 | |||
139 | /** | ||
140 | * Create our database indices. | ||
141 | * | ||
142 | * @param dbh handle to the database | ||
143 | */ | ||
144 | static void | ||
145 | create_indices (sqlite3 * dbh) | ||
146 | { | ||
147 | /* create indices */ | ||
148 | if ( (SQLITE_OK != | ||
149 | sqlite3_exec (dbh, | ||
150 | "CREATE INDEX IF NOT EXISTS ir_pkey_reverse " | ||
151 | "ON ns098records (zone_private_key,pkey)", | ||
152 | NULL, NULL, NULL)) || | ||
153 | (SQLITE_OK != | ||
154 | sqlite3_exec (dbh, | ||
155 | "CREATE INDEX IF NOT EXISTS ir_pkey_iter " | ||
156 | "ON ns098records (zone_private_key,uid)", | ||
157 | NULL, NULL, NULL)) ) | ||
158 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
159 | "Failed to create indices: %s\n", | ||
160 | sqlite3_errmsg (dbh)); | ||
161 | } | ||
162 | |||
163 | |||
164 | #if 0 | ||
165 | #define CHECK(a) GNUNET_break(a) | ||
166 | #define ENULL NULL | ||
167 | #else | ||
168 | #define ENULL &e | ||
169 | #define ENULL_DEFINED 1 | ||
170 | #define CHECK(a) if (! (a)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "%s\n", e); sqlite3_free(e); } | ||
171 | #endif | ||
172 | |||
173 | |||
174 | /** | ||
175 | * Initialize the database connections and associated | 109 | * Initialize the database connections and associated |
176 | * data structures (create tables and indices | 110 | * data structures (create tables and indices |
177 | * as needed as well). | 111 | * as needed as well). |
@@ -182,17 +116,66 @@ create_indices (sqlite3 * dbh) | |||
182 | static int | 116 | static int |
183 | database_setup (struct Plugin *plugin) | 117 | database_setup (struct Plugin *plugin) |
184 | { | 118 | { |
185 | sqlite3_stmt *stmt; | 119 | char *sqlite_filename; |
186 | char *afsdir; | 120 | struct GNUNET_SQ_ExecuteStatement es[] = { |
187 | #if ENULL_DEFINED | 121 | GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"), |
188 | char *e; | 122 | GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"), |
189 | #endif | 123 | GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"), |
124 | GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"), | ||
125 | GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""), | ||
126 | GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"), | ||
127 | GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"), | ||
128 | GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records (" | ||
129 | " uid INTEGER PRIMARY KEY," | ||
130 | " zone_private_key BLOB NOT NULL," | ||
131 | " pkey BLOB," | ||
132 | " rvalue INT8 NOT NULL," | ||
133 | " record_count INT NOT NULL," | ||
134 | " record_data BLOB NOT NULL," | ||
135 | " label TEXT NOT NULL" | ||
136 | ")"), | ||
137 | GNUNET_SQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_reverse " | ||
138 | "ON ns098records (zone_private_key,pkey)"), | ||
139 | GNUNET_SQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_iter " | ||
140 | "ON ns098records (zone_private_key,uid)"), | ||
141 | GNUNET_SQ_EXECUTE_STATEMENT_END | ||
142 | }; | ||
143 | struct GNUNET_SQ_PrepareStatement ps[] = { | ||
144 | GNUNET_SQ_make_prepare ("INSERT INTO ns098records " | ||
145 | "(zone_private_key,pkey,rvalue,record_count,record_data,label)" | ||
146 | " VALUES (?, ?, ?, ?, ?, ?)", | ||
147 | &plugin->store_records), | ||
148 | GNUNET_SQ_make_prepare ("DELETE FROM ns098records " | ||
149 | "WHERE zone_private_key=? AND label=?", | ||
150 | &plugin->delete_records), | ||
151 | GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label" | ||
152 | " FROM ns098records" | ||
153 | " WHERE zone_private_key=? AND pkey=?", | ||
154 | &plugin->zone_to_name), | ||
155 | GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label" | ||
156 | " FROM ns098records" | ||
157 | " WHERE zone_private_key=? AND _rowid_ >= ?" | ||
158 | " ORDER BY _rowid_ ASC" | ||
159 | " LIMIT ?", | ||
160 | &plugin->iterate_zone), | ||
161 | GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label,zone_private_key" | ||
162 | " FROM ns098records" | ||
163 | " WHERE _rowid_ >= ?" | ||
164 | " ORDER BY _rowid_ ASC" | ||
165 | " LIMIT ?", | ||
166 | &plugin->iterate_all_zones), | ||
167 | GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label,zone_private_key" | ||
168 | " FROM ns098records" | ||
169 | " WHERE zone_private_key=? AND label=?", | ||
170 | &plugin->lookup_label), | ||
171 | GNUNET_SQ_PREPARE_END | ||
172 | }; | ||
190 | 173 | ||
191 | if (GNUNET_OK != | 174 | if (GNUNET_OK != |
192 | GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, | 175 | GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, |
193 | "namestore-sqlite", | 176 | "namestore-sqlite", |
194 | "FILENAME", | 177 | "FILENAME", |
195 | &afsdir)) | 178 | &sqlite_filename)) |
196 | { | 179 | { |
197 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | 180 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, |
198 | "namestore-sqlite", | 181 | "namestore-sqlite", |
@@ -200,132 +183,51 @@ database_setup (struct Plugin *plugin) | |||
200 | return GNUNET_SYSERR; | 183 | return GNUNET_SYSERR; |
201 | } | 184 | } |
202 | if (GNUNET_OK != | 185 | if (GNUNET_OK != |
203 | GNUNET_DISK_file_test (afsdir)) | 186 | GNUNET_DISK_file_test (sqlite_filename)) |
204 | { | 187 | { |
205 | if (GNUNET_OK != | 188 | if (GNUNET_OK != |
206 | GNUNET_DISK_directory_create_for_file (afsdir)) | 189 | GNUNET_DISK_directory_create_for_file (sqlite_filename)) |
207 | { | 190 | { |
208 | GNUNET_break (0); | 191 | GNUNET_break (0); |
209 | GNUNET_free (afsdir); | 192 | GNUNET_free (sqlite_filename); |
210 | return GNUNET_SYSERR; | 193 | return GNUNET_SYSERR; |
211 | } | 194 | } |
212 | } | 195 | } |
213 | /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */ | 196 | /* sqlite_filename should be UTF-8-encoded. If it isn't, it's a bug */ |
214 | plugin->fn = afsdir; | 197 | plugin->fn = sqlite_filename; |
215 | 198 | ||
216 | /* Open database and precompile statements */ | 199 | /* Open database and precompile statements */ |
217 | if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK) | 200 | if (SQLITE_OK != |
201 | sqlite3_open (plugin->fn, | ||
202 | &plugin->dbh)) | ||
218 | { | 203 | { |
219 | LOG (GNUNET_ERROR_TYPE_ERROR, | 204 | LOG (GNUNET_ERROR_TYPE_ERROR, |
220 | _("Unable to initialize SQLite: %s.\n"), | 205 | _("Unable to initialize SQLite: %s.\n"), |
221 | sqlite3_errmsg (plugin->dbh)); | 206 | sqlite3_errmsg (plugin->dbh)); |
222 | return GNUNET_SYSERR; | 207 | return GNUNET_SYSERR; |
223 | } | 208 | } |
224 | CHECK (SQLITE_OK == | 209 | GNUNET_break (SQLITE_OK == |
225 | sqlite3_exec (plugin->dbh, | 210 | sqlite3_busy_timeout (plugin->dbh, |
226 | "PRAGMA temp_store=MEMORY", NULL, NULL, | 211 | BUSY_TIMEOUT_MS)); |
227 | ENULL)); | 212 | if (GNUNET_OK != |
228 | CHECK (SQLITE_OK == | 213 | GNUNET_SQ_exec_statements (plugin->dbh, |
229 | sqlite3_exec (plugin->dbh, | 214 | es)) |
230 | "PRAGMA synchronous=NORMAL", NULL, NULL, | ||
231 | ENULL)); | ||
232 | CHECK (SQLITE_OK == | ||
233 | sqlite3_exec (plugin->dbh, | ||
234 | "PRAGMA legacy_file_format=OFF", NULL, NULL, | ||
235 | ENULL)); | ||
236 | CHECK (SQLITE_OK == | ||
237 | sqlite3_exec (plugin->dbh, | ||
238 | "PRAGMA auto_vacuum=INCREMENTAL", NULL, | ||
239 | NULL, ENULL)); | ||
240 | CHECK (SQLITE_OK == | ||
241 | sqlite3_exec (plugin->dbh, | ||
242 | "PRAGMA encoding=\"UTF-8\"", NULL, | ||
243 | NULL, ENULL)); | ||
244 | CHECK (SQLITE_OK == | ||
245 | sqlite3_exec (plugin->dbh, | ||
246 | "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, | ||
247 | ENULL)); | ||
248 | CHECK (SQLITE_OK == | ||
249 | sqlite3_exec (plugin->dbh, | ||
250 | "PRAGMA page_size=4092", NULL, NULL, | ||
251 | ENULL)); | ||
252 | |||
253 | CHECK (SQLITE_OK == | ||
254 | sqlite3_busy_timeout (plugin->dbh, | ||
255 | BUSY_TIMEOUT_MS)); | ||
256 | |||
257 | |||
258 | /* Create table */ | ||
259 | CHECK (SQLITE_OK == | ||
260 | sq_prepare (plugin->dbh, | ||
261 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns098records'", | ||
262 | &stmt)); | ||
263 | if ( (sqlite3_step (stmt) == SQLITE_DONE) && | ||
264 | (SQLITE_OK != | ||
265 | sqlite3_exec (plugin->dbh, | ||
266 | "CREATE TABLE ns098records (" | ||
267 | " uid INTEGER PRIMARY KEY," | ||
268 | " zone_private_key BLOB NOT NULL," | ||
269 | " pkey BLOB," | ||
270 | " rvalue INT8 NOT NULL," | ||
271 | " record_count INT NOT NULL," | ||
272 | " record_data BLOB NOT NULL," | ||
273 | " label TEXT NOT NULL" | ||
274 | ")", | ||
275 | NULL, NULL, NULL)) ) | ||
276 | { | 215 | { |
277 | LOG_SQLITE (plugin, | 216 | GNUNET_break (0); |
278 | GNUNET_ERROR_TYPE_ERROR, | 217 | LOG (GNUNET_ERROR_TYPE_ERROR, |
279 | "sqlite3_exec"); | 218 | _("Failed to setup database at `%s'\n"), |
280 | sqlite3_finalize (stmt); | 219 | plugin->fn); |
281 | return GNUNET_SYSERR; | 220 | return GNUNET_SYSERR; |
282 | } | 221 | } |
283 | sqlite3_finalize (stmt); | 222 | |
284 | 223 | if (GNUNET_OK != | |
285 | create_indices (plugin->dbh); | 224 | GNUNET_SQ_prepare (plugin->dbh, |
286 | 225 | ps)) | |
287 | if ( (SQLITE_OK != | ||
288 | sq_prepare (plugin->dbh, | ||
289 | "INSERT INTO ns098records (zone_private_key, pkey, rvalue, record_count, record_data, label)" | ||
290 | " VALUES (?, ?, ?, ?, ?, ?)", | ||
291 | &plugin->store_records)) || | ||
292 | (SQLITE_OK != | ||
293 | sq_prepare (plugin->dbh, | ||
294 | "DELETE FROM ns098records WHERE zone_private_key=? AND label=?", | ||
295 | &plugin->delete_records)) || | ||
296 | (SQLITE_OK != | ||
297 | sq_prepare (plugin->dbh, | ||
298 | "SELECT uid,record_count,record_data,label" | ||
299 | " FROM ns098records" | ||
300 | " WHERE zone_private_key=? AND pkey=?", | ||
301 | &plugin->zone_to_name)) || | ||
302 | (SQLITE_OK != | ||
303 | sq_prepare (plugin->dbh, | ||
304 | "SELECT uid,record_count,record_data,label" | ||
305 | " FROM ns098records" | ||
306 | " WHERE zone_private_key=? AND _rowid_ >= ?" | ||
307 | " ORDER BY _rowid_ ASC" | ||
308 | " LIMIT ?", | ||
309 | &plugin->iterate_zone)) || | ||
310 | (SQLITE_OK != | ||
311 | sq_prepare (plugin->dbh, | ||
312 | "SELECT uid,record_count,record_data,label,zone_private_key" | ||
313 | " FROM ns098records" | ||
314 | " WHERE _rowid_ >= ?" | ||
315 | " ORDER BY _rowid_ ASC" | ||
316 | " LIMIT ?", | ||
317 | &plugin->iterate_all_zones)) || | ||
318 | (SQLITE_OK != | ||
319 | sq_prepare (plugin->dbh, | ||
320 | "SELECT uid,record_count,record_data,label,zone_private_key" | ||
321 | " FROM ns098records" | ||
322 | " WHERE zone_private_key=? AND label=?", | ||
323 | &plugin->lookup_label)) | ||
324 | ) | ||
325 | { | 226 | { |
326 | LOG_SQLITE (plugin, | 227 | GNUNET_break (0); |
327 | GNUNET_ERROR_TYPE_ERROR, | 228 | LOG (GNUNET_ERROR_TYPE_ERROR, |
328 | "precompiling"); | 229 | _("Failed to setup database at `%s'\n"), |
230 | plugin->fn); | ||
329 | return GNUNET_SYSERR; | 231 | return GNUNET_SYSERR; |
330 | } | 232 | } |
331 | return GNUNET_OK; | 233 | return GNUNET_OK; |