aboutsummaryrefslogtreecommitdiff
path: root/src/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/db.c')
-rw-r--r--src/db.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/db.c b/src/db.c
index 627efbc..c809bea 100644
--- a/src/db.c
+++ b/src/db.c
@@ -206,6 +206,12 @@ static const char SCHEMA_V1[] =
" UNIQUE (org_id, id),"
" UNIQUE (org_id, sha256, filename)"
") STRICT;\n"
+ "CREATE TRIGGER attachments_no_update BEFORE UPDATE ON attachments BEGIN"
+ " SELECT RAISE(ABORT, 'attachments are append-only');"
+ "END;\n"
+ "CREATE TRIGGER attachments_no_delete BEFORE DELETE ON attachments BEGIN"
+ " SELECT RAISE(ABORT, 'attachments are append-only');"
+ "END;\n"
"CREATE TABLE voucher_attachments ("
" org_id INTEGER NOT NULL,"
@@ -433,6 +439,25 @@ static int db_upgrade_v6(sqlite3 *db, char **err)
" DEFAULT ''", err);
}
+/* v7: attachments are immutable too — the content-addressed underlag may
+ never be updated or deleted, only linked/unlinked. */
+static int db_upgrade_v7(sqlite3 *db, char **err)
+{
+ if (db_exec(db,
+ "CREATE TRIGGER IF NOT EXISTS attachments_no_update"
+ " BEFORE UPDATE ON attachments BEGIN"
+ " SELECT RAISE(ABORT, 'attachments are append-only');"
+ "END",
+ err) != 0)
+ return -1;
+ return db_exec(db,
+ "CREATE TRIGGER IF NOT EXISTS attachments_no_delete"
+ " BEFORE DELETE ON attachments BEGIN"
+ " SELECT RAISE(ABORT, 'attachments are append-only');"
+ "END",
+ err);
+}
+
static int db_upgrade(sqlite3 *db, int from, char **err)
{
if (db_exec(db, "BEGIN IMMEDIATE", err) != 0)
@@ -457,6 +482,10 @@ static int db_upgrade(sqlite3 *db, int from, char **err)
db_exec(db, "ROLLBACK", NULL);
return -1;
}
+ if (from < 7 && db_upgrade_v7(db, err) != 0) {
+ db_exec(db, "ROLLBACK", NULL);
+ return -1;
+ }
char *sql = sqlite3_mprintf(
"UPDATE meta SET value='%d' WHERE key='schema_version'",
BOKF_SCHEMA_VERSION);