24 #include <config/sqlite.h>
25 #include <core/threading/mutex.h>
26 #include <core/exceptions/system.h>
44 #define TABLE_HOST_CONFIG "config"
45 #define TABLE_DEFAULT_CONFIG "defaults.config"
46 #define TABLE_HOST_TAGGED "tagged_config"
48 #define SQL_CREATE_TABLE_HOST_CONFIG \
49 "CREATE TABLE IF NOT EXISTS config (\n" \
50 " path TEXT NOT NULL,\n" \
51 " type TEXT NOT NULL,\n" \
52 " value NOT NULL,\n" \
54 " PRIMARY KEY (path)\n" \
57 #define SQL_CREATE_TABLE_DEFAULT_CONFIG \
58 "CREATE TABLE IF NOT EXISTS defaults.config (\n" \
59 " path TEXT NOT NULL,\n" \
60 " type TEXT NOT NULL,\n" \
61 " value NOT NULL,\n" \
63 " PRIMARY KEY (path)\n" \
66 #define SQL_CREATE_TABLE_TAGGED_CONFIG \
67 "CREATE TABLE IF NOT EXISTS tagged_config (\n" \
68 " tag TEXT NOT NULL,\n" \
69 " path TEXT NOT NULL,\n" \
70 " type TEXT NOT NULL,\n" \
71 " value NOT NULL,\n" \
73 " PRIMARY KEY (tag, path)\n" \
76 #define SQL_CREATE_TABLE_MODIFIED_CONFIG \
77 "CREATE TABLE IF NOT EXISTS modified.config (\n" \
78 " path TEXT NOT NULL,\n" \
79 " type TEXT NOT NULL,\n" \
80 " value NOT NULL,\n" \
82 " modtype TEXT NOT NULL,\n" \
83 " oldvalue NOT NULL,\n" \
84 " PRIMARY KEY (path)\n" \
87 #define SQL_ATTACH_DEFAULTS \
88 "ATTACH DATABASE '%s' AS defaults"
90 #define SQL_ATTACH_MODIFIED \
91 "ATTACH DATABASE ':memory:' AS modified"
93 #define SQL_ATTACH_DUMPED \
94 "ATTACH DATABASE '%s' AS dumped"
96 #define SQL_DETACH_DUMPED \
97 "DETACH DATABASE dumped"
99 #define SQL_SELECT_VALUE_TYPE \
100 "SELECT type, value, 0 AS is_default FROM config WHERE path=? UNION " \
101 "SELECT type, value, 1 AS is_default FROM defaults.config AS dc " \
102 "WHERE path=? AND NOT EXISTS " \
103 "(SELECT path FROM config WHERE dc.path=path)"
105 #define SQL_SELECT_COMPLETE \
106 "SELECT *, 0 AS is_default FROM config WHERE path LIKE ? UNION " \
107 "SELECT *, 1 AS is_default FROM defaults.config AS dc " \
108 "WHERE path LIKE ? AND NOT EXISTS " \
109 "(SELECT path FROM config WHERE dc.path = path) " \
112 #define SQL_SELECT_TYPE \
113 "SELECT type, 0 AS is_default FROM config WHERE path=? UNION " \
114 "SELECT type, 1 AS is_default FROM defaults.config AS dc " \
115 "WHERE path=? AND NOT EXISTS " \
116 "(SELECT path FROM config WHERE dc.path = path)"
118 #define SQL_SELECT_COMMENT \
119 "SELECT comment, 0 AS is_default FROM config WHERE path=?"
121 #define SQL_SELECT_DEFAULT_COMMENT \
122 "SELECT comment, 1 AS is_default FROM defaults.config AS dc " \
125 #define SQL_UPDATE_VALUE \
126 "UPDATE config SET value=? WHERE path=?"
128 #define SQL_UPDATE_DEFAULT_VALUE \
129 "UPDATE defaults.config SET value=? WHERE path=?"
131 #define SQL_UPDATE_COMMENT \
132 "UPDATE config SET comment=? WHERE path=?"
134 #define SQL_UPDATE_DEFAULT_COMMENT \
135 "UPDATE defaults.config SET comment=? WHERE path=?"
137 #define SQL_INSERT_VALUE \
138 "INSERT INTO config (path, type, value) VALUES (?, ?, ?)"
140 #define SQL_INSERT_DEFAULT_VALUE \
141 "INSERT INTO defaults.config (path, type, value) VALUES (?, ?, ?)"
143 #define SQL_SELECT_TAGS \
144 "SELECT tag FROM tagged_config GROUP BY tag"
146 #define SQL_INSERT_TAG \
147 "INSERT INTO tagged_config " \
148 "(tag, path, type, value, comment) " \
149 "SELECT \"%s\",* FROM config"
151 #define SQL_SELECT_ALL \
152 "SELECT *, 0 AS is_default FROM config UNION " \
153 "SELECT *, 1 AS is_default FROM defaults.config AS dc " \
154 "WHERE NOT EXISTS " \
155 "(SELECT path FROM config WHERE dc.path = path) " \
158 #define SQL_SELECT_ALL_DEFAULT \
159 "SELECT *, 1 AS is_default FROM defaults.config"
161 #define SQL_SELECT_ALL_HOSTSPECIFIC \
162 "SELECT *, 0 AS is_default FROM config"
164 #define SQL_DELETE_VALUE \
165 "DELETE FROM config WHERE path=?"
167 #define SQL_DELETE_DEFAULT_VALUE \
168 "DELETE FROM defaults.config WHERE path=?"
170 #define SQL_UPDATE_DEFAULT_DB \
171 "INSERT INTO config SELECT * FROM defaults.config AS dc " \
172 "WHERE NOT EXISTS (SELECT path from config WHERE path = dc.path)"
174 #define SQL_UPDATE_MODIFIED_DB_ADDED \
175 "INSERT INTO modified.config " \
176 " SELECT duc.*,'added' AS modtype, duc.value " \
177 " FROM dumped.config AS duc " \
178 " WHERE NOT EXISTS (SELECT dc.path FROM defaults.config AS dc " \
179 " WHERE dc.path=duc.path) " \
182 #define SQL_UPDATE_MODIFIED_DB_ERASED \
183 "INSERT INTO modified.config " \
184 " SELECT dc.*,'erased' AS modtype, dc.value " \
185 " FROM defaults.config AS dc " \
186 " WHERE NOT EXISTS (SELECT duc.path FROM dumped.config AS duc " \
187 " WHERE duc.path=dc.path) " \
190 #define SQL_UPDATE_MODIFIED_DB_CHANGED \
191 "INSERT INTO modified.config " \
192 " SELECT duc.*,'changed' AS modtype, dc.value " \
193 " FROM dumped.config AS duc, defaults.config AS dc " \
194 " WHERE duc.path = dc.path " \
195 " AND (dc.type != duc.type OR dc.value != duc.value) " \
198 #define SQL_COPY_DUMP \
199 "DELETE FROM defaults.config; " \
200 "INSERT INTO defaults.config SELECT * FROM dumped.config"
202 #define SQL_SELECT_MODIFIED_ALL \
203 "SELECT * FROM modified.config"
227 __userconfdir = NULL;
228 __default_file = NULL;
229 __default_sql = NULL;
243 const char *userconfdir)
248 __sysconfdir = strdup(sysconfdir);
249 __default_file = NULL;
250 __default_sql = NULL;
252 if (userconfdir != NULL) {
253 __userconfdir = strdup(userconfdir);
255 const char *homedir = getenv(
"HOME");
256 if (homedir == NULL) {
257 __userconfdir = strdup(sysconfdir);
259 if (asprintf(&__userconfdir,
"%s/%s", homedir, USERDIR) == -1) {
260 __userconfdir = strdup(sysconfdir);
271 if ( sqlite3_close(db) == SQLITE_BUSY ) {
272 printf(
"Boom, we are dead, database cannot be closed "
273 "because there are open handles\n");
277 if (__host_file) free(__host_file);
278 if (__default_file) free(__default_file);
279 if (__default_sql) free(__default_sql);
280 if (__sysconfdir) free(__sysconfdir);
281 if (__userconfdir) free(__userconfdir);
336 SQLiteConfiguration::init_dbs()
339 if ( (sqlite3_exec(db, SQL_CREATE_TABLE_HOST_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK) ||
340 (sqlite3_exec(db, SQL_CREATE_TABLE_DEFAULT_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK) ||
341 (sqlite3_exec(db, SQL_CREATE_TABLE_TAGGED_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK) ) {
358 std::string tisql =
"PRAGMA table_info(\"";
363 if ( sqlite3_prepare(tdb, tisql.c_str(), -1, &stmt, 0) != SQLITE_OK ) {
366 std::string value_query =
"SELECT 'INSERT INTO ' || '\"";
367 value_query += table_name;
368 value_query +=
"\"' || ' VALUES(' || ";
369 int rv = sqlite3_step(stmt);
370 while ( rv == SQLITE_ROW ) {
371 value_query +=
"quote(\"";
372 value_query += (
const char *)sqlite3_column_text(stmt, 1);
373 value_query +=
"\") || ";
374 rv = sqlite3_step(stmt);
375 if ( rv == SQLITE_ROW ) {
376 value_query +=
" ',' || ";
379 value_query +=
"')' FROM ";
380 value_query += table_name;
381 sqlite3_finalize(stmt);
384 if ( sqlite3_prepare(tdb, value_query.c_str(), -1, &vstmt, 0) != SQLITE_OK ) {
387 while ( sqlite3_step(vstmt) == SQLITE_ROW ) {
388 fprintf(f,
"%s;\n", sqlite3_column_text(vstmt, 0));
390 sqlite3_finalize(vstmt);
394 SQLiteConfiguration::dump(::sqlite3 *tdb,
const char *dumpfile)
396 FILE *f = fopen(dumpfile,
"w");
398 throw CouldNotOpenFileException(dumpfile, errno,
"Could not open dump file");
401 fprintf(f,
"BEGIN TRANSACTION;\n");
403 const char *sql =
"SELECT name, sql FROM sqlite_master "
404 "WHERE sql NOT NULL AND type=='table'";
406 if ( (sqlite3_prepare(tdb, sql, -1, &stmt, 0) != SQLITE_OK) || ! stmt ) {
407 throw ConfigurationException(
"dump_query/prepare", sqlite3_errmsg(tdb));
409 while ( sqlite3_step(stmt) == SQLITE_ROW ) {
410 fprintf(f,
"%s;\n", sqlite3_column_text(stmt, 1));
411 dump_table(f, tdb, (
const char *)sqlite3_column_text(stmt, 0));
413 sqlite3_finalize(stmt);
415 fprintf(f,
"COMMIT;\n");
428 if ( __default_sql ) {
430 if ( sqlite3_open(__default_file, &tdb) == SQLITE_OK ) {
432 dump(tdb, __default_sql);
443 SQLiteConfiguration::import(::sqlite3 *tdb,
const char *dumpfile)
445 FILE *f = fopen(dumpfile,
"r");
456 while (! feof(f) && (i <
sizeof(line) - 1)) {
457 if (fread(&(line[i]), 1, 1, f) == 1) {
459 if ( (i > 2) && (line[i-1] ==
'\n') && (line[i-2] ==
';') ) {
467 if ( line[0] != 0 ) {
468 if ( sqlite3_exec(tdb, line, 0, 0, &errmsg) != SQLITE_OK ) {
469 ConfigurationException e(errmsg, line);
470 sqlite3_free(errmsg);
481 SQLiteConfiguration::import_default(
const char *default_sql)
483 char *tmpfile = strdup(TMPDIR
"/tmp_default_XXXXXX");
484 tmpfile = mktemp(tmpfile);
485 if ( tmpfile[0] == 0 ) {
486 throw CouldNotOpenConfigException(
"Failed to create temp file for default DB import");
491 if ( sqlite3_open(tmpfile, &dump_db) == SQLITE_OK ) {
492 import(dump_db, default_sql);
493 sqlite3_close(dump_db);
495 throw CouldNotOpenConfigException(
"Failed to import dump file into temp DB");
501 if ( asprintf(&attach_sql, SQL_ATTACH_DUMPED, tmpfile) == -1 ) {
502 throw CouldNotOpenConfigException(
"Could not create attachment SQL in merge");
504 if ( sqlite3_exec(db, attach_sql, NULL, NULL, &errmsg) != SQLITE_OK ) {
506 CouldNotOpenConfigException e(
"Could not attach dump DB in merge: %s", errmsg);
507 sqlite3_free(errmsg);
513 if ( (sqlite3_exec(db, SQL_ATTACH_MODIFIED, NULL, NULL, &errmsg) != SQLITE_OK) ||
514 (sqlite3_exec(db, SQL_CREATE_TABLE_MODIFIED_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK) ) {
515 CouldNotOpenConfigException ce(
"Could not create or attach modified memory database: %s", errmsg);
516 sqlite3_free(errmsg);
521 if ( (sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_ADDED, NULL, NULL, &errmsg) != SQLITE_OK) ||
522 (sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_ERASED, NULL, NULL, &errmsg) != SQLITE_OK) ||
523 (sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_CHANGED, NULL, NULL, &errmsg) != SQLITE_OK) ) {
524 CouldNotOpenConfigException ce(
"Could not update modified memory database: %s", errmsg);
525 sqlite3_free(errmsg);
530 if ( (sqlite3_exec(db, SQL_COPY_DUMP, NULL, NULL, &errmsg) != SQLITE_OK) ) {
531 CouldNotOpenConfigException ce(
"Could not copy dump to default: %s", errmsg);
532 sqlite3_free(errmsg);
537 if ( sqlite3_exec(db, SQL_DETACH_DUMPED, NULL, NULL, &errmsg) != SQLITE_OK ) {
538 CouldNotOpenConfigException e(
"Could not detach dump DB in import: %s", errmsg);
539 sqlite3_free(errmsg);
554 const char *sql =
"BEGIN DEFERRED TRANSACTION;";
556 sql =
"BEGIN IMMEDIATE TRANSACTION;";
558 sql =
"BEGIN EXCLUSIVE TRANSACTION;";
562 if ( (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) ) {
571 const char *sql =
"COMMIT TRANSACTION;";
574 if ( (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) ) {
584 const char *sql =
"ROLLBACK TRANSACTION;";
587 if ( (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) ) {
593 SQLiteConfiguration::attach_default(
const char *db_file)
597 if ( asprintf(&attach_sql, SQL_ATTACH_DEFAULTS, db_file) == -1 ) {
600 if (sqlite3_exec(db, attach_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
601 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
602 ce.append(
"Failed to attach default file (%s)", db_file);
616 if (__default_file) free(__default_file);
617 if (__default_sql) free(__default_sql);
618 __default_file = NULL;
619 __default_sql = NULL;
621 const char *try_paths[] = {__sysconfdir, __userconfdir};
622 int try_paths_len = 2;
628 if ( asprintf(&host_name,
"%s.db", hostinfo.
short_name()) == -1 ) {
632 host_name = strdup(name);
636 if (strcmp(host_name,
":memory:") == 0) {
637 if (sqlite3_open(host_name, &db) != SQLITE_OK) {
639 ce.
append(
"Failed to open host db (memory)");
642 }
else if (host_name[0] ==
'/') {
644 if (sqlite3_open(host_name, &db) == SQLITE_OK) {
645 __host_file = strdup(host_name);
648 ce.
append(
"Failed to open host db (absolute)");
653 for (
int i = 0; i < try_paths_len; ++i) {
655 if (asprintf(&path,
"%s/%s", try_paths[i], host_name) != -1) {
656 if (sqlite3_open(path, &db) == SQLITE_OK) {
664 if (__host_file == NULL) {
666 ce.
append(
"Failed to open host db (paths)");
672 if (defaults_name == NULL) {
673 defaults_name =
"default.sql";
677 if (strcmp(defaults_name,
":memory:") == 0) {
679 attach_default(
":memory:");
684 __default_file = strdup(
":memory:");
686 if (defaults_name[0] ==
'/') {
688 __default_sql = strdup(defaults_name);
691 for (
int i = 0; i < try_paths_len; ++i) {
693 if (asprintf(&path,
"%s/%s", try_paths[i], defaults_name) != -1) {
694 if (access(path, F_OK | R_OK) == 0) {
695 __default_sql = path;
708 size_t len = strlen(defaults_name);
709 if (fnmatch(
"*.sql", defaults_name, FNM_PATHNAME) == 0) {
710 defaults_db = (
char *)calloc(1, len);
711 strncpy(defaults_db, defaults_name, len - 3);
712 strcat(defaults_db,
"db");
714 defaults_db = (
char *)calloc(1, len + 4);
715 strcpy(defaults_db, defaults_name);
716 strcat(defaults_db,
".db");
719 if (defaults_db[0] ==
'/') {
721 attach_default(defaults_db);
722 __default_file = defaults_db;
730 for (
int i = 0; i < try_paths_len; ++i) {
732 if (asprintf(&path,
"%s/%s", try_paths[i], defaults_db) != -1) {
734 attach_default(path);
735 __default_file = path;
745 if (__default_file == NULL) {
753 if ( __default_sql ) import_default(__default_sql);
770 load(NULL, NULL, tag);
787 while ( i->
next() ) {
790 }
else if ( i->
is_int() ) {
820 if ( asprintf(&insert_sql, SQL_INSERT_TAG, tag) == -1 ) {
825 if (sqlite3_exec(db, insert_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
837 std::list<std::string>
841 std::list<std::string> l;
844 if ( sqlite3_prepare(db, SQL_SELECT_TAGS, -1, &stmt, &tail) != SQLITE_OK ) {
848 while ( sqlite3_step(stmt) == SQLITE_ROW ) {
849 l.push_back((
char *)sqlite3_column_text(stmt, 0));
851 sqlite3_finalize(stmt);
865 if ( sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK ) {
869 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
873 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
877 e = ( sqlite3_step(stmt) == SQLITE_ROW );
878 sqlite3_finalize(stmt);
894 if ( sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK ) {
898 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
902 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
906 if ( sqlite3_step(stmt) == SQLITE_ROW ) {
907 s = (
char *)sqlite3_column_text(stmt, 0);
908 sqlite3_finalize(stmt);
912 sqlite3_finalize(stmt);
928 if ( sqlite3_prepare(db, SQL_SELECT_COMMENT, -1, &stmt, &tail) != SQLITE_OK ) {
932 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
936 if ( sqlite3_step(stmt) == SQLITE_ROW ) {
937 s = (
char *)sqlite3_column_text(stmt, 0);
938 sqlite3_finalize(stmt);
942 sqlite3_finalize(stmt);
958 if ( sqlite3_prepare(db, SQL_SELECT_DEFAULT_COMMENT, -1, &stmt, &tail) != SQLITE_OK ) {
962 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
966 if ( sqlite3_step(stmt) == SQLITE_ROW ) {
967 s = (
char *)sqlite3_column_text(stmt, 0);
968 sqlite3_finalize(stmt);
972 sqlite3_finalize(stmt);
989 return (
get_type(path) ==
"unsigned int");
1010 return (
get_type(path) ==
"string");
1022 if ( sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK ) {
1026 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
1030 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
1034 e = ( (sqlite3_step(stmt) == SQLITE_ROW) && (sqlite3_column_int(stmt, 1) == 1 ));
1035 sqlite3_finalize(stmt);
1054 if ( sqlite3_prepare(db, SQL_SELECT_VALUE_TYPE, -1, &stmt, &tail) != SQLITE_OK ) {
1057 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
1058 throw ConfigurationException(
"get_value/bind/path (1)", sqlite3_errmsg(db));
1060 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
1061 throw ConfigurationException(
"get_value/bind/path (2)", sqlite3_errmsg(db));
1064 if ( sqlite3_step(stmt) == SQLITE_ROW ) {
1065 if ( type == NULL ) {
1069 if (strcmp((
char *)sqlite3_column_text(stmt, 0), type) != 0) {
1070 ConfigTypeMismatchException ce(path, (
char *)sqlite3_column_text(stmt, 0), type);
1071 sqlite3_finalize(stmt);
1078 sqlite3_finalize(stmt);
1079 throw ConfigEntryNotFoundException(path);
1091 float f = (float)sqlite3_column_double(stmt, 1);
1092 sqlite3_finalize(stmt);
1110 int i = sqlite3_column_int(stmt, 1);
1111 sqlite3_finalize(stmt);
1133 int i = sqlite3_column_int(stmt, 1);
1134 sqlite3_finalize(stmt);
1152 int i = sqlite3_column_int(stmt, 1);
1153 sqlite3_finalize(stmt);
1170 const char *c = (
char *)sqlite3_column_text(stmt, 1);
1172 sqlite3_finalize(stmt);
1177 e.
append(
"SQLiteConfiguration::get_string: Fetching %s failed.", path);
1190 if ( sqlite3_prepare(db, SQL_SELECT_COMPLETE, -1, &stmt, &tail) != SQLITE_OK ) {
1193 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
1196 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
1205 SQLiteConfiguration::prepare_update(
const char *sql,
1211 if ( sqlite3_prepare(db, sql, -1, &stmt, &tail) != SQLITE_OK ) {
1214 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
1215 ConfigurationException ce(
"prepare_update/bind", sqlite3_errmsg(db));
1216 sqlite3_finalize(stmt);
1225 SQLiteConfiguration::prepare_insert_value(
const char *sql,
const char *type,
1231 if ( sqlite3_prepare(db, sql, -1, &stmt, &tail) != SQLITE_OK ) {
1232 throw ConfigurationException(
"prepare_insert_value/prepare", sqlite3_errmsg(db));
1234 if ( (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) ||
1235 (sqlite3_bind_text(stmt, 2, type, -1, NULL) != SQLITE_OK) ) {
1236 ConfigurationException ce(
"prepare_insert_value/bind", sqlite3_errmsg(db));
1237 sqlite3_finalize(stmt);
1246 SQLiteConfiguration::execute_insert_or_update(sqlite3_stmt *stmt)
1248 if ( sqlite3_step(stmt) != SQLITE_DONE ) {
1249 ConfigurationException ce(
"execute_insert_or_update", sqlite3_errmsg(db));
1250 sqlite3_finalize(stmt);
1259 sqlite3_stmt *stmt = NULL;
1264 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1265 if ( (sqlite3_bind_double(stmt, 1, f) != SQLITE_OK) ) {
1267 sqlite3_finalize(stmt);
1271 execute_insert_or_update(stmt);
1272 sqlite3_finalize(stmt);
1274 if ( stmt != NULL ) sqlite3_finalize(stmt);
1279 if ( sqlite3_changes(db) == 0 ) {
1283 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"float", path);
1284 if ( (sqlite3_bind_double(stmt, 3, f) != SQLITE_OK) ) {
1286 sqlite3_finalize(stmt);
1290 execute_insert_or_update(stmt);
1291 sqlite3_finalize(stmt);
1293 if ( stmt != NULL ) sqlite3_finalize(stmt);
1308 sqlite3_stmt *stmt = NULL;
1313 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1314 if ( (sqlite3_bind_int(stmt, 1, uint) != SQLITE_OK) ) {
1316 sqlite3_finalize(stmt);
1320 execute_insert_or_update(stmt);
1321 sqlite3_finalize(stmt);
1323 if ( stmt != NULL ) sqlite3_finalize(stmt);
1328 if ( sqlite3_changes(db) == 0 ) {
1332 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"unsigned int", path);
1333 if ( (sqlite3_bind_int(stmt, 3, uint) != SQLITE_OK) ) {
1335 sqlite3_finalize(stmt);
1339 execute_insert_or_update(stmt);
1340 sqlite3_finalize(stmt);
1342 if ( stmt != NULL ) sqlite3_finalize(stmt);
1356 sqlite3_stmt *stmt = NULL;
1361 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1362 if ( (sqlite3_bind_int(stmt, 1, i) != SQLITE_OK) ) {
1364 sqlite3_finalize(stmt);
1368 execute_insert_or_update(stmt);
1369 sqlite3_finalize(stmt);
1371 if ( stmt != NULL ) sqlite3_finalize(stmt);
1376 if ( sqlite3_changes(db) == 0 ) {
1380 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"int", path);
1381 if ( (sqlite3_bind_int(stmt, 3, i) != SQLITE_OK) ) {
1383 sqlite3_finalize(stmt);
1387 execute_insert_or_update(stmt);
1388 sqlite3_finalize(stmt);
1390 if ( stmt != NULL ) sqlite3_finalize(stmt);
1405 sqlite3_stmt *stmt = NULL;
1410 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1411 if ( (sqlite3_bind_int(stmt, 1, (b ? 1 : 0)) != SQLITE_OK) ) {
1413 sqlite3_finalize(stmt);
1417 execute_insert_or_update(stmt);
1418 sqlite3_finalize(stmt);
1420 if ( stmt != NULL ) sqlite3_finalize(stmt);
1425 if ( sqlite3_changes(db) == 0 ) {
1429 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"bool", path);
1430 if ( (sqlite3_bind_int(stmt, 3, (b ? 1 : 0)) != SQLITE_OK) ) {
1432 sqlite3_finalize(stmt);
1436 execute_insert_or_update(stmt);
1437 sqlite3_finalize(stmt);
1439 if ( stmt != NULL ) sqlite3_finalize(stmt);
1455 sqlite3_stmt *stmt = NULL;
1459 size_t s_length = strlen(s);
1462 stmt = prepare_update(SQL_UPDATE_VALUE, path);
1463 if ( (sqlite3_bind_text(stmt, 1, s, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
1465 sqlite3_finalize(stmt);
1469 execute_insert_or_update(stmt);
1470 sqlite3_finalize(stmt);
1472 if ( stmt != NULL ) sqlite3_finalize(stmt);
1477 if ( sqlite3_changes(db) == 0 ) {
1481 stmt = prepare_insert_value(SQL_INSERT_VALUE,
"string", path);
1482 if ( (sqlite3_bind_text(stmt, 3, s, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
1484 sqlite3_finalize(stmt);
1488 execute_insert_or_update(stmt);
1489 sqlite3_finalize(stmt);
1491 if ( stmt != NULL ) sqlite3_finalize(stmt);
1513 sqlite3_stmt *stmt = NULL;
1517 size_t s_length = strlen(comment);
1520 stmt = prepare_update(SQL_UPDATE_COMMENT, path);
1521 if ( (sqlite3_bind_text(stmt, 1, comment, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
1523 sqlite3_finalize(stmt);
1527 execute_insert_or_update(stmt);
1528 sqlite3_finalize(stmt);
1530 if ( stmt != NULL ) sqlite3_finalize(stmt);
1535 if ( sqlite3_changes(db) == 0 ) {
1560 if ( sqlite3_prepare(db, SQL_DELETE_VALUE, -1, &stmt, &tail) != SQLITE_OK ) {
1563 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
1565 sqlite3_finalize(stmt);
1569 if ( sqlite3_step(stmt) != SQLITE_DONE ) {
1571 sqlite3_finalize(stmt);
1575 sqlite3_finalize(stmt);
1584 sqlite3_stmt *stmt = NULL;
1589 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1590 if ( (sqlite3_bind_double(stmt, 1, f) != SQLITE_OK) ) {
1592 sqlite3_finalize(stmt);
1596 execute_insert_or_update(stmt);
1597 sqlite3_finalize(stmt);
1599 if ( stmt != NULL ) sqlite3_finalize(stmt);
1604 if ( sqlite3_changes(db) == 0 ) {
1608 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"float", path);
1609 if ( (sqlite3_bind_double(stmt, 3, f) != SQLITE_OK) ) {
1611 sqlite3_finalize(stmt);
1615 execute_insert_or_update(stmt);
1616 sqlite3_finalize(stmt);
1618 if ( stmt != NULL ) sqlite3_finalize(stmt);
1633 sqlite3_stmt *stmt = NULL;
1638 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1639 if ( (sqlite3_bind_int(stmt, 1, uint) != SQLITE_OK) ) {
1641 sqlite3_finalize(stmt);
1645 execute_insert_or_update(stmt);
1646 sqlite3_finalize(stmt);
1648 if ( stmt != NULL ) sqlite3_finalize(stmt);
1653 if ( sqlite3_changes(db) == 0 ) {
1657 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"unsigned int", path);
1658 if ( (sqlite3_bind_int(stmt, 3, uint) != SQLITE_OK) ) {
1660 sqlite3_finalize(stmt);
1664 execute_insert_or_update(stmt);
1665 sqlite3_finalize(stmt);
1667 if ( stmt != NULL ) sqlite3_finalize(stmt);
1681 sqlite3_stmt *stmt = NULL;
1685 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1686 if ( (sqlite3_bind_int(stmt, 1, i) != SQLITE_OK) ) {
1688 sqlite3_finalize(stmt);
1692 execute_insert_or_update(stmt);
1693 sqlite3_finalize(stmt);
1695 if ( stmt != NULL ) sqlite3_finalize(stmt);
1700 if ( sqlite3_changes(db) == 0 ) {
1703 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"int", path);
1704 if ( (sqlite3_bind_int(stmt, 3, i) != SQLITE_OK) ) {
1706 sqlite3_finalize(stmt);
1710 execute_insert_or_update(stmt);
1711 sqlite3_finalize(stmt);
1713 if ( stmt != NULL ) sqlite3_finalize(stmt);
1728 sqlite3_stmt *stmt = NULL;
1733 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1734 if ( (sqlite3_bind_int(stmt, 1, (b ? 1 : 0)) != SQLITE_OK) ) {
1736 sqlite3_finalize(stmt);
1740 execute_insert_or_update(stmt);
1741 sqlite3_finalize(stmt);
1743 if ( stmt != NULL ) sqlite3_finalize(stmt);
1748 if ( sqlite3_changes(db) == 0 ) {
1752 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"bool", path);
1753 if ( (sqlite3_bind_int(stmt, 3, (b ? 1 : 0)) != SQLITE_OK) ) {
1755 sqlite3_finalize(stmt);
1759 execute_insert_or_update(stmt);
1760 sqlite3_finalize(stmt);
1762 if ( stmt != NULL ) sqlite3_finalize(stmt);
1778 sqlite3_stmt *stmt = NULL;
1781 size_t s_length = strlen(s);
1784 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
1785 if ( (sqlite3_bind_text(stmt, 1, s, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
1787 sqlite3_finalize(stmt);
1791 execute_insert_or_update(stmt);
1792 sqlite3_finalize(stmt);
1794 if ( stmt != NULL ) sqlite3_finalize(stmt);
1799 if ( sqlite3_changes(db) == 0 ) {
1803 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE,
"string", path);
1804 if ( (sqlite3_bind_text(stmt, 3, s, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
1806 sqlite3_finalize(stmt);
1810 execute_insert_or_update(stmt);
1811 sqlite3_finalize(stmt);
1813 if ( stmt != NULL ) sqlite3_finalize(stmt);
1835 sqlite3_stmt *stmt = NULL;
1838 size_t s_length = strlen(comment);
1841 stmt = prepare_update(SQL_UPDATE_DEFAULT_COMMENT, path);
1842 if ( (sqlite3_bind_text(stmt, 1, comment, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
1844 sqlite3_finalize(stmt);
1848 execute_insert_or_update(stmt);
1849 sqlite3_finalize(stmt);
1851 if ( stmt != NULL ) sqlite3_finalize(stmt);
1856 if ( sqlite3_changes(db) == 0 ) {
1881 if ( sqlite3_prepare(db, SQL_DELETE_DEFAULT_VALUE, -1, &stmt, &tail) != SQLITE_OK ) {
1884 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
1886 sqlite3_finalize(stmt);
1890 if ( sqlite3_step(stmt) != SQLITE_DONE ) {
1892 sqlite3_finalize(stmt);
1896 sqlite3_finalize(stmt);
1939 if ( sqlite3_prepare(db, SQL_SELECT_ALL, -1, &stmt, &tail) != SQLITE_OK ) {
1953 if ( sqlite3_prepare(db, SQL_SELECT_ALL_DEFAULT, -1, &stmt, &tail) != SQLITE_OK ) {
1966 if ( sqlite3_prepare(db, SQL_SELECT_ALL_HOSTSPECIFIC, -1, &stmt, &tail) != SQLITE_OK ) {
1984 if ( sqlite3_prepare(db, SQL_SELECT_MODIFIED_ALL, -1, &stmt, &tail) != SQLITE_OK ) {
2010 if ( asprintf(&p,
"%s%%", path) == -1 ) {
2014 if ( sqlite3_prepare(db, SQL_SELECT_COMPLETE, -1, &stmt, &tail) != SQLITE_OK ) {
2018 if ( sqlite3_bind_text(stmt, 1, p, -1, NULL) != SQLITE_OK ) {
2022 if ( sqlite3_bind_text(stmt, 2, p, -1, NULL) != SQLITE_OK ) {
2050 if ( __stmt != NULL ) {
2051 sqlite3_finalize(__stmt);
2054 if ( __p != NULL ) {
2067 if ( __stmt == NULL)
return false;
2069 if (sqlite3_step(__stmt) == SQLITE_ROW ) {
2072 sqlite3_finalize(__stmt);
2086 return ( __stmt != NULL);
2096 return (
const char *)sqlite3_column_text(__stmt, 0);
2106 return (
const char *)sqlite3_column_text(__stmt, 1);
2116 return (strcmp(
"float", (
const char *)sqlite3_column_text(__stmt, 1)) == 0);
2126 return (strcmp(
"unsigned int", (
const char *)sqlite3_column_text(__stmt, 1)) == 0);
2135 return (strcmp(
"int", (
const char *)sqlite3_column_text(__stmt, 1)) == 0);
2145 return (strcmp(
"bool", (
const char *)sqlite3_column_text(__stmt, 1)) == 0);
2155 return (strcmp(
"string", (
const char *)sqlite3_column_text(__stmt, 1)) == 0);
2161 return (sqlite3_column_int(__stmt, 4) == 1);
2171 return (
float)sqlite3_column_double(__stmt, 2);
2181 int i = sqlite3_column_int(__stmt, 2);
2196 return sqlite3_column_int(__stmt, 2);
2205 return (sqlite3_column_int(__stmt, 2) != 0);
2214 return (
const char *)sqlite3_column_text(__stmt, 2);
2224 return (
const char *)sqlite3_column_text(__stmt, 2);
2233 const char *c = (
const char *)sqlite3_column_text(__stmt, 3);
2246 const char *c = (
const char *)sqlite3_column_text(__stmt, 4);
2262 const char *c = (
const char *)sqlite3_column_text(__stmt, 5);
virtual bool is_float() const =0
Check if current value is a float.
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 int get_int(const char *path)
Get value from configuration which is of type int.
SQLite configuration value iterator.
virtual bool is_bool() const
Check if current value is a bool.
SQLiteConfiguration()
Constructor.
virtual bool get_bool(const char *path)
Get value from configuration which is of type bool.
virtual bool is_bool() const =0
Check if current value is a bool.
Fawkes library namespace.
void unlock()
Unlock the mutex.
Thrown if config could not be opened.
virtual std::string get_string() const =0
Get string value.
virtual int get_int() const
Get int value.
virtual std::string get_string() const
Get string value.
virtual bool is_string() const =0
Check if current value is a string.
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 bool is_uint() const =0
Check if current value is a unsigned int.
virtual void set_default_bool(const char *path, bool b)
Set new default value in configuration of type bool.
std::string get_modtype() const
Get modification type.
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.
bool try_lock()
Try to lock the config.
virtual const char * path() const =0
Path of value.
virtual bool is_float() const
Check if current value is a float.
virtual std::string get_comment(const char *path)
Get comment of value at given path.
static void dump_table(FILE *f,::sqlite3 *tdb, const char *table_name)
Dump table.
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.
void try_dump()
Try to dump default configuration.
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 void load(const char *filename, const char *defaults_filename, const char *tag=NULL)
Load configuration.
virtual unsigned int get_uint() const =0
Get unsigned int value.
virtual ~SQLiteConfiguration()
Destructor.
virtual float get_float(const char *path)
Get value from configuration which is of type float.
virtual float get_float() const
Get float value.
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 std::string get_as_string() const
Get value as string.
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_int() const
Check if current value is a int.
virtual bool is_string(const char *path)
Check if a value is of type string.
Immediately acquire lock, no more reading or writing possible.
virtual bool next()
Check if there is another element and advance to this if possible.
virtual const char * path() const
Path of value.
virtual bool is_int() const =0
Check if current value is a int.
virtual void tag(const char *tag)
Tag this configuration version.
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
Check if current value is a unsigned int.
virtual void set_bool(const char *path, bool b)
Set new value in configuration of type bool.
virtual std::string get_comment() const
Get comment.
virtual bool get_bool() const =0
Get bool value.
void transaction_rollback()
Rollback SQL Transaction.
virtual ~SQLiteValueIterator()
Destructor.
virtual const char * type() const
Type of value.
virtual bool exists(const char *path)
Check if a given value exists.
Generic configuration exception.
bool try_lock()
Tries to lock the mutex.
virtual bool get_bool() const
Get bool value.
virtual unsigned int get_uint() const
Get unsigned int value.
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.
void notify_handlers(const char *path, bool comment_changed=false)
Notify handlers for given path.
ValueIterator * iterator_hostspecific()
Iterator for all host-specific values.
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.
void lock()
Lock this mutex.
virtual void erase_default(const char *path)
Erase the given default value from the configuration.
virtual std::list< std::string > tags()
List of tags.
void transaction_commit()
Commit SQL Transaction.
Mutex mutual exclusion lock.
std::string get_oldvalue() const
Get old value (as string).
Interface for configuration handling.
virtual void set_comment(const char *path, std::string &comment)
Set new comment for existing value.
virtual bool is_string() const
Check if current value is a string.
virtual bool valid() const
Check if the current element is valid.
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 bool is_default() const
Check if current value was read from the default config.
virtual void lock()=0
Lock the config.
transaction_type_t
Transaction type.
virtual int get_int() const =0
Get int value.
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.