#include "frame.pb.h"
#include <string>
+#include <unordered_set>
using namespace std;
exit(1);
}
+ // Set an effectively infinite timeout for waiting for write locks;
+ // if we get SQLITE_LOCKED, we just exit out, so this is much better.
+ ret = sqlite3_busy_timeout(db, 3600000);
+ if (ret != SQLITE_OK) {
+ fprintf(stderr, "sqlite3_busy_timeout: %s\n", sqlite3_errmsg(db));
+ exit(1);
+ }
+
sqlite3_exec(db, R"(
CREATE TABLE IF NOT EXISTS state (state BLOB);
- )", nullptr, nullptr, nullptr); // Ignore errors.
+ )",
+ nullptr, nullptr, nullptr); // Ignore errors.
+
+ sqlite3_exec(db, "CREATE UNIQUE INDEX only_one_state ON state (1);", nullptr, nullptr, nullptr); // Ignore errors.
sqlite3_exec(db, R"(
CREATE TABLE IF NOT EXISTS settings (settings BLOB);
- )", nullptr, nullptr, nullptr); // Ignore errors.
+ )",
+ nullptr, nullptr, nullptr); // Ignore errors.
+
+ sqlite3_exec(db, "CREATE UNIQUE INDEX only_one_settings ON settings (1);", nullptr, nullptr, nullptr); // Ignore errors.
sqlite3_exec(db, R"(
DROP TABLE file;
- )", nullptr, nullptr, nullptr); // Ignore errors.
+ )",
+ nullptr, nullptr, nullptr); // Ignore errors.
sqlite3_exec(db, R"(
DROP TABLE frame;
- )", nullptr, nullptr, nullptr); // Ignore errors.
+ )",
+ nullptr, nullptr, nullptr); // Ignore errors.
sqlite3_exec(db, R"(
CREATE TABLE IF NOT EXISTS filev2 (
size BIGINT NOT NULL,
frames BLOB NOT NULL
);
- )", nullptr, nullptr, nullptr); // Ignore errors.
+ )",
+ nullptr, nullptr, nullptr); // Ignore errors.
sqlite3_exec(db, "PRAGMA journal_mode=WAL", nullptr, nullptr, nullptr); // Ignore errors.
sqlite3_exec(db, "PRAGMA synchronous=NORMAL", nullptr, nullptr, nullptr); // Ignore errors.
exit(1);
}
- ret = sqlite3_exec(db, "DELETE FROM state", nullptr, nullptr, nullptr);
- if (ret != SQLITE_OK) {
- fprintf(stderr, "DELETE: %s\n", sqlite3_errmsg(db));
- exit(1);
- }
-
sqlite3_stmt *stmt;
- ret = sqlite3_prepare_v2(db, "INSERT INTO state VALUES (?)", -1, &stmt, 0);
+ ret = sqlite3_prepare_v2(db, "REPLACE INTO state VALUES (?)", -1, &stmt, 0);
if (ret != SQLITE_OK) {
- fprintf(stderr, "INSERT prepare: %s\n", sqlite3_errmsg(db));
+ fprintf(stderr, "REPLACE prepare: %s\n", sqlite3_errmsg(db));
exit(1);
}
ret = sqlite3_step(stmt);
if (ret == SQLITE_ROW) {
- fprintf(stderr, "INSERT step: %s\n", sqlite3_errmsg(db));
+ fprintf(stderr, "REPLACE step: %s\n", sqlite3_errmsg(db));
exit(1);
}
ret = sqlite3_finalize(stmt);
if (ret != SQLITE_OK) {
- fprintf(stderr, "INSERT finalize: %s\n", sqlite3_errmsg(db));
+ fprintf(stderr, "REPLACE finalize: %s\n", sqlite3_errmsg(db));
exit(1);
}
exit(1);
}
- ret = sqlite3_exec(db, "DELETE FROM settings", nullptr, nullptr, nullptr);
- if (ret != SQLITE_OK) {
- fprintf(stderr, "DELETE: %s\n", sqlite3_errmsg(db));
- exit(1);
- }
-
sqlite3_stmt *stmt;
- ret = sqlite3_prepare_v2(db, "INSERT INTO settings VALUES (?)", -1, &stmt, 0);
+ ret = sqlite3_prepare_v2(db, "REPLACE INTO settings VALUES (?)", -1, &stmt, 0);
if (ret != SQLITE_OK) {
- fprintf(stderr, "INSERT prepare: %s\n", sqlite3_errmsg(db));
+ fprintf(stderr, "REPLACE prepare: %s\n", sqlite3_errmsg(db));
exit(1);
}
ret = sqlite3_step(stmt);
if (ret == SQLITE_ROW) {
- fprintf(stderr, "INSERT step: %s\n", sqlite3_errmsg(db));
+ fprintf(stderr, "REPLACE step: %s\n", sqlite3_errmsg(db));
exit(1);
}
ret = sqlite3_finalize(stmt);
if (ret != SQLITE_OK) {
- fprintf(stderr, "INSERT finalize: %s\n", sqlite3_errmsg(db));
+ fprintf(stderr, "REPLACE finalize: %s\n", sqlite3_errmsg(db));
exit(1);
}
// Delete any existing instances with this filename.
sqlite3_stmt *stmt;
- ret = sqlite3_prepare_v2(db, "DELETE FROM filev2 WHERE filename=?", -1, &stmt, 0);
- if (ret != SQLITE_OK) {
- fprintf(stderr, "DELETE prepare: %s\n", sqlite3_errmsg(db));
- exit(1);
- }
-
- sqlite3_bind_text(stmt, 1, filename.data(), filename.size(), SQLITE_STATIC);
-
- ret = sqlite3_step(stmt);
- if (ret == SQLITE_ROW) {
- fprintf(stderr, "DELETE step: %s\n", sqlite3_errmsg(db));
- exit(1);
- }
-
- ret = sqlite3_finalize(stmt);
- if (ret != SQLITE_OK) {
- fprintf(stderr, "DELETE finalize: %s\n", sqlite3_errmsg(db));
- exit(1);
- }
-
// Create the protobuf blob for the new row.
FileContentsProto file_contents;
unordered_set<unsigned> seen_stream_idx; // Usually only one.
file_contents.SerializeToString(&serialized);
// Insert the new row.
- ret = sqlite3_prepare_v2(db, "INSERT INTO filev2 (filename, size, frames) VALUES (?, ?, ?)", -1, &stmt, 0);
+ ret = sqlite3_prepare_v2(db, "REPLACE INTO filev2 (filename, size, frames) VALUES (?, ?, ?)", -1, &stmt, 0);
if (ret != SQLITE_OK) {
fprintf(stderr, "INSERT prepare: %s\n", sqlite3_errmsg(db));
exit(1);
ret = sqlite3_step(stmt);
if (ret == SQLITE_ROW) {
- fprintf(stderr, "INSERT step: %s\n", sqlite3_errmsg(db));
+ fprintf(stderr, "REPLACE step: %s\n", sqlite3_errmsg(db));
exit(1);
}
ret = sqlite3_finalize(stmt);
if (ret != SQLITE_OK) {
- fprintf(stderr, "INSERT finalize: %s\n", sqlite3_errmsg(db));
+ fprintf(stderr, "REPLACE finalize: %s\n", sqlite3_errmsg(db));
exit(1);
}
ret = sqlite3_exec(db, R"(
CREATE TEMPORARY TABLE used_filenames ( filename VARCHAR NOT NULL PRIMARY KEY )
- )", nullptr, nullptr, nullptr);
+ )",
+ nullptr, nullptr, nullptr);
if (ret != SQLITE_OK) {
fprintf(stderr, "CREATE TEMPORARY TABLE: %s\n", sqlite3_errmsg(db));
ret = sqlite3_exec(db, R"(
DELETE FROM filev2 WHERE filename NOT IN ( SELECT filename FROM used_filenames )
- )", nullptr, nullptr, nullptr);
+ )",
+ nullptr, nullptr, nullptr);
if (ret != SQLITE_OK) {
fprintf(stderr, "DELETE: %s\n", sqlite3_errmsg(db));
ret = sqlite3_exec(db, R"(
DROP TABLE used_filenames
- )", nullptr, nullptr, nullptr);
+ )",
+ nullptr, nullptr, nullptr);
if (ret != SQLITE_OK) {
fprintf(stderr, "DROP TABLE: %s\n", sqlite3_errmsg(db));