00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config/sqlite.h>
00025 #include <core/threading/mutex.h>
00026 #include <core/exceptions/system.h>
00027
00028 #include <sqlite3.h>
00029
00030 #ifndef _GNU_SOURCE
00031 #define _GNU_SOURCE
00032 #endif
00033 #include <cstdio>
00034 #include <cstdlib>
00035 #include <cstring>
00036 #include <cerrno>
00037 #include <unistd.h>
00038 #include <fnmatch.h>
00039
00040 namespace fawkes {
00041
00042
00043
00044 #define TABLE_HOST_CONFIG "config"
00045 #define TABLE_DEFAULT_CONFIG "defaults.config"
00046 #define TABLE_HOST_TAGGED "tagged_config"
00047
00048 #define SQL_CREATE_TABLE_HOST_CONFIG \
00049 "CREATE TABLE IF NOT EXISTS config (\n" \
00050 " path TEXT NOT NULL,\n" \
00051 " type TEXT NOT NULL,\n" \
00052 " value NOT NULL,\n" \
00053 " comment TEXT,\n" \
00054 " PRIMARY KEY (path)\n" \
00055 ")"
00056
00057 #define SQL_CREATE_TABLE_DEFAULT_CONFIG \
00058 "CREATE TABLE IF NOT EXISTS defaults.config (\n" \
00059 " path TEXT NOT NULL,\n" \
00060 " type TEXT NOT NULL,\n" \
00061 " value NOT NULL,\n" \
00062 " comment TEXT,\n" \
00063 " PRIMARY KEY (path)\n" \
00064 ")"
00065
00066 #define SQL_CREATE_TABLE_TAGGED_CONFIG \
00067 "CREATE TABLE IF NOT EXISTS tagged_config (\n" \
00068 " tag TEXT NOT NULL,\n" \
00069 " path TEXT NOT NULL,\n" \
00070 " type TEXT NOT NULL,\n" \
00071 " value NOT NULL,\n" \
00072 " comment TEXT,\n" \
00073 " PRIMARY KEY (tag, path)\n" \
00074 ")"
00075
00076 #define SQL_CREATE_TABLE_MODIFIED_CONFIG \
00077 "CREATE TABLE IF NOT EXISTS modified.config (\n" \
00078 " path TEXT NOT NULL,\n" \
00079 " type TEXT NOT NULL,\n" \
00080 " value NOT NULL,\n" \
00081 " comment TEXT,\n" \
00082 " modtype TEXT NOT NULL,\n" \
00083 " oldvalue NOT NULL,\n" \
00084 " PRIMARY KEY (path)\n" \
00085 ")"
00086
00087 #define SQL_ATTACH_DEFAULTS \
00088 "ATTACH DATABASE '%s' AS defaults"
00089
00090 #define SQL_ATTACH_MODIFIED \
00091 "ATTACH DATABASE ':memory:' AS modified"
00092
00093 #define SQL_ATTACH_DUMPED \
00094 "ATTACH DATABASE '%s' AS dumped"
00095
00096 #define SQL_DETACH_DUMPED \
00097 "DETACH DATABASE dumped"
00098
00099 #define SQL_SELECT_VALUE_TYPE \
00100 "SELECT type, value, 0 AS is_default FROM config WHERE path=? UNION " \
00101 "SELECT type, value, 1 AS is_default FROM defaults.config AS dc " \
00102 "WHERE path=? AND NOT EXISTS " \
00103 "(SELECT path FROM config WHERE dc.path=path)"
00104
00105 #define SQL_SELECT_COMPLETE \
00106 "SELECT *, 0 AS is_default FROM config WHERE path LIKE ? UNION " \
00107 "SELECT *, 1 AS is_default FROM defaults.config AS dc " \
00108 "WHERE path LIKE ? AND NOT EXISTS " \
00109 "(SELECT path FROM config WHERE dc.path = path) " \
00110 "ORDER BY path"
00111
00112 #define SQL_SELECT_TYPE \
00113 "SELECT type, 0 AS is_default FROM config WHERE path=? UNION " \
00114 "SELECT type, 1 AS is_default FROM defaults.config AS dc " \
00115 "WHERE path=? AND NOT EXISTS " \
00116 "(SELECT path FROM config WHERE dc.path = path)"
00117
00118 #define SQL_SELECT_COMMENT \
00119 "SELECT comment, 0 AS is_default FROM config WHERE path=?"
00120
00121 #define SQL_SELECT_DEFAULT_COMMENT \
00122 "SELECT comment, 1 AS is_default FROM defaults.config AS dc " \
00123 "WHERE dc.path=?"
00124
00125 #define SQL_UPDATE_VALUE \
00126 "UPDATE config SET value=? WHERE path=?"
00127
00128 #define SQL_UPDATE_DEFAULT_VALUE \
00129 "UPDATE defaults.config SET value=? WHERE path=?"
00130
00131 #define SQL_UPDATE_COMMENT \
00132 "UPDATE config SET comment=? WHERE path=?"
00133
00134 #define SQL_UPDATE_DEFAULT_COMMENT \
00135 "UPDATE defaults.config SET comment=? WHERE path=?"
00136
00137 #define SQL_INSERT_VALUE \
00138 "INSERT INTO config (path, type, value) VALUES (?, ?, ?)"
00139
00140 #define SQL_INSERT_DEFAULT_VALUE \
00141 "INSERT INTO defaults.config (path, type, value) VALUES (?, ?, ?)"
00142
00143 #define SQL_SELECT_TAGS \
00144 "SELECT tag FROM tagged_config GROUP BY tag"
00145
00146 #define SQL_INSERT_TAG \
00147 "INSERT INTO tagged_config " \
00148 "(tag, path, type, value, comment) " \
00149 "SELECT \"%s\",* FROM config"
00150
00151 #define SQL_SELECT_ALL \
00152 "SELECT *, 0 AS is_default FROM config UNION " \
00153 "SELECT *, 1 AS is_default FROM defaults.config AS dc " \
00154 "WHERE NOT EXISTS " \
00155 "(SELECT path FROM config WHERE dc.path = path) " \
00156 "ORDER BY path"
00157
00158 #define SQL_SELECT_ALL_DEFAULT \
00159 "SELECT *, 1 AS is_default FROM defaults.config"
00160
00161 #define SQL_SELECT_ALL_HOSTSPECIFIC \
00162 "SELECT *, 0 AS is_default FROM config"
00163
00164 #define SQL_DELETE_VALUE \
00165 "DELETE FROM config WHERE path=?"
00166
00167 #define SQL_DELETE_DEFAULT_VALUE \
00168 "DELETE FROM defaults.config WHERE path=?"
00169
00170 #define SQL_UPDATE_DEFAULT_DB \
00171 "INSERT INTO config SELECT * FROM defaults.config AS dc " \
00172 "WHERE NOT EXISTS (SELECT path from config WHERE path = dc.path)"
00173
00174 #define SQL_UPDATE_MODIFIED_DB_ADDED \
00175 "INSERT INTO modified.config " \
00176 " SELECT duc.*,'added' AS modtype, duc.value " \
00177 " FROM dumped.config AS duc " \
00178 " WHERE NOT EXISTS (SELECT dc.path FROM defaults.config AS dc " \
00179 " WHERE dc.path=duc.path) " \
00180 " ORDER BY path"
00181
00182 #define SQL_UPDATE_MODIFIED_DB_ERASED \
00183 "INSERT INTO modified.config " \
00184 " SELECT dc.*,'erased' AS modtype, dc.value " \
00185 " FROM defaults.config AS dc " \
00186 " WHERE NOT EXISTS (SELECT duc.path FROM dumped.config AS duc " \
00187 " WHERE duc.path=dc.path) " \
00188 " ORDER BY path"
00189
00190 #define SQL_UPDATE_MODIFIED_DB_CHANGED \
00191 "INSERT INTO modified.config " \
00192 " SELECT duc.*,'changed' AS modtype, dc.value " \
00193 " FROM dumped.config AS duc, defaults.config AS dc " \
00194 " WHERE duc.path = dc.path " \
00195 " AND (dc.type != duc.type OR dc.value != duc.value) " \
00196 " ORDER BY duc.path"
00197
00198 #define SQL_COPY_DUMP \
00199 "DELETE FROM defaults.config; " \
00200 "INSERT INTO defaults.config SELECT * FROM dumped.config"
00201
00202 #define SQL_SELECT_MODIFIED_ALL \
00203 "SELECT * FROM modified.config"
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 SQLiteConfiguration::SQLiteConfiguration()
00222 {
00223 opened = false;
00224 mutex = new Mutex();
00225
00226 __sysconfdir = NULL;
00227 __userconfdir = NULL;
00228 __default_file = NULL;
00229 __default_sql = NULL;
00230
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 SQLiteConfiguration::SQLiteConfiguration(const char *sysconfdir,
00243 const char *userconfdir)
00244 {
00245 opened = false;
00246 mutex = new Mutex();
00247
00248 __sysconfdir = strdup(sysconfdir);
00249 __default_file = NULL;
00250 __default_sql = NULL;
00251
00252 if (userconfdir != NULL) {
00253 __userconfdir = strdup(userconfdir);
00254 } else {
00255 const char *homedir = getenv("HOME");
00256 if (homedir == NULL) {
00257 __userconfdir = strdup(sysconfdir);
00258 } else {
00259 if (asprintf(&__userconfdir, "%s/%s", homedir, USERDIR) == -1) {
00260 __userconfdir = strdup(sysconfdir);
00261 }
00262 }
00263 }
00264 }
00265
00266
00267 SQLiteConfiguration::~SQLiteConfiguration()
00268 {
00269 if (opened) {
00270 opened = false;
00271 if ( sqlite3_close(db) == SQLITE_BUSY ) {
00272 printf("Boom, we are dead, database cannot be closed "
00273 "because there are open handles\n");
00274 }
00275 }
00276
00277 if (__host_file) free(__host_file);
00278 if (__default_file) free(__default_file);
00279 if (__default_sql) free(__default_sql);
00280 if (__sysconfdir) free(__sysconfdir);
00281 if (__userconfdir) free(__userconfdir);
00282 delete mutex;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void
00336 SQLiteConfiguration::init_dbs()
00337 {
00338 char *errmsg;
00339 if ( (sqlite3_exec(db, SQL_CREATE_TABLE_HOST_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK) ||
00340 (sqlite3_exec(db, SQL_CREATE_TABLE_DEFAULT_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK) ||
00341 (sqlite3_exec(db, SQL_CREATE_TABLE_TAGGED_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK) ) {
00342 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
00343 sqlite3_close(db);
00344 throw ce;
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355 static void
00356 dump_table(FILE *f, ::sqlite3 *tdb, const char *table_name)
00357 {
00358 std::string tisql = "PRAGMA table_info(\"";
00359 tisql += table_name;
00360 tisql += "\");";
00361
00362 sqlite3_stmt *stmt;
00363 if ( sqlite3_prepare(tdb, tisql.c_str(), -1, &stmt, 0) != SQLITE_OK ) {
00364 throw ConfigurationException("dump_table/prepare", sqlite3_errmsg(tdb));
00365 }
00366 std::string value_query = "SELECT 'INSERT INTO ' || '\"";
00367 value_query += table_name;
00368 value_query += "\"' || ' VALUES(' || ";
00369 int rv = sqlite3_step(stmt);
00370 while ( rv == SQLITE_ROW ) {
00371 value_query += "quote(\"";
00372 value_query += (const char *)sqlite3_column_text(stmt, 1);
00373 value_query += "\") || ";
00374 rv = sqlite3_step(stmt);
00375 if ( rv == SQLITE_ROW ) {
00376 value_query += " ',' || ";
00377 }
00378 }
00379 value_query += "')' FROM ";
00380 value_query += table_name;
00381 sqlite3_finalize(stmt);
00382
00383 sqlite3_stmt *vstmt;
00384 if ( sqlite3_prepare(tdb, value_query.c_str(), -1, &vstmt, 0) != SQLITE_OK ) {
00385 throw ConfigurationException("dump_table/prepare 2", sqlite3_errmsg(tdb));
00386 }
00387 while ( sqlite3_step(vstmt) == SQLITE_ROW ) {
00388 fprintf(f, "%s;\n", sqlite3_column_text(vstmt, 0));
00389 }
00390 sqlite3_finalize(vstmt);
00391 }
00392
00393 void
00394 SQLiteConfiguration::dump(::sqlite3 *tdb, const char *dumpfile)
00395 {
00396 FILE *f = fopen(dumpfile, "w");
00397 if ( ! f ) {
00398 throw CouldNotOpenFileException(dumpfile, errno, "Could not open dump file");
00399 }
00400
00401 fprintf(f, "BEGIN TRANSACTION;\n");
00402
00403 const char *sql = "SELECT name, sql FROM sqlite_master "
00404 "WHERE sql NOT NULL AND type=='table'";
00405 sqlite3_stmt *stmt;
00406 if ( (sqlite3_prepare(tdb, sql, -1, &stmt, 0) != SQLITE_OK) || ! stmt ) {
00407 throw ConfigurationException("dump_query/prepare", sqlite3_errmsg(tdb));
00408 }
00409 while ( sqlite3_step(stmt) == SQLITE_ROW ) {
00410 fprintf(f, "%s;\n", sqlite3_column_text(stmt, 1));
00411 dump_table(f, tdb, (const char *)sqlite3_column_text(stmt, 0));
00412 }
00413 sqlite3_finalize(stmt);
00414
00415 fprintf(f, "COMMIT;\n");
00416 fclose(f);
00417 }
00418
00419
00420
00421
00422
00423
00424
00425 void
00426 SQLiteConfiguration::try_dump()
00427 {
00428 if ( __default_sql ) {
00429 sqlite3 *tdb;
00430 if ( sqlite3_open(__default_file, &tdb) == SQLITE_OK ) {
00431 try {
00432 dump(tdb, __default_sql);
00433 sqlite3_close(tdb);
00434 } catch (Exception &e) {
00435 sqlite3_close(tdb);
00436 throw;
00437 }
00438 }
00439 }
00440 }
00441
00442 void
00443 SQLiteConfiguration::import(::sqlite3 *tdb, const char *dumpfile)
00444 {
00445 FILE *f = fopen(dumpfile, "r");
00446
00447 if (! f) {
00448 throw CouldNotOpenConfigException("Import failed, could not open dump file");
00449 }
00450
00451 char line[4096];
00452 char *errmsg;
00453 while (! feof(f) ) {
00454 line[0] = 0;
00455 unsigned int i = 0;
00456 while (! feof(f) && (i < sizeof(line) - 1)) {
00457 if (fread(&(line[i]), 1, 1, f) == 1) {
00458 ++i;
00459 if ( (i > 2) && (line[i-1] == '\n') && (line[i-2] == ';') ) {
00460 break;
00461 }
00462 } else {
00463 break;
00464 }
00465 }
00466 line[i] = 0;
00467 if ( line[0] != 0 ) {
00468 if ( sqlite3_exec(tdb, line, 0, 0, &errmsg) != SQLITE_OK ) {
00469 ConfigurationException e(errmsg, line);
00470 sqlite3_free(errmsg);
00471 throw e;
00472 }
00473 }
00474 }
00475
00476 fclose(f);
00477 }
00478
00479
00480 void
00481 SQLiteConfiguration::import_default(const char *default_sql)
00482 {
00483 char *tmpfile = strdup(TMPDIR"/tmp_default_XXXXXX");
00484 tmpfile = mktemp(tmpfile);
00485 if ( tmpfile[0] == 0 ) {
00486 throw CouldNotOpenConfigException("Failed to create temp file for default DB import");
00487 }
00488
00489
00490 sqlite3 *dump_db;
00491 if ( sqlite3_open(tmpfile, &dump_db) == SQLITE_OK ) {
00492 import(dump_db, default_sql);
00493 sqlite3_close(dump_db);
00494 } else {
00495 throw CouldNotOpenConfigException("Failed to import dump file into temp DB");
00496 }
00497
00498
00499 char *attach_sql;
00500 char *errmsg;
00501 if ( asprintf(&attach_sql, SQL_ATTACH_DUMPED, tmpfile) == -1 ) {
00502 throw CouldNotOpenConfigException("Could not create attachment SQL in merge");
00503 }
00504 if ( sqlite3_exec(db, attach_sql, NULL, NULL, &errmsg) != SQLITE_OK ) {
00505 free(attach_sql);
00506 CouldNotOpenConfigException e("Could not attach dump DB in merge: %s", errmsg);
00507 sqlite3_free(errmsg);
00508 throw e;
00509 }
00510 free(attach_sql);
00511
00512
00513 if ( (sqlite3_exec(db, SQL_ATTACH_MODIFIED, NULL, NULL, &errmsg) != SQLITE_OK) ||
00514 (sqlite3_exec(db, SQL_CREATE_TABLE_MODIFIED_CONFIG, NULL, NULL, &errmsg) != SQLITE_OK) ) {
00515 CouldNotOpenConfigException ce("Could not create or attach modified memory database: %s", errmsg);
00516 sqlite3_free(errmsg);
00517 throw ce;
00518 }
00519
00520
00521 if ( (sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_ADDED, NULL, NULL, &errmsg) != SQLITE_OK) ||
00522 (sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_ERASED, NULL, NULL, &errmsg) != SQLITE_OK) ||
00523 (sqlite3_exec(db, SQL_UPDATE_MODIFIED_DB_CHANGED, NULL, NULL, &errmsg) != SQLITE_OK) ) {
00524 CouldNotOpenConfigException ce("Could not update modified memory database: %s", errmsg);
00525 sqlite3_free(errmsg);
00526 throw ce;
00527 }
00528
00529
00530 if ( (sqlite3_exec(db, SQL_COPY_DUMP, NULL, NULL, &errmsg) != SQLITE_OK) ) {
00531 CouldNotOpenConfigException ce("Could not copy dump to default: %s", errmsg);
00532 sqlite3_free(errmsg);
00533 throw ce;
00534 }
00535
00536
00537 if ( sqlite3_exec(db, SQL_DETACH_DUMPED, NULL, NULL, &errmsg) != SQLITE_OK ) {
00538 CouldNotOpenConfigException e("Could not detach dump DB in import: %s", errmsg);
00539 sqlite3_free(errmsg);
00540 throw e;
00541 }
00542
00543 unlink(tmpfile);
00544 free(tmpfile);
00545 }
00546
00547
00548
00549
00550
00551 void
00552 SQLiteConfiguration::transaction_begin(transaction_type_t ttype)
00553 {
00554 const char *sql = "BEGIN DEFERRED TRANSACTION;";
00555 if (ttype == TRANSACTION_IMMEDIATE) {
00556 sql = "BEGIN IMMEDIATE TRANSACTION;";
00557 } else if (ttype == TRANSACTION_EXCLUSIVE) {
00558 sql = "BEGIN EXCLUSIVE TRANSACTION;";
00559 }
00560
00561 char *errmsg;
00562 if ( (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) ) {
00563 throw ConfigurationException("Could not begin transaction (%s)", errmsg);
00564 }
00565 }
00566
00567
00568 void
00569 SQLiteConfiguration::transaction_commit()
00570 {
00571 const char *sql = "COMMIT TRANSACTION;";
00572
00573 char *errmsg;
00574 if ( (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) ) {
00575 throw ConfigurationException("Could not commit transaction (%s)", errmsg);
00576 }
00577 }
00578
00579
00580
00581 void
00582 SQLiteConfiguration::transaction_rollback()
00583 {
00584 const char *sql = "ROLLBACK TRANSACTION;";
00585
00586 char *errmsg;
00587 if ( (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) ) {
00588 throw ConfigurationException("Could not rollback transaction (%s)", errmsg);
00589 }
00590 }
00591
00592 void
00593 SQLiteConfiguration::attach_default(const char *db_file)
00594 {
00595 char *errmsg;
00596 char *attach_sql;
00597 if ( asprintf(&attach_sql, SQL_ATTACH_DEFAULTS, db_file) == -1 ) {
00598 throw CouldNotOpenConfigException("Could not create attachment SQL");
00599 }
00600 if (sqlite3_exec(db, attach_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
00601 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
00602 ce.append("Failed to attach default file (%s)", db_file);
00603 free(attach_sql);
00604 throw ce;
00605 }
00606 free(attach_sql);
00607 }
00608
00609
00610 void
00611 SQLiteConfiguration::load(const char *name, const char *defaults_name,
00612 const char *tag)
00613 {
00614 mutex->lock();
00615
00616 if (__default_file) free(__default_file);
00617 if (__default_sql) free(__default_sql);
00618 __default_file = NULL;
00619 __default_sql = NULL;
00620
00621 const char *try_paths[] = {__sysconfdir, __userconfdir};
00622 int try_paths_len = 2;
00623
00624 char *host_name;
00625
00626 if (name == NULL) {
00627 HostInfo hostinfo;
00628 if ( asprintf(&host_name, "%s.db", hostinfo.short_name()) == -1 ) {
00629 host_name = strdup(hostinfo.short_name());
00630 }
00631 } else {
00632 host_name = strdup(name);
00633 }
00634
00635
00636 if (strcmp(host_name, ":memory:") == 0) {
00637 if (sqlite3_open(host_name, &db) != SQLITE_OK) {
00638 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
00639 ce.append("Failed to open host db (memory)");
00640 throw ce;
00641 }
00642 } else if (host_name[0] == '/') {
00643
00644 if (sqlite3_open(host_name, &db) == SQLITE_OK) {
00645 __host_file = strdup(host_name);
00646 } else {
00647 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
00648 ce.append("Failed to open host db (absolute)");
00649 throw ce;
00650 }
00651 } else {
00652
00653 for (int i = 0; i < try_paths_len; ++i) {
00654 char *path;
00655 if (asprintf(&path, "%s/%s", try_paths[i], host_name) != -1) {
00656 if (sqlite3_open(path, &db) == SQLITE_OK) {
00657 __host_file = path;
00658 break;
00659 } else {
00660 free(path);
00661 }
00662 }
00663 }
00664 if (__host_file == NULL) {
00665 CouldNotOpenConfigException ce(sqlite3_errmsg(db));
00666 ce.append("Failed to open host db (paths)");
00667 free(host_name);
00668 throw ce;
00669 }
00670 }
00671
00672 if (defaults_name == NULL) {
00673 defaults_name = "default.sql";
00674 }
00675
00676
00677 if (strcmp(defaults_name, ":memory:") == 0) {
00678 try {
00679 attach_default(":memory:");
00680 } catch (...) {
00681 free(host_name);
00682 throw;
00683 }
00684 __default_file = strdup(":memory:");
00685 } else {
00686 if (defaults_name[0] == '/') {
00687
00688 __default_sql = strdup(defaults_name);
00689 } else {
00690
00691 for (int i = 0; i < try_paths_len; ++i) {
00692 char *path;
00693 if (asprintf(&path, "%s/%s", try_paths[i], defaults_name) != -1) {
00694 if (access(path, F_OK | R_OK) == 0) {
00695 __default_sql = path;
00696 break;
00697 } else {
00698 free(path);
00699 }
00700 }
00701 }
00702 }
00703
00704
00705
00706
00707 char *defaults_db;
00708 size_t len = strlen(defaults_name);
00709 if (fnmatch("*.sql", defaults_name, FNM_PATHNAME) == 0) {
00710 defaults_db = (char *)calloc(1, len);
00711 strncpy(defaults_db, defaults_name, len - 3);
00712 strcat(defaults_db, "db");
00713 } else {
00714 defaults_db = (char *)calloc(1, len + 4);
00715 strcpy(defaults_db, defaults_name);
00716 strcat(defaults_db, ".db");
00717 }
00718
00719 if (defaults_db[0] == '/') {
00720 try {
00721 attach_default(defaults_db);
00722 __default_file = defaults_db;
00723 } catch (...) {
00724 free(host_name);
00725 free(defaults_db);
00726 throw;
00727 }
00728 } else {
00729
00730 for (int i = 0; i < try_paths_len; ++i) {
00731 char *path;
00732 if (asprintf(&path, "%s/%s", try_paths[i], defaults_db) != -1) {
00733 try {
00734 attach_default(path);
00735 __default_file = path;
00736 break;
00737 } catch (CouldNotOpenConfigException &e) {
00738 free(path);
00739 }
00740 }
00741 }
00742 }
00743 free(defaults_db);
00744
00745 if (__default_file == NULL) {
00746 free(host_name);
00747 throw CouldNotOpenConfigException("Could not create default filename");
00748 }
00749 }
00750
00751 init_dbs();
00752
00753 if ( __default_sql ) import_default(__default_sql);
00754 free(host_name);
00755
00756 opened = true;
00757
00758 mutex->unlock();
00759 }
00760
00761
00762
00763
00764
00765
00766
00767 void
00768 SQLiteConfiguration::load(const char *tag)
00769 {
00770 load(NULL, NULL, tag);
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781 void
00782 SQLiteConfiguration::copy(Configuration *copyconf)
00783 {
00784 copyconf->lock();
00785 transaction_begin();
00786 Configuration::ValueIterator *i = copyconf->iterator();
00787 while ( i->next() ) {
00788 if ( i->is_float() ) {
00789 set_float(i->path(), i->get_float());
00790 } else if ( i->is_int() ) {
00791 set_int(i->path(), i->get_int());
00792 } else if ( i->is_uint() ) {
00793 set_uint(i->path(), i->get_uint());
00794 } else if ( i->is_bool() ) {
00795 set_bool(i->path(), i->get_bool());
00796 } else if ( i->is_string() ) {
00797 std::string s = i->get_string();
00798 set_string(i->path(), s);
00799 }
00800 }
00801 delete i;
00802 transaction_commit();
00803 copyconf->unlock();
00804 }
00805
00806
00807
00808
00809
00810
00811
00812 void
00813 SQLiteConfiguration::tag(const char *tag)
00814 {
00815 char *insert_sql;
00816 char *errmsg;
00817
00818 mutex->lock();
00819
00820 if ( asprintf(&insert_sql, SQL_INSERT_TAG, tag) == -1 ) {
00821 mutex->unlock();
00822 throw ConfigurationException("Could not create insert statement for tagging");
00823 }
00824
00825 if (sqlite3_exec(db, insert_sql, NULL, NULL, &errmsg) != SQLITE_OK) {
00826 ConfigurationException ce("Could not insert tag", sqlite3_errmsg(db));
00827 free(insert_sql);
00828 mutex->unlock();
00829 throw ce;
00830 }
00831
00832 free(insert_sql);
00833 mutex->unlock();
00834 }
00835
00836
00837 std::list<std::string>
00838 SQLiteConfiguration::tags()
00839 {
00840 mutex->lock();
00841 std::list<std::string> l;
00842 sqlite3_stmt *stmt;
00843 const char *tail;
00844 if ( sqlite3_prepare(db, SQL_SELECT_TAGS, -1, &stmt, &tail) != SQLITE_OK ) {
00845 mutex->unlock();
00846 throw ConfigurationException("get_type: Preparation SQL failed");
00847 }
00848 while ( sqlite3_step(stmt) == SQLITE_ROW ) {
00849 l.push_back((char *)sqlite3_column_text(stmt, 0));
00850 }
00851 sqlite3_finalize(stmt);
00852 mutex->unlock();
00853 return l;
00854 }
00855
00856
00857 bool
00858 SQLiteConfiguration::exists(const char *path)
00859 {
00860 mutex->lock();
00861 sqlite3_stmt *stmt;
00862 const char *tail;
00863 bool e;
00864
00865 if ( sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK ) {
00866 mutex->unlock();
00867 throw ConfigurationException("exists/prepare", sqlite3_errmsg(db));
00868 }
00869 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
00870 mutex->unlock();
00871 throw ConfigurationException("exists/bind/path", sqlite3_errmsg(db));
00872 }
00873 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
00874 mutex->unlock();
00875 throw ConfigurationException("exists/bind/path", sqlite3_errmsg(db));
00876 }
00877 e = ( sqlite3_step(stmt) == SQLITE_ROW );
00878 sqlite3_finalize(stmt);
00879
00880 mutex->unlock();
00881 return e;
00882 }
00883
00884
00885 std::string
00886 SQLiteConfiguration::get_type(const char *path)
00887 {
00888 sqlite3_stmt *stmt;
00889 const char *tail;
00890 std::string s = "";
00891
00892 mutex->lock();
00893
00894 if ( sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK ) {
00895 mutex->unlock();
00896 throw ConfigurationException("get_type: Preparation SQL failed");
00897 }
00898 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
00899 mutex->unlock();
00900 throw ConfigurationException("get_type: Binding text for path failed (1)");
00901 }
00902 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
00903 mutex->unlock();
00904 throw ConfigurationException("get_type: Binding text for path failed (2)");
00905 }
00906 if ( sqlite3_step(stmt) == SQLITE_ROW ) {
00907 s = (char *)sqlite3_column_text(stmt, 0);
00908 sqlite3_finalize(stmt);
00909 mutex->unlock();
00910 return s;
00911 } else {
00912 sqlite3_finalize(stmt);
00913 mutex->unlock();
00914 throw ConfigEntryNotFoundException(path);
00915 }
00916 }
00917
00918
00919 std::string
00920 SQLiteConfiguration::get_comment(const char *path)
00921 {
00922 sqlite3_stmt *stmt;
00923 const char *tail;
00924 std::string s = "";
00925
00926 mutex->lock();
00927
00928 if ( sqlite3_prepare(db, SQL_SELECT_COMMENT, -1, &stmt, &tail) != SQLITE_OK ) {
00929 mutex->unlock();
00930 throw ConfigurationException("get_comment: Preparation SQL failed");
00931 }
00932 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
00933 mutex->unlock();
00934 throw ConfigurationException("get_comment: Binding text for path failed (1)");
00935 }
00936 if ( sqlite3_step(stmt) == SQLITE_ROW ) {
00937 s = (char *)sqlite3_column_text(stmt, 0);
00938 sqlite3_finalize(stmt);
00939 mutex->unlock();
00940 return s;
00941 } else {
00942 sqlite3_finalize(stmt);
00943 mutex->unlock();
00944 throw ConfigEntryNotFoundException(path);
00945 }
00946 }
00947
00948
00949 std::string
00950 SQLiteConfiguration::get_default_comment(const char *path)
00951 {
00952 sqlite3_stmt *stmt;
00953 const char *tail;
00954 std::string s = "";
00955
00956 mutex->lock();
00957
00958 if ( sqlite3_prepare(db, SQL_SELECT_DEFAULT_COMMENT, -1, &stmt, &tail) != SQLITE_OK ) {
00959 mutex->unlock();
00960 throw ConfigurationException("get_default_comment: Preparation SQL failed");
00961 }
00962 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
00963 mutex->unlock();
00964 throw ConfigurationException("get_default_comment: Binding text for path failed (1)");
00965 }
00966 if ( sqlite3_step(stmt) == SQLITE_ROW ) {
00967 s = (char *)sqlite3_column_text(stmt, 0);
00968 sqlite3_finalize(stmt);
00969 mutex->unlock();
00970 return s;
00971 } else {
00972 sqlite3_finalize(stmt);
00973 mutex->unlock();
00974 throw ConfigEntryNotFoundException(path);
00975 }
00976 }
00977
00978
00979 bool
00980 SQLiteConfiguration::is_float(const char *path)
00981 {
00982 return (get_type(path) == "float");
00983 }
00984
00985
00986 bool
00987 SQLiteConfiguration::is_uint(const char *path)
00988 {
00989 return (get_type(path) == "unsigned int");
00990 }
00991
00992
00993 bool
00994 SQLiteConfiguration::is_int(const char *path)
00995 {
00996 return (get_type(path) == "int");
00997 }
00998
00999
01000 bool
01001 SQLiteConfiguration::is_bool(const char *path)
01002 {
01003 return (get_type(path) == "bool");
01004 }
01005
01006
01007 bool
01008 SQLiteConfiguration::is_string(const char *path)
01009 {
01010 return (get_type(path) == "string");
01011 }
01012
01013
01014 bool
01015 SQLiteConfiguration::is_default(const char *path)
01016 {
01017 mutex->lock();
01018 sqlite3_stmt *stmt;
01019 const char *tail;
01020 bool e;
01021
01022 if ( sqlite3_prepare(db, SQL_SELECT_TYPE, -1, &stmt, &tail) != SQLITE_OK ) {
01023 mutex->unlock();
01024 throw ConfigurationException("is_default/prepare", sqlite3_errmsg(db));
01025 }
01026 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
01027 mutex->unlock();
01028 throw ConfigurationException("is_default/bind/path", sqlite3_errmsg(db));
01029 }
01030 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
01031 mutex->unlock();
01032 throw ConfigurationException("is_default/bind/path", sqlite3_errmsg(db));
01033 }
01034 e = ( (sqlite3_step(stmt) == SQLITE_ROW) && (sqlite3_column_int(stmt, 1) == 1 ));
01035 sqlite3_finalize(stmt);
01036
01037 mutex->unlock();
01038 return e;
01039 }
01040
01041
01042
01043
01044
01045
01046
01047 sqlite3_stmt *
01048 SQLiteConfiguration::get_value(const char *path,
01049 const char *type)
01050 {
01051 sqlite3_stmt *stmt;
01052 const char *tail;
01053
01054 if ( sqlite3_prepare(db, SQL_SELECT_VALUE_TYPE, -1, &stmt, &tail) != SQLITE_OK ) {
01055 throw ConfigurationException("get_value/prepare", sqlite3_errmsg(db));
01056 }
01057 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
01058 throw ConfigurationException("get_value/bind/path (1)", sqlite3_errmsg(db));
01059 }
01060 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
01061 throw ConfigurationException("get_value/bind/path (2)", sqlite3_errmsg(db));
01062 }
01063
01064 if ( sqlite3_step(stmt) == SQLITE_ROW ) {
01065 if ( type == NULL ) {
01066
01067 return stmt;
01068 } else {
01069 if (strcmp((char *)sqlite3_column_text(stmt, 0), type) != 0) {
01070 ConfigTypeMismatchException ce(path, (char *)sqlite3_column_text(stmt, 0), type);
01071 sqlite3_finalize(stmt);
01072 throw ce;
01073 } else {
01074 return stmt;
01075 }
01076 }
01077 } else {
01078 sqlite3_finalize(stmt);
01079 throw ConfigEntryNotFoundException(path);
01080 }
01081 }
01082
01083
01084 float
01085 SQLiteConfiguration::get_float(const char *path)
01086 {
01087 sqlite3_stmt *stmt;
01088 mutex->lock();
01089 try {
01090 stmt = get_value(path, "float");
01091 float f = (float)sqlite3_column_double(stmt, 1);
01092 sqlite3_finalize(stmt);
01093 mutex->unlock();
01094 return f;
01095 } catch (Exception &e) {
01096
01097 mutex->unlock();
01098 throw;
01099 }
01100 }
01101
01102
01103 unsigned int
01104 SQLiteConfiguration::get_uint(const char *path)
01105 {
01106 sqlite3_stmt *stmt;
01107 mutex->lock();
01108 try {
01109 stmt = get_value(path, "unsigned int");
01110 int i = sqlite3_column_int(stmt, 1);
01111 sqlite3_finalize(stmt);
01112 if ( i < 0 ) {
01113 mutex->unlock();
01114 throw ConfigTypeMismatchException(path, "int", "unsigned int");
01115 }
01116 mutex->unlock();
01117 return i;
01118 } catch (Exception &e) {
01119
01120 mutex->unlock();
01121 throw;
01122 }
01123 }
01124
01125
01126 int
01127 SQLiteConfiguration::get_int(const char *path)
01128 {
01129 sqlite3_stmt *stmt;
01130 mutex->lock();
01131 try {
01132 stmt = get_value(path, "int");
01133 int i = sqlite3_column_int(stmt, 1);
01134 sqlite3_finalize(stmt);
01135 mutex->unlock();
01136 return i;
01137 } catch (Exception &e) {
01138
01139 mutex->unlock();
01140 throw;
01141 }
01142 }
01143
01144
01145 bool
01146 SQLiteConfiguration::get_bool(const char *path)
01147 {
01148 sqlite3_stmt *stmt;
01149 mutex->lock();
01150 try {
01151 stmt = get_value(path, "bool");
01152 int i = sqlite3_column_int(stmt, 1);
01153 sqlite3_finalize(stmt);
01154 mutex->unlock();
01155 return (i != 0);
01156 } catch (Exception &e) {
01157
01158 mutex->unlock();
01159 throw;
01160 }
01161 }
01162
01163 std::string
01164 SQLiteConfiguration::get_string(const char *path)
01165 {
01166 sqlite3_stmt *stmt;
01167 mutex->lock();
01168 try {
01169 stmt = get_value(path, "string");
01170 const char *c = (char *)sqlite3_column_text(stmt, 1);
01171 std::string rv = c;
01172 sqlite3_finalize(stmt);
01173 mutex->unlock();
01174 return rv;
01175 } catch (Exception &e) {
01176
01177 e.append("SQLiteConfiguration::get_string: Fetching %s failed.", path);
01178 mutex->unlock();
01179 throw;
01180 }
01181 }
01182
01183
01184 Configuration::ValueIterator *
01185 SQLiteConfiguration::get_value(const char *path)
01186 {
01187 sqlite3_stmt *stmt;
01188 const char *tail;
01189
01190 if ( sqlite3_prepare(db, SQL_SELECT_COMPLETE, -1, &stmt, &tail) != SQLITE_OK ) {
01191 throw ConfigurationException("get_value/prepare", sqlite3_errmsg(db));
01192 }
01193 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
01194 throw ConfigurationException("get_value/bind/path (1)", sqlite3_errmsg(db));
01195 }
01196 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
01197 throw ConfigurationException("get_value/bind/path (2)", sqlite3_errmsg(db));
01198 }
01199
01200 return new SQLiteValueIterator(stmt);
01201 }
01202
01203
01204 sqlite3_stmt *
01205 SQLiteConfiguration::prepare_update(const char *sql,
01206 const char *path)
01207 {
01208 sqlite3_stmt *stmt;
01209 const char *tail;
01210
01211 if ( sqlite3_prepare(db, sql, -1, &stmt, &tail) != SQLITE_OK ) {
01212 throw ConfigurationException("prepare_update/prepare", sqlite3_errmsg(db));
01213 }
01214 if ( sqlite3_bind_text(stmt, 2, path, -1, NULL) != SQLITE_OK ) {
01215 ConfigurationException ce("prepare_update/bind", sqlite3_errmsg(db));
01216 sqlite3_finalize(stmt);
01217 throw ce;
01218 }
01219
01220 return stmt;
01221 }
01222
01223
01224 sqlite3_stmt *
01225 SQLiteConfiguration::prepare_insert_value(const char *sql, const char *type,
01226 const char *path)
01227 {
01228 sqlite3_stmt *stmt;
01229 const char *tail;
01230
01231 if ( sqlite3_prepare(db, sql, -1, &stmt, &tail) != SQLITE_OK ) {
01232 throw ConfigurationException("prepare_insert_value/prepare", sqlite3_errmsg(db));
01233 }
01234 if ( (sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK) ||
01235 (sqlite3_bind_text(stmt, 2, type, -1, NULL) != SQLITE_OK) ) {
01236 ConfigurationException ce("prepare_insert_value/bind", sqlite3_errmsg(db));
01237 sqlite3_finalize(stmt);
01238 throw ce;
01239 }
01240
01241 return stmt;
01242 }
01243
01244
01245 void
01246 SQLiteConfiguration::execute_insert_or_update(sqlite3_stmt *stmt)
01247 {
01248 if ( sqlite3_step(stmt) != SQLITE_DONE ) {
01249 ConfigurationException ce("execute_insert_or_update", sqlite3_errmsg(db));
01250 sqlite3_finalize(stmt);
01251 throw ce;
01252 }
01253 }
01254
01255
01256 void
01257 SQLiteConfiguration::set_float(const char *path, float f)
01258 {
01259 sqlite3_stmt *stmt = NULL;
01260
01261 mutex->lock();
01262
01263 try {
01264 stmt = prepare_update(SQL_UPDATE_VALUE, path);
01265 if ( (sqlite3_bind_double(stmt, 1, f) != SQLITE_OK) ) {
01266 ConfigurationException ce("set_float/update/bind", sqlite3_errmsg(db));
01267 sqlite3_finalize(stmt);
01268 mutex->unlock();
01269 throw ce;
01270 }
01271 execute_insert_or_update(stmt);
01272 sqlite3_finalize(stmt);
01273 } catch (Exception &e) {
01274 if ( stmt != NULL ) sqlite3_finalize(stmt);
01275 mutex->unlock();
01276 throw;
01277 }
01278
01279 if ( sqlite3_changes(db) == 0 ) {
01280
01281
01282 try {
01283 stmt = prepare_insert_value(SQL_INSERT_VALUE, "float", path);
01284 if ( (sqlite3_bind_double(stmt, 3, f) != SQLITE_OK) ) {
01285 ConfigurationException ce("set_float/insert/bind", sqlite3_errmsg(db));
01286 sqlite3_finalize(stmt);
01287 mutex->unlock();
01288 throw ce;
01289 }
01290 execute_insert_or_update(stmt);
01291 sqlite3_finalize(stmt);
01292 } catch (Exception &e) {
01293 if ( stmt != NULL ) sqlite3_finalize(stmt);
01294 mutex->unlock();
01295 throw;
01296 }
01297 }
01298
01299 mutex->unlock();
01300
01301 ChangeHandlerList *h = find_handlers(path);
01302 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01303 (*i)->config_value_changed(path, false, f);
01304 }
01305 delete h;
01306 }
01307
01308
01309 void
01310 SQLiteConfiguration::set_uint(const char *path, unsigned int uint)
01311 {
01312 sqlite3_stmt *stmt = NULL;
01313
01314 mutex->lock();
01315
01316 try {
01317 stmt = prepare_update(SQL_UPDATE_VALUE, path);
01318 if ( (sqlite3_bind_int(stmt, 1, uint) != SQLITE_OK) ) {
01319 ConfigurationException ce("set_uint/update/bind", sqlite3_errmsg(db));
01320 sqlite3_finalize(stmt);
01321 mutex->unlock();
01322 throw ce;
01323 }
01324 execute_insert_or_update(stmt);
01325 sqlite3_finalize(stmt);
01326 } catch (Exception &e) {
01327 if ( stmt != NULL ) sqlite3_finalize(stmt);
01328 mutex->unlock();
01329 throw;
01330 }
01331
01332 if ( sqlite3_changes(db) == 0 ) {
01333
01334
01335 try {
01336 stmt = prepare_insert_value(SQL_INSERT_VALUE, "unsigned int", path);
01337 if ( (sqlite3_bind_int(stmt, 3, uint) != SQLITE_OK) ) {
01338 ConfigurationException ce("set_uint/insert/bind", sqlite3_errmsg(db));
01339 sqlite3_finalize(stmt);
01340 mutex->unlock();
01341 throw ce;
01342 }
01343 execute_insert_or_update(stmt);
01344 sqlite3_finalize(stmt);
01345 } catch (Exception &e) {
01346 if ( stmt != NULL ) sqlite3_finalize(stmt);
01347 mutex->unlock();
01348 throw;
01349 }
01350 }
01351 mutex->unlock();
01352
01353 ChangeHandlerList *h = find_handlers(path);
01354 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01355 (*i)->config_value_changed(path, false, uint);
01356 }
01357 delete h;
01358 }
01359
01360
01361 void
01362 SQLiteConfiguration::set_int(const char *path, int i)
01363 {
01364 sqlite3_stmt *stmt = NULL;
01365
01366 mutex->lock();
01367
01368 try {
01369 stmt = prepare_update(SQL_UPDATE_VALUE, path);
01370 if ( (sqlite3_bind_int(stmt, 1, i) != SQLITE_OK) ) {
01371 ConfigurationException ce("set_int/update/bind", sqlite3_errmsg(db));
01372 sqlite3_finalize(stmt);
01373 mutex->unlock();
01374 throw ce;
01375 }
01376 execute_insert_or_update(stmt);
01377 sqlite3_finalize(stmt);
01378 } catch (Exception &e) {
01379 if ( stmt != NULL ) sqlite3_finalize(stmt);
01380 mutex->unlock();
01381 throw;
01382 }
01383
01384 if ( sqlite3_changes(db) == 0 ) {
01385
01386
01387 try {
01388 stmt = prepare_insert_value(SQL_INSERT_VALUE, "int", path);
01389 if ( (sqlite3_bind_int(stmt, 3, i) != SQLITE_OK) ) {
01390 ConfigurationException ce("set_int/insert/bind", sqlite3_errmsg(db));
01391 sqlite3_finalize(stmt);
01392 mutex->unlock();
01393 throw ce;
01394 }
01395 execute_insert_or_update(stmt);
01396 sqlite3_finalize(stmt);
01397 } catch (Exception &e) {
01398 if ( stmt != NULL ) sqlite3_finalize(stmt);
01399 mutex->unlock();
01400 throw;
01401 }
01402 }
01403
01404 mutex->unlock();
01405
01406 ChangeHandlerList *h = find_handlers(path);
01407 for (ChangeHandlerList::const_iterator j = h->begin(); j != h->end(); ++j) {
01408 (*j)->config_value_changed(path, false, i);
01409 }
01410 delete h;
01411 }
01412
01413
01414 void
01415 SQLiteConfiguration::set_bool(const char *path, bool b)
01416 {
01417 sqlite3_stmt *stmt = NULL;
01418
01419 mutex->lock();
01420
01421 try {
01422 stmt = prepare_update(SQL_UPDATE_VALUE, path);
01423 if ( (sqlite3_bind_int(stmt, 1, (b ? 1 : 0)) != SQLITE_OK) ) {
01424 ConfigurationException ce("set_bool/update/bind", sqlite3_errmsg(db));
01425 sqlite3_finalize(stmt);
01426 mutex->unlock();
01427 throw ce;
01428 }
01429 execute_insert_or_update(stmt);
01430 sqlite3_finalize(stmt);
01431 } catch (Exception &e) {
01432 if ( stmt != NULL ) sqlite3_finalize(stmt);
01433 mutex->unlock();
01434 throw;
01435 }
01436
01437 if ( sqlite3_changes(db) == 0 ) {
01438
01439
01440 try {
01441 stmt = prepare_insert_value(SQL_INSERT_VALUE, "bool", path);
01442 if ( (sqlite3_bind_int(stmt, 3, (b ? 1 : 0)) != SQLITE_OK) ) {
01443 ConfigurationException ce("set_bool/insert/bind", sqlite3_errmsg(db));
01444 sqlite3_finalize(stmt);
01445 mutex->unlock();
01446 throw ce;
01447 }
01448 execute_insert_or_update(stmt);
01449 sqlite3_finalize(stmt);
01450 } catch (Exception &e) {
01451 if ( stmt != NULL ) sqlite3_finalize(stmt);
01452 mutex->unlock();
01453 throw;
01454 }
01455 }
01456
01457 mutex->unlock();
01458
01459 ChangeHandlerList *h = find_handlers(path);
01460 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01461 (*i)->config_value_changed(path, false, b);
01462 }
01463 delete h;
01464 }
01465
01466
01467 void
01468 SQLiteConfiguration::set_string(const char *path,
01469 const char *s)
01470 {
01471 sqlite3_stmt *stmt = NULL;
01472
01473 mutex->lock();
01474
01475 size_t s_length = strlen(s);
01476
01477 try {
01478 stmt = prepare_update(SQL_UPDATE_VALUE, path);
01479 if ( (sqlite3_bind_text(stmt, 1, s, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
01480 ConfigurationException ce("set_string/update/bind", sqlite3_errmsg(db));
01481 sqlite3_finalize(stmt);
01482 mutex->unlock();
01483 throw ce;
01484 }
01485 execute_insert_or_update(stmt);
01486 sqlite3_finalize(stmt);
01487 } catch (Exception &e) {
01488 if ( stmt != NULL ) sqlite3_finalize(stmt);
01489 mutex->unlock();
01490 throw;
01491 }
01492
01493 if ( sqlite3_changes(db) == 0 ) {
01494
01495
01496 try {
01497 stmt = prepare_insert_value(SQL_INSERT_VALUE, "string", path);
01498 if ( (sqlite3_bind_text(stmt, 3, s, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
01499 ConfigurationException ce("set_string/insert/bind", sqlite3_errmsg(db));
01500 sqlite3_finalize(stmt);
01501 mutex->unlock();
01502 throw ce;
01503 }
01504 execute_insert_or_update(stmt);
01505 sqlite3_finalize(stmt);
01506 } catch (Exception &e) {
01507 if ( stmt != NULL ) sqlite3_finalize(stmt);
01508 mutex->unlock();
01509 throw;
01510 }
01511 }
01512
01513 mutex->unlock();
01514
01515 ChangeHandlerList *h = find_handlers(path);
01516 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01517 (*i)->config_value_changed(path, false, s);
01518 }
01519 delete h;
01520 }
01521
01522
01523 void
01524 SQLiteConfiguration::set_string(const char *path, std::string &s)
01525 {
01526 set_string(path, s.c_str());
01527 }
01528
01529
01530 void
01531 SQLiteConfiguration::set_comment(const char *path, const char *comment)
01532 {
01533 sqlite3_stmt *stmt = NULL;
01534
01535 mutex->lock();
01536
01537 size_t s_length = strlen(comment);
01538
01539 try {
01540 stmt = prepare_update(SQL_UPDATE_COMMENT, path);
01541 if ( (sqlite3_bind_text(stmt, 1, comment, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
01542 ConfigurationException ce("set_string/update/bind", sqlite3_errmsg(db));
01543 sqlite3_finalize(stmt);
01544 mutex->unlock();
01545 throw ce;
01546 }
01547 execute_insert_or_update(stmt);
01548 sqlite3_finalize(stmt);
01549 } catch (Exception &e) {
01550 if ( stmt != NULL ) sqlite3_finalize(stmt);
01551 mutex->unlock();
01552 throw;
01553 }
01554
01555 if ( sqlite3_changes(db) == 0 ) {
01556
01557 mutex->unlock();
01558 throw ConfigurationException("set_comment", "Cannot set comment for inexistent path");
01559 }
01560
01561 mutex->unlock();
01562
01563 ChangeHandlerList *h = find_handlers(path);
01564 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01565 (*i)->config_comment_changed(path, false, comment);
01566 }
01567 delete h;
01568 }
01569
01570
01571 void
01572 SQLiteConfiguration::set_comment(const char *path, std::string &comment)
01573 {
01574 set_comment(path, comment.c_str());
01575 }
01576
01577
01578 void
01579 SQLiteConfiguration::erase(const char *path)
01580 {
01581 sqlite3_stmt *stmt;
01582 const char *tail;
01583
01584 if ( sqlite3_prepare(db, SQL_DELETE_VALUE, -1, &stmt, &tail) != SQLITE_OK ) {
01585 throw ConfigurationException("erase/prepare", sqlite3_errmsg(db));
01586 }
01587 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
01588 ConfigurationException ce("erase/bind", sqlite3_errmsg(db));
01589 sqlite3_finalize(stmt);
01590 throw ce;
01591 }
01592
01593 if ( sqlite3_step(stmt) != SQLITE_DONE ) {
01594 ConfigurationException ce("erase/execute", sqlite3_errmsg(db));
01595 sqlite3_finalize(stmt);
01596 throw ce;
01597 }
01598
01599 sqlite3_finalize(stmt);
01600
01601 ChangeHandlerList *h = find_handlers(path);
01602 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01603 (*i)->config_value_erased(path, false);
01604 }
01605 delete h;
01606 }
01607
01608
01609 void
01610 SQLiteConfiguration::set_default_float(const char *path, float f)
01611 {
01612 sqlite3_stmt *stmt = NULL;
01613
01614 mutex->lock();
01615
01616 try {
01617 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
01618 if ( (sqlite3_bind_double(stmt, 1, f) != SQLITE_OK) ) {
01619 ConfigurationException ce("set_default_float/update/bind", sqlite3_errmsg(db));
01620 sqlite3_finalize(stmt);
01621 mutex->unlock();
01622 throw ce;
01623 }
01624 execute_insert_or_update(stmt);
01625 sqlite3_finalize(stmt);
01626 } catch (Exception &e) {
01627 if ( stmt != NULL ) sqlite3_finalize(stmt);
01628 mutex->unlock();
01629 throw;
01630 }
01631
01632 if ( sqlite3_changes(db) == 0 ) {
01633
01634
01635 try {
01636 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "float", path);
01637 if ( (sqlite3_bind_double(stmt, 3, f) != SQLITE_OK) ) {
01638 ConfigurationException ce("set_default_float/insert/bind", sqlite3_errmsg(db));
01639 sqlite3_finalize(stmt);
01640 mutex->unlock();
01641 throw ce;
01642 }
01643 execute_insert_or_update(stmt);
01644 sqlite3_finalize(stmt);
01645 } catch (Exception &e) {
01646 if ( stmt != NULL ) sqlite3_finalize(stmt);
01647 mutex->unlock();
01648 throw;
01649 }
01650 }
01651
01652 mutex->unlock();
01653
01654 ChangeHandlerList *h = find_handlers(path);
01655 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01656 (*i)->config_value_changed(path, true, f);
01657 }
01658 delete h;
01659 }
01660
01661
01662 void
01663 SQLiteConfiguration::set_default_uint(const char *path, unsigned int uint)
01664 {
01665 sqlite3_stmt *stmt = NULL;
01666
01667 mutex->lock();
01668
01669 try {
01670 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
01671 if ( (sqlite3_bind_int(stmt, 1, uint) != SQLITE_OK) ) {
01672 ConfigurationException ce("set_default_uint/update/bind", sqlite3_errmsg(db));
01673 sqlite3_finalize(stmt);
01674 mutex->unlock();
01675 throw ce;
01676 }
01677 execute_insert_or_update(stmt);
01678 sqlite3_finalize(stmt);
01679 } catch (Exception &e) {
01680 if ( stmt != NULL ) sqlite3_finalize(stmt);
01681 mutex->unlock();
01682 throw;
01683 }
01684
01685 if ( sqlite3_changes(db) == 0 ) {
01686
01687
01688 try {
01689 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "unsigned int", path);
01690 if ( (sqlite3_bind_int(stmt, 3, uint) != SQLITE_OK) ) {
01691 ConfigurationException ce("set_default_uint/insert/bind", sqlite3_errmsg(db));
01692 sqlite3_finalize(stmt);
01693 mutex->unlock();
01694 throw ce;
01695 }
01696 execute_insert_or_update(stmt);
01697 sqlite3_finalize(stmt);
01698 } catch (Exception &e) {
01699 if ( stmt != NULL ) sqlite3_finalize(stmt);
01700 mutex->unlock();
01701 throw;
01702 }
01703 }
01704 mutex->unlock();
01705
01706 ChangeHandlerList *h = find_handlers(path);
01707 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01708 (*i)->config_value_changed(path, true, uint);
01709 }
01710 delete h;
01711 }
01712
01713
01714 void
01715 SQLiteConfiguration::set_default_int(const char *path, int i)
01716 {
01717 sqlite3_stmt *stmt = NULL;
01718 mutex->lock();
01719
01720 try {
01721 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
01722 if ( (sqlite3_bind_int(stmt, 1, i) != SQLITE_OK) ) {
01723 ConfigurationException ce("set_default_int/update/bind", sqlite3_errmsg(db));
01724 sqlite3_finalize(stmt);
01725 mutex->unlock();
01726 throw ce;
01727 }
01728 execute_insert_or_update(stmt);
01729 sqlite3_finalize(stmt);
01730 } catch (Exception &e) {
01731 if ( stmt != NULL ) sqlite3_finalize(stmt);
01732 mutex->unlock();
01733 throw;
01734 }
01735
01736 if ( sqlite3_changes(db) == 0 ) {
01737
01738 try {
01739 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "int", path);
01740 if ( (sqlite3_bind_int(stmt, 3, i) != SQLITE_OK) ) {
01741 ConfigurationException ce("set_default_int/insert/bind", sqlite3_errmsg(db));
01742 sqlite3_finalize(stmt);
01743 mutex->unlock();
01744 throw ce;
01745 }
01746 execute_insert_or_update(stmt);
01747 sqlite3_finalize(stmt);
01748 } catch (Exception &e) {
01749 if ( stmt != NULL ) sqlite3_finalize(stmt);
01750 mutex->unlock();
01751 throw;
01752 }
01753 }
01754
01755 mutex->unlock();
01756
01757 ChangeHandlerList *h = find_handlers(path);
01758 for (ChangeHandlerList::const_iterator j = h->begin(); j != h->end(); ++j) {
01759 (*j)->config_value_changed(path, true, i);
01760 }
01761 delete h;
01762 }
01763
01764
01765 void
01766 SQLiteConfiguration::set_default_bool(const char *path, bool b)
01767 {
01768 sqlite3_stmt *stmt = NULL;
01769
01770 mutex->lock();
01771
01772 try {
01773 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
01774 if ( (sqlite3_bind_int(stmt, 1, (b ? 1 : 0)) != SQLITE_OK) ) {
01775 ConfigurationException ce("set_default_bool/update/bind", sqlite3_errmsg(db));
01776 sqlite3_finalize(stmt);
01777 mutex->unlock();
01778 throw ce;
01779 }
01780 execute_insert_or_update(stmt);
01781 sqlite3_finalize(stmt);
01782 } catch (Exception &e) {
01783 if ( stmt != NULL ) sqlite3_finalize(stmt);
01784 mutex->unlock();
01785 throw;
01786 }
01787
01788 if ( sqlite3_changes(db) == 0 ) {
01789
01790
01791 try {
01792 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "bool", path);
01793 if ( (sqlite3_bind_int(stmt, 3, (b ? 1 : 0)) != SQLITE_OK) ) {
01794 ConfigurationException ce("set_default_bool/insert/bind", sqlite3_errmsg(db));
01795 sqlite3_finalize(stmt);
01796 mutex->unlock();
01797 throw ce;
01798 }
01799 execute_insert_or_update(stmt);
01800 sqlite3_finalize(stmt);
01801 } catch (Exception &e) {
01802 if ( stmt != NULL ) sqlite3_finalize(stmt);
01803 mutex->unlock();
01804 throw;
01805 }
01806 }
01807
01808 mutex->unlock();
01809
01810 ChangeHandlerList *h = find_handlers(path);
01811 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01812 (*i)->config_value_changed(path, true, b);
01813 }
01814 delete h;
01815 }
01816
01817
01818 void
01819 SQLiteConfiguration::set_default_string(const char *path,
01820 const char *s)
01821 {
01822 sqlite3_stmt *stmt = NULL;
01823
01824 mutex->lock();
01825 size_t s_length = strlen(s);
01826
01827 try {
01828 stmt = prepare_update(SQL_UPDATE_DEFAULT_VALUE, path);
01829 if ( (sqlite3_bind_text(stmt, 1, s, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
01830 ConfigurationException ce("set_default_string/update/bind", sqlite3_errmsg(db));
01831 sqlite3_finalize(stmt);
01832 mutex->unlock();
01833 throw ce;
01834 }
01835 execute_insert_or_update(stmt);
01836 sqlite3_finalize(stmt);
01837 } catch (Exception &e) {
01838 if ( stmt != NULL ) sqlite3_finalize(stmt);
01839 mutex->unlock();
01840 throw;
01841 }
01842
01843 if ( sqlite3_changes(db) == 0 ) {
01844
01845
01846 try {
01847 stmt = prepare_insert_value(SQL_INSERT_DEFAULT_VALUE, "string", path);
01848 if ( (sqlite3_bind_text(stmt, 3, s, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
01849 ConfigurationException ce("set_default_string/insert/bind", sqlite3_errmsg(db));
01850 sqlite3_finalize(stmt);
01851 mutex->unlock();
01852 throw ce;
01853 }
01854 execute_insert_or_update(stmt);
01855 sqlite3_finalize(stmt);
01856 } catch (Exception &e) {
01857 if ( stmt != NULL ) sqlite3_finalize(stmt);
01858 mutex->unlock();
01859 throw;
01860 }
01861 }
01862
01863 mutex->unlock();
01864
01865 ChangeHandlerList *h = find_handlers(path);
01866 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01867 (*i)->config_value_changed(path, true, s);
01868 }
01869 delete h;
01870 }
01871
01872
01873 void
01874 SQLiteConfiguration::set_default_string(const char *path, std::string &s)
01875 {
01876 set_default_string(path, s.c_str());
01877 }
01878
01879
01880 void
01881 SQLiteConfiguration::set_default_comment(const char *path, const char *comment)
01882 {
01883 sqlite3_stmt *stmt = NULL;
01884
01885 mutex->lock();
01886 size_t s_length = strlen(comment);
01887
01888 try {
01889 stmt = prepare_update(SQL_UPDATE_DEFAULT_COMMENT, path);
01890 if ( (sqlite3_bind_text(stmt, 1, comment, s_length, SQLITE_STATIC) != SQLITE_OK) ) {
01891 ConfigurationException ce("set_default_comment/update/bind", sqlite3_errmsg(db));
01892 sqlite3_finalize(stmt);
01893 mutex->unlock();
01894 throw ce;
01895 }
01896 execute_insert_or_update(stmt);
01897 sqlite3_finalize(stmt);
01898 } catch (Exception &e) {
01899 if ( stmt != NULL ) sqlite3_finalize(stmt);
01900 mutex->unlock();
01901 throw;
01902 }
01903
01904 if ( sqlite3_changes(db) == 0 ) {
01905
01906 mutex->unlock();
01907 throw ConfigurationException("set_default_comment", "Cannot set comment for inexistent path");
01908 }
01909
01910 mutex->unlock();
01911
01912 ChangeHandlerList *h = find_handlers(path);
01913 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01914 (*i)->config_comment_changed(path, true, comment);
01915 }
01916 delete h;
01917 }
01918
01919
01920 void
01921 SQLiteConfiguration::set_default_comment(const char *path, std::string &comment)
01922 {
01923 set_default_comment(path, comment.c_str());
01924 }
01925
01926
01927 void
01928 SQLiteConfiguration::erase_default(const char *path)
01929 {
01930 sqlite3_stmt *stmt;
01931 const char *tail;
01932
01933 if ( sqlite3_prepare(db, SQL_DELETE_DEFAULT_VALUE, -1, &stmt, &tail) != SQLITE_OK ) {
01934 throw ConfigurationException("erase_default/prepare", sqlite3_errmsg(db));
01935 }
01936 if ( sqlite3_bind_text(stmt, 1, path, -1, NULL) != SQLITE_OK ) {
01937 ConfigurationException ce("erase_default/bind", sqlite3_errmsg(db));
01938 sqlite3_finalize(stmt);
01939 throw ce;
01940 }
01941
01942 if ( sqlite3_step(stmt) != SQLITE_DONE ) {
01943 ConfigurationException ce("erase_default/execute", sqlite3_errmsg(db));
01944 sqlite3_finalize(stmt);
01945 throw ce;
01946 }
01947
01948 sqlite3_finalize(stmt);
01949
01950 ChangeHandlerList *h = find_handlers(path);
01951 for (ChangeHandlerList::const_iterator i = h->begin(); i != h->end(); ++i) {
01952 (*i)->config_value_erased(path, true);
01953 }
01954 delete h;
01955 }
01956
01957
01958
01959
01960
01961
01962 void
01963 SQLiteConfiguration::lock()
01964 {
01965 mutex->lock();
01966 }
01967
01968
01969
01970
01971
01972
01973 bool
01974 SQLiteConfiguration::try_lock()
01975 {
01976 return mutex->try_lock();
01977 }
01978
01979
01980
01981
01982 void
01983 SQLiteConfiguration::unlock()
01984 {
01985 mutex->unlock();
01986 }
01987
01988
01989 Configuration::ValueIterator *
01990 SQLiteConfiguration::iterator()
01991 {
01992 sqlite3_stmt *stmt;
01993 const char *tail;
01994
01995 if ( sqlite3_prepare(db, SQL_SELECT_ALL, -1, &stmt, &tail) != SQLITE_OK ) {
01996 throw ConfigurationException("iterator: Preparation SQL failed");
01997 }
01998
01999 return new SQLiteValueIterator(stmt);
02000 }
02001
02002
02003 Configuration::ValueIterator *
02004 SQLiteConfiguration::iterator_default()
02005 {
02006 sqlite3_stmt *stmt;
02007 const char *tail;
02008
02009 if ( sqlite3_prepare(db, SQL_SELECT_ALL_DEFAULT, -1, &stmt, &tail) != SQLITE_OK ) {
02010 throw ConfigurationException("iterator_default: Preparation SQL failed");
02011 }
02012
02013 return new SQLiteValueIterator(stmt);
02014 }
02015
02016 Configuration::ValueIterator *
02017 SQLiteConfiguration::iterator_hostspecific()
02018 {
02019 sqlite3_stmt *stmt;
02020 const char *tail;
02021
02022 if ( sqlite3_prepare(db, SQL_SELECT_ALL_HOSTSPECIFIC, -1, &stmt, &tail) != SQLITE_OK ) {
02023 throw ConfigurationException("iterator_hostspecific: Preparation SQL failed");
02024 }
02025
02026 return new SQLiteValueIterator(stmt);
02027 }
02028
02029
02030
02031
02032
02033
02034 SQLiteConfiguration::SQLiteValueIterator *
02035 SQLiteConfiguration::modified_iterator()
02036 {
02037 sqlite3_stmt *stmt;
02038 const char *tail;
02039
02040 if ( sqlite3_prepare(db, SQL_SELECT_MODIFIED_ALL, -1, &stmt, &tail) != SQLITE_OK ) {
02041 throw ConfigurationException("modified_iterator: Preparation SQL failed");
02042 }
02043
02044 return new SQLiteValueIterator(stmt);
02045 }
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059 Configuration::ValueIterator *
02060 SQLiteConfiguration::search(const char *path)
02061 {
02062 sqlite3_stmt *stmt;
02063 const char *tail;
02064
02065 char *p;
02066 if ( asprintf(&p, "%s%%", path) == -1 ) {
02067 throw ConfigurationException("search: could not allocate component string");
02068 }
02069
02070 if ( sqlite3_prepare(db, SQL_SELECT_COMPLETE, -1, &stmt, &tail) != SQLITE_OK ) {
02071 free(p);
02072 throw ConfigurationException("begin: Preparation SQL failed");
02073 }
02074 if ( sqlite3_bind_text(stmt, 1, p, -1, NULL) != SQLITE_OK ) {
02075 free(p);
02076 throw ConfigurationException("begin: Binding text for path failed (1)");
02077 }
02078 if ( sqlite3_bind_text(stmt, 2, p, -1, NULL) != SQLITE_OK ) {
02079 free(p);
02080 throw ConfigurationException("begin: Binding text for path failed (2)");
02081 }
02082
02083 return new SQLiteValueIterator(stmt, p);
02084 }
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096 SQLiteConfiguration::SQLiteValueIterator::SQLiteValueIterator(::sqlite3_stmt *stmt, void *p)
02097 {
02098 __stmt = stmt;
02099 __p = p;
02100 }
02101
02102
02103
02104 SQLiteConfiguration::SQLiteValueIterator::~SQLiteValueIterator()
02105 {
02106 if ( __stmt != NULL ) {
02107 sqlite3_finalize(__stmt);
02108 __stmt = NULL;
02109 }
02110 if ( __p != NULL ) {
02111 free(__p);
02112 }
02113 }
02114
02115
02116
02117
02118
02119
02120 bool
02121 SQLiteConfiguration::SQLiteValueIterator::next()
02122 {
02123 if ( __stmt == NULL) return false;
02124
02125 if (sqlite3_step(__stmt) == SQLITE_ROW ) {
02126 return true;
02127 } else {
02128 sqlite3_finalize(__stmt);
02129 __stmt = NULL;
02130 return false;
02131 }
02132 }
02133
02134
02135
02136
02137
02138
02139 bool
02140 SQLiteConfiguration::SQLiteValueIterator::valid()
02141 {
02142 return ( __stmt != NULL);
02143 }
02144
02145
02146
02147
02148
02149 const char *
02150 SQLiteConfiguration::SQLiteValueIterator::path()
02151 {
02152 return (const char *)sqlite3_column_text(__stmt, 0);
02153 }
02154
02155
02156
02157
02158
02159 const char *
02160 SQLiteConfiguration::SQLiteValueIterator::type()
02161 {
02162 return (const char *)sqlite3_column_text(__stmt, 1);
02163 }
02164
02165
02166
02167
02168
02169 bool
02170 SQLiteConfiguration::SQLiteValueIterator::is_float()
02171 {
02172 return (strcmp("float", (const char *)sqlite3_column_text(__stmt, 1)) == 0);
02173 }
02174
02175
02176
02177
02178
02179 bool
02180 SQLiteConfiguration::SQLiteValueIterator::is_uint()
02181 {
02182 return (strcmp("unsigned int", (const char *)sqlite3_column_text(__stmt, 1)) == 0);
02183 }
02184
02185
02186
02187
02188 bool
02189 SQLiteConfiguration::SQLiteValueIterator::is_int()
02190 {
02191 return (strcmp("int", (const char *)sqlite3_column_text(__stmt, 1)) == 0);
02192 }
02193
02194
02195
02196
02197
02198 bool
02199 SQLiteConfiguration::SQLiteValueIterator::is_bool()
02200 {
02201 return (strcmp("bool", (const char *)sqlite3_column_text(__stmt, 1)) == 0);
02202 }
02203
02204
02205
02206
02207
02208 bool
02209 SQLiteConfiguration::SQLiteValueIterator::is_string()
02210 {
02211 return (strcmp("string", (const char *)sqlite3_column_text(__stmt, 1)) == 0);
02212 }
02213
02214 bool
02215 SQLiteConfiguration::SQLiteValueIterator::is_default()
02216 {
02217 return (sqlite3_column_int(__stmt, 4) == 1);
02218 }
02219
02220
02221
02222
02223
02224 float
02225 SQLiteConfiguration::SQLiteValueIterator::get_float()
02226 {
02227 return (float)sqlite3_column_double(__stmt, 2);
02228 }
02229
02230
02231
02232
02233
02234 unsigned int
02235 SQLiteConfiguration::SQLiteValueIterator::get_uint()
02236 {
02237 int i = sqlite3_column_int(__stmt, 2);
02238 if( i < 0 ) {
02239 return 0;
02240 } else {
02241 return i;
02242 }
02243 }
02244
02245
02246
02247
02248
02249 int
02250 SQLiteConfiguration::SQLiteValueIterator::get_int()
02251 {
02252 return sqlite3_column_int(__stmt, 2);
02253 }
02254
02255
02256
02257
02258 bool
02259 SQLiteConfiguration::SQLiteValueIterator::get_bool()
02260 {
02261 return (sqlite3_column_int(__stmt, 2) != 0);
02262 }
02263
02264
02265
02266
02267 std::string
02268 SQLiteConfiguration::SQLiteValueIterator::get_string()
02269 {
02270 return (const char *)sqlite3_column_text(__stmt, 2);
02271 }
02272
02273
02274
02275
02276
02277 std::string
02278 SQLiteConfiguration::SQLiteValueIterator::get_as_string()
02279 {
02280 return (const char *)sqlite3_column_text(__stmt, 2);
02281 }
02282
02283
02284
02285
02286 std::string
02287 SQLiteConfiguration::SQLiteValueIterator::get_comment()
02288 {
02289 const char *c = (const char *)sqlite3_column_text(__stmt, 3);
02290 return c ? c : "";
02291 }
02292
02293
02294
02295
02296
02297
02298
02299 std::string
02300 SQLiteConfiguration::SQLiteValueIterator::get_modtype()
02301 {
02302 const char *c = (const char *)sqlite3_column_text(__stmt, 4);
02303 return c ? c : "";
02304 }
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315 std::string
02316 SQLiteConfiguration::SQLiteValueIterator::get_oldvalue()
02317 {
02318 const char *c = (const char *)sqlite3_column_text(__stmt, 5);
02319 return c ? c : "";
02320 }
02321
02322
02323 }