Complete storage and search foundation
This commit is contained in:
Generated
+1
-1
@@ -77,7 +77,7 @@ checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
|
||||
|
||||
[[package]]
|
||||
name = "app"
|
||||
version = "0.1.26"
|
||||
version = "0.1.32"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rusqlite",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "app"
|
||||
version = "0.1.26"
|
||||
version = "0.1.32"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
license = ""
|
||||
|
||||
+50
-3
@@ -226,6 +226,7 @@ fn open_db(app: &AppHandle) -> Result<Connection, String> {
|
||||
let mut conn = Connection::open(path).map_err(|err| err.to_string())?;
|
||||
migrate(&conn)?;
|
||||
seed(&mut conn)?;
|
||||
sync_search_indexes(&conn)?;
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
@@ -297,6 +298,20 @@ fn migrate(conn: &Connection) -> Result<(), String> {
|
||||
FOREIGN KEY (verse_id) REFERENCES verses(id),
|
||||
FOREIGN KEY (tag_id) REFERENCES tags(id)
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS verses_fts USING fts5(
|
||||
text,
|
||||
reference,
|
||||
content='verses',
|
||||
content_rowid='id'
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_verses_reference ON verses(book, chapter, verse);
|
||||
CREATE INDEX IF NOT EXISTS idx_verse_strongs_strong ON verse_strongs(strong);
|
||||
CREATE INDEX IF NOT EXISTS idx_verse_strongs_verse ON verse_strongs(verse_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_verse_footnotes_verse ON verse_footnotes(verse_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_verse_tags_tag ON verse_tags(tag_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_tags_label ON tags(label);
|
||||
",
|
||||
)
|
||||
.map_err(|err| err.to_string())?;
|
||||
@@ -778,20 +793,28 @@ fn load_verses(conn: &Connection, query: Option<&str>) -> Result<Vec<Verse>, Str
|
||||
|
||||
match query {
|
||||
Some(query) => {
|
||||
let fts_query = search_query_for_fts(query);
|
||||
if fts_query.is_empty() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
let pattern = format!("%{}%", query);
|
||||
let mut stmt = conn
|
||||
.prepare(
|
||||
"
|
||||
SELECT v.id, v.book, v.chapter, v.verse, v.text
|
||||
FROM verses v
|
||||
JOIN verses_fts fts ON fts.rowid = v.id
|
||||
WHERE verses_fts MATCH ?1
|
||||
UNION
|
||||
SELECT id, book, chapter, verse, text
|
||||
FROM verses
|
||||
WHERE text LIKE ?1
|
||||
OR book || ' ' || chapter || ':' || verse LIKE ?1
|
||||
WHERE book || ' ' || chapter || ':' || verse LIKE ?2
|
||||
ORDER BY id
|
||||
",
|
||||
)
|
||||
.map_err(|err| err.to_string())?;
|
||||
let rows = stmt
|
||||
.query_map(params![pattern], row_to_verse_shell)
|
||||
.query_map(params![fts_query, pattern], row_to_verse_shell)
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
for row in rows {
|
||||
@@ -1110,6 +1133,30 @@ fn load_all_tags(conn: &Connection) -> Result<Vec<Tag>, String> {
|
||||
Ok(tags)
|
||||
}
|
||||
|
||||
fn sync_search_indexes(conn: &Connection) -> Result<(), String> {
|
||||
let verse_count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM verses", [], |row| row.get(0))
|
||||
.map_err(|err| err.to_string())?;
|
||||
let fts_count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM verses_fts", [], |row| row.get(0))
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
if verse_count != fts_count {
|
||||
conn.execute("INSERT INTO verses_fts(verses_fts) VALUES('rebuild')", [])
|
||||
.map_err(|err| err.to_string())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn search_query_for_fts(query: &str) -> String {
|
||||
query
|
||||
.split(|char: char| !char.is_ascii_alphanumeric())
|
||||
.filter(|token| !token.is_empty())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
fn looks_like_strongs(query: &str) -> bool {
|
||||
let mut chars = query.chars();
|
||||
matches!(chars.next(), Some('G' | 'g' | 'H' | 'h')) && chars.all(|char| char.is_ascii_digit())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||
"productName": "Libre Study",
|
||||
"version": "0.1.26",
|
||||
"version": "0.1.32",
|
||||
"identifier": "org.librestudy.desktop",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
|
||||
Reference in New Issue
Block a user