-- FROZEN FIXTURE. querylog.db schema version 1: byte-for-byte the `ddl` text of
-- `src/storage/querylog_schema.zig`, which is the schema the 0.0.12 and 0.0.13
-- binaries created and the one version 1 names.
--
-- IMMUTABLE once released. The release gate byte-compares this file against the
-- previous tag and fails the cut on any edit, because it is the starting point
-- every future migration is proved against: editing it would prove a migration
-- against a file no operator ever had. A new schema version ships a NEW pair.
--
-- The `PRAGMA user_version` stamp is deliberately NOT part of this file. The
-- loader applies it, which is what lets one fixture serve both the version-1
-- stamp and the 0.0.12/0.0.13 legacy fingerprint.

CREATE TABLE domains (
    id INTEGER PRIMARY KEY,
    domain TEXT NOT NULL UNIQUE
);

CREATE TABLE query_log (
    id INTEGER PRIMARY KEY,
    timestamp INTEGER NOT NULL,
    domain_id INTEGER NOT NULL REFERENCES domains(id),
    client_ip TEXT NOT NULL,            -- text, not a FK: log rows are immutable facts
    qtype INTEGER,
    blocked INTEGER NOT NULL,
    response_time_us INTEGER,
    cache_hit INTEGER,
    upstream TEXT,
    qclass INTEGER NOT NULL,
    rcode INTEGER NOT NULL,
    group_id INTEGER,                   -- text/id pairs, not FKs: a renamed
    group_name TEXT,                    -- group must not rewrite history
    policy_action TEXT NOT NULL,
    policy_reason TEXT NOT NULL,
    matched TEXT,
    source_id INTEGER,
    source_name TEXT,
    cname_target TEXT,
    safe_search_target TEXT,
    route_kind TEXT NOT NULL,
    forward_zone TEXT,
    CHECK (rcode BETWEEN 0 AND 4095)    -- twelve bits (RFC 6891 6.1.3)
);
CREATE INDEX idx_query_log_ts ON query_log(timestamp);
CREATE INDEX idx_query_log_client ON query_log(client_ip);
CREATE INDEX idx_query_log_domain ON query_log(domain_id);

CREATE TABLE querylog_meta (
    id INTEGER PRIMARY KEY CHECK (id = 1),   -- one row, enforced by the schema
    created_at INTEGER NOT NULL,
    available_since INTEGER NOT NULL
);
INSERT INTO querylog_meta (id, created_at, available_since)
VALUES (1, unixepoch(), unixepoch() + 1);

CREATE TABLE bucket_totals (
    bucket INTEGER PRIMARY KEY,
    queries INTEGER NOT NULL,
    blocked INTEGER NOT NULL,
    cached INTEGER NOT NULL,
    rt_sum INTEGER NOT NULL,     -- sum(response_time_us) over timed rows
    rt_count INTEGER NOT NULL    -- count(response_time_us)
) WITHOUT ROWID;

CREATE TABLE bucket_clients (
    bucket INTEGER NOT NULL,
    client_ip TEXT NOT NULL,
    queries INTEGER NOT NULL,
    PRIMARY KEY (bucket, client_ip)
) WITHOUT ROWID;

CREATE TABLE bucket_types (
    bucket INTEGER NOT NULL,
    qtype INTEGER NOT NULL,      -- -1 encodes a NULL qtype, losslessly
    count INTEGER NOT NULL,
    PRIMARY KEY (bucket, qtype)
) WITHOUT ROWID;

CREATE TABLE bucket_routes (
    bucket INTEGER NOT NULL,
    route_kind TEXT NOT NULL,
    source_present INTEGER NOT NULL,  -- 0: source NULL; 1: source = source_text
    source_text TEXT NOT NULL,        -- '' when source_present = 0
    count INTEGER NOT NULL,
    PRIMARY KEY (bucket, route_kind, source_present, source_text),
    CHECK (source_present IN (0, 1)),
    CHECK (source_present = 1 OR source_text = '')
) WITHOUT ROWID;
