use std::num::NonZeroU32;
use rusqlite::{config::DbConfig, Transaction};
use super::connection::ConnectionOpener;
#[derive(Debug)]
pub struct Schema;
impl ConnectionOpener for Schema {
const MAX_SCHEMA_VERSION: u32 = 1;
type Error = SchemaError;
fn setup(conn: &mut rusqlite::Connection) -> Result<(), Self::Error> {
conn.execute_batch(
"
-- we unconditionally want write-ahead-logging mode
PRAGMA journal_mode = WAL;
-- Sync at the most criticial moments, but not with every write
PRAGMA synchronous = NORMAL;
-- limit size of the journal. TODO(bug 2049290): value currently arbitrary.
-- needs refinement.
PRAGMA journal_size_limit = 512000; -- 512 KB.
-- We don't care about temp tables being persisted to disk
PRAGMA temp_store = MEMORY;
-- allows adding incremental cleanup later
PRAGMA auto_vacuum = INCREMENTAL;
",
)?;
conn.set_db_config(DbConfig::SQLITE_DBCONFIG_DEFENSIVE, true)?;
conn.set_db_config(DbConfig::SQLITE_DBCONFIG_DQS_DML, false)?;
conn.set_db_config(DbConfig::SQLITE_DBCONFIG_DQS_DDL, false)?;
conn.set_db_config(DbConfig::SQLITE_DBCONFIG_TRUSTED_SCHEMA, true)?;
Ok(())
}
fn create(tx: &mut Transaction<'_>) -> Result<(), Self::Error> {
tx.execute_batch(
"CREATE TABLE telemetry(
id TEXT NOT NULL,
ping TEXT NOT NULL,
lifetime TEXT NOT NULL,
labels TEXT NOT NULL, -- can't be null or ON CONFLICT won't work
value BLOB,
UNIQUE(id, ping, labels)
);",
)?;
Ok(())
}
fn upgrade(_: &mut Transaction<'_>, to_version: NonZeroU32) -> Result<(), Self::Error> {
Err(SchemaError::UnsupportedSchemaVersion(to_version.get()))
}
}
#[derive(thiserror::Error, Debug)]
pub enum SchemaError {
#[error("unsupported schema version: {0}")]
UnsupportedSchemaVersion(u32),
#[error("sqlite: {0}")]
Sqlite(#[from] rusqlite::Error),
}