schema: collapse config.db to a single baseline, ddl_v1 stays editable until v0.1
This commit is contained in:
@@ -91,7 +91,7 @@ Two SQLite files with opposite write profiles, isolated from each other:
|
||||
|
||||
### 3.7 Upgrades: Auto-Migration (Decision J)
|
||||
|
||||
- `config.db`: numbered, sequential SQL migration steps compiled into the binary. At startup: read schema version row, apply newer steps inside a transaction, continue. Operator upgrade = install binary, restart.
|
||||
- `config.db`: numbered, sequential SQL migration steps compiled into the binary. At startup: read schema version row, apply newer steps inside a transaction, continue. Operator upgrade = install binary, restart. Before v0.1 the list holds one step — the baseline of §11.2, edited in place — because nxdns has no installs and a step exists only to reconcile a database somebody already has.
|
||||
- `querylog.db`: **no migrations.** On schema mismatch: rename aside, recreate fresh.
|
||||
|
||||
### 3.8 Blocklist Storage (Decision A)
|
||||
@@ -105,7 +105,7 @@ Blocklist domains are **not** stored in SQLite — they are a cache of re-downlo
|
||||
|
||||
### 3.9 Rule Model (Decision B)
|
||||
|
||||
Rule kinds: `exact`, parent-walk (implicit via candidate chain), `wildcard` (`*` segment patterns, e.g. `*.doubleclick.net`, `ads.*.example.com`), `regex` (the linear-time engine of `filter/regex.zig`, matched unanchored against the whole normalized name). Actions: `allow` | `block`. Kind is an explicit column, which is what let the third kind arrive as one migration step rather than a schema break. A regex pattern is stored exactly as written — it is not a name, so it is never lowercased or dot-stripped — and is compiled at both edges: `config/validate.zig` refuses a bad one with the limit it hit, and `filter/rules.zig` compiles it once per snapshot.
|
||||
Rule kinds: `exact`, parent-walk (implicit via candidate chain), `wildcard` (`*` segment patterns, e.g. `*.doubleclick.net`, `ads.*.example.com`), `regex` (the linear-time engine of `filter/regex.zig`, matched unanchored against the whole normalized name). Actions: `allow` | `block`. Kind is an explicit column, so a fourth kind widens one `CHECK` and touches no other table. A regex pattern is stored exactly as written — it is not a name, so it is never lowercased or dot-stripped — and is compiled at both edges: `config/validate.zig` refuses a bad one with the limit it hit, and `filter/rules.zig` compiles it once per snapshot.
|
||||
|
||||
### 3.10 Filtering Precedence
|
||||
|
||||
@@ -364,13 +364,14 @@ Per-group boolean. Rewrites known engine domains to their safe-search CNAME targ
|
||||
|
||||
### 11.2 config.db Schema (v1 baseline)
|
||||
|
||||
The DDL below is the **version 1** schema this plan froze, kept for the table
|
||||
shapes it argues for. It is not the live schema and must not be implemented
|
||||
against: that is `src/storage/config_schema.zig` plus the steps in
|
||||
`src/storage/migrations.zig`, currently at **version 4**. The steps since v1 add
|
||||
`upstreams.tls_name` (2), `blocklist_sources.exception_count` (3), and the
|
||||
`regex` rule kind (4) — so the `kind` CHECK below admits two of the three kinds
|
||||
the database now accepts, lacking `regex`.
|
||||
The DDL below is the live schema, kept byte-identical to
|
||||
`src/storage/config_schema.zig`. `src/storage/migrations.zig` carries it as its
|
||||
one and only step, so a database is at **version 1** or it does not exist.
|
||||
|
||||
Until nxdns reaches v0.1 this baseline is **editable**: a schema change edits
|
||||
this section and `config_schema.zig` together and adds no migration step. nxdns
|
||||
has no installs, so there is no database for a step to reconcile. At v0.1 the
|
||||
baseline freezes and every later change becomes an append-only step.
|
||||
|
||||
```sql
|
||||
CREATE TABLE schema_version (version INTEGER NOT NULL);
|
||||
@@ -403,7 +404,8 @@ CREATE TABLE upstreams (
|
||||
id INTEGER PRIMARY KEY,
|
||||
url TEXT NOT NULL UNIQUE,
|
||||
priority INTEGER NOT NULL DEFAULT 100,
|
||||
enabled INTEGER NOT NULL DEFAULT 1
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
tls_name TEXT NOT NULL DEFAULT '' -- DoT verification name; empty verifies against the url host
|
||||
);
|
||||
|
||||
CREATE TABLE blocklist_sources (
|
||||
@@ -415,6 +417,7 @@ CREATE TABLE blocklist_sources (
|
||||
last_updated INTEGER,
|
||||
domain_count INTEGER NOT NULL DEFAULT 0,
|
||||
wildcard_count INTEGER NOT NULL DEFAULT 0,
|
||||
exception_count INTEGER NOT NULL DEFAULT 0,
|
||||
skipped_regex_count INTEGER NOT NULL DEFAULT 0,
|
||||
checksum TEXT
|
||||
);
|
||||
@@ -429,7 +432,7 @@ CREATE TABLE rules (
|
||||
id INTEGER PRIMARY KEY,
|
||||
group_id INTEGER NOT NULL REFERENCES groups(id) ON DELETE CASCADE,
|
||||
pattern TEXT NOT NULL,
|
||||
kind TEXT NOT NULL CHECK(kind IN ('exact','wildcard')),
|
||||
kind TEXT NOT NULL CHECK(kind IN ('exact','wildcard','regex')),
|
||||
action TEXT NOT NULL CHECK(action IN ('allow','block')),
|
||||
created_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user