23 #include <config/sqlite.h> 24 #include <core/exceptions/software.h> 25 #include <core/exceptions/system.h> 26 #include <core/threading/mutex.h> 44 #define TABLE_HOST_CONFIG "config" 45 #define TABLE_DEFAULT_CONFIG "defaults.config" 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" \ 53 " PRIMARY KEY (path)\n" \ 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" \ 62 " PRIMARY KEY (path)\n" \ 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" \ 71 " modtype TEXT NOT NULL,\n" \ 72 " oldvalue NOT NULL,\n" \ 73 " PRIMARY KEY (path)\n" \ 76 #define SQL_ATTACH_DEFAULTS "ATTACH DATABASE '%s' AS defaults" 78 #define SQL_ATTACH_MODIFIED "ATTACH DATABASE ':memory:' AS modified" 80 #define SQL_ATTACH_DUMPED "ATTACH DATABASE '%s' AS dumped" 82 #define SQL_DETACH_DUMPED "DETACH DATABASE dumped" 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)" 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) " \ 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)" 103 #define SQL_SELECT_COMMENT "SELECT comment, 0 AS is_default FROM config WHERE path=?" 105 #define SQL_SELECT_DEFAULT_COMMENT \ 106 "SELECT comment, 1 AS is_default FROM defaults.config AS dc " \ 109 #define SQL_UPDATE_VALUE "UPDATE config SET value=? WHERE path=?" 111 #define SQL_UPDATE_DEFAULT_VALUE "UPDATE defaults.config SET value=? WHERE path=?" 113 #define SQL_UPDATE_COMMENT "UPDATE config SET comment=? WHERE path=?" 115 #define SQL_UPDATE_DEFAULT_COMMENT "UPDATE defaults.config SET comment=? WHERE path=?" 117 #define SQL_INSERT_VALUE "INSERT INTO config (path, type, value) VALUES (?, ?, ?)" 119 #define SQL_INSERT_DEFAULT_VALUE "INSERT INTO defaults.config (path, type, value) VALUES (?, ?, ?)" 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) " \ 128 #define SQL_SELECT_ALL_DEFAULT "SELECT *, 1 AS is_default FROM defaults.config" 130 #define SQL_SELECT_ALL_HOSTSPECIFIC "SELECT *, 0 AS is_default FROM config" 132 #define SQL_DELETE_VALUE "DELETE FROM config WHERE path=?" 134 #define SQL_DELETE_DEFAULT_VALUE "DELETE FROM defaults.config WHERE path=?" 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)" 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) " \ 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) " \ 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) " \ 164 #define SQL_COPY_DUMP \ 165 "DELETE FROM defaults.config; " \ 166 "INSERT INTO defaults.config SELECT * FROM dumped.config" 168 #define SQL_SELECT_MODIFIED_ALL "SELECT * FROM modified.config" 170 #define MEMORY_DUMP_DB_NAME "file:tmp_dump_db?mode=memory&cache=shared" 194 default_file_ = NULL;
212 sysconfdir_ = strdup(sysconfdir);
213 default_file_ = NULL;
216 if (userconfdir != NULL) {
217 userconfdir_ = strdup(userconfdir);
219 const char *homedir = getenv(
"HOME");
220 if (homedir == NULL) {
221 userconfdir_ = strdup(sysconfdir);
223 if (asprintf(&userconfdir_,
"%s/%s", homedir, USERDIR) == -1) {
224 userconfdir_ = strdup(sysconfdir);
235 if (sqlite3_close(db) == SQLITE_BUSY) {
236 printf(
"Boom, we are dead, database cannot be closed " 237 "because there are open handles\n");
289 SQLiteConfiguration::init_dbs()
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)) {
309 std::string tisql =
"PRAGMA table_info(\"";
314 if (sqlite3_prepare(tdb, tisql.c_str(), -1, &stmt, 0) != SQLITE_OK) {
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 +=
" ',' || ";
330 value_query +=
"')' FROM ";
331 value_query += table_name;
332 sqlite3_finalize(stmt);
335 if (sqlite3_prepare(tdb, value_query.c_str(), -1, &vstmt, 0) != SQLITE_OK) {
338 while (sqlite3_step(vstmt) == SQLITE_ROW) {
339 fprintf(f,
"%s;\n", sqlite3_column_text(vstmt, 0));
341 sqlite3_finalize(vstmt);
345 SQLiteConfiguration::dump(::sqlite3 *tdb,
const char *dumpfile)
347 FILE *f = fopen(dumpfile,
"w");
349 throw CouldNotOpenFileException(dumpfile, errno,
"Could not open dump file");
352 fprintf(f,
"BEGIN TRANSACTION;\n");
354 const char *sql =
"SELECT name, sql FROM sqlite_master " 355 "WHERE sql NOT NULL AND type=='table'";
357 if ((sqlite3_prepare(tdb, sql, -1, &stmt, 0) != SQLITE_OK) || !stmt) {
358 throw ConfigurationException(
"dump_query/prepare", sqlite3_errmsg(tdb));
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));
364 sqlite3_finalize(stmt);
366 fprintf(f,
"COMMIT;\n");
380 if (sqlite3_open(default_file_, &tdb) == SQLITE_OK) {
382 dump(tdb, default_sql_);
401 return std::string(line);
405 SQLiteConfiguration::import(::sqlite3 *tdb,
const char *dumpfile)
407 FILE *f = fopen(dumpfile,
"r");
410 throw CouldNotOpenConfigException(
"Import failed, could not open dump file");
418 while (!feof(f) && (i <
sizeof(line) - 1)) {
419 if (fread(&(line[i]), 1, 1, f) == 1) {
421 if ((i > 2) && (line[i - 1] ==
'\n') && (line[i - 2] ==
';')) {
432 if (sqlite3_exec(tdb, stmt.c_str(), 0, 0, &errmsg) != SQLITE_OK) {
433 ConfigurationException e(errmsg, line);
434 sqlite3_free(errmsg);
445 SQLiteConfiguration::import_default(
const char *default_sql)
449 if (sqlite3_open(MEMORY_DUMP_DB_NAME, &dump_db) == SQLITE_OK) {
450 import(dump_db, default_sql);
451 sqlite3_close(dump_db);
453 throw CouldNotOpenConfigException(
"Failed to import dump file into temp DB");
459 if (asprintf(&attach_sql, SQL_ATTACH_DUMPED, MEMORY_DUMP_DB_NAME) == -1) {
460 throw CouldNotOpenConfigException(
"Could not create attachment SQL in merge");
462 if (sqlite3_exec(db, attach_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
464 CouldNotOpenConfigException e(
"Could not attach dump DB in merge: %s", errmsg);
465 sqlite3_free(errmsg);
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",
475 sqlite3_free(errmsg);
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);
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);
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);
509 const char *sql =
"BEGIN DEFERRED TRANSACTION;";
511 sql =
"BEGIN IMMEDIATE TRANSACTION;";
513 sql =
"BEGIN EXCLUSIVE TRANSACTION;";
517 if ((sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)) {
526 const char *sql =
"COMMIT TRANSACTION;";
529 if ((sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)) {
538 const char *sql =
"ROLLBACK TRANSACTION;";
541 if ((sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)) {
547 SQLiteConfiguration::attach_default(
const char *db_file)
551 if (asprintf(&attach_sql, SQL_ATTACH_DEFAULTS, db_file) == -1) {
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);
572 default_file_ = NULL;
575 const char *try_paths[] = {sysconfdir_, userconfdir_};
576 int try_paths_len = 2;
578 char *host_name = NULL;
580 if (strcmp(file_path,
":memory:") == 0) {
581 host_file_ = strdup(
":memory:");
583 if (sqlite3_open(file_path, &db) != SQLITE_OK) {
585 ce.
append(
"Failed to open memory database");
590 if (asprintf(&host_name,
"%s.db", hostinfo.
short_name()) == -1) {
596 for (
int i = 0; i < try_paths_len; ++i) {
598 if (asprintf(&path,
"%s/%s", try_paths[i], host_name) != -1) {
599 if (sqlite3_open(path, &db) == SQLITE_OK) {
609 if (host_file_ == NULL) {
611 ce.
append(
"Failed to open host db (paths)");
617 if (file_path == NULL) {
618 file_path =
"default.sql";
622 if (strcmp(file_path,
":memory:") == 0) {
624 attach_default(
":memory:");
630 default_file_ = strdup(
":memory:");
632 if (file_path[0] ==
'/') {
634 default_sql_ = strdup(file_path);
637 for (
int i = 0; i < try_paths_len; ++i) {
639 if (asprintf(&path,
"%s/%s", try_paths[i], file_path) != -1) {
640 if (access(path, F_OK | R_OK) == 0) {
654 size_t len = strlen(file_path);
655 if (fnmatch(
"*.sql", file_path, FNM_PATHNAME) == 0) {
656 defaults_db = (
char *)calloc(1, len);
657 strncpy(defaults_db, file_path, len - 3);
658 strcat(defaults_db,
"db");
660 defaults_db = (
char *)calloc(1, len + 4);
661 strcpy(defaults_db, file_path);
662 strcat(defaults_db,
".db");
665 if (defaults_db[0] ==
'/') {
667 attach_default(defaults_db);
668 default_file_ = defaults_db;
677 for (
int i = 0; i < try_paths_len; ++i) {
679 if (asprintf(&path,
"%s/%s", try_paths[i], defaults_db) != -1) {
681 attach_default(path);
682 default_file_ = path;
692 if (default_file_ == NULL) {
702 import_default(default_sql_);
751 if (sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK) {
755 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
759 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
763 e = (sqlite3_step(stmt) == SQLITE_ROW);
764 sqlite3_finalize(stmt);
779 if (sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK) {
783 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
787 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
791 if (sqlite3_step(stmt) == SQLITE_ROW) {
792 s = (
char *)sqlite3_column_text(stmt, 0);
793 sqlite3_finalize(stmt);
797 sqlite3_finalize(stmt);
812 if (sqlite3_prepare(db, SQL_SELECT_COMMENT, -1, &stmt, &tail) != SQLITE_OK) {
816 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
820 if (sqlite3_step(stmt) == SQLITE_ROW) {
821 s = (
char *)sqlite3_column_text(stmt, 0);
822 sqlite3_finalize(stmt);
826 sqlite3_finalize(stmt);
841 if (sqlite3_prepare(db, SQL_SELECT_DEFAULT_COMMENT, -1, &stmt, &tail) != SQLITE_OK) {
845 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
849 if (sqlite3_step(stmt) == SQLITE_ROW) {
850 s = (
char *)sqlite3_column_text(stmt, 0);
851 sqlite3_finalize(stmt);
855 sqlite3_finalize(stmt);
870 return (
get_type(path) ==
"unsigned int");
888 return (
get_type(path) ==
"string");
905 if (sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK) {
909 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
913 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
917 e = ((sqlite3_step(stmt) == SQLITE_ROW) && (sqlite3_column_int(stmt, 1) == 1));
918 sqlite3_finalize(stmt);
929 SQLiteConfiguration::get_typed_value(
const char *path,
const char *type)
934 if (sqlite3_prepare(db, SQL_SELECT_VALUE_TYPE, -1, &stmt, &tail) != SQLITE_OK) {
937 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
938 throw ConfigurationException(
"get_typed_value/bind/path (1)", sqlite3_errmsg(db));
940 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
941 throw ConfigurationException(
"get_typed_value/bind/path (2)", sqlite3_errmsg(db));
944 if (sqlite3_step(stmt) == SQLITE_ROW) {
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);
958 sqlite3_finalize(stmt);
959 throw ConfigEntryNotFoundException(path);
969 stmt = get_typed_value(path,
"float");
970 float f = (float)sqlite3_column_double(stmt, 1);
971 sqlite3_finalize(stmt);
987 stmt = get_typed_value(path,
"unsigned int");
988 int i = sqlite3_column_int(stmt, 1);
989 sqlite3_finalize(stmt);
1009 stmt = get_typed_value(path,
"int");
1010 int i = sqlite3_column_int(stmt, 1);
1011 sqlite3_finalize(stmt);
1027 stmt = get_typed_value(path,
"bool");
1028 int i = sqlite3_column_int(stmt, 1);
1029 sqlite3_finalize(stmt);
1045 stmt = get_typed_value(path,
"string");
1046 const char *c = (
char *)sqlite3_column_text(stmt, 1);
1048 sqlite3_finalize(stmt);
1053 e.
append(
"SQLiteConfiguration::get_string: Fetching %s failed.", path);
1065 std::vector<unsigned int>
1083 std::vector<std::string>
1095 if (sqlite3_prepare(db, SQL_SELECT_COMPLETE, -1, &stmt, &tail) != SQLITE_OK) {
1098 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
1101 if (sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK) {
1109 SQLiteConfiguration::prepare_update(
const char *sql,
const char *path)
1114 if (sqlite3_prepare(db, sql, -1, &stmt, &tail) != SQLITE_OK) {
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);
1127 SQLiteConfiguration::prepare_insert_value(
const char *sql,
const char *type,
const char *path)
1132 if (sqlite3_prepare(db, sql, -1, &stmt, &tail) != SQLITE_OK) {
1133 throw ConfigurationException(
"prepare_insert_value/prepare", sqlite3_errmsg(db));
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);
1146 SQLiteConfiguration::execute_insert_or_update(sqlite3_stmt *stmt)
1148 if (sqlite3_step(stmt) != SQLITE_DONE) {
1149 ConfigurationException ce(
"execute_insert_or_update", sqlite3_errmsg(db));
1150 sqlite3_finalize(stmt);
1158 sqlite3_stmt *stmt = NULL;
1163 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1164 if ((sqlite3_bind_double(stmt, 1, f) != SQLITE_OK)) {
1166 sqlite3_finalize(stmt);
1170 execute_insert_or_update(stmt);
1171 sqlite3_finalize(stmt);
1174 sqlite3_finalize(stmt);
1179 if (sqlite3_changes(db) == 0) {
1183 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"float", path);
1184 if ((sqlite3_bind_double(stmt, 3, f) != SQLITE_OK)) {
1186 sqlite3_finalize(stmt);
1190 execute_insert_or_update(stmt);
1191 sqlite3_finalize(stmt);
1194 sqlite3_finalize(stmt);
1208 sqlite3_stmt *stmt = NULL;
1213 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1214 if ((sqlite3_bind_int(stmt, 1, uint) != SQLITE_OK)) {
1216 sqlite3_finalize(stmt);
1220 execute_insert_or_update(stmt);
1221 sqlite3_finalize(stmt);
1224 sqlite3_finalize(stmt);
1229 if (sqlite3_changes(db) == 0) {
1233 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"unsigned int", path);
1234 if ((sqlite3_bind_int(stmt, 3, uint) != SQLITE_OK)) {
1236 sqlite3_finalize(stmt);
1240 execute_insert_or_update(stmt);
1241 sqlite3_finalize(stmt);
1244 sqlite3_finalize(stmt);
1257 sqlite3_stmt *stmt = NULL;
1262 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1263 if ((sqlite3_bind_int(stmt, 1, i) != SQLITE_OK)) {
1265 sqlite3_finalize(stmt);
1269 execute_insert_or_update(stmt);
1270 sqlite3_finalize(stmt);
1273 sqlite3_finalize(stmt);
1278 if (sqlite3_changes(db) == 0) {
1282 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"int", path);
1283 if ((sqlite3_bind_int(stmt, 3, i) != SQLITE_OK)) {
1285 sqlite3_finalize(stmt);
1289 execute_insert_or_update(stmt);
1290 sqlite3_finalize(stmt);
1293 sqlite3_finalize(stmt);
1307 sqlite3_stmt *stmt = NULL;
1312 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1313 if ((sqlite3_bind_int(stmt, 1, (b ? 1 : 0)) != SQLITE_OK)) {
1315 sqlite3_finalize(stmt);
1319 execute_insert_or_update(stmt);
1320 sqlite3_finalize(stmt);
1323 sqlite3_finalize(stmt);
1328 if (sqlite3_changes(db) == 0) {
1332 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"bool", path);
1333 if ((sqlite3_bind_int(stmt, 3, (b ? 1 : 0)) != SQLITE_OK)) {
1335 sqlite3_finalize(stmt);
1339 execute_insert_or_update(stmt);
1340 sqlite3_finalize(stmt);
1343 sqlite3_finalize(stmt);
1357 sqlite3_stmt *stmt = NULL;
1361 size_t s_length = strlen(s);
1364 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1365 if ((sqlite3_bind_text(stmt, 1, s, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1367 sqlite3_finalize(stmt);
1371 execute_insert_or_update(stmt);
1372 sqlite3_finalize(stmt);
1375 sqlite3_finalize(stmt);
1380 if (sqlite3_changes(db) == 0) {
1384 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"string", path);
1385 if ((sqlite3_bind_text(stmt, 3, s, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1387 sqlite3_finalize(stmt);
1391 execute_insert_or_update(stmt);
1392 sqlite3_finalize(stmt);
1395 sqlite3_finalize(stmt);
1451 sqlite3_stmt *stmt = NULL;
1455 size_t s_length = strlen(comment);
1458 stmt = prepare_update(SQL_UPDATE_COMMENT, path);
1459 if ((sqlite3_bind_text(stmt, 1, comment, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1461 sqlite3_finalize(stmt);
1465 execute_insert_or_update(stmt);
1466 sqlite3_finalize(stmt);
1469 sqlite3_finalize(stmt);
1474 if (sqlite3_changes(db) == 0) {
1497 if (sqlite3_prepare(db, SQL_DELETE_VALUE, -1, &stmt, &tail) != SQLITE_OK) {
1500 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
1502 sqlite3_finalize(stmt);
1506 if (sqlite3_step(stmt) != SQLITE_DONE) {
1508 sqlite3_finalize(stmt);
1512 sqlite3_finalize(stmt);
1520 sqlite3_stmt *stmt = NULL;
1525 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1526 if ((sqlite3_bind_double(stmt, 1, f) != SQLITE_OK)) {
1528 sqlite3_finalize(stmt);
1532 execute_insert_or_update(stmt);
1533 sqlite3_finalize(stmt);
1536 sqlite3_finalize(stmt);
1541 if (sqlite3_changes(db) == 0) {
1545 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"float", path);
1546 if ((sqlite3_bind_double(stmt, 3, f) != SQLITE_OK)) {
1548 sqlite3_finalize(stmt);
1552 execute_insert_or_update(stmt);
1553 sqlite3_finalize(stmt);
1556 sqlite3_finalize(stmt);
1570 sqlite3_stmt *stmt = NULL;
1575 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1576 if ((sqlite3_bind_int(stmt, 1, uint) != SQLITE_OK)) {
1578 sqlite3_finalize(stmt);
1582 execute_insert_or_update(stmt);
1583 sqlite3_finalize(stmt);
1586 sqlite3_finalize(stmt);
1591 if (sqlite3_changes(db) == 0) {
1595 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"unsigned int", path);
1596 if ((sqlite3_bind_int(stmt, 3, uint) != SQLITE_OK)) {
1598 sqlite3_finalize(stmt);
1602 execute_insert_or_update(stmt);
1603 sqlite3_finalize(stmt);
1606 sqlite3_finalize(stmt);
1619 sqlite3_stmt *stmt = NULL;
1623 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1624 if ((sqlite3_bind_int(stmt, 1, i) != SQLITE_OK)) {
1626 sqlite3_finalize(stmt);
1630 execute_insert_or_update(stmt);
1631 sqlite3_finalize(stmt);
1634 sqlite3_finalize(stmt);
1639 if (sqlite3_changes(db) == 0) {
1642 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"int", path);
1643 if ((sqlite3_bind_int(stmt, 3, i) != SQLITE_OK)) {
1645 sqlite3_finalize(stmt);
1649 execute_insert_or_update(stmt);
1650 sqlite3_finalize(stmt);
1653 sqlite3_finalize(stmt);
1667 sqlite3_stmt *stmt = NULL;
1672 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1673 if ((sqlite3_bind_int(stmt, 1, (b ? 1 : 0)) != SQLITE_OK)) {
1675 sqlite3_finalize(stmt);
1679 execute_insert_or_update(stmt);
1680 sqlite3_finalize(stmt);
1683 sqlite3_finalize(stmt);
1688 if (sqlite3_changes(db) == 0) {
1692 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"bool", path);
1693 if ((sqlite3_bind_int(stmt, 3, (b ? 1 : 0)) != SQLITE_OK)) {
1695 sqlite3_finalize(stmt);
1699 execute_insert_or_update(stmt);
1700 sqlite3_finalize(stmt);
1703 sqlite3_finalize(stmt);
1717 sqlite3_stmt *stmt = NULL;
1720 size_t s_length = strlen(s);
1723 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1724 if ((sqlite3_bind_text(stmt, 1, s, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1726 sqlite3_finalize(stmt);
1730 execute_insert_or_update(stmt);
1731 sqlite3_finalize(stmt);
1734 sqlite3_finalize(stmt);
1739 if (sqlite3_changes(db) == 0) {
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)) {
1746 sqlite3_finalize(stmt);
1750 execute_insert_or_update(stmt);
1751 sqlite3_finalize(stmt);
1754 sqlite3_finalize(stmt);
1774 sqlite3_stmt *stmt = NULL;
1777 size_t s_length = strlen(comment);
1780 stmt = prepare_update(SQL_UPDATE_DEFAULT_COMMENT, path);
1781 if ((sqlite3_bind_text(stmt, 1, comment, s_length, SQLITE_STATIC) != SQLITE_OK)) {
1783 sqlite3_finalize(stmt);
1787 execute_insert_or_update(stmt);
1788 sqlite3_finalize(stmt);
1791 sqlite3_finalize(stmt);
1796 if (sqlite3_changes(db) == 0) {
1819 if (sqlite3_prepare(db, SQL_DELETE_DEFAULT_VALUE, -1, &stmt, &tail) != SQLITE_OK) {
1822 if (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) {
1824 sqlite3_finalize(stmt);
1828 if (sqlite3_step(stmt) != SQLITE_DONE) {
1830 sqlite3_finalize(stmt);
1834 sqlite3_finalize(stmt);
1874 if (sqlite3_prepare(db, SQL_SELECT_ALL, -1, &stmt, &tail) != SQLITE_OK) {
1894 if (sqlite3_prepare(db, SQL_SELECT_ALL_DEFAULT, -1, &stmt, &tail) != SQLITE_OK) {
1914 if (sqlite3_prepare(db, SQL_SELECT_ALL_HOSTSPECIFIC, -1, &stmt, &tail) != SQLITE_OK) {
1932 if (sqlite3_prepare(db, SQL_SELECT_MODIFIED_ALL, -1, &stmt, &tail) != SQLITE_OK) {
1957 if (asprintf(&p,
"%s%%", path) == -1) {
1961 if (sqlite3_prepare(db, SQL_SELECT_COMPLETE, -1, &stmt, &tail) != SQLITE_OK) {
1965 if (sqlite3_bind_text(stmt, 1, p, -1, NULL) != SQLITE_OK) {
1969 if (sqlite3_bind_text(stmt, 2, p, -1, NULL) != SQLITE_OK) {
1995 if (stmt_ != NULL) {
1996 sqlite3_finalize(stmt_);
2014 if (sqlite3_step(stmt_) == SQLITE_ROW) {
2017 sqlite3_finalize(stmt_);
2031 return (stmt_ != NULL);
2040 return (
const char *)sqlite3_column_text(stmt_, 0);
2049 return (
const char *)sqlite3_column_text(stmt_, 1);
2055 return (strcmp(
"float", (
const char *)sqlite3_column_text(stmt_, 1)) == 0);
2061 return (strcmp(
"unsigned int", (
const char *)sqlite3_column_text(stmt_, 1)) == 0);
2067 return (strcmp(
"int", (
const char *)sqlite3_column_text(stmt_, 1)) == 0);
2073 return (strcmp(
"bool", (
const char *)sqlite3_column_text(stmt_, 1)) == 0);
2079 return (strcmp(
"string", (
const char *)sqlite3_column_text(stmt_, 1)) == 0);
2097 return (sqlite3_column_int(stmt_, 4) == 1);
2106 return (
float)sqlite3_column_double(stmt_, 2);
2115 int i = sqlite3_column_int(stmt_, 2);
2129 return sqlite3_column_int(stmt_, 2);
2138 return (sqlite3_column_int(stmt_, 2) != 0);
2147 return (
const char *)sqlite3_column_text(stmt_, 2);
2156 std::vector<unsigned int>
2174 std::vector<std::string>
2186 return (
const char *)sqlite3_column_text(stmt_, 2);
2195 const char *c = (
const char *)sqlite3_column_text(stmt_, 3);
2208 const char *c = (
const char *)sqlite3_column_text(stmt_, 4);
2222 const char *c = (
const char *)sqlite3_column_text(stmt_, 5);
const char * short_name()
Get short hostname (up to first dot).
void lock()
Lock the config.
virtual ValueIterator * iterator()=0
Iterator for all values.
virtual void erase(const char *path)
Erase the given value from the configuration.
virtual std::string get_string(const char *path)
Get value from configuration which is of type string.
virtual bool is_default(const char *path)
Check if a value was read from the default config.
ValueIterator * iterator()
Iterator for all values.
virtual bool is_list(const char *path)
Check if a value is a list.
virtual int get_int(const char *path)
Get value from configuration which is of type int.
virtual int get_int() const
Get int value.
virtual bool is_bool() const
Check if current value is a bool.
virtual unsigned int get_uint() const
Get unsigned int value.
SQLite configuration value iterator.
static std::string sql_escape_noop(const char *line)
SQL escaping stub.
SQLiteConfiguration()
Constructor.
virtual bool get_bool(const char *path)
Get value from configuration which is of type bool.
virtual std::vector< std::string > get_strings() const
Get list of values from configuration which is of type string.
virtual std::vector< float > get_floats(const char *path)
Get list of values from configuration which is of type float.
virtual bool is_bool() const =0
Check if current value is a bool.
Fawkes library namespace.
void unlock()
Unlock the mutex.
Called method has not been implemented.
virtual std::vector< int > get_ints() const
Get list of values from configuration which is of type int.
virtual void set_bools(const char *path, std::vector< bool > &b)
Set new value in configuration of type bool.
Thrown if config could not be opened.
virtual std::string get_default_comment(const char *path)
Get comment of value at given path.
ValueIterator * search(const char *path)
Iterator with search results.
virtual unsigned int get_uint(const char *path)
Get value from configuration which is of type unsigned int.
Thrown if a config entry could not be found.
virtual void set_default_bool(const char *path, bool b)
Set new default value in configuration of type bool.
virtual bool next()=0
Check if there is another element and advance to this if possible.
virtual std::vector< float > get_floats() const
Get list of values from configuration which is of type float.
virtual float get_float() const =0
Get float value.
virtual unsigned int get_uint() const =0
Get unsigned int value.
virtual std::string get_as_string() const
Get value as string.
bool try_lock()
Try to lock the config.
virtual bool is_float() const =0
Check if current value is a float.
virtual size_t get_list_size() const
Get number of elements in list value.
virtual std::string get_comment(const char *path)
Get comment of value at given path.
virtual bool is_string() const
Check if current value is a string.
virtual bool is_int() const =0
Check if current value is a int.
void transaction_begin(transaction_type_t ttype=TRANSACTION_DEFERRED)
Begin SQL Transaction.
virtual void set_default_float(const char *path, float f)
Set new default value in configuration of type float.
virtual void copy(Configuration *copyconf)
Copy all values from the given configuration.
virtual bool get_bool() const =0
Get bool value.
virtual void set_strings(const char *path, std::vector< std::string > &s)
Set new value in configuration of type string.
void try_dump()
Try to dump default configuration.
virtual void load(const char *filename)
Load configuration.
virtual std::string get_string() const
Get string value.
virtual int get_int() const =0
Get int value.
virtual void set_default_string(const char *path, std::string &s)
Set new default value in configuration of type string.
virtual bool is_int(const char *path)
Check if a value is of type int.
virtual ~SQLiteConfiguration()
Destructor.
virtual std::vector< unsigned int > get_uints(const char *path)
Get list of values from configuration which is of type unsigned int.
virtual std::vector< bool > get_bools(const char *path)
Get list of values from configuration which is of type bool.
virtual bool is_string() const =0
Check if current value is a string.
virtual float get_float(const char *path)
Get value from configuration which is of type float.
virtual std::string get_type(const char *path)
Get type of value at given path.
virtual bool is_uint(const char *path)
Check if a value is of type unsigned int.
virtual bool is_uint() const
Check if current value is a unsigned int.
Base class for exceptions in Fawkes.
virtual void set_float(const char *path, float f)
Set new value in configuration of type float.
virtual bool is_string(const char *path)
Check if a value is of type string.
Immediately acquire lock, no more reading or writing possible.
std::string get_oldvalue() const
Get old value (as string).
virtual bool next()
Check if there is another element and advance to this if possible.
virtual void set_default_comment(const char *path, const char *comment)
Set new default comment for existing default configuration value.
Thrown if there a type problem was detected for example if you tried to query a float with get_int().
virtual void set_int(const char *path, int i)
Set new value in configuration of type int.
virtual bool is_uint() const =0
Check if current value is a unsigned int.
virtual bool is_list() const
Check if a value is a list.
virtual std::vector< int > get_ints(const char *path)
Get list of values from configuration which is of type int.
virtual void set_bool(const char *path, bool b)
Set new value in configuration of type bool.
virtual std::string get_string() const =0
Get string value.
void transaction_rollback()
Rollback SQL Transaction.
virtual ~SQLiteValueIterator()
Destructor.
virtual bool is_int() const
Check if current value is a int.
virtual bool exists(const char *path)
Check if a given value exists.
Generic configuration exception.
virtual const char * path() const =0
Path of value.
bool try_lock()
Tries to lock the mutex.
virtual const char * type() const
Type of value.
virtual std::vector< bool > get_bools() const
Get list of values from configuration which is of type bool.
virtual void unlock()=0
Unlock the config.
virtual bool is_bool(const char *path)
Check if a value is of type bool.
virtual bool is_float(const char *path)
Check if a value is of type float.
virtual ValueIterator * get_value(const char *path)
Get value from configuration.
ValueIterator * iterator_default()
Iterator for all default values.
virtual std::vector< unsigned int > get_uints() const
Get list of values from configuration which is of type unsigned int.
void notify_handlers(const char *path, bool comment_changed=false)
Notify handlers for given path.
virtual bool valid() const
Check if the current element is valid.
std::string get_modtype() const
Get modification type.
virtual bool is_default() const
Check if current value was read from the default config.
ValueIterator * iterator_hostspecific()
Iterator for all host-specific values.
virtual void set_floats(const char *path, std::vector< float > &f)
Set new value in configuration of type float.
Iterator interface to iterate over config values.
void unlock()
Unlock the config.
virtual void set_uint(const char *path, unsigned int uint)
Set new value in configuration of type unsigned int.
virtual void set_default_uint(const char *path, unsigned int uint)
Set new default value in configuration of type unsigned int.
virtual void set_string(const char *path, std::string &s)
Set new value in configuration of type string.
static void dump_table(FILE *f, ::sqlite3 *tdb, const char *table_name)
Dump table.
virtual void set_ints(const char *path, std::vector< int > &i)
Set new value in configuration of type int.
void lock()
Lock this mutex.
virtual void erase_default(const char *path)
Erase the given default value from the configuration.
void transaction_commit()
Commit SQL Transaction.
virtual std::vector< std::string > get_strings(const char *path)
Get list of values from configuration which is of type string.
virtual void set_uints(const char *path, std::vector< unsigned int > &uint)
Set new value in configuration of type unsigned int.
virtual bool get_bool() const
Get bool value.
Mutex mutual exclusion lock.
virtual bool is_float() const
Check if current value is a float.
virtual const char * path() const
Path of value.
virtual float get_float() const
Get float value.
Interface for configuration handling.
virtual void set_comment(const char *path, std::string &comment)
Set new comment for existing value.
virtual std::string get_comment() const
Get comment.
SQLiteValueIterator(::sqlite3_stmt *stmt, void *p=NULL)
Constructor.
void append(const char *format,...)
Append messages to the message list.
Immediately acquire lock, reading remains possible.
virtual void lock()=0
Lock the config.
transaction_type_t
Transaction type.
SQLiteValueIterator * modified_iterator()
Iterator for modified values.
virtual void set_default_int(const char *path, int i)
Set new default value in configuration of type int.