From 0d0f36ae5292c918042b843961d402056076b9a8 Mon Sep 17 00:00:00 2001 From: Felix Perktold Date: Wed, 22 Jul 2026 03:17:51 +0200 Subject: init --- db_init.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 db_init.c (limited to 'db_init.c') diff --git a/db_init.c b/db_init.c new file mode 100644 index 0000000..b3a93db --- /dev/null +++ b/db_init.c @@ -0,0 +1,54 @@ +#include +#include +#include "db_init.h" + +static const char *SCHEMA = + "PRAGMA journal_mode = WAL;" + "PRAGMA busy_timeout = 5000;" + "CREATE TABLE IF NOT EXISTS urls (" + " id INTEGER PRIMARY KEY," + " url TEXT UNIQUE NOT NULL," + " status TEXT NOT NULL DEFAULT 'pending'" + " CHECK (status IN ('pending','in_progress','done','failed','skipped'))" + ");" + "CREATE INDEX IF NOT EXISTS idx_urls_status ON urls(status);" + "CREATE TABLE IF NOT EXISTS links (" + " from_id INTEGER NOT NULL REFERENCES urls(id)," + " to_id INTEGER NOT NULL REFERENCES urls(id)," + " UNIQUE(from_id, to_id)" + ");" + /* crash recovery: anything left mid-fetch from a previous run goes back to pending */ + "UPDATE urls SET status = 'pending' WHERE status = 'in_progress';"; + +/* Opens (creating if needed) and initializes the DB. Returns NULL on failure. */ +sqlite3 *db_init(const char *path) { + sqlite3 *db; + if (sqlite3_open(path, &db) != SQLITE_OK) { + fprintf(stderr, "db_init: cannot open %s: %s\n", path, sqlite3_errmsg(db)); + sqlite3_close(db); + return NULL; + } + + char *err = NULL; + if (sqlite3_exec(db, SCHEMA, NULL, NULL, &err) != SQLITE_OK) { + fprintf(stderr, "db_init: schema error: %s\n", err); + sqlite3_free(err); + sqlite3_close(db); + return NULL; + } + + return db; +} + +/* Each worker thread should open its own connection with the same PRAGMAs + * (WAL is persisted in the file, but busy_timeout is per-connection): */ +sqlite3 *db_open_worker(const char *path) { + sqlite3 *db; + if (sqlite3_open(path, &db) != SQLITE_OK) { + fprintf(stderr, "db_open_worker: cannot open %s: %s\n", path, sqlite3_errmsg(db)); + sqlite3_close(db); + return NULL; + } + sqlite3_exec(db, "PRAGMA busy_timeout = 5000;", NULL, NULL, NULL); + return db; +} -- cgit v1.2.3