| 56 | } // namespace |
| 57 | |
| 58 | SqliteLogger::SqliteLogger(const Tree& tree, std::filesystem::path const& filepath, |
| 59 | bool append) |
| 60 | : StatusChangeLogger() // Deferred subscription |
| 61 | { |
| 62 | const auto extension = filepath.filename().extension(); |
| 63 | if(extension != ".db3" && extension != ".btdb") |
| 64 | { |
| 65 | throw RuntimeError("SqliteLogger: the file extension must be [.db3] or [.btdb]"); |
| 66 | } |
| 67 | |
| 68 | enableTransitionToIdle(true); |
| 69 | |
| 70 | // Open database |
| 71 | const int rc = sqlite3_open(filepath.string().c_str(), &db_); |
| 72 | if(rc != SQLITE_OK) |
| 73 | { |
| 74 | throw RuntimeError(std::string("Cannot open database: ") + sqlite3_errmsg(db_)); |
| 75 | } |
| 76 | |
| 77 | // Create tables |
| 78 | execSQL(db_, "CREATE TABLE IF NOT EXISTS Transitions (" |
| 79 | "timestamp INTEGER PRIMARY KEY NOT NULL, " |
| 80 | "session_id INTEGER NOT NULL, " |
| 81 | "node_uid INTEGER NOT NULL, " |
| 82 | "duration INTEGER, " |
| 83 | "state INTEGER NOT NULL," |
| 84 | "extra_data VARCHAR );"); |
| 85 | |
| 86 | execSQL(db_, "CREATE TABLE IF NOT EXISTS Nodes (" |
| 87 | "session_id INTEGER NOT NULL, " |
| 88 | "fullpath VARCHAR, " |
| 89 | "node_uid INTEGER NOT NULL );"); |
| 90 | |
| 91 | execSQL(db_, "CREATE TABLE IF NOT EXISTS Definitions (" |
| 92 | "session_id INTEGER PRIMARY KEY AUTOINCREMENT, " |
| 93 | "date TEXT NOT NULL," |
| 94 | "xml_tree TEXT NOT NULL);"); |
| 95 | |
| 96 | if(!append) |
| 97 | { |
| 98 | execSQL(db_, "DELETE from Transitions;"); |
| 99 | execSQL(db_, "DELETE from Definitions;"); |
| 100 | execSQL(db_, "DELETE from Nodes;"); |
| 101 | } |
| 102 | |
| 103 | // Insert tree definition |
| 104 | auto tree_xml = WriteTreeToXML(tree, true, true); |
| 105 | sqlite3_stmt* stmt = prepareStatement(db_, "INSERT into Definitions (date, xml_tree) " |
| 106 | "VALUES (datetime('now','localtime'),?);"); |
| 107 | sqlite3_bind_text(stmt, 1, tree_xml.c_str(), -1, SQLITE_TRANSIENT); |
| 108 | execStatement(stmt); |
| 109 | |
| 110 | // Get session_id |
| 111 | stmt = prepareStatement(db_, "SELECT MAX(session_id) FROM Definitions LIMIT 1;"); |
| 112 | if(sqlite3_step(stmt) == SQLITE_ROW) |
| 113 | { |
| 114 | session_id_ = sqlite3_column_int(stmt, 0); |
| 115 | } |
nothing calls this directly
no test coverage detected