Fawkes API Fawkes Development Version
sqlite.cpp
1
2/***************************************************************************
3 * sqlite.cpp - Fawkes configuration stored in a SQLite database
4 *
5 * Created: Wed Dec 06 17:23:00 2006
6 * Copyright 2006-2018 Tim Niemueller [www.niemueller.de]
7 ****************************************************************************/
8
9/* This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version. A runtime exception applies to
13 * this software (see LICENSE.GPL_WRE file mentioned below for details).
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
21 */
22
23#include <config/sqlite.h>
24#include <core/exceptions/software.h>
25#include <core/exceptions/system.h>
26#include <core/threading/mutex.h>
27
28#include <sqlite3.h>
29
30#ifndef _GNU_SOURCE
31# define _GNU_SOURCE
32#endif
33#include <cerrno>
34#include <cstdio>
35#include <cstdlib>
36#include <cstring>
37#include <fnmatch.h>
38#include <unistd.h>
39
40namespace fawkes {
41
42/* SQLite statements */
43
44#define TABLE_HOST_CONFIG "config"
45#define TABLE_DEFAULT_CONFIG "defaults.config"
46
47#define SQL_CREATE_TABLE_HOST_CONFIG \
48 "CREATE TABLE IF NOT EXISTS config (\n" \
49 " path TEXT NOT NULL,\n" \
50 " type TEXT NOT NULL,\n" \
51 " value NOT NULL,\n" \
52 " comment TEXT,\n" \
53 " PRIMARY KEY (path)\n" \
54 ")"
55
56#define SQL_CREATE_TABLE_DEFAULT_CONFIG \
57 "CREATE TABLE IF NOT EXISTS defaults.config (\n" \
58 " path TEXT NOT NULL,\n" \
59 " type TEXT NOT NULL,\n" \
60 " value NOT NULL,\n" \
61 " comment TEXT,\n" \
62 " PRIMARY KEY (path)\n" \
63 ")"
64
65#define SQL_CREATE_TABLE_MODIFIED_CONFIG \
66 "CREATE TABLE IF NOT EXISTS modified.config (\n" \
67 " path TEXT NOT NULL,\n" \
68 " type TEXT NOT NULL,\n" \
69 " value NOT NULL,\n" \
70 " comment TEXT,\n" \
71 " modtype TEXT NOT NULL,\n" \
72 " oldvalue NOT NULL,\n" \
73 " PRIMARY KEY (path)\n" \
74 ")"
75
76#define SQL_ATTACH_DEFAULTS "ATTACH DATABASE '%s' AS defaults"
77
78#define SQL_ATTACH_MODIFIED "ATTACH DATABASE ':memory:' AS modified"
79
80#define SQL_ATTACH_DUMPED "ATTACH DATABASE '%s' AS dumped"
81
82#define SQL_DETACH_DUMPED "DETACH DATABASE dumped"
83
84#define SQL_SELECT_VALUE_TYPE \
85 "SELECT type, value, 0 AS is_default FROM config WHERE path=? UNION " \
86 "SELECT type, value, 1 AS is_default FROM defaults.config AS dc " \
87 "WHERE path=? AND NOT EXISTS " \
88 "(SELECT path FROM config WHERE dc.path=path)"
89
90#define SQL_SELECT_COMPLETE \
91 "SELECT *, 0 AS is_default FROM config WHERE path LIKE ? UNION " \
92 "SELECT *, 1 AS is_default FROM defaults.config AS dc " \
93 "WHERE path LIKE ? AND NOT EXISTS " \
94 "(SELECT path FROM config WHERE dc.path = path) " \
95 "ORDER BY path"
96
97#define SQL_SELECT_TYPE \
98 "SELECT type, 0 AS is_default FROM config WHERE path=? UNION " \
99 "SELECT type, 1 AS is_default FROM defaults.config AS dc " \
100 "WHERE path=? AND NOT EXISTS " \
101 "(SELECT path FROM config WHERE dc.path = path)"
102
103#define SQL_SELECT_COMMENT "SELECT comment, 0 AS is_default FROM config WHERE path=?"
104
105#define SQL_SELECT_DEFAULT_COMMENT \
106 "SELECT comment, 1 AS is_default FROM defaults.config AS dc " \
107 "WHERE dc.path=?"
108
109#define SQL_UPDATE_VALUE "UPDATE config SET value=? WHERE path=?"
110
111#define SQL_UPDATE_DEFAULT_VALUE "UPDATE defaults.config SET value=? WHERE path=?"
112
113#define SQL_UPDATE_COMMENT "UPDATE config SET comment=? WHERE path=?"
114
115#define SQL_UPDATE_DEFAULT_COMMENT "UPDATE defaults.config SET comment=? WHERE path=?"
116
117#define SQL_INSERT_VALUE "INSERT INTO config (path, type, value) VALUES (?, ?, ?)"
118
119#define SQL_INSERT_DEFAULT_VALUE "INSERT INTO defaults.config (path, type, value) VALUES (?, ?, ?)"
120
121#define SQL_SELECT_ALL \
122 "SELECT *, 0 AS is_default FROM config UNION " \
123 "SELECT *, 1 AS is_default FROM defaults.config AS dc " \
124 "WHERE NOT EXISTS " \
125 "(SELECT path FROM config WHERE dc.path = path) " \
126 "ORDER BY path"
127
128#define SQL_SELECT_ALL_DEFAULT "SELECT *, 1 AS is_default FROM defaults.config"
129
130#define SQL_SELECT_ALL_HOSTSPECIFIC "SELECT *, 0 AS is_default FROM config"
131
132#define SQL_DELETE_VALUE "DELETE FROM config WHERE path=?"
133
134#define SQL_DELETE_DEFAULT_VALUE "DELETE FROM defaults.config WHERE path=?"
135
136#define SQL_UPDATE_DEFAULT_DB \
137 "INSERT INTO config SELECT * FROM defaults.config AS dc " \
138 "WHERE NOT EXISTS (SELECT path from config WHERE path = dc.path)"
139
140#define SQL_UPDATE_MODIFIED_DB_ADDED \
141 "INSERT INTO modified.config " \
142 " SELECT duc.*,'added' AS modtype, duc.value " \
143 " FROM dumped.config AS duc " \
144 " WHERE NOT EXISTS (SELECT dc.path FROM defaults.config AS dc " \
145 " WHERE dc.path=duc.path) " \
146 " ORDER BY path"
147
148#define SQL_UPDATE_MODIFIED_DB_ERASED \
149 "INSERT INTO modified.config " \
150 " SELECT dc.*,'erased' AS modtype, dc.value " \
151 " FROM defaults.config AS dc " \
152 " WHERE NOT EXISTS (SELECT duc.path FROM dumped.config AS duc " \
153 " WHERE duc.path=dc.path) " \
154 " ORDER BY path"
155
156#define SQL_UPDATE_MODIFIED_DB_CHANGED \
157 "INSERT INTO modified.config " \
158 " SELECT duc.*,'changed' AS modtype, dc.value " \
159 " FROM dumped.config AS duc, defaults.config AS dc " \
160 " WHERE duc.path = dc.path " \
161 " AND (dc.type != duc.type OR dc.value != duc.value) " \
162 " ORDER BY duc.path"
163
164#define SQL_COPY_DUMP \
165 "DELETE FROM defaults.config; " \
166 "INSERT INTO defaults.config SELECT * FROM dumped.config"
167
168#define SQL_SELECT_MODIFIED_ALL "SELECT * FROM modified.config"
169
170#define MEMORY_DUMP_DB_NAME "file:tmp_dump_db?mode=memory&cache=shared"
171
172/** @class SQLiteConfiguration <config/sqlite.h>
173 * Configuration storage using SQLite.
174 * This implementation of the Configuration interface uses SQLite to store the
175 * configuration.
176 *
177 * The configuration uses two databases, one is used to store the host-specific
178 * configuration and the other one is used to store the default values. Only the
179 * default database is meant to reside under version control.
180 *
181 * See init() for the structure of the databases. This class strictly serializes
182 * all accesses to the database such that only one thread at a time can modify the
183 * database.
184 */
185
186/** Constructor. */
188{
189 opened = false;
190 mutex = new Mutex();
191
192 sysconfdir_ = NULL;
193 userconfdir_ = NULL;
194 default_file_ = NULL;
195 default_sql_ = NULL;
196}
197
198/** Constructor.
199 * @param sysconfdir system configuration directory, will be searched for
200 * default configuration file, and system will try to create host-specific
201 * database if writable
202 * @param userconfdir user configuration directory, will be searched preferably
203 * for default configuration file, and will be used to create host-specific
204 * database if sysconfdir is not writable. This directory will be created
205 * if it does not exist during load().
206 */
207SQLiteConfiguration::SQLiteConfiguration(const char *sysconfdir, const char *userconfdir)
208{
209 opened = false;
210 mutex = new Mutex();
211
212 sysconfdir_ = strdup(sysconfdir);
213 default_file_ = NULL;
214 default_sql_ = NULL;
215
216 if (userconfdir != NULL) {
217 userconfdir_ = strdup(userconfdir);
218 } else {
219 const char *homedir = getenv("HOME");
220 if (homedir == NULL) {
221 userconfdir_ = strdup(sysconfdir);
222 } else {
223 if (asprintf(&userconfdir_, "%s/%s", homedir, USERDIR) == -1) {
224 userconfdir_ = strdup(sysconfdir);
225 }
226 }
227 }
228}
229
230/** Destructor. */
232{
233 if (opened) {
234 opened = false;
235 if (sqlite3_close(db) == SQLITE_BUSY) {
236 printf("Boom, we are dead, database cannot be closed "
237 "because there are open handles\n");
238 }
239 }
240
241 if (host_file_)
242 free(host_file_);
243 if (default_file_)
244 free(default_file_);
245 if (default_sql_)
246 free(default_sql_);
247 if (sysconfdir_)
248 free(sysconfdir_);
249 if (userconfdir_)
250 free(userconfdir_);
251 delete mutex;
252}
253
254/** Initialize the configuration database(s).
255 * Initialize databases. If the host-specific database already exists
256 * an exception is thrown. You have to delete it before calling
257 * init(). First the host-specific database is created. It will
258 * contain one table, named 'config'. The 'config' table will hold the
259 * current configuration for this machine.
260 *
261 * The 'config' table is created with the following schema:
262 * @code
263 * CREATE TABLE IF NOT EXISTS config (
264 * path TEXT NOT NULL,
265 * type TEXT NOT NULL,
266 * value NOT NULL,
267 * comment TEXT,
268 * PRIMARY KEY (path)
269 * )
270 * @endcode
271 * If a default database is found the values from this database are copied
272 * to the config table.
273 * The defaults config database is created with the following structure:
274 * @code
275 * CREATE TABLE IF NOT EXISTS defaults.config (
276 * path TEXT NOT NULL,
277 * type TEXT NOT NULL,
278 * value NOT NULL,
279 * comment TEXT,
280 * PRIMARY KEY (path)
281 * )
282 * @endcode
283 *
284 * If no default database exists it is created. The database is kept in a file
285 * called default.db. It contains a single table called 'config' with the same
286 * structure as the 'config' table in the host-specific database.
287 */
288void
289SQLiteConfiguration::init_dbs()
290{
291 char *errmsg;
292 if ((sqlite3_exec(db, SQL_CREATE_TABLE_HOST_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK)
293 || (sqlite3_exec(db, SQL_CREATE_TABLE_DEFAULT_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK)) {
294 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
295 sqlite3_close(db);
296 throw ce;
297 }
298}
299
300/** Dump table.
301 * Dumps a table to the given file.
302 * @param f file to write to
303 * @param tdb SQLite3 database to read from
304 * @param table_name Name of the table to dump
305 */
306static void
307dump_table(FILE *f, ::sqlite3 *tdb, const char *table_name)
308{
309 std::string tisql = "PRAGMA table_info(\"";
310 tisql += table_name;
311 tisql += "\");";
312
313 sqlite3_stmt *stmt;
314 if (sqlite3_prepare(tdb, tisql.c_str(), -1, &stmt, 0) != SQLITE_OK) {
315 throw ConfigurationException("dump_table/prepare", sqlite3_errmsg(tdb));
316 }
317 std::string value_query = "SELECT 'INSERT INTO ' || '\"";
318 value_query += table_name;
319 value_query += "\"' || ' VALUES(' || ";
320 int rv = sqlite3_step(stmt);
321 while (rv == SQLITE_ROW) {
322 value_query += "quote(\"";
323 value_query += (const char *)sqlite3_column_text(stmt, 1);
324 value_query += "\") || ";
325 rv = sqlite3_step(stmt);
326 if (rv == SQLITE_ROW) {
327 value_query += " ',' || ";
328 }
329 }
330 value_query += "')' FROM ";
331 value_query += table_name;
332 sqlite3_finalize(stmt);
333
334 sqlite3_stmt *vstmt;
335 if (sqlite3_prepare(tdb, value_query.c_str(), -1, &vstmt, 0) != SQLITE_OK) {
336 throw ConfigurationException("dump_table/prepare 2", sqlite3_errmsg(tdb));
337 }
338 while (sqlite3_step(vstmt) == SQLITE_ROW) {
339 fprintf(f, "%s;\n", sqlite3_column_text(vstmt, 0));
340 }
341 sqlite3_finalize(vstmt);
342}
343
344void
345SQLiteConfiguration::dump(::sqlite3 *tdb, const char *dumpfile)
346{
347 FILE *f = fopen(dumpfile, "w");
348 if (!f) {
349 throw CouldNotOpenFileException(dumpfile, errno, "Could not open dump file");
350 }
351
352 fprintf(f, "BEGIN TRANSACTION;\n");
353
354 const char *sql = "SELECT name, sql FROM sqlite_master "
355 "WHERE sql NOT NULL AND type=='table'";
356 sqlite3_stmt *stmt;
357 if ((sqlite3_prepare(tdb, sql, -1, &stmt, 0) != SQLITE_OK) || !stmt) {
358 throw ConfigurationException("dump_query/prepare", sqlite3_errmsg(tdb));
359 }
360 while (sqlite3_step(stmt) == SQLITE_ROW) {
361 fprintf(f, "%s;\n", sqlite3_column_text(stmt, 1));
362 dump_table(f, tdb, (const char *)sqlite3_column_text(stmt, 0));
363 }
364 sqlite3_finalize(stmt);
365
366 fprintf(f, "COMMIT;\n");
367 fclose(f);
368}
369
370/** Try to dump default configuration.
371 * This method will try to open the SQL dump file for writing and dump
372 * the current content of the default database into the file.
373 * @exception Exception thrown if dumping fails
374 */
375void
377{
378 if (default_sql_) {
379 sqlite3 *tdb;
380 if (sqlite3_open(default_file_, &tdb) == SQLITE_OK) {
381 try {
382 dump(tdb, default_sql_);
383 sqlite3_close(tdb);
384 } catch (Exception &e) {
385 sqlite3_close(tdb);
386 throw;
387 }
388 }
389 }
390}
391
392/** SQL escaping stub.
393 * This could be extended to perform actual escaping on the provided
394 * SQL line.
395 * @param line line to check
396 * @return string conversion of line
397 */
398static std::string
399sql_escape_noop(const char *line)
400{
401 return std::string(line);
402}
403
404void
405SQLiteConfiguration::import(::sqlite3 *tdb, const char *dumpfile)
406{
407 FILE *f = fopen(dumpfile, "r");
408
409 if (!f) {
410 throw CouldNotOpenConfigException("Import failed, could not open dump file");
411 }
412
413 char line[4096];
414 char *errmsg;
415 while (!feof(f)) {
416 line[0] = 0;
417 unsigned int i = 0;
418 while (!feof(f) && (i < sizeof(line) - 1)) {
419 if (fread(&(line[i]), 1, 1, f) == 1) {
420 ++i;
421 if ((i > 2) && (line[i - 1] == '\n') && (line[i - 2] == ';')) {
422 break;
423 }
424 } else {
425 break;
426 }
427 }
428 line[i] = 0;
429 if (line[0] != 0) {
430 std::string stmt{sql_escape_noop(line)};
431
432 if (sqlite3_exec(tdb, stmt.c_str(), 0, 0, &errmsg) != SQLITE_OK) {
433 ConfigurationException e(errmsg, line);
434 sqlite3_free(errmsg);
435 fclose(f);
436 throw e;
437 }
438 }
439 }
440
441 fclose(f);
442}
443
444void
445SQLiteConfiguration::import_default(const char *default_sql)
446{
447 // Import .sql file into dump database (temporary file)
448 sqlite3 *dump_db;
449 if (sqlite3_open(MEMORY_DUMP_DB_NAME, &dump_db) == SQLITE_OK) {
450 import(dump_db, default_sql);
451 sqlite3_close(dump_db);
452 } else {
453 throw CouldNotOpenConfigException("Failed to import dump file into temp DB");
454 }
455
456 // Attach dump database as "dumped"
457 char *attach_sql;
458 char *errmsg;
459 if (asprintf(&attach_sql, SQL_ATTACH_DUMPED, MEMORY_DUMP_DB_NAME) == -1) {
460 throw CouldNotOpenConfigException("Could not create attachment SQL in merge");
461 }
462 if (sqlite3_exec(db, attach_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
463 free(attach_sql);
464 CouldNotOpenConfigException e("Could not attach dump DB in merge: %s", errmsg);
465 sqlite3_free(errmsg);
466 throw e;
467 }
468 free(attach_sql);
469
470 // Create "modified" database for a list of modified values, only stored in RAM
471 if ((sqlite3_exec(db, SQL_ATTACH_MODIFIED, NULL, NULL, &errmsg) != SQLITE_OK)
472 || (sqlite3_exec(db, SQL_CREATE_TABLE_MODIFIED_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK)) {
473 CouldNotOpenConfigException ce("Could not create or attach modified memory database: %s",
474 errmsg);
475 sqlite3_free(errmsg);
476 throw ce;
477 }
478
479 // Compare old and new database, copying modifications to "modified" database
480 if ((sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_ADDED, NULL, NULL, &errmsg) != SQLITE_OK)
481 || (sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_ERASED, NULL, NULL, &errmsg) != SQLITE_OK)
482 || (sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_CHANGED, NULL, NULL, &errmsg) != SQLITE_OK)) {
483 CouldNotOpenConfigException ce("Could not update modified memory database: %s", errmsg);
484 sqlite3_free(errmsg);
485 throw ce;
486 }
487
488 // Copy dump to defaults DB, overwriting everything
489 if ((sqlite3_exec(db, SQL_COPY_DUMP, NULL, NULL, &errmsg) != SQLITE_OK)) {
490 CouldNotOpenConfigException ce("Could not copy dump to default: %s", errmsg);
491 sqlite3_free(errmsg);
492 throw ce;
493 }
494
495 // Detach dumped DB, no longer required
496 if (sqlite3_exec(db, SQL_DETACH_DUMPED, NULL, NULL, &errmsg) != SQLITE_OK) {
497 CouldNotOpenConfigException e("Could not detach dump DB in import: %s", errmsg);
498 sqlite3_free(errmsg);
499 throw e;
500 }
501}
502
503/** Begin SQL Transaction.
504 * @param ttype transaction type
505 */
506void
508{
509 const char *sql = "BEGIN DEFERRED TRANSACTION;";
510 if (ttype == TRANSACTION_IMMEDIATE) {
511 sql = "BEGIN IMMEDIATE TRANSACTION;";
512 } else if (ttype == TRANSACTION_EXCLUSIVE) {
513 sql = "BEGIN EXCLUSIVE TRANSACTION;";
514 }
515
516 char *errmsg;
517 if ((sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)) {
518 throw ConfigurationException("Could not begin transaction (%s)", errmsg);
519 }
520}
521
522/** Commit SQL Transaction. */
523void
525{
526 const char *sql = "COMMIT TRANSACTION;";
527
528 char *errmsg;
529 if ((sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)) {
530 throw ConfigurationException("Could not commit transaction (%s)", errmsg);
531 }
532}
533
534/** Rollback SQL Transaction. */
535void
537{
538 const char *sql = "ROLLBACK TRANSACTION;";
539
540 char *errmsg;
541 if ((sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)) {
542 throw ConfigurationException("Could not rollback transaction (%s)", errmsg);
543 }
544}
545
546void
547SQLiteConfiguration::attach_default(const char *db_file)
548{
549 char *errmsg;
550 char *attach_sql;
551 if (asprintf(&attach_sql, SQL_ATTACH_DEFAULTS, db_file) == -1) {
552 throw CouldNotOpenConfigException("Could not create attachment SQL");
553 }
554 if (sqlite3_exec(db, attach_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
555 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
556 ce.append("Failed to attach default file (%s)", db_file);
557 free(attach_sql);
558 throw ce;
559 }
560 free(attach_sql);
561}
562
563void
564SQLiteConfiguration::load(const char *file_path)
565{
566 mutex->lock();
567
568 if (default_file_)
569 free(default_file_);
570 if (default_sql_)
571 free(default_sql_);
572 default_file_ = NULL;
573 default_sql_ = NULL;
574
575 const char *try_paths[] = {sysconfdir_, userconfdir_};
576 int try_paths_len = 2;
577
578 char *host_name = NULL;
579
580 if (strcmp(file_path, ":memory:") == 0) {
581 host_file_ = strdup(":memory:");
582
583 if (sqlite3_open(file_path, &db) != SQLITE_OK) {
584 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
585 ce.append("Failed to open memory database");
586 throw ce;
587 }
588 } else {
589 HostInfo hostinfo;
590 if (asprintf(&host_name, "%s.db", hostinfo.short_name()) == -1) {
591 host_name = strdup(hostinfo.short_name());
592 }
593
594 // determine host file
595 // try sysconfdir and userconfdir
596 for (int i = 0; i < try_paths_len; ++i) {
597 char *path;
598 if (asprintf(&path, "%s/%s", try_paths[i], host_name) != -1) {
599 if (sqlite3_open(path, &db) == SQLITE_OK) {
600 host_file_ = path;
601 break;
602 } else {
603 free(path);
604 }
605 }
606 }
607 }
608
609 if (host_file_ == NULL) {
610 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
611 ce.append("Failed to open host db (paths)");
612 if (host_name)
613 free(host_name);
614 throw ce;
615 }
616
617 if (file_path == NULL) {
618 file_path = "default.sql";
619 }
620
621 // determine default file
622 if (strcmp(file_path, ":memory:") == 0) {
623 try {
624 attach_default(":memory:");
625 } catch (...) {
626 if (host_name)
627 free(host_name);
628 throw;
629 }
630 default_file_ = strdup(":memory:");
631 } else {
632 if (file_path[0] == '/') {
633 // absolute path, take as is
634 default_sql_ = strdup(file_path);
635 } else {
636 // try sysconfdir and userconfdir
637 for (int i = 0; i < try_paths_len; ++i) {
638 char *path;
639 if (asprintf(&path, "%s/%s", try_paths[i], file_path) != -1) {
640 if (access(path, F_OK | R_OK) == 0) {
641 default_sql_ = path;
642 break;
643 } else {
644 free(path);
645 }
646 }
647 }
648 }
649
650 // Now go for the .db filename
651
652 // generate filename
653 char * defaults_db;
654 size_t len = strlen(file_path);
655 if (fnmatch("*.sql", file_path, FNM_PATHNAME) == 0) {
656 defaults_db = (char *)calloc(1, len); // yes, that's one byte less!
657 strncpy(defaults_db, file_path, len - 3);
658 strcat(defaults_db, "db");
659 } else {
660 defaults_db = (char *)calloc(1, len + 4);
661 strcpy(defaults_db, file_path);
662 strcat(defaults_db, ".db");
663 }
664
665 if (defaults_db[0] == '/') {
666 try {
667 attach_default(defaults_db);
668 default_file_ = defaults_db;
669 } catch (...) {
670 if (host_name)
671 free(host_name);
672 free(defaults_db);
673 throw;
674 }
675 } else {
676 // check directories
677 for (int i = 0; i < try_paths_len; ++i) {
678 char *path;
679 if (asprintf(&path, "%s/%s", try_paths[i], defaults_db) != -1) {
680 try {
681 attach_default(path);
682 default_file_ = path;
683 break;
684 } catch (CouldNotOpenConfigException &e) {
685 free(path);
686 }
687 }
688 }
689 }
690 free(defaults_db);
691
692 if (default_file_ == NULL) {
693 if (host_name)
694 free(host_name);
695 throw CouldNotOpenConfigException("Could not create default filename");
696 }
697 }
698
699 init_dbs();
700
701 if (default_sql_)
702 import_default(default_sql_);
703 if (host_name)
704 free(host_name);
705
706 opened = true;
707
708 mutex->unlock();
709}
710
711/** Copy all values from the given configuration.
712 * All values from the given configuration are copied. Old values are not erased
713 * so that the copied values will overwrite existing values, new values are
714 * created, but values existent in current config but not in the copie config
715 * will remain unchanged.
716 * @param copyconf configuration to copy
717 */
718void
720{
721 copyconf->lock();
723 Configuration::ValueIterator *i = copyconf->iterator();
724 while (i->next()) {
725 if (i->is_float()) {
726 set_float(i->path(), i->get_float());
727 } else if (i->is_int()) {
728 set_int(i->path(), i->get_int());
729 } else if (i->is_uint()) {
730 set_uint(i->path(), i->get_uint());
731 } else if (i->is_bool()) {
732 set_bool(i->path(), i->get_bool());
733 } else if (i->is_string()) {
734 std::string s = i->get_string();
735 set_string(i->path(), s);
736 }
737 }
738 delete i;
740 copyconf->unlock();
741}
742
743bool
745{
746 mutex->lock();
747 sqlite3_stmt *stmt;
748 const char * tail;
749 bool e;
750
751 if (sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK) {
752 mutex->unlock();
753 throw ConfigurationException("exists/prepare", sqlite3_errmsg(db));
754 }
755 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
756 mutex->unlock();
757 throw ConfigurationException("exists/bind/path", sqlite3_errmsg(db));
758 }
759 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
760 mutex->unlock();
761 throw ConfigurationException("exists/bind/path", sqlite3_errmsg(db));
762 }
763 e = (sqlite3_step(stmt) == SQLITE_ROW);
764 sqlite3_finalize(stmt);
765
766 mutex->unlock();
767 return e;
768}
769
770std::string
772{
773 sqlite3_stmt *stmt;
774 const char * tail;
775 std::string s = "";
776
777 mutex->lock();
778
779 if (sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK) {
780 mutex->unlock();
781 throw ConfigurationException("get_type: Preparation SQL failed");
782 }
783 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
784 mutex->unlock();
785 throw ConfigurationException("get_type: Binding text for path failed (1)");
786 }
787 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
788 mutex->unlock();
789 throw ConfigurationException("get_type: Binding text for path failed (2)");
790 }
791 if (sqlite3_step(stmt) == SQLITE_ROW) {
792 s = (char *)sqlite3_column_text(stmt, 0);
793 sqlite3_finalize(stmt);
794 mutex->unlock();
795 return s;
796 } else {
797 sqlite3_finalize(stmt);
798 mutex->unlock();
800 }
801}
802
803std::string
805{
806 sqlite3_stmt *stmt;
807 const char * tail;
808 std::string s = "";
809
810 mutex->lock();
811
812 if (sqlite3_prepare(db, SQL_SELECT_COMMENT, -1, &stmt, &tail) != SQLITE_OK) {
813 mutex->unlock();
814 throw ConfigurationException("get_comment: Preparation SQL failed");
815 }
816 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
817 mutex->unlock();
818 throw ConfigurationException("get_comment: Binding text for path failed (1)");
819 }
820 if (sqlite3_step(stmt) == SQLITE_ROW) {
821 s = (char *)sqlite3_column_text(stmt, 0);
822 sqlite3_finalize(stmt);
823 mutex->unlock();
824 return s;
825 } else {
826 sqlite3_finalize(stmt);
827 mutex->unlock();
829 }
830}
831
832std::string
834{
835 sqlite3_stmt *stmt;
836 const char * tail;
837 std::string s = "";
838
839 mutex->lock();
840
841 if (sqlite3_prepare(db, SQL_SELECT_DEFAULT_COMMENT, -1, &stmt, &tail) != SQLITE_OK) {
842 mutex->unlock();
843 throw ConfigurationException("get_default_comment: Preparation SQL failed");
844 }
845 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
846 mutex->unlock();
847 throw ConfigurationException("get_default_comment: Binding text for path failed (1)");
848 }
849 if (sqlite3_step(stmt) == SQLITE_ROW) {
850 s = (char *)sqlite3_column_text(stmt, 0);
851 sqlite3_finalize(stmt);
852 mutex->unlock();
853 return s;
854 } else {
855 sqlite3_finalize(stmt);
856 mutex->unlock();
858 }
859}
860
861bool
863{
864 return (get_type(path) == "float");
865}
866
867bool
869{
870 return (get_type(path) == "unsigned int");
871}
872
873bool
875{
876 return (get_type(path) == "int");
877}
878
879bool
881{
882 return (get_type(path) == "bool");
883}
884
885bool
887{
888 return (get_type(path) == "string");
889}
890
891bool
893{
894 return false;
895}
896
897bool
899{
900 mutex->lock();
901 sqlite3_stmt *stmt;
902 const char * tail;
903 bool e;
904
905 if (sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK) {
906 mutex->unlock();
907 throw ConfigurationException("is_default/prepare", sqlite3_errmsg(db));
908 }
909 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
910 mutex->unlock();
911 throw ConfigurationException("is_default/bind/path", sqlite3_errmsg(db));
912 }
913 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
914 mutex->unlock();
915 throw ConfigurationException("is_default/bind/path", sqlite3_errmsg(db));
916 }
917 e = ((sqlite3_step(stmt) == SQLITE_ROW) && (sqlite3_column_int(stmt, 1) == 1));
918 sqlite3_finalize(stmt);
919
920 mutex->unlock();
921 return e;
922}
923
924/** Get a value from the database.
925 * @param path path
926 * @param type desired value, NULL to omit type check
927 */
928sqlite3_stmt *
929SQLiteConfiguration::get_typed_value(const char *path, const char *type)
930{
931 sqlite3_stmt *stmt;
932 const char * tail;
933
934 if (sqlite3_prepare(db, SQL_SELECT_VALUE_TYPE, -1, &stmt, &tail) != SQLITE_OK) {
935 throw ConfigurationException("get_typed_value/prepare", sqlite3_errmsg(db));
936 }
937 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
938 throw ConfigurationException("get_typed_value/bind/path (1)", sqlite3_errmsg(db));
939 }
940 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
941 throw ConfigurationException("get_typed_value/bind/path (2)", sqlite3_errmsg(db));
942 }
943
944 if (sqlite3_step(stmt) == SQLITE_ROW) {
945 if (type == NULL) {
946 // type check omitted
947 return stmt;
948 } else {
949 if (strcmp((char *)sqlite3_column_text(stmt, 0), type) != 0) {
950 ConfigTypeMismatchException ce(path, (char *)sqlite3_column_text(stmt, 0), type);
951 sqlite3_finalize(stmt);
952 throw ce;
953 } else {
954 return stmt;
955 }
956 }
957 } else {
958 sqlite3_finalize(stmt);
959 throw ConfigEntryNotFoundException(path);
960 }
961}
962
963float
965{
966 sqlite3_stmt *stmt;
967 mutex->lock();
968 try {
969 stmt = get_typed_value(path, "float");
970 float f = (float)sqlite3_column_double(stmt, 1);
971 sqlite3_finalize(stmt);
972 mutex->unlock();
973 return f;
974 } catch (Exception &e) {
975 // we can't handle
976 mutex->unlock();
977 throw;
978 }
979}
980
981unsigned int
983{
984 sqlite3_stmt *stmt;
985 mutex->lock();
986 try {
987 stmt = get_typed_value(path, "unsigned int");
988 int i = sqlite3_column_int(stmt, 1);
989 sqlite3_finalize(stmt);
990 if (i < 0) {
991 mutex->unlock();
992 throw ConfigTypeMismatchException(path, "int", "unsigned int");
993 }
994 mutex->unlock();
995 return i;
996 } catch (Exception &e) {
997 // we can't handle
998 mutex->unlock();
999 throw;
1000 }
1001}
1002
1003int
1005{
1006 sqlite3_stmt *stmt;
1007 mutex->lock();
1008 try {
1009 stmt = get_typed_value(path, "int");
1010 int i = sqlite3_column_int(stmt, 1);
1011 sqlite3_finalize(stmt);
1012 mutex->unlock();
1013 return i;
1014 } catch (Exception &e) {
1015 // we can't handle
1016 mutex->unlock();
1017 throw;
1018 }
1019}
1020
1021bool
1023{
1024 sqlite3_stmt *stmt;
1025 mutex->lock();
1026 try {
1027 stmt = get_typed_value(path, "bool");
1028 int i = sqlite3_column_int(stmt, 1);
1029 sqlite3_finalize(stmt);
1030 mutex->unlock();
1031 return (i != 0);
1032 } catch (Exception &e) {
1033 // we can't handle
1034 mutex->unlock();
1035 throw;
1036 }
1037}
1038
1039std::string
1041{
1042 sqlite3_stmt *stmt;
1043 mutex->lock();
1044 try {
1045 stmt = get_typed_value(path, "string");
1046 const char *c = (char *)sqlite3_column_text(stmt, 1);
1047 std::string rv = c;
1048 sqlite3_finalize(stmt);
1049 mutex->unlock();
1050 return rv;
1051 } catch (Exception &e) {
1052 // we can't handle
1053 e.append("SQLiteConfiguration::get_string: Fetching %s failed.", path);
1054 mutex->unlock();
1055 throw;
1056 }
1057}
1058
1059std::vector<float>
1061{
1062 throw NotImplementedException("SQLiteConf: list values are not supported");
1063}
1064
1065std::vector<unsigned int>
1067{
1068 throw NotImplementedException("SQLiteConf: list values are not supported");
1069}
1070
1071std::vector<int>
1073{
1074 throw NotImplementedException("SQLiteConf: list values are not supported");
1075}
1076
1077std::vector<bool>
1079{
1080 throw NotImplementedException("SQLiteConf: list values are not supported");
1081}
1082
1083std::vector<std::string>
1085{
1086 throw NotImplementedException("SQLiteConf: list values are not supported");
1087}
1088
1091{
1092 sqlite3_stmt *stmt;
1093 const char * tail;
1094
1095 if (sqlite3_prepare(db, SQL_SELECT_COMPLETE, -1, &stmt, &tail) != SQLITE_OK) {
1096 throw ConfigurationException("get_value/prepare", sqlite3_errmsg(db));
1097 }
1098 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
1099 throw ConfigurationException("get_value/bind/path (1)", sqlite3_errmsg(db));
1100 }
1101 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
1102 throw ConfigurationException("get_value/bind/path (2)", sqlite3_errmsg(db));
1103 }
1104
1105 return new SQLiteValueIterator(stmt);
1106}
1107
1108sqlite3_stmt *
1109SQLiteConfiguration::prepare_update(const char *sql, const char *path)
1110{
1111 sqlite3_stmt *stmt;
1112 const char * tail;
1113
1114 if (sqlite3_prepare(db, sql, -1, &stmt, &tail) != SQLITE_OK) {
1115 throw ConfigurationException("prepare_update/prepare", sqlite3_errmsg(db));
1116 }
1117 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
1118 ConfigurationException ce("prepare_update/bind", sqlite3_errmsg(db));
1119 sqlite3_finalize(stmt);
1120 throw ce;
1121 }
1122
1123 return stmt;
1124}
1125
1126sqlite3_stmt *
1127SQLiteConfiguration::prepare_insert_value(const char *sql, const char *type, const char *path)
1128{
1129 sqlite3_stmt *stmt;
1130 const char * tail;
1131
1132 if (sqlite3_prepare(db, sql, -1, &stmt, &tail) != SQLITE_OK) {
1133 throw ConfigurationException("prepare_insert_value/prepare", sqlite3_errmsg(db));
1134 }
1135 if ((sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK)
1136 || (sqlite3_bind_text(stmt, 2, type, -1, NULL) != SQLITE_OK)) {
1137 ConfigurationException ce("prepare_insert_value/bind", sqlite3_errmsg(db));
1138 sqlite3_finalize(stmt);
1139 throw ce;
1140 }
1141
1142 return stmt;
1143}
1144
1145void
1146SQLiteConfiguration::execute_insert_or_update(sqlite3_stmt *stmt)
1147{
1148 if (sqlite3_step(stmt) != SQLITE_DONE) {
1149 ConfigurationException ce("execute_insert_or_update", sqlite3_errmsg(db));
1150 sqlite3_finalize(stmt);
1151 throw ce;
1152 }
1153}
1154
1155void
1156SQLiteConfiguration::set_float(const char *path, float f)
1157{
1158 sqlite3_stmt *stmt = NULL;
1159
1160 mutex->lock();
1161
1162 try {
1163 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1164 if ((sqlite3_bind_double(stmt, 1, f) != SQLITE_OK)) {
1165 ConfigurationException ce("set_float/update/bind", sqlite3_errmsg(db));
1166 sqlite3_finalize(stmt);
1167 mutex->unlock();
1168 throw ce;
1169 }
1170 execute_insert_or_update(stmt);
1171 sqlite3_finalize(stmt);
1172 } catch (Exception &e) {
1173 if (stmt != NULL)
1174 sqlite3_finalize(stmt);
1175 mutex->unlock();
1176 throw;
1177 }
1178
1179 if (sqlite3_changes(db) == 0) {
1180 // value did not exist, insert
1181
1182 try {
1183 stmt = prepare_insert_value(SQL_INSERT_VALUE, "float", path);
1184 if ((sqlite3_bind_double(stmt, 3, f) != SQLITE_OK)) {
1185 ConfigurationException ce("set_float/insert/bind", sqlite3_errmsg(db));
1186 sqlite3_finalize(stmt);
1187 mutex->unlock();
1188 throw ce;
1189 }
1190 execute_insert_or_update(stmt);
1191 sqlite3_finalize(stmt);
1192 } catch (Exception &e) {
1193 if (stmt != NULL)
1194 sqlite3_finalize(stmt);
1195 mutex->unlock();
1196 throw;
1197 }
1198 }
1199
1200 mutex->unlock();
1201
1202 notify_handlers(path);
1203}
1204
1205void
1206SQLiteConfiguration::set_uint(const char *path, unsigned int uint)
1207{
1208 sqlite3_stmt *stmt = NULL;
1209
1210 mutex->lock();
1211
1212 try {
1213 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1214 if ((sqlite3_bind_int(stmt, 1, uint) != SQLITE_OK)) {
1215 ConfigurationException ce("set_uint/update/bind", sqlite3_errmsg(db));
1216 sqlite3_finalize(stmt);
1217 mutex->unlock();
1218 throw ce;
1219 }
1220 execute_insert_or_update(stmt);
1221 sqlite3_finalize(stmt);
1222 } catch (Exception &e) {
1223 if (stmt != NULL)
1224 sqlite3_finalize(stmt);
1225 mutex->unlock();
1226 throw;
1227 }
1228
1229 if (sqlite3_changes(db) == 0) {
1230 // value did not exist, insert
1231
1232 try {
1233 stmt = prepare_insert_value(SQL_INSERT_VALUE, "unsigned int", path);
1234 if ((sqlite3_bind_int(stmt, 3, uint) != SQLITE_OK)) {
1235 ConfigurationException ce("set_uint/insert/bind", sqlite3_errmsg(db));
1236 sqlite3_finalize(stmt);
1237 mutex->unlock();
1238 throw ce;
1239 }
1240 execute_insert_or_update(stmt);
1241 sqlite3_finalize(stmt);
1242 } catch (Exception &e) {
1243 if (stmt != NULL)
1244 sqlite3_finalize(stmt);
1245 mutex->unlock();
1246 throw;
1247 }
1248 }
1249 mutex->unlock();
1250
1251 notify_handlers(path);
1252}
1253
1254void
1255SQLiteConfiguration::set_int(const char *path, int i)
1256{
1257 sqlite3_stmt *stmt = NULL;
1258
1259 mutex->lock();
1260
1261 try {
1262 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1263 if ((sqlite3_bind_int(stmt, 1, i) != SQLITE_OK)) {
1264 ConfigurationException ce("set_int/update/bind", sqlite3_errmsg(db));
1265 sqlite3_finalize(stmt);
1266 mutex->unlock();
1267 throw ce;
1268 }
1269 execute_insert_or_update(stmt);
1270 sqlite3_finalize(stmt);
1271 } catch (Exception &e) {
1272 if (stmt != NULL)
1273 sqlite3_finalize(stmt);
1274 mutex->unlock();
1275 throw;
1276 }
1277
1278 if (sqlite3_changes(db) == 0) {
1279 // value did not exist, insert
1280
1281 try {
1282 stmt = prepare_insert_value(SQL_INSERT_VALUE, "int", path);
1283 if ((sqlite3_bind_int(stmt, 3, i) != SQLITE_OK)) {
1284 ConfigurationException ce("set_int/insert/bind", sqlite3_errmsg(db));
1285 sqlite3_finalize(stmt);
1286 mutex->unlock();
1287 throw ce;
1288 }
1289 execute_insert_or_update(stmt);
1290 sqlite3_finalize(stmt);
1291 } catch (Exception &e) {
1292 if (stmt != NULL)
1293 sqlite3_finalize(stmt);
1294 mutex->unlock();
1295 throw;
1296 }
1297 }
1298
1299 mutex->unlock();
1300
1301 notify_handlers(path);
1302}
1303
1304void
1305SQLiteConfiguration::set_bool(const char *path, bool b)
1306{
1307 sqlite3_stmt *stmt = NULL;
1308
1309 mutex->lock();
1310
1311 try {
1312 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1313 if ((sqlite3_bind_int(stmt, 1, (b ? 1 : 0)) != SQLITE_OK)) {
1314 ConfigurationException ce("set_bool/update/bind", sqlite3_errmsg(db));
1315 sqlite3_finalize(stmt);
1316 mutex->unlock();
1317 throw ce;
1318 }
1319 execute_insert_or_update(stmt);
1320 sqlite3_finalize(stmt);
1321 } catch (Exception &e) {
1322 if (stmt != NULL)
1323 sqlite3_finalize(stmt);
1324 mutex->unlock();
1325 throw;
1326 }
1327
1328 if (sqlite3_changes(db) == 0) {
1329 // value did not exist, insert
1330
1331 try {
1332 stmt = prepare_insert_value(SQL_INSERT_VALUE, "bool", path);
1333 if ((sqlite3_bind_int(stmt, 3, (b ? 1 : 0)) != SQLITE_OK)) {
1334 ConfigurationException ce("set_bool/insert/bind", sqlite3_errmsg(db));
1335 sqlite3_finalize(stmt);
1336 mutex->unlock();
1337 throw ce;
1338 }
1339 execute_insert_or_update(stmt);
1340 sqlite3_finalize(stmt);
1341 } catch (Exception &e) {
1342 if (stmt != NULL)
1343 sqlite3_finalize(stmt);
1344 mutex->unlock();
1345 throw;
1346 }
1347 }
1348
1349 mutex->unlock();
1350
1351 notify_handlers(path);
1352}
1353
1354void
1355SQLiteConfiguration::set_string(const char *path, const char *s)
1356{
1357 sqlite3_stmt *stmt = NULL;
1358
1359 mutex->lock();
1360
1361 size_t s_length = strlen(s);
1362
1363 try {
1364 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1365 if ((sqlite3_bind_text(stmt, 1, s, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1366 ConfigurationException ce("set_string/update/bind", sqlite3_errmsg(db));
1367 sqlite3_finalize(stmt);
1368 mutex->unlock();
1369 throw ce;
1370 }
1371 execute_insert_or_update(stmt);
1372 sqlite3_finalize(stmt);
1373 } catch (Exception &e) {
1374 if (stmt != NULL)
1375 sqlite3_finalize(stmt);
1376 mutex->unlock();
1377 throw;
1378 }
1379
1380 if (sqlite3_changes(db) == 0) {
1381 // value did not exist, insert
1382
1383 try {
1384 stmt = prepare_insert_value(SQL_INSERT_VALUE, "string", path);
1385 if ((sqlite3_bind_text(stmt, 3, s, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1386 ConfigurationException ce("set_string/insert/bind", sqlite3_errmsg(db));
1387 sqlite3_finalize(stmt);
1388 mutex->unlock();
1389 throw ce;
1390 }
1391 execute_insert_or_update(stmt);
1392 sqlite3_finalize(stmt);
1393 } catch (Exception &e) {
1394 if (stmt != NULL)
1395 sqlite3_finalize(stmt);
1396 mutex->unlock();
1397 throw;
1398 }
1399 }
1400
1401 mutex->unlock();
1402
1403 notify_handlers(path);
1404}
1405
1406void
1407SQLiteConfiguration::set_string(const char *path, std::string &s)
1408{
1409 set_string(path, s.c_str());
1410}
1411
1412void
1413SQLiteConfiguration::set_floats(const char *path, std::vector<float> &f)
1414{
1415 throw NotImplementedException("SQLiteConf: list values are not supported");
1416}
1417
1418void
1419SQLiteConfiguration::set_uints(const char *path, std::vector<unsigned int> &u)
1420{
1421 throw NotImplementedException("SQLiteConf: list values are not supported");
1422}
1423
1424void
1425SQLiteConfiguration::set_ints(const char *path, std::vector<int> &i)
1426{
1427 throw NotImplementedException("SQLiteConf: list values are not supported");
1428}
1429
1430void
1431SQLiteConfiguration::set_bools(const char *path, std::vector<bool> &b)
1432{
1433 throw NotImplementedException("SQLiteConf: list values are not supported");
1434}
1435
1436void
1437SQLiteConfiguration::set_strings(const char *path, std::vector<std::string> &s)
1438{
1439 throw NotImplementedException("SQLiteConf: list values are not supported");
1440}
1441
1442void
1443SQLiteConfiguration::set_strings(const char *path, std::vector<const char *> &s)
1444{
1445 throw NotImplementedException("SQLiteConf: list values are not supported");
1446}
1447
1448void
1449SQLiteConfiguration::set_comment(const char *path, const char *comment)
1450{
1451 sqlite3_stmt *stmt = NULL;
1452
1453 mutex->lock();
1454
1455 size_t s_length = strlen(comment);
1456
1457 try {
1458 stmt = prepare_update(SQL_UPDATE_COMMENT, path);
1459 if ((sqlite3_bind_text(stmt, 1, comment, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1460 ConfigurationException ce("set_string/update/bind", sqlite3_errmsg(db));
1461 sqlite3_finalize(stmt);
1462 mutex->unlock();
1463 throw ce;
1464 }
1465 execute_insert_or_update(stmt);
1466 sqlite3_finalize(stmt);
1467 } catch (Exception &e) {
1468 if (stmt != NULL)
1469 sqlite3_finalize(stmt);
1470 mutex->unlock();
1471 throw;
1472 }
1473
1474 if (sqlite3_changes(db) == 0) {
1475 // value did not exist, insert
1476 mutex->unlock();
1477 throw ConfigurationException("set_comment", "Cannot set comment for inexistent path");
1478 }
1479
1480 mutex->unlock();
1481
1482 notify_handlers(path, true);
1483}
1484
1485void
1486SQLiteConfiguration::set_comment(const char *path, std::string &comment)
1487{
1488 set_comment(path, comment.c_str());
1489}
1490
1491void
1493{
1494 sqlite3_stmt *stmt;
1495 const char * tail;
1496
1497 if (sqlite3_prepare(db, SQL_DELETE_VALUE, -1, &stmt, &tail) != SQLITE_OK) {
1498 throw ConfigurationException("erase/prepare", sqlite3_errmsg(db));
1499 }
1500 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
1501 ConfigurationException ce("erase/bind", sqlite3_errmsg(db));
1502 sqlite3_finalize(stmt);
1503 throw ce;
1504 }
1505
1506 if (sqlite3_step(stmt) != SQLITE_DONE) {
1507 ConfigurationException ce("erase/execute", sqlite3_errmsg(db));
1508 sqlite3_finalize(stmt);
1509 throw ce;
1510 }
1511
1512 sqlite3_finalize(stmt);
1513
1514 notify_handlers(path);
1515}
1516
1517void
1519{
1520 sqlite3_stmt *stmt = NULL;
1521
1522 mutex->lock();
1523
1524 try {
1525 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1526 if ((sqlite3_bind_double(stmt, 1, f) != SQLITE_OK)) {
1527 ConfigurationException ce("set_default_float/update/bind", sqlite3_errmsg(db));
1528 sqlite3_finalize(stmt);
1529 mutex->unlock();
1530 throw ce;
1531 }
1532 execute_insert_or_update(stmt);
1533 sqlite3_finalize(stmt);
1534 } catch (Exception &e) {
1535 if (stmt != NULL)
1536 sqlite3_finalize(stmt);
1537 mutex->unlock();
1538 throw;
1539 }
1540
1541 if (sqlite3_changes(db) == 0) {
1542 // value did not exist, insert
1543
1544 try {
1545 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "float", path);
1546 if ((sqlite3_bind_double(stmt, 3, f) != SQLITE_OK)) {
1547 ConfigurationException ce("set_default_float/insert/bind", sqlite3_errmsg(db));
1548 sqlite3_finalize(stmt);
1549 mutex->unlock();
1550 throw ce;
1551 }
1552 execute_insert_or_update(stmt);
1553 sqlite3_finalize(stmt);
1554 } catch (Exception &e) {
1555 if (stmt != NULL)
1556 sqlite3_finalize(stmt);
1557 mutex->unlock();
1558 throw;
1559 }
1560 }
1561
1562 mutex->unlock();
1563
1564 notify_handlers(path);
1565}
1566
1567void
1568SQLiteConfiguration::set_default_uint(const char *path, unsigned int uint)
1569{
1570 sqlite3_stmt *stmt = NULL;
1571
1572 mutex->lock();
1573
1574 try {
1575 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1576 if ((sqlite3_bind_int(stmt, 1, uint) != SQLITE_OK)) {
1577 ConfigurationException ce("set_default_uint/update/bind", sqlite3_errmsg(db));
1578 sqlite3_finalize(stmt);
1579 mutex->unlock();
1580 throw ce;
1581 }
1582 execute_insert_or_update(stmt);
1583 sqlite3_finalize(stmt);
1584 } catch (Exception &e) {
1585 if (stmt != NULL)
1586 sqlite3_finalize(stmt);
1587 mutex->unlock();
1588 throw;
1589 }
1590
1591 if (sqlite3_changes(db) == 0) {
1592 // value did not exist, insert
1593
1594 try {
1595 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "unsigned int", path);
1596 if ((sqlite3_bind_int(stmt, 3, uint) != SQLITE_OK)) {
1597 ConfigurationException ce("set_default_uint/insert/bind", sqlite3_errmsg(db));
1598 sqlite3_finalize(stmt);
1599 mutex->unlock();
1600 throw ce;
1601 }
1602 execute_insert_or_update(stmt);
1603 sqlite3_finalize(stmt);
1604 } catch (Exception &e) {
1605 if (stmt != NULL)
1606 sqlite3_finalize(stmt);
1607 mutex->unlock();
1608 throw;
1609 }
1610 }
1611 mutex->unlock();
1612
1613 notify_handlers(path);
1614}
1615
1616void
1618{
1619 sqlite3_stmt *stmt = NULL;
1620 mutex->lock();
1621
1622 try {
1623 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1624 if ((sqlite3_bind_int(stmt, 1, i) != SQLITE_OK)) {
1625 ConfigurationException ce("set_default_int/update/bind", sqlite3_errmsg(db));
1626 sqlite3_finalize(stmt);
1627 mutex->unlock();
1628 throw ce;
1629 }
1630 execute_insert_or_update(stmt);
1631 sqlite3_finalize(stmt);
1632 } catch (Exception &e) {
1633 if (stmt != NULL)
1634 sqlite3_finalize(stmt);
1635 mutex->unlock();
1636 throw;
1637 }
1638
1639 if (sqlite3_changes(db) == 0) {
1640 // value did not exist, insert
1641 try {
1642 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "int", path);
1643 if ((sqlite3_bind_int(stmt, 3, i) != SQLITE_OK)) {
1644 ConfigurationException ce("set_default_int/insert/bind", sqlite3_errmsg(db));
1645 sqlite3_finalize(stmt);
1646 mutex->unlock();
1647 throw ce;
1648 }
1649 execute_insert_or_update(stmt);
1650 sqlite3_finalize(stmt);
1651 } catch (Exception &e) {
1652 if (stmt != NULL)
1653 sqlite3_finalize(stmt);
1654 mutex->unlock();
1655 throw;
1656 }
1657 }
1658
1659 mutex->unlock();
1660
1661 notify_handlers(path);
1662}
1663
1664void
1666{
1667 sqlite3_stmt *stmt = NULL;
1668
1669 mutex->lock();
1670
1671 try {
1672 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1673 if ((sqlite3_bind_int(stmt, 1, (b ? 1 : 0)) != SQLITE_OK)) {
1674 ConfigurationException ce("set_default_bool/update/bind", sqlite3_errmsg(db));
1675 sqlite3_finalize(stmt);
1676 mutex->unlock();
1677 throw ce;
1678 }
1679 execute_insert_or_update(stmt);
1680 sqlite3_finalize(stmt);
1681 } catch (Exception &e) {
1682 if (stmt != NULL)
1683 sqlite3_finalize(stmt);
1684 mutex->unlock();
1685 throw;
1686 }
1687
1688 if (sqlite3_changes(db) == 0) {
1689 // value did not exist, insert
1690
1691 try {
1692 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "bool", path);
1693 if ((sqlite3_bind_int(stmt, 3, (b ? 1 : 0)) != SQLITE_OK)) {
1694 ConfigurationException ce("set_default_bool/insert/bind", sqlite3_errmsg(db));
1695 sqlite3_finalize(stmt);
1696 mutex->unlock();
1697 throw ce;
1698 }
1699 execute_insert_or_update(stmt);
1700 sqlite3_finalize(stmt);
1701 } catch (Exception &e) {
1702 if (stmt != NULL)
1703 sqlite3_finalize(stmt);
1704 mutex->unlock();
1705 throw;
1706 }
1707 }
1708
1709 mutex->unlock();
1710
1711 notify_handlers(path);
1712}
1713
1714void
1715SQLiteConfiguration::set_default_string(const char *path, const char *s)
1716{
1717 sqlite3_stmt *stmt = NULL;
1718
1719 mutex->lock();
1720 size_t s_length = strlen(s);
1721
1722 try {
1723 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1724 if ((sqlite3_bind_text(stmt, 1, s, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1725 ConfigurationException ce("set_default_string/update/bind", sqlite3_errmsg(db));
1726 sqlite3_finalize(stmt);
1727 mutex->unlock();
1728 throw ce;
1729 }
1730 execute_insert_or_update(stmt);
1731 sqlite3_finalize(stmt);
1732 } catch (Exception &e) {
1733 if (stmt != NULL)
1734 sqlite3_finalize(stmt);
1735 mutex->unlock();
1736 throw;
1737 }
1738
1739 if (sqlite3_changes(db) == 0) {
1740 // value did not exist, insert
1741
1742 try {
1743 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "string", path);
1744 if ((sqlite3_bind_text(stmt, 3, s, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1745 ConfigurationException ce("set_default_string/insert/bind", sqlite3_errmsg(db));
1746 sqlite3_finalize(stmt);
1747 mutex->unlock();
1748 throw ce;
1749 }
1750 execute_insert_or_update(stmt);
1751 sqlite3_finalize(stmt);
1752 } catch (Exception &e) {
1753 if (stmt != NULL)
1754 sqlite3_finalize(stmt);
1755 mutex->unlock();
1756 throw;
1757 }
1758 }
1759
1760 mutex->unlock();
1761
1762 notify_handlers(path);
1763}
1764
1765void
1766SQLiteConfiguration::set_default_string(const char *path, std::string &s)
1767{
1768 set_default_string(path, s.c_str());
1769}
1770
1771void
1772SQLiteConfiguration::set_default_comment(const char *path, const char *comment)
1773{
1774 sqlite3_stmt *stmt = NULL;
1775
1776 mutex->lock();
1777 size_t s_length = strlen(comment);
1778
1779 try {
1780 stmt = prepare_update(SQL_UPDATE_DEFAULT_COMMENT, path);
1781 if ((sqlite3_bind_text(stmt, 1, comment, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1782 ConfigurationException ce("set_default_comment/update/bind", sqlite3_errmsg(db));
1783 sqlite3_finalize(stmt);
1784 mutex->unlock();
1785 throw ce;
1786 }
1787 execute_insert_or_update(stmt);
1788 sqlite3_finalize(stmt);
1789 } catch (Exception &e) {
1790 if (stmt != NULL)
1791 sqlite3_finalize(stmt);
1792 mutex->unlock();
1793 throw;
1794 }
1795
1796 if (sqlite3_changes(db) == 0) {
1797 // value did not exist, insert
1798 mutex->unlock();
1799 throw ConfigurationException("set_default_comment", "Cannot set comment for inexistent path");
1800 }
1801
1802 mutex->unlock();
1803
1804 notify_handlers(path);
1805}
1806
1807void
1808SQLiteConfiguration::set_default_comment(const char *path, std::string &comment)
1809{
1810 set_default_comment(path, comment.c_str());
1811}
1812
1813void
1815{
1816 sqlite3_stmt *stmt;
1817 const char * tail;
1818
1819 if (sqlite3_prepare(db, SQL_DELETE_DEFAULT_VALUE, -1, &stmt, &tail) != SQLITE_OK) {
1820 throw ConfigurationException("erase_default/prepare", sqlite3_errmsg(db));
1821 }
1822 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
1823 ConfigurationException ce("erase_default/bind", sqlite3_errmsg(db));
1824 sqlite3_finalize(stmt);
1825 throw ce;
1826 }
1827
1828 if (sqlite3_step(stmt) != SQLITE_DONE) {
1829 ConfigurationException ce("erase_default/execute", sqlite3_errmsg(db));
1830 sqlite3_finalize(stmt);
1831 throw ce;
1832 }
1833
1834 sqlite3_finalize(stmt);
1835
1836 notify_handlers(path);
1837}
1838
1839/** Lock the config.
1840 * No further changes or queries can be executed on the configuration and will block until
1841 * the config is unlocked.
1842 */
1843void
1845{
1846 mutex->lock();
1847}
1848
1849/** Try to lock the config.
1850 * @see Configuration::lock()
1851 * @return true, if the lock has been aquired, false otherwise
1852 */
1853bool
1855{
1856 return mutex->try_lock();
1857}
1858
1859/** Unlock the config.
1860 * Modifications and queries are possible again.
1861 */
1862void
1864{
1865 mutex->unlock();
1866}
1867
1870{
1871 sqlite3_stmt *stmt;
1872 const char * tail;
1873
1874 if (sqlite3_prepare(db, SQL_SELECT_ALL, -1, &stmt, &tail) != SQLITE_OK) {
1875 throw ConfigurationException("iterator: Preparation SQL failed");
1876 }
1877
1878 return new SQLiteValueIterator(stmt);
1879}
1880
1881/** Iterator for all default values.
1882 * Returns an iterator that can be used to iterate over all default values in
1883 * the current default configuration. Note that this might return less paths than
1884 * available, because the values for which no default entry exists are not
1885 * returned.
1886 * @return iterator over all default values
1887 */
1890{
1891 sqlite3_stmt *stmt;
1892 const char * tail;
1893
1894 if (sqlite3_prepare(db, SQL_SELECT_ALL_DEFAULT, -1, &stmt, &tail) != SQLITE_OK) {
1895 throw ConfigurationException("iterator_default: Preparation SQL failed");
1896 }
1897
1898 return new SQLiteValueIterator(stmt);
1899}
1900
1901/** Iterator for all host-specific values.
1902 * Returns an iterator that can be used to iterate over all host-specific values
1903 * in the current configuration. Note that this might return less paths than
1904 * available, because the default values for which no host-specific entry exists
1905 * are not returned.
1906 * @return iterator over all host-specific values
1907 */
1910{
1911 sqlite3_stmt *stmt;
1912 const char * tail;
1913
1914 if (sqlite3_prepare(db, SQL_SELECT_ALL_HOSTSPECIFIC, -1, &stmt, &tail) != SQLITE_OK) {
1915 throw ConfigurationException("iterator_hostspecific: Preparation SQL failed");
1916 }
1917
1918 return new SQLiteValueIterator(stmt);
1919}
1920
1921/** Iterator for modified values.
1922 * Returns an iterator that can be used to iterate over all values that have been
1923 * modified in the default database in the last load (added, erased or changed).
1924 * @return iterator over all values
1925 */
1928{
1929 sqlite3_stmt *stmt;
1930 const char * tail;
1931
1932 if (sqlite3_prepare(db, SQL_SELECT_MODIFIED_ALL, -1, &stmt, &tail) != SQLITE_OK) {
1933 throw ConfigurationException("modified_iterator: Preparation SQL failed");
1934 }
1935
1936 return new SQLiteValueIterator(stmt);
1937}
1938
1939/** Iterator with search results.
1940 * Returns an iterator that can be used to iterate over the search results. All values
1941 * whose component and path start with the given strings are returned.
1942 * A call like
1943 * @code
1944 * config->search("");
1945 * @endcode
1946 * is effectively the same as a call to iterator().
1947 * @param path start of path
1948 * @return iterator to search results
1949 */
1952{
1953 sqlite3_stmt *stmt;
1954 const char * tail;
1955
1956 char *p;
1957 if (asprintf(&p, "%s%%", path) == -1) {
1958 throw ConfigurationException("search: could not allocate component string");
1959 }
1960
1961 if (sqlite3_prepare(db, SQL_SELECT_COMPLETE, -1, &stmt, &tail) != SQLITE_OK) {
1962 free(p);
1963 throw ConfigurationException("begin: Preparation SQL failed");
1964 }
1965 if (sqlite3_bind_text(stmt, 1, p, -1, NULL) != SQLITE_OK) {
1966 free(p);
1967 throw ConfigurationException("begin: Binding text for path failed (1)");
1968 }
1969 if (sqlite3_bind_text(stmt, 2, p, -1, NULL) != SQLITE_OK) {
1970 free(p);
1971 throw ConfigurationException("begin: Binding text for path failed (2)");
1972 }
1973
1974 return new SQLiteValueIterator(stmt, p);
1975}
1976
1977/** @class SQLiteConfiguration::SQLiteValueIterator config/sqlite.h
1978 * SQLite configuration value iterator.
1979 */
1980
1981/** Constructor.
1982 * @param stmt compiled SQLite statement
1983 * @param p pointer to arbitrary data that is freed (not deleted!) when the iterator
1984 * is deleted.
1985 */
1987{
1988 stmt_ = stmt;
1989 p_ = p;
1990}
1991
1992/** Destructor. */
1994{
1995 if (stmt_ != NULL) {
1996 sqlite3_finalize(stmt_);
1997 stmt_ = NULL;
1998 }
1999 if (p_ != NULL) {
2000 free(p_);
2001 }
2002}
2003
2004/* Check if there is another element and advance to this if possible.
2005 * This advances to the next element, if there is one.
2006 * @return true, if another element has been reached, false otherwise
2007 */
2008bool
2010{
2011 if (stmt_ == NULL)
2012 return false;
2013
2014 if (sqlite3_step(stmt_) == SQLITE_ROW) {
2015 return true;
2016 } else {
2017 sqlite3_finalize(stmt_);
2018 stmt_ = NULL;
2019 return false;
2020 }
2021}
2022
2023/** Check if the current element is valid.
2024 * This is much like the classic end element for iterators. If the iterator is
2025 * invalid there all subsequent calls to next() shall fail.
2026 * @return true, if the iterator is still valid, false otherwise
2027 */
2028bool
2030{
2031 return (stmt_ != NULL);
2032}
2033
2034/** Path of value.
2035 * @return path of value
2036 */
2037const char *
2039{
2040 return (const char *)sqlite3_column_text(stmt_, 0);
2041}
2042
2043/** Type of value.
2044 * @return string representation of value type.
2045 */
2046const char *
2048{
2049 return (const char *)sqlite3_column_text(stmt_, 1);
2050}
2051
2052bool
2054{
2055 return (strcmp("float", (const char *)sqlite3_column_text(stmt_, 1)) == 0);
2056}
2057
2058bool
2060{
2061 return (strcmp("unsigned int", (const char *)sqlite3_column_text(stmt_, 1)) == 0);
2062}
2063
2064bool
2066{
2067 return (strcmp("int", (const char *)sqlite3_column_text(stmt_, 1)) == 0);
2068}
2069
2070bool
2072{
2073 return (strcmp("bool", (const char *)sqlite3_column_text(stmt_, 1)) == 0);
2074}
2075
2076bool
2078{
2079 return (strcmp("string", (const char *)sqlite3_column_text(stmt_, 1)) == 0);
2080}
2081
2082bool
2084{
2085 return false;
2086}
2087
2088size_t
2090{
2091 return 0;
2092}
2093
2094bool
2096{
2097 return (sqlite3_column_int(stmt_, 4) == 1);
2098}
2099
2100/** Get float value.
2101 * @return value
2102 */
2103float
2105{
2106 return (float)sqlite3_column_double(stmt_, 2);
2107}
2108
2109/** Get unsigned int value.
2110 * @return value
2111 */
2112unsigned int
2114{
2115 int i = sqlite3_column_int(stmt_, 2);
2116 if (i < 0) {
2117 return 0;
2118 } else {
2119 return i;
2120 }
2121}
2122
2123/** Get int value.
2124 * @return value
2125 */
2126int
2128{
2129 return sqlite3_column_int(stmt_, 2);
2130}
2131
2132/** Get bool value.
2133 * @return value
2134 */
2135bool
2137{
2138 return (sqlite3_column_int(stmt_, 2) != 0);
2139}
2140
2141/** Get string value.
2142 * @return value
2143 */
2144std::string
2146{
2147 return (const char *)sqlite3_column_text(stmt_, 2);
2148}
2149
2150std::vector<float>
2152{
2153 throw NotImplementedException("SQLiteConf: list values are not supported");
2154}
2155
2156std::vector<unsigned int>
2158{
2159 throw NotImplementedException("SQLiteConf: list values are not supported");
2160}
2161
2162std::vector<int>
2164{
2165 throw NotImplementedException("SQLiteConf: list values are not supported");
2166}
2167
2168std::vector<bool>
2170{
2171 throw NotImplementedException("SQLiteConf: list values are not supported");
2172}
2173
2174std::vector<std::string>
2176{
2177 throw NotImplementedException("SQLiteConf: list values are not supported");
2178}
2179
2180/** Get value as string.
2181 * @return value
2182 */
2183std::string
2185{
2186 return (const char *)sqlite3_column_text(stmt_, 2);
2187}
2188
2189/** Get comment.
2190 * @return string comment value
2191 */
2192std::string
2194{
2195 const char *c = (const char *)sqlite3_column_text(stmt_, 3);
2196 return c ? c : "";
2197}
2198
2199/** Get modification type.
2200 * This can only be called if the iterator has been retrieved via
2201 * SQLiteConfiguration::modified_iterator(). Otherwise the return value is
2202 * always and empty string.
2203 * @return string modification type
2204 */
2205std::string
2207{
2208 const char *c = (const char *)sqlite3_column_text(stmt_, 4);
2209 return c ? c : "";
2210}
2211
2212/** Get old value (as string).
2213 * This can only be called if the iterator has been retrieved via
2214 * SQLiteConfiguration::modified_iterator(). The value is always returned
2215 * as string, as it is meant for debugging purposes only. Otherwise the
2216 * return value is always and empty string.
2217 * @return string modification type
2218 */
2219std::string
2221{
2222 const char *c = (const char *)sqlite3_column_text(stmt_, 5);
2223 return c ? c : "";
2224}
2225
2226} // end namespace fawkes
Thrown if a config entry could not be found.
Definition: config.h:47
Thrown if there a type problem was detected for example if you tried to query a float with get_int().
Definition: config.h:53
Generic configuration exception.
Definition: config.h:40
Iterator interface to iterate over config values.
Definition: config.h:75
virtual bool is_uint() const =0
Check if current value is a unsigned int.
virtual const char * path() const =0
Path of value.
virtual bool get_bool() const =0
Get bool value.
virtual unsigned int get_uint() const =0
Get unsigned int value.
virtual bool next()=0
Check if there is another element and advance to this if possible.
virtual float get_float() const =0
Get float value.
virtual bool is_float() const =0
Check if current value is a float.
virtual bool is_int() const =0
Check if current value is a int.
virtual bool is_string() const =0
Check if current value is a string.
virtual bool is_bool() const =0
Check if current value is a bool.
virtual int get_int() const =0
Get int value.
virtual std::string get_string() const =0
Get string value.
Interface for configuration handling.
Definition: config.h:68
void notify_handlers(const char *path, bool comment_changed=false)
Notify handlers for given path.
Definition: config.cpp:674
virtual ValueIterator * iterator()=0
Iterator for all values.
virtual void lock()=0
Lock the config.
virtual void unlock()=0
Unlock the config.
Thrown if config could not be opened.
Definition: config.h:59
Base class for exceptions in Fawkes.
Definition: exception.h:36
void append(const char *format,...) noexcept
Append messages to the message list.
Definition: exception.cpp:333
Host information.
Definition: hostinfo.h:32
const char * short_name()
Get short hostname (up to first dot).
Definition: hostinfo.cpp:109
Mutex mutual exclusion lock.
Definition: mutex.h:33
bool try_lock()
Tries to lock the mutex.
Definition: mutex.cpp:117
void lock()
Lock this mutex.
Definition: mutex.cpp:87
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
Called method has not been implemented.
Definition: software.h:105
SQLite configuration value iterator.
Definition: sqlite.h:119
virtual std::vector< float > get_floats() const
Get list of values from configuration which is of type float.
Definition: sqlite.cpp:2151
virtual std::vector< unsigned int > get_uints() const
Get list of values from configuration which is of type unsigned int.
Definition: sqlite.cpp:2157
virtual const char * path() const
Path of value.
Definition: sqlite.cpp:2038
virtual size_t get_list_size() const
Get number of elements in list value.
Definition: sqlite.cpp:2089
virtual std::string get_as_string() const
Get value as string.
Definition: sqlite.cpp:2184
virtual std::vector< std::string > get_strings() const
Get list of values from configuration which is of type string.
Definition: sqlite.cpp:2175
virtual bool next()
Check if there is another element and advance to this if possible.
Definition: sqlite.cpp:2009
virtual bool is_uint() const
Check if current value is a unsigned int.
Definition: sqlite.cpp:2059
virtual int get_int() const
Get int value.
Definition: sqlite.cpp:2127
virtual const char * type() const
Type of value.
Definition: sqlite.cpp:2047
virtual bool get_bool() const
Get bool value.
Definition: sqlite.cpp:2136
virtual bool is_default() const
Check if current value was read from the default config.
Definition: sqlite.cpp:2095
virtual float get_float() const
Get float value.
Definition: sqlite.cpp:2104
virtual bool is_int() const
Check if current value is a int.
Definition: sqlite.cpp:2065
SQLiteValueIterator(::sqlite3_stmt *stmt, void *p=NULL)
Constructor.
Definition: sqlite.cpp:1986
virtual std::string get_string() const
Get string value.
Definition: sqlite.cpp:2145
virtual unsigned int get_uint() const
Get unsigned int value.
Definition: sqlite.cpp:2113
virtual std::vector< bool > get_bools() const
Get list of values from configuration which is of type bool.
Definition: sqlite.cpp:2169
virtual std::string get_comment() const
Get comment.
Definition: sqlite.cpp:2193
virtual bool is_bool() const
Check if current value is a bool.
Definition: sqlite.cpp:2071
std::string get_oldvalue() const
Get old value (as string).
Definition: sqlite.cpp:2220
virtual bool is_string() const
Check if current value is a string.
Definition: sqlite.cpp:2077
std::string get_modtype() const
Get modification type.
Definition: sqlite.cpp:2206
virtual bool is_float() const
Check if current value is a float.
Definition: sqlite.cpp:2053
virtual bool valid() const
Check if the current element is valid.
Definition: sqlite.cpp:2029
virtual bool is_list() const
Check if a value is a list.
Definition: sqlite.cpp:2083
virtual std::vector< int > get_ints() const
Get list of values from configuration which is of type int.
Definition: sqlite.cpp:2163
virtual void set_floats(const char *path, std::vector< float > &f)
Set new value in configuration of type float.
Definition: sqlite.cpp:1413
virtual ValueIterator * get_value(const char *path)
Get value from configuration.
Definition: sqlite.cpp:1090
void lock()
Lock the config.
Definition: sqlite.cpp:1844
virtual std::vector< unsigned int > get_uints(const char *path)
Get list of values from configuration which is of type unsigned int.
Definition: sqlite.cpp:1066
virtual std::vector< float > get_floats(const char *path)
Get list of values from configuration which is of type float.
Definition: sqlite.cpp:1060
virtual void erase_default(const char *path)
Erase the given default value from the configuration.
Definition: sqlite.cpp:1814
virtual std::string get_comment(const char *path)
Get comment of value at given path.
Definition: sqlite.cpp:804
virtual void set_default_int(const char *path, int i)
Set new default value in configuration of type int.
Definition: sqlite.cpp:1617
ValueIterator * iterator()
Iterator for all values.
Definition: sqlite.cpp:1869
void transaction_rollback()
Rollback SQL Transaction.
Definition: sqlite.cpp:536
virtual bool is_list(const char *path)
Check if a value is a list.
Definition: sqlite.cpp:892
virtual void set_string(const char *path, std::string &s)
Set new value in configuration of type string.
Definition: sqlite.cpp:1407
virtual void erase(const char *path)
Erase the given value from the configuration.
Definition: sqlite.cpp:1492
virtual void set_uint(const char *path, unsigned int uint)
Set new value in configuration of type unsigned int.
Definition: sqlite.cpp:1206
virtual bool get_bool(const char *path)
Get value from configuration which is of type bool.
Definition: sqlite.cpp:1022
ValueIterator * iterator_hostspecific()
Iterator for all host-specific values.
Definition: sqlite.cpp:1909
virtual void set_bool(const char *path, bool b)
Set new value in configuration of type bool.
Definition: sqlite.cpp:1305
virtual int get_int(const char *path)
Get value from configuration which is of type int.
Definition: sqlite.cpp:1004
void try_dump()
Try to dump default configuration.
Definition: sqlite.cpp:376
virtual bool is_string(const char *path)
Check if a value is of type string.
Definition: sqlite.cpp:886
virtual bool is_default(const char *path)
Check if a value was read from the default config.
Definition: sqlite.cpp:898
virtual void copy(Configuration *copyconf)
Copy all values from the given configuration.
Definition: sqlite.cpp:719
virtual void set_default_bool(const char *path, bool b)
Set new default value in configuration of type bool.
Definition: sqlite.cpp:1665
virtual void set_strings(const char *path, std::vector< std::string > &s)
Set new value in configuration of type string.
Definition: sqlite.cpp:1437
virtual void set_default_uint(const char *path, unsigned int uint)
Set new default value in configuration of type unsigned int.
Definition: sqlite.cpp:1568
virtual void set_default_comment(const char *path, const char *comment)
Set new default comment for existing default configuration value.
Definition: sqlite.cpp:1772
virtual void set_uints(const char *path, std::vector< unsigned int > &uint)
Set new value in configuration of type unsigned int.
Definition: sqlite.cpp:1419
virtual bool is_float(const char *path)
Check if a value is of type float.
Definition: sqlite.cpp:862
virtual void set_int(const char *path, int i)
Set new value in configuration of type int.
Definition: sqlite.cpp:1255
virtual ~SQLiteConfiguration()
Destructor.
Definition: sqlite.cpp:231
virtual std::string get_string(const char *path)
Get value from configuration which is of type string.
Definition: sqlite.cpp:1040
virtual std::vector< std::string > get_strings(const char *path)
Get list of values from configuration which is of type string.
Definition: sqlite.cpp:1084
virtual bool is_bool(const char *path)
Check if a value is of type bool.
Definition: sqlite.cpp:880
SQLiteConfiguration()
Constructor.
Definition: sqlite.cpp:187
virtual void set_default_float(const char *path, float f)
Set new default value in configuration of type float.
Definition: sqlite.cpp:1518
virtual std::vector< int > get_ints(const char *path)
Get list of values from configuration which is of type int.
Definition: sqlite.cpp:1072
virtual std::string get_type(const char *path)
Get type of value at given path.
Definition: sqlite.cpp:771
ValueIterator * search(const char *path)
Iterator with search results.
Definition: sqlite.cpp:1951
virtual void set_float(const char *path, float f)
Set new value in configuration of type float.
Definition: sqlite.cpp:1156
virtual unsigned int get_uint(const char *path)
Get value from configuration which is of type unsigned int.
Definition: sqlite.cpp:982
void unlock()
Unlock the config.
Definition: sqlite.cpp:1863
virtual void set_bools(const char *path, std::vector< bool > &b)
Set new value in configuration of type bool.
Definition: sqlite.cpp:1431
virtual std::string get_default_comment(const char *path)
Get comment of value at given path.
Definition: sqlite.cpp:833
virtual void set_comment(const char *path, std::string &comment)
Set new comment for existing value.
Definition: sqlite.cpp:1486
void transaction_begin(transaction_type_t ttype=TRANSACTION_DEFERRED)
Begin SQL Transaction.
Definition: sqlite.cpp:507
virtual float get_float(const char *path)
Get value from configuration which is of type float.
Definition: sqlite.cpp:964
bool try_lock()
Try to lock the config.
Definition: sqlite.cpp:1854
virtual void load(const char *filename)
Load configuration.
Definition: sqlite.cpp:564
virtual std::vector< bool > get_bools(const char *path)
Get list of values from configuration which is of type bool.
Definition: sqlite.cpp:1078
virtual bool is_uint(const char *path)
Check if a value is of type unsigned int.
Definition: sqlite.cpp:868
ValueIterator * iterator_default()
Iterator for all default values.
Definition: sqlite.cpp:1889
SQLiteValueIterator * modified_iterator()
Iterator for modified values.
Definition: sqlite.cpp:1927
virtual void set_ints(const char *path, std::vector< int > &i)
Set new value in configuration of type int.
Definition: sqlite.cpp:1425
virtual bool is_int(const char *path)
Check if a value is of type int.
Definition: sqlite.cpp:874
virtual void set_default_string(const char *path, std::string &s)
Set new default value in configuration of type string.
Definition: sqlite.cpp:1766
void transaction_commit()
Commit SQL Transaction.
Definition: sqlite.cpp:524
virtual bool exists(const char *path)
Check if a given value exists.
Definition: sqlite.cpp:744
transaction_type_t
Transaction type.
Definition: sqlite.h:107
@ TRANSACTION_EXCLUSIVE
Immediately acquire lock, no more reading or writing possible.
Definition: sqlite.h:110
@ TRANSACTION_IMMEDIATE
Immediately acquire lock, reading remains possible.
Definition: sqlite.h:109
Fawkes library namespace.
static std::string sql_escape_noop(const char *line)
SQL escaping stub.
Definition: sqlite.cpp:399
static void dump_table(FILE *f, ::sqlite3 *tdb, const char *table_name)
Dump table.
Definition: sqlite.cpp:307