85 lines
2.8 KiB
Rust
85 lines
2.8 KiB
Rust
|
|
//! SQL strings for the current schema. Versioned; [`migrate`](super::migrate)
|
||
|
|
//! drives the upgrade path.
|
||
|
|
|
||
|
|
/// Pragmas applied on every connection open. Tuned for write throughput during
|
||
|
|
/// indexing; a clean shutdown re-enables journal_mode/synchronous via
|
||
|
|
/// [`super::repo::checkpoint_and_close`].
|
||
|
|
pub const PRAGMAS_FAST: &str = "
|
||
|
|
PRAGMA journal_mode = OFF;
|
||
|
|
PRAGMA synchronous = 0;
|
||
|
|
PRAGMA cache_size = 10000;
|
||
|
|
PRAGMA temp_store = MEMORY;
|
||
|
|
PRAGMA foreign_keys = ON;
|
||
|
|
";
|
||
|
|
|
||
|
|
/// The full current schema. Applied by [`migrate::open_and_migrate`] when
|
||
|
|
/// the DB is fresh or has been wiped during upgrade.
|
||
|
|
///
|
||
|
|
/// FTS5 is a *regular* (non-contentless) virtual table so `snippet()` and
|
||
|
|
/// `highlight()` can read the stored text. This also means there is no
|
||
|
|
/// separate `documents` table — FTS5 *is* the text store.
|
||
|
|
pub const SCHEMA_CURRENT: &str = r#"
|
||
|
|
CREATE TABLE schema_info (
|
||
|
|
key TEXT PRIMARY KEY,
|
||
|
|
value TEXT NOT NULL
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE files (
|
||
|
|
id INTEGER PRIMARY KEY,
|
||
|
|
name TEXT NOT NULL,
|
||
|
|
path TEXT NOT NULL UNIQUE,
|
||
|
|
parent TEXT NOT NULL,
|
||
|
|
size INTEGER NOT NULL,
|
||
|
|
mtime INTEGER NOT NULL,
|
||
|
|
inode INTEGER,
|
||
|
|
device_id INTEGER,
|
||
|
|
mime TEXT,
|
||
|
|
type INTEGER NOT NULL DEFAULT 0,
|
||
|
|
basic_state INTEGER NOT NULL DEFAULT 0, -- 0=pending 1=done 2=failed
|
||
|
|
content_state INTEGER NOT NULL DEFAULT 0, -- 0=pending 1=done 2=failed 3=n/a
|
||
|
|
failure_msg TEXT,
|
||
|
|
hash BLOB
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX idx_files_parent ON files(parent);
|
||
|
|
CREATE INDEX idx_files_mtime ON files(mtime);
|
||
|
|
CREATE INDEX idx_files_type ON files(type);
|
||
|
|
CREATE INDEX idx_files_mime ON files(mime);
|
||
|
|
CREATE INDEX idx_files_hash ON files(hash);
|
||
|
|
CREATE INDEX idx_files_content_pending ON files(id) WHERE content_state = 0;
|
||
|
|
|
||
|
|
CREATE TABLE properties (
|
||
|
|
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
||
|
|
key TEXT NOT NULL,
|
||
|
|
value TEXT NOT NULL,
|
||
|
|
PRIMARY KEY (file_id, key)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE failed_files (
|
||
|
|
file_id INTEGER PRIMARY KEY REFERENCES files(id) ON DELETE CASCADE,
|
||
|
|
reason TEXT,
|
||
|
|
ts INTEGER NOT NULL
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE config_validation (
|
||
|
|
key TEXT PRIMARY KEY,
|
||
|
|
value TEXT NOT NULL
|
||
|
|
);
|
||
|
|
"#;
|
||
|
|
|
||
|
|
/// FTS5 virtual table DDL. Separate because the tokenizer is config-driven.
|
||
|
|
///
|
||
|
|
/// Regular (not contentless, not external-content) FTS5: the table stores
|
||
|
|
/// its own text, which enables `snippet()`/`highlight()` and makes row-level
|
||
|
|
/// INSERT/UPDATE/DELETE work with normal SQL semantics. `rowid` is supplied
|
||
|
|
/// by the caller and must equal `files.id`.
|
||
|
|
pub fn fts_create_sql(tokenizer: &str) -> String {
|
||
|
|
format!(
|
||
|
|
"CREATE VIRTUAL TABLE searchabletext USING fts5(\
|
||
|
|
name, text, properties, \
|
||
|
|
tokenize='{}'\
|
||
|
|
);",
|
||
|
|
tokenizer.replace('\'', "''")
|
||
|
|
)
|
||
|
|
}
|