Skip to content

Commit

Permalink
sqlite: add fts optimize command
Browse files Browse the repository at this point in the history
This command will free up FTS space. Normally not needed, but if
trying to shrink the size of your database file it can be useful.

More or less equivalent to:

  INSERT INTO ft(ft) VALUES('optimize');

but uses the merge command to divide the task into multiple steps.
  • Loading branch information
jasonish committed Aug 11, 2023
1 parent 2a42697 commit f153bfd
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
38 changes: 37 additions & 1 deletion src/commands/sqlite/fts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ use crate::sqlite::{
use anyhow::Result;
use rusqlite::{params, Transaction};
use serde_json::Value;
use tracing::{info, warn};
use tracing::{debug, info, warn};

pub(super) fn fts(args: &FtsArgs) -> Result<()> {
match &args.command {
FtsCommand::Enable { force, filename } => fts_enable(force, filename),
FtsCommand::Disable { force, filename } => fts_disable(force, filename),
FtsCommand::Check { filename } => fts_check(filename),
FtsCommand::Optimize { filename } => fts_optimize(filename),
}
}

Expand Down Expand Up @@ -83,6 +84,41 @@ fn fts_check(filename: &str) -> Result<()> {
Ok(())
}

fn fts_optimize(filename: &str) -> Result<()> {
let conn = ConnectionBuilder::filename(Some(filename)).open(false)?;

if !conn.has_table("fts")? {
warn!("FTS is not enabled");
return Ok(());
}

let get_total_changes = || -> Result<i64> {
let rows = conn.query_row("select total_changes()", [], |row| {
let count: i64 = row.get(0)?;
Ok(count)
})?;
Ok(rows)
};

let mut last_total_changes = get_total_changes()?;

let mut st = conn.prepare("insert into fts(fts, rank) values ('merge', -500)")?;
st.execute([])?;

loop {
conn.execute("insert into fts(fts, rank) values ('merge', 500)", [])?;
let total_changes = get_total_changes()?;
let changes = total_changes - last_total_changes;
debug!("Modified rows: {changes}");
if changes < 2 {
break;
}
last_total_changes = total_changes;
}

Ok(())
}

fn reindex_fts(tx: &Transaction) -> Result<usize> {
let mut st = tx.prepare("select rowid, timestamp, source from events order by rowid")?;
let mut rows = st.query([])?;
Expand Down
6 changes: 6 additions & 0 deletions src/commands/sqlite/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ enum FtsCommand {
#[arg(value_name = "DB_FILENAME")]
filename: String,
},

/// Optimize FTS data
Optimize {
#[arg(value_name = "DB_FILENAME")]
filename: String,
},
}

#[derive(Debug, Parser)]
Expand Down

0 comments on commit f153bfd

Please sign in to comment.