From 549ec338105e849ded8e779ea6ad6fe9b92a52b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 26 Feb 2020 11:37:18 +0100 Subject: [PATCH 01/33] database: Allow marking the database for a reindex. --- src/database/mod.rs | 19 ++++++++++------- src/database/static_methods.rs | 37 ++++++++++++++++++++++++++++++++-- src/error.rs | 3 +++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index e6a6113..1994169 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -49,7 +49,7 @@ use crate::events::CheckpointDirection; #[cfg(test)] use crate::EVENT; -const DATABASE_VERSION: i64 = 2; +const DATABASE_VERSION: i64 = 3; pub(crate) enum ThreadMessage { Event((Event, Profile)), @@ -98,13 +98,13 @@ impl Database { let manager = SqliteConnectionManager::file(&db_path); let pool = r2d2::Pool::new(manager)?; - let connection = Arc::new(pool.get()?); + let mut connection = pool.get()?; connection.pragma_update(None, "foreign_keys", &1 as &dyn ToSql)?; Database::unlock(&connection, config)?; - let version = match Database::get_version(&connection) { - Ok(v) => v, + let (version, reindex_needed) = match Database::get_version(&mut connection) { + Ok(ret) => ret, Err(e) => return Err(Error::DatabaseOpenError(e.to_string())), }; @@ -114,6 +114,10 @@ impl Database { return Err(Error::DatabaseVersionError); } + if reindex_needed { + return Err(Error::ReindexError) + } + let index = Database::create_index(&path, &config)?; let writer = index.get_writer()?; @@ -129,7 +133,7 @@ impl Database { Ok(Database { path: path.into(), - connection, + connection: Arc::new(connection), pool, _write_thread: t_handle, tx, @@ -869,9 +873,10 @@ fn database_upgrade_v1() { path.pop(); path.pop(); path.push("data/database/v1"); - let db = Database::new(path).unwrap(); + let mut db = Database::new(path).unwrap(); + let mut connection = db.get_connection().unwrap(); - let version = Database::get_version(&db.connection).unwrap(); + let (version, _) = Database::get_version(&mut connection).unwrap(); assert_eq!(version, DATABASE_VERSION); let result = db.search("Hello", &SearchConfig::new()).unwrap(); diff --git a/src/database/static_methods.rs b/src/database/static_methods.rs index 9a82308..bc7ba6b 100644 --- a/src/database/static_methods.rs +++ b/src/database/static_methods.rs @@ -132,7 +132,7 @@ impl Database { Ok(ret) } - pub(crate) fn get_version(connection: &rusqlite::Connection) -> Result { + pub(crate) fn get_version(connection: &mut rusqlite::Connection) -> Result<(i64, bool)> { connection.execute( "CREATE TABLE IF NOT EXISTS version ( id INTEGER NOT NULL PRIMARY KEY CHECK (id = 1), @@ -141,6 +141,19 @@ impl Database { NO_PARAMS, )?; + connection.execute( + "CREATE TABLE IF NOT EXISTS reindex_needed ( + id INTEGER NOT NULL PRIMARY KEY CHECK (id = 1), + reindex_needed BOOL NOT NULL + )", + NO_PARAMS, + )?; + + connection.execute( + "INSERT OR IGNORE INTO reindex_needed ( reindex_needed ) VALUES(?1)", + &[false], + )?; + connection.execute( "INSERT OR IGNORE INTO version ( version ) VALUES(?1)", &[DATABASE_VERSION], @@ -149,6 +162,12 @@ impl Database { let mut version: i64 = connection.query_row("SELECT version FROM version", NO_PARAMS, |row| row.get(0))?; + let mut reindex_needed: bool = connection.query_row( + "SELECT reindex_needed FROM reindex_needed", + NO_PARAMS, + |row| row.get(0), + )?; + // Do database migrations here before bumping the database version. if version == 1 { @@ -169,7 +188,21 @@ impl Database { version = 2; } - Ok(version) + if version == 2 { + let transaction = connection.transaction()?; + + transaction.execute( + "UPDATE reindex_needed SET reindex_needed = ?1", + &[true], + )?; + transaction.execute("UPDATE version SET version = '3'", NO_PARAMS)?; + transaction.commit()?; + + reindex_needed = true; + version = 3; + } + + Ok((version, reindex_needed)) } pub(crate) fn create_tables(conn: &rusqlite::Connection) -> Result<()> { diff --git a/src/error.rs b/src/error.rs index 38d7977..a9cfa1d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -51,6 +51,9 @@ pub enum Error { /// Error signaling that sqlcipher support is missing. #[fail(display = "Sqlcipher error: {}", _0)] SqlCipherError(String), + /// Error indicating that the index needs to be rebuild. + #[fail(display = "Error opening the database, the index needs to be rebuild.")] + ReindexError, } impl From for Error { From 0ae4f35b6867366fee9850a5e6617fbf16236879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Sat, 29 Feb 2020 11:28:29 +0100 Subject: [PATCH 02/33] dirty: Reindex support. --- seshat-node/native/src/lib.rs | 51 ++++++++------- seshat-node/native/src/utils.rs | 34 +++++++++- src/database/mod.rs | 110 +++++++++++++++++++++++++++++++- src/lib.rs | 2 +- 4 files changed, 168 insertions(+), 29 deletions(-) diff --git a/seshat-node/native/src/lib.rs b/seshat-node/native/src/lib.rs index e21a736..e11fee6 100644 --- a/seshat-node/native/src/lib.rs +++ b/seshat-node/native/src/lib.rs @@ -16,41 +16,44 @@ mod tasks; mod utils; use neon::prelude::*; -use seshat::{Config, Database, Language, LoadConfig, LoadDirection, Profile}; +use seshat::{Config, Database, LoadConfig, LoadDirection, Profile}; use crate::tasks::*; use crate::utils::*; pub struct SeshatDatabase(Option); +pub struct DatabaseManager { + path: std::path::PathBuf, + total_events: u64, + completed_events: u64, + config: Config, +} + declare_types! { - pub class Seshat for SeshatDatabase { + pub class Test for DatabaseManager { init(mut cx) { let db_path: String = cx.argument::(0)?.value(); - let mut config = Config::new(); - - if let Some(c) = cx.argument_opt(1) { - let c = c.downcast::().or_throw(&mut cx)?; - - if let Ok(l) = c.get(&mut cx, "language") { - if let Ok(l) = l.downcast::() { - let language = Language::from(l.value().as_ref()); - match language { - Language::Unknown => return cx.throw_type_error( - format!("Unsuported language: {}", l.value()) - ), - _ => {config = config.set_language(&language);} - } - } - } + let args = cx.argument_opt(1); + let config = parse_database_config(&mut cx, args)?; - if let Ok(p) = c.get(&mut cx, "passphrase") { - if let Ok(p) = p.downcast::() { - let passphrase: String = p.value(); - config = config.set_passphrase(passphrase); - } + Ok( + DatabaseManager { + path: db_path.into(), + total_events: 0, + completed_events: 0, + config, } - } + ) + } + } + + pub class Seshat for SeshatDatabase { + init(mut cx) { + let db_path: String = cx.argument::(0)?.value(); + let args = cx.argument_opt(1); + + let config = parse_database_config(&mut cx, args)?; let db = match Database::new_with_config(&db_path, &config) { Ok(db) => db, diff --git a/seshat-node/native/src/utils.rs b/seshat-node/native/src/utils.rs index 2b16143..1f4bd2a 100644 --- a/seshat-node/native/src/utils.rs +++ b/seshat-node/native/src/utils.rs @@ -18,9 +18,41 @@ use neon_serde; use serde_json; use seshat::{ CheckpointDirection, CrawlerCheckpoint, Event, EventType, Profile, Receiver, SearchConfig, - SearchResult, + SearchResult, Config, Language }; +pub(crate) fn parse_database_config( + cx: &mut CallContext, + argument: Option>, +) -> Result { + let mut config = Config::new(); + + if let Some(c) = argument { + let c = c.downcast::().or_throw(&mut *cx)?; + + if let Ok(l) = c.get(&mut *cx, "language") { + if let Ok(l) = l.downcast::() { + let language = Language::from(l.value().as_ref()); + match language { + Language::Unknown => return cx.throw_type_error( + format!("Unsuported language: {}", l.value()) + ), + _ => {config = config.set_language(&language);} + } + } + } + + if let Ok(p) = c.get(&mut *cx, "passphrase") { + if let Ok(p) = p.downcast::() { + let passphrase: String = p.value(); + config = config.set_passphrase(passphrase); + } + } + } + + Ok(config) +} + pub(crate) fn parse_search_object( cx: &mut CallContext, argument: Handle, diff --git a/src/database/mod.rs b/src/database/mod.rs index 1994169..c558ac0 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -29,12 +29,12 @@ use std::sync::Arc; use std::thread; use std::thread::JoinHandle; -use crate::config::{Config, SearchConfig}; +use crate::config::{Config, SearchConfig, LoadConfig}; pub use crate::database::connection::{Connection, DatabaseStats}; pub use crate::database::searcher::{SearchResult, Searcher}; use crate::database::writer::Writer; use crate::error::{Error, Result}; -use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile}; +use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile, SerializedEvent}; use crate::index::{Index, Writer as IndexWriter}; #[cfg(test)] @@ -50,6 +50,7 @@ use crate::events::CheckpointDirection; use crate::EVENT; const DATABASE_VERSION: i64 = 3; +const EVENTS_DB_NAME: &str = "events.db"; pub(crate) enum ThreadMessage { Event((Event, Profile)), @@ -68,6 +69,109 @@ pub struct Database { config: Config, } +pub struct ReadOnlyDatabase { + path: PathBuf, + connection: PooledConnection, + pool: r2d2::Pool, + config: Config, + index_deleted: bool, +} + +impl ReadOnlyDatabase { + /// Open a read-only Seshat database. + /// + /// # Arguments + /// + /// * `path` - The directory where the database will be stored in. This + /// should be an empty directory if a new database should be created. + pub fn new>(path: P) -> Result + where + PathBuf: std::convert::From

, + { + Self::new_with_config(path, &Config::new()) + } + + /// Open a read-only Seshat database with the provided config. + /// + /// # Arguments + /// + /// * `path` - The directory where the database will be stored in. This + /// should be an empty directory if a new database should be created. + /// + /// * `config` - Configuration that changes the behaviour of the database. + pub fn new_with_config>(path: P, config: &Config) -> Result + where + PathBuf: std::convert::From

, + { + let db_path = path.as_ref().join(EVENTS_DB_NAME); + let manager = SqliteConnectionManager::file(&db_path); + let pool = r2d2::Pool::new(manager)?; + + let mut connection = pool.get()?; + connection.pragma_update(None, "foreign_keys", &1 as &dyn ToSql)?; + + Database::unlock(&connection, config)?; + + let (version, _) = match Database::get_version(&mut connection) { + Ok(ret) => ret, + Err(e) => return Err(Error::DatabaseOpenError(e.to_string())), + }; + + Database::create_tables(&connection)?; + + if version != DATABASE_VERSION { + return Err(Error::DatabaseVersionError); + } + + Ok(Self { + path: path.into(), + connection, + pool, + config: config.clone(), + index_deleted: false, + }) + } + + /// Delete the Seshat index, leaving only the events database. + pub fn delete_the_index(&mut self) -> std::io::Result<()> { + for entry in fs::read_dir(&self.path)? { + let entry = entry?; + let path = entry.path(); + + // Skip removing directories, we don't create subdirs in our + // database dir. + if path.is_dir() { + continue + } + + if let Some(file_name) = path.file_name() { + // Skip removing the events database, those will be needed for + // reindexing. + if file_name == EVENTS_DB_NAME { + continue + } + + fs::remove_file(path)? + } + } + self.index_deleted = true; + Ok(()) + } + + pub fn load_file_events( + &self, + load_config: &LoadConfig, + ) -> Result> { + Ok(Database::load_file_events( + &self.connection, + &load_config.room_id, + load_config.limit, + load_config.from_event.as_ref().map(|x| &**x), + &load_config.direction, + )?) + } +} + type WriterRet = (JoinHandle<()>, Sender); impl Database { @@ -94,7 +198,7 @@ impl Database { where PathBuf: std::convert::From

, { - let db_path = path.as_ref().join("events.db"); + let db_path = path.as_ref().join(EVENTS_DB_NAME); let manager = SqliteConnectionManager::file(&db_path); let pool = r2d2::Pool::new(manager)?; diff --git a/src/lib.rs b/src/lib.rs index ac164a7..cba9b23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,7 @@ mod error; mod events; mod index; -pub use database::{Connection, Database, DatabaseStats, SearchResult, Searcher}; +pub use database::{Connection, ReadOnlyDatabase, Database, DatabaseStats, SearchResult, Searcher}; pub use error::{Error, Result}; From ba56da56757d1bd5c28639a5017417c9edb24bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 2 Mar 2020 13:17:43 +0100 Subject: [PATCH 03/33] index: Index the server timestamp and sender. This will allow the index to be searched by the sender or timestamp. --- src/index/mod.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/index/mod.rs b/src/index/mod.rs index 891f347..9259942 100644 --- a/src/index/mod.rs +++ b/src/index/mod.rs @@ -18,9 +18,11 @@ mod encrypted_dir; mod encrypted_stream; mod japanese_tokenizer; +use std::convert::TryInto; use std::path::Path; use std::time::Duration; use tantivy as tv; +use tantivy::chrono::{NaiveDateTime, Utc}; use crate::config::{Config, Language, SearchConfig}; use crate::events::{Event, EventId, EventType}; @@ -75,6 +77,8 @@ pub(crate) struct Index { topic_field: tv::schema::Field, name_field: tv::schema::Field, event_id_field: tv::schema::Field, + sender_field: tv::schema::Field, + date_field: tv::schema::Field, room_id_field: tv::schema::Field, } @@ -84,6 +88,8 @@ pub(crate) struct Writer { pub(crate) topic_field: tv::schema::Field, pub(crate) name_field: tv::schema::Field, pub(crate) event_id_field: tv::schema::Field, + pub(crate) sender_field: tv::schema::Field, + pub(crate) date_field: tv::schema::Field, pub(crate) added_events: usize, pub(crate) commit_timestamp: std::time::Instant, room_id_field: tv::schema::Field, @@ -125,6 +131,18 @@ impl Writer { doc.add_text(self.event_id_field, &event.event_id); doc.add_text(self.room_id_field, &event.room_id); + doc.add_text(self.sender_field, &event.sender); + + let seconds: i64 = event.server_ts / 1000; + let nano_seconds: u32 = ((event.server_ts % 1000) * 1000) + .try_into() + .unwrap_or_default(); + let naive_date = NaiveDateTime::from_timestamp_opt(seconds, nano_seconds); + + if let Some(d) = naive_date { + let date = tv::DateTime::from_utc(d, Utc); + doc.add_date(self.date_field, &date); + } self.inner.add_document(doc); self.added_events += 1; @@ -139,6 +157,10 @@ pub(crate) struct IndexSearcher { pub(crate) topic_field: tv::schema::Field, pub(crate) name_field: tv::schema::Field, pub(crate) room_id_field: tv::schema::Field, + #[used] + pub(crate) sender_field: tv::schema::Field, + #[used] + pub(crate) date_field: tv::schema::Field, pub(crate) event_id_field: tv::schema::Field, } @@ -213,7 +235,11 @@ impl Index { let body_field = schemabuilder.add_text_field("body", text_field_options.clone()); let topic_field = schemabuilder.add_text_field("topic", text_field_options.clone()); let name_field = schemabuilder.add_text_field("name", text_field_options); + + let date_field = schemabuilder.add_date_field("date", tv::schema::INDEXED); + let room_id_field = schemabuilder.add_text_field("room_id", tv::schema::STRING); + let sender_field = schemabuilder.add_text_field("sender", tv::schema::STRING); let event_id_field = schemabuilder.add_text_field("event_id", tv::schema::STORED); @@ -245,6 +271,8 @@ impl Index { topic_field, name_field, event_id_field, + sender_field, + date_field, room_id_field, }) } @@ -312,6 +340,8 @@ impl Index { topic_field: self.topic_field, name_field: self.name_field, room_id_field: self.room_id_field, + sender_field: self.sender_field, + date_field: self.date_field, event_id_field: self.event_id_field, } } @@ -330,6 +360,8 @@ impl Index { name_field: self.name_field, event_id_field: self.event_id_field, room_id_field: self.room_id_field, + sender_field: self.sender_field, + date_field: self.date_field, added_events: 0, commit_timestamp: std::time::Instant::now(), }) From 378238f726c4401c76c415054a71b456fc4b6093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 2 Mar 2020 13:35:56 +0100 Subject: [PATCH 04/33] seshat: Format the repo. --- src/config.rs | 1 + src/database/mod.rs | 8 ++++---- src/database/static_methods.rs | 5 +---- src/lib.rs | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/config.rs b/src/config.rs index 5d32dc8..fdb35dc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -305,6 +305,7 @@ impl LoadConfig { /// * `event_id` - An event id of a previous event returned by this /// method. If set events that are older than the event with the given /// event ID will be returned. + #[allow(clippy::wrong_self_convention)] pub fn from_event>(mut self, event_id: E) -> Self { self.from_event = Some(event_id.into()); self diff --git a/src/database/mod.rs b/src/database/mod.rs index c558ac0..9a0e1d8 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -29,7 +29,7 @@ use std::sync::Arc; use std::thread; use std::thread::JoinHandle; -use crate::config::{Config, SearchConfig, LoadConfig}; +use crate::config::{Config, LoadConfig, SearchConfig}; pub use crate::database::connection::{Connection, DatabaseStats}; pub use crate::database::searcher::{SearchResult, Searcher}; use crate::database::writer::Writer; @@ -141,14 +141,14 @@ impl ReadOnlyDatabase { // Skip removing directories, we don't create subdirs in our // database dir. if path.is_dir() { - continue + continue; } if let Some(file_name) = path.file_name() { // Skip removing the events database, those will be needed for // reindexing. if file_name == EVENTS_DB_NAME { - continue + continue; } fs::remove_file(path)? @@ -219,7 +219,7 @@ impl Database { } if reindex_needed { - return Err(Error::ReindexError) + return Err(Error::ReindexError); } let index = Database::create_index(&path, &config)?; diff --git a/src/database/static_methods.rs b/src/database/static_methods.rs index bc7ba6b..77a9122 100644 --- a/src/database/static_methods.rs +++ b/src/database/static_methods.rs @@ -191,10 +191,7 @@ impl Database { if version == 2 { let transaction = connection.transaction()?; - transaction.execute( - "UPDATE reindex_needed SET reindex_needed = ?1", - &[true], - )?; + transaction.execute("UPDATE reindex_needed SET reindex_needed = ?1", &[true])?; transaction.execute("UPDATE version SET version = '3'", NO_PARAMS)?; transaction.commit()?; diff --git a/src/lib.rs b/src/lib.rs index cba9b23..710c13e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,7 @@ mod error; mod events; mod index; -pub use database::{Connection, ReadOnlyDatabase, Database, DatabaseStats, SearchResult, Searcher}; +pub use database::{Connection, Database, DatabaseStats, ReadOnlyDatabase, SearchResult, Searcher}; pub use error::{Error, Result}; From 9cbb560f8fc8f303b5e3440c89a72336cca0f923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 2 Mar 2020 16:33:58 +0100 Subject: [PATCH 05/33] database: Move the readonly database into a separate module. --- src/database/mod.rs | 105 +--------------------------------- src/database/read_only.rs | 115 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 103 deletions(-) create mode 100644 src/database/read_only.rs diff --git a/src/database/mod.rs b/src/database/mod.rs index 9a0e1d8..cf82737 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -16,6 +16,7 @@ mod connection; mod searcher; mod static_methods; mod writer; +mod read_only; use fs_extra::dir; use r2d2::PooledConnection; @@ -32,6 +33,7 @@ use std::thread::JoinHandle; use crate::config::{Config, LoadConfig, SearchConfig}; pub use crate::database::connection::{Connection, DatabaseStats}; pub use crate::database::searcher::{SearchResult, Searcher}; +pub use crate::database::read_only::ReadOnlyDatabase; use crate::database::writer::Writer; use crate::error::{Error, Result}; use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile, SerializedEvent}; @@ -69,109 +71,6 @@ pub struct Database { config: Config, } -pub struct ReadOnlyDatabase { - path: PathBuf, - connection: PooledConnection, - pool: r2d2::Pool, - config: Config, - index_deleted: bool, -} - -impl ReadOnlyDatabase { - /// Open a read-only Seshat database. - /// - /// # Arguments - /// - /// * `path` - The directory where the database will be stored in. This - /// should be an empty directory if a new database should be created. - pub fn new>(path: P) -> Result - where - PathBuf: std::convert::From

, - { - Self::new_with_config(path, &Config::new()) - } - - /// Open a read-only Seshat database with the provided config. - /// - /// # Arguments - /// - /// * `path` - The directory where the database will be stored in. This - /// should be an empty directory if a new database should be created. - /// - /// * `config` - Configuration that changes the behaviour of the database. - pub fn new_with_config>(path: P, config: &Config) -> Result - where - PathBuf: std::convert::From

, - { - let db_path = path.as_ref().join(EVENTS_DB_NAME); - let manager = SqliteConnectionManager::file(&db_path); - let pool = r2d2::Pool::new(manager)?; - - let mut connection = pool.get()?; - connection.pragma_update(None, "foreign_keys", &1 as &dyn ToSql)?; - - Database::unlock(&connection, config)?; - - let (version, _) = match Database::get_version(&mut connection) { - Ok(ret) => ret, - Err(e) => return Err(Error::DatabaseOpenError(e.to_string())), - }; - - Database::create_tables(&connection)?; - - if version != DATABASE_VERSION { - return Err(Error::DatabaseVersionError); - } - - Ok(Self { - path: path.into(), - connection, - pool, - config: config.clone(), - index_deleted: false, - }) - } - - /// Delete the Seshat index, leaving only the events database. - pub fn delete_the_index(&mut self) -> std::io::Result<()> { - for entry in fs::read_dir(&self.path)? { - let entry = entry?; - let path = entry.path(); - - // Skip removing directories, we don't create subdirs in our - // database dir. - if path.is_dir() { - continue; - } - - if let Some(file_name) = path.file_name() { - // Skip removing the events database, those will be needed for - // reindexing. - if file_name == EVENTS_DB_NAME { - continue; - } - - fs::remove_file(path)? - } - } - self.index_deleted = true; - Ok(()) - } - - pub fn load_file_events( - &self, - load_config: &LoadConfig, - ) -> Result> { - Ok(Database::load_file_events( - &self.connection, - &load_config.room_id, - load_config.limit, - load_config.from_event.as_ref().map(|x| &**x), - &load_config.direction, - )?) - } -} - type WriterRet = (JoinHandle<()>, Sender); impl Database { diff --git a/src/database/read_only.rs b/src/database/read_only.rs new file mode 100644 index 0000000..af56d92 --- /dev/null +++ b/src/database/read_only.rs @@ -0,0 +1,115 @@ +use std::path::{Path, PathBuf}; +use std::fs; + +use r2d2::PooledConnection; +use r2d2_sqlite::SqliteConnectionManager; +use rusqlite::{ToSql, NO_PARAMS}; + +use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile, SerializedEvent}; +use crate::error::{Error, Result}; +use crate::config::{Config, LoadConfig, SearchConfig}; +use crate::Database; +use crate::database::{DATABASE_VERSION, EVENTS_DB_NAME}; + +pub struct ReadOnlyDatabase { + path: PathBuf, + connection: PooledConnection, + pool: r2d2::Pool, + config: Config, + index_deleted: bool, +} + +impl ReadOnlyDatabase { + /// Open a read-only Seshat database. + /// + /// # Arguments + /// + /// * `path` - The directory where the database will be stored in. This + /// should be an empty directory if a new database should be created. + pub fn new>(path: P) -> Result + where + PathBuf: std::convert::From

, + { + Self::new_with_config(path, &Config::new()) + } + + /// Open a read-only Seshat database with the provided config. + /// + /// # Arguments + /// + /// * `path` - The directory where the database will be stored in. This + /// should be an empty directory if a new database should be created. + /// + /// * `config` - Configuration that changes the behaviour of the database. + pub fn new_with_config>(path: P, config: &Config) -> Result + where + PathBuf: std::convert::From

, + { + let db_path = path.as_ref().join(EVENTS_DB_NAME); + let manager = SqliteConnectionManager::file(&db_path); + let pool = r2d2::Pool::new(manager)?; + + let mut connection = pool.get()?; + connection.pragma_update(None, "foreign_keys", &1 as &dyn ToSql)?; + + Database::unlock(&connection, config)?; + + let (version, _) = match Database::get_version(&mut connection) { + Ok(ret) => ret, + Err(e) => return Err(Error::DatabaseOpenError(e.to_string())), + }; + + Database::create_tables(&connection)?; + + if version != DATABASE_VERSION { + return Err(Error::DatabaseVersionError); + } + + Ok(Self { + path: path.into(), + connection, + pool, + config: config.clone(), + index_deleted: false, + }) + } + + /// Delete the Seshat index, leaving only the events database. + pub fn delete_the_index(&mut self) -> std::io::Result<()> { + for entry in fs::read_dir(&self.path)? { + let entry = entry?; + let path = entry.path(); + + // Skip removing directories, we don't create subdirs in our + // database dir. + if path.is_dir() { + continue; + } + + if let Some(file_name) = path.file_name() { + // Skip removing the events database, those will be needed for + // reindexing. + if file_name == EVENTS_DB_NAME { + continue; + } + + fs::remove_file(path)? + } + } + self.index_deleted = true; + Ok(()) + } + + pub fn load_file_events( + &self, + load_config: &LoadConfig, + ) -> Result> { + Ok(Database::load_file_events( + &self.connection, + &load_config.room_id, + load_config.limit, + load_config.from_event.as_ref().map(|x| &**x), + &load_config.direction, + )?) + } +} From 0fc2a66c18e787b42987d3167d77c0be23091dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 3 Mar 2020 09:51:15 +0100 Subject: [PATCH 06/33] database: Rename the ReadonlyDatabase to RecoveryDatabase. --- src/database/mod.rs | 8 ++++---- src/database/{read_only.rs => recovery.rs} | 14 ++++++++------ src/lib.rs | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) rename src/database/{read_only.rs => recovery.rs} (91%) diff --git a/src/database/mod.rs b/src/database/mod.rs index cf82737..e1f6563 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -16,7 +16,7 @@ mod connection; mod searcher; mod static_methods; mod writer; -mod read_only; +mod recovery; use fs_extra::dir; use r2d2::PooledConnection; @@ -30,13 +30,13 @@ use std::sync::Arc; use std::thread; use std::thread::JoinHandle; -use crate::config::{Config, LoadConfig, SearchConfig}; +use crate::config::{Config, SearchConfig}; pub use crate::database::connection::{Connection, DatabaseStats}; pub use crate::database::searcher::{SearchResult, Searcher}; -pub use crate::database::read_only::ReadOnlyDatabase; +pub use crate::database::recovery::RecoveryDatabase; use crate::database::writer::Writer; use crate::error::{Error, Result}; -use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile, SerializedEvent}; +use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile}; use crate::index::{Index, Writer as IndexWriter}; #[cfg(test)] diff --git a/src/database/read_only.rs b/src/database/recovery.rs similarity index 91% rename from src/database/read_only.rs rename to src/database/recovery.rs index af56d92..9603085 100644 --- a/src/database/read_only.rs +++ b/src/database/recovery.rs @@ -3,15 +3,15 @@ use std::fs; use r2d2::PooledConnection; use r2d2_sqlite::SqliteConnectionManager; -use rusqlite::{ToSql, NO_PARAMS}; +use rusqlite::{ToSql}; -use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile, SerializedEvent}; +use crate::events::{Profile, SerializedEvent}; use crate::error::{Error, Result}; -use crate::config::{Config, LoadConfig, SearchConfig}; +use crate::config::{Config, LoadConfig}; use crate::Database; use crate::database::{DATABASE_VERSION, EVENTS_DB_NAME}; -pub struct ReadOnlyDatabase { +pub struct RecoveryDatabase { path: PathBuf, connection: PooledConnection, pool: r2d2::Pool, @@ -19,7 +19,7 @@ pub struct ReadOnlyDatabase { index_deleted: bool, } -impl ReadOnlyDatabase { +impl RecoveryDatabase { /// Open a read-only Seshat database. /// /// # Arguments @@ -33,7 +33,7 @@ impl ReadOnlyDatabase { Self::new_with_config(path, &Config::new()) } - /// Open a read-only Seshat database with the provided config. + /// Open a recovery Seshat database with the provided config. /// /// # Arguments /// @@ -75,6 +75,8 @@ impl ReadOnlyDatabase { } /// Delete the Seshat index, leaving only the events database. + /// + /// After this operation is done, the index can be rebuilt. pub fn delete_the_index(&mut self) -> std::io::Result<()> { for entry in fs::read_dir(&self.path)? { let entry = entry?; diff --git a/src/lib.rs b/src/lib.rs index 710c13e..7cc7554 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,7 @@ mod error; mod events; mod index; -pub use database::{Connection, Database, DatabaseStats, ReadOnlyDatabase, SearchResult, Searcher}; +pub use database::{Connection, Database, DatabaseStats, RecoveryDatabase, SearchResult, Searcher}; pub use error::{Error, Result}; From 71c0847df0ae9e75380f7689715c622410d757af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 3 Mar 2020 15:07:24 +0100 Subject: [PATCH 07/33] database: More work on the recovery db. --- Cargo.toml | 1 + src/database/recovery.rs | 142 ++++++++++++++++++++++++++++++--- src/database/static_methods.rs | 42 ++++++++++ 3 files changed, 175 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 10fe1ef..c20c516 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,4 @@ byteorder = "1.3.2" tempfile = "3.1.0" lazy_static = "1.4.0" fake = "2.2.0" +serde_json = "*" diff --git a/src/database/recovery.rs b/src/database/recovery.rs index 9603085..7b17341 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -1,22 +1,41 @@ use std::path::{Path, PathBuf}; +use std::sync::atomic::AtomicU64; +use std::sync::Arc; use std::fs; use r2d2::PooledConnection; use r2d2_sqlite::SqliteConnectionManager; use rusqlite::{ToSql}; -use crate::events::{Profile, SerializedEvent}; +use crate::events::{Event, SerializedEvent}; use crate::error::{Error, Result}; -use crate::config::{Config, LoadConfig}; +use crate::config::{Config}; use crate::Database; +use crate::index::{Index, Writer}; use crate::database::{DATABASE_VERSION, EVENTS_DB_NAME}; pub struct RecoveryDatabase { path: PathBuf, connection: PooledConnection, + #[used] pool: r2d2::Pool, config: Config, + recovery_info: RecoveryInfo, index_deleted: bool, + index: Option, + index_writer: Option, +} + +#[derive(Debug, Clone)] +pub struct RecoveryInfo { + total_event_count: u64, + reindexed_events: Arc, +} + +impl RecoveryInfo { + pub fn total_events(&self) -> u64 { + self.total_event_count + } } impl RecoveryDatabase { @@ -65,12 +84,22 @@ impl RecoveryDatabase { return Err(Error::DatabaseVersionError); } + let event_count = Database::get_event_count(&connection)?; + + let info = RecoveryInfo { + total_event_count: event_count as u64, + reindexed_events: Arc::new(AtomicU64::new(0)), + }; + Ok(Self { path: path.into(), connection, pool, config: config.clone(), + recovery_info: info, index_deleted: false, + index: None, + index_writer: None, }) } @@ -102,16 +131,109 @@ impl RecoveryDatabase { Ok(()) } - pub fn load_file_events( + pub fn load_events( &self, - load_config: &LoadConfig, - ) -> Result> { - Ok(Database::load_file_events( + limit: usize, + from_event: Option<&Event>, + ) -> Result> { + Ok(Database::load_all_events( &self.connection, - &load_config.room_id, - load_config.limit, - load_config.from_event.as_ref().map(|x| &**x), - &load_config.direction, + limit, + from_event, )?) } + + pub fn open_index(&mut self) -> Result<()> { + let index = Index::new(&self.path, &self.config)?; + let writer = index.get_writer()?; + self.index = Some(index); + self.index_writer = Some(writer); + + Ok(()) + } + + pub fn info(&self) -> &RecoveryInfo { + &self.recovery_info + } + + pub fn index_events(&mut self, events: &Vec) -> Result<()> { + match self.index_writer.as_mut() { + Some(writer) => events.iter().map(|e| writer.add_event(e)).collect(), + None => panic!("Index wasn't deleted"), + } + + Ok(()) + } + + /// Commit the recovery database and mark is as reindexed. + pub fn commit(mut self) -> Result<()> { + self.index_writer.as_mut().unwrap().force_commit()?; + self.connection.execute("UPDATE reindex_needed SET reindex_needed = ?1", &[false])?; + Ok(()) + } +} + +#[cfg(test)] +mod test { + use std::path::PathBuf; + use crate::{Database, Event, EventType, Error, RecoveryDatabase}; + use serde_json::{Value}; + + fn event_from_json(event_source: &str) -> Event { + let object: Value = serde_json::from_str(event_source).expect("Can't deserialize event source"); + let content = &object["content"]; + let event_type = &object["type"]; + + let event_type = match event_type.as_str().unwrap() { + "m.room.message" => EventType::Message, + "m.room.name" => EventType::Name, + "m.room.topic" => EventType::Topic, + _ => panic!("Invalid event type"), + }; + + let (content_value, msgtype) = match event_type { + EventType::Message => (content["body"].as_str().unwrap(), Some(content["msgtype"].as_str().unwrap())), + EventType::Topic => (content["topic"].as_str().unwrap(), None), + EventType::Name => (content["name"].as_str().unwrap(), None), + }; + + Event::new( + event_type, + content_value, + msgtype, + object["event_id"].as_str().unwrap(), + object["sender"].as_str().unwrap(), + object["origin_server_ts"].as_u64().unwrap() as i64, + object["room_id"].as_str().unwrap(), + &event_source, + ) + } + + #[test] + fn test_recovery() { + let mut path = PathBuf::from(file!()); + path.pop(); + path.pop(); + path.pop(); + path.push("data/database/v1"); + let db = Database::new(&path); + + match db { + Ok(_) => panic!("Database doesn't need a reindex."), + Err(e) => match e { + Error::ReindexError => (), + e => panic!("Database doesn't need a reindex: {}", e), + } + } + + let mut recovery_db = RecoveryDatabase::new(path).expect("Can't open recovery db"); + assert_ne!(recovery_db.info().total_events(), 0); + recovery_db.delete_the_index().unwrap(); + + let events = recovery_db.load_events(10, None).unwrap(); + + assert!(!events.is_empty()); + + let events: Vec = events.iter().map(|e| event_from_json(e)).collect(); + } } diff --git a/src/database/static_methods.rs b/src/database/static_methods.rs index 77a9122..04bfbc8 100644 --- a/src/database/static_methods.rs +++ b/src/database/static_methods.rs @@ -457,6 +457,48 @@ impl Database { } } + pub(crate) fn load_all_events( + connection: &rusqlite::Connection, + limit: usize, + from_event: Option<&Event>, + ) -> rusqlite::Result> { + match from_event { + Some(event) => { + let mut stmt = connection.prepare( + "SELECT source FROM events + WHERE ( + (type == 'm.room.message') & + (event_id != ?1) & + (server_ts <= ?2) + ) ORDER BY server_ts DESC LIMIT ?3 + ", + )?; + + let events = stmt.query_map( + &vec![ + &event.event_id as &dyn ToSql, + &event.server_ts as &dyn ToSql, + &(limit as i64), + ], + |row| { Ok(row.get(0)?) }, + )?; + events.collect() + } + None => { + let mut stmt = connection.prepare( + "SELECT source FROM events + WHERE type == 'm.room.message' + ORDER BY server_ts DESC LIMIT ?1 + ", + )?; + + let events = + stmt.query_map(&vec![&(limit as i64)], |row| { Ok(row.get(0)?) })?; + events.collect() + } + } + } + pub(crate) fn load_file_events( connection: &rusqlite::Connection, room_id: &str, From de85c233faf0ad6a423da98a624712001e217113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 3 Mar 2020 15:07:43 +0100 Subject: [PATCH 08/33] events: Fix the event sources. --- src/events.rs | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/events.rs b/src/events.rs index 6925fd0..1ea592d 100644 --- a/src/events.rs +++ b/src/events.rs @@ -208,32 +208,32 @@ impl Profile { } #[cfg(test)] -pub static EVENT_SOURCE: &str = "{ - content: { - body: Test message, msgtype: m.text +pub static EVENT_SOURCE: &str = r#"{ + "content": { + "body": "Test message, msgtype: m.text" }, - event_id: $15163622445EBvZJ:localhost, - origin_server_ts: 1516362244026, - sender: @example2:localhost, - type: m.room.message, - unsigned: {age: 43289803095}, - user_id: @example2:localhost, - age: 43289803095 -}"; + "event_id": "$15163622445EBvZJ:localhost", + "origin_server_ts": 1516362244026, + "sender": "@example2:localhost", + "type": "m.room.message", + "unsigned": {"age": 43289803095}, + "user_id": "@example2:localhost", + "age": 43289803095 +}"#; #[cfg(test)] -pub static TOPIC_EVENT_SOURCE: &str = "{ - content: { - topic: Test topic +pub static TOPIC_EVENT_SOURCE: &str = r#"{ + "content": { + "topic": "Test topic" }, - event_id: $15163622448EBvZJ:localhost, - origin_server_ts: 1516362244050, - sender: @example2:localhost, - type: m.room.topic, - unsigned: {age: 43289803098}, - user_id: @example2:localhost, - age: 43289803098 -}"; + "event_id": "$15163622448EBvZJ:localhost", + "origin_server_ts": 1516362244050, + "sender": "@example2:localhost", + "type": "m.room.topic", + "unsigned": {"age": 43289803098}, + "user_id": "@example2:localhost", + "age": 43289803098 +}"#; #[cfg(test)] lazy_static! { From af106dd7ed13aecd69b75654e589e7bb114cb803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 3 Mar 2020 16:57:54 +0100 Subject: [PATCH 09/33] database: Improve the recovery test. --- src/database/mod.rs | 4 +- src/database/recovery.rs | 88 +++++++++++++++++++++++++++------- src/database/static_methods.rs | 5 +- 3 files changed, 75 insertions(+), 22 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index e1f6563..ccfe25d 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -13,10 +13,10 @@ // limitations under the License. mod connection; +mod recovery; mod searcher; mod static_methods; mod writer; -mod recovery; use fs_extra::dir; use r2d2::PooledConnection; @@ -32,8 +32,8 @@ use std::thread::JoinHandle; use crate::config::{Config, SearchConfig}; pub use crate::database::connection::{Connection, DatabaseStats}; -pub use crate::database::searcher::{SearchResult, Searcher}; pub use crate::database::recovery::RecoveryDatabase; +pub use crate::database::searcher::{SearchResult, Searcher}; use crate::database::writer::Writer; use crate::error::{Error, Result}; use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile}; diff --git a/src/database/recovery.rs b/src/database/recovery.rs index 7b17341..bf60a68 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -1,18 +1,18 @@ +use std::fs; use std::path::{Path, PathBuf}; -use std::sync::atomic::AtomicU64; +use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; -use std::fs; use r2d2::PooledConnection; use r2d2_sqlite::SqliteConnectionManager; -use rusqlite::{ToSql}; +use rusqlite::ToSql; -use crate::events::{Event, SerializedEvent}; +use crate::config::Config; +use crate::database::{DATABASE_VERSION, EVENTS_DB_NAME}; use crate::error::{Error, Result}; -use crate::config::{Config}; -use crate::Database; +use crate::events::{Event, SerializedEvent}; use crate::index::{Index, Writer}; -use crate::database::{DATABASE_VERSION, EVENTS_DB_NAME}; +use crate::Database; pub struct RecoveryDatabase { path: PathBuf, @@ -36,6 +36,10 @@ impl RecoveryInfo { pub fn total_events(&self) -> u64 { self.total_event_count } + + pub fn reindexed_events(&self) -> &AtomicU64 { + &self.reindexed_events + } } impl RecoveryDatabase { @@ -162,25 +166,32 @@ impl RecoveryDatabase { None => panic!("Index wasn't deleted"), } + self.recovery_info + .reindexed_events + .fetch_add(events.len() as u64, Ordering::SeqCst); + Ok(()) } /// Commit the recovery database and mark is as reindexed. pub fn commit(mut self) -> Result<()> { self.index_writer.as_mut().unwrap().force_commit()?; - self.connection.execute("UPDATE reindex_needed SET reindex_needed = ?1", &[false])?; + self.connection + .execute("UPDATE reindex_needed SET reindex_needed = ?1", &[false])?; Ok(()) } } #[cfg(test)] mod test { + use crate::{Database, Error, Event, EventType, RecoveryDatabase}; + use serde_json::Value; use std::path::PathBuf; - use crate::{Database, Event, EventType, Error, RecoveryDatabase}; - use serde_json::{Value}; + use std::sync::atomic::Ordering; fn event_from_json(event_source: &str) -> Event { - let object: Value = serde_json::from_str(event_source).expect("Can't deserialize event source"); + let object: Value = + serde_json::from_str(event_source).expect("Can't deserialize event source"); let content = &object["content"]; let event_type = &object["type"]; @@ -192,7 +203,7 @@ mod test { }; let (content_value, msgtype) = match event_type { - EventType::Message => (content["body"].as_str().unwrap(), Some(content["msgtype"].as_str().unwrap())), + EventType::Message => (content["body"].as_str().unwrap(), Some("m.text")), EventType::Topic => (content["topic"].as_str().unwrap(), None), EventType::Name => (content["name"].as_str().unwrap(), None), }; @@ -215,7 +226,7 @@ mod test { path.pop(); path.pop(); path.pop(); - path.push("data/database/v1"); + path.push("data/database/v2"); let db = Database::new(&path); match db { @@ -223,17 +234,60 @@ mod test { Err(e) => match e { Error::ReindexError => (), e => panic!("Database doesn't need a reindex: {}", e), - } + }, } let mut recovery_db = RecoveryDatabase::new(path).expect("Can't open recovery db"); assert_ne!(recovery_db.info().total_events(), 0); - recovery_db.delete_the_index().unwrap(); + recovery_db + .delete_the_index() + .expect("Can't delete the index"); + recovery_db + .open_index() + .expect("Can't open the new the index"); - let events = recovery_db.load_events(10, None).unwrap(); + let events = recovery_db + .load_events(10, None) + .expect("Can't load events"); assert!(!events.is_empty()); + assert_eq!(events.len(), 10); + + let mut events: Vec = events.iter().map(|e| event_from_json(e)).collect(); + + recovery_db.index_events(&events).unwrap(); + assert_eq!( + recovery_db + .info() + .reindexed_events() + .load(Ordering::Relaxed), + 10 + ); + + loop { + let serialized_events = recovery_db + .load_events(10, events.last()) + .expect("Can't load events"); + + if serialized_events.is_empty() { + break; + } + + events = serialized_events + .iter() + .map(|e| event_from_json(e)) + .collect(); + recovery_db.index_events(&events).unwrap(); + } + + assert_eq!( + recovery_db + .info() + .reindexed_events() + .load(Ordering::Relaxed), + 999 + ); - let events: Vec = events.iter().map(|e| event_from_json(e)).collect(); + recovery_db.commit().unwrap(); } } diff --git a/src/database/static_methods.rs b/src/database/static_methods.rs index 04bfbc8..c656dd8 100644 --- a/src/database/static_methods.rs +++ b/src/database/static_methods.rs @@ -480,7 +480,7 @@ impl Database { &event.server_ts as &dyn ToSql, &(limit as i64), ], - |row| { Ok(row.get(0)?) }, + |row| Ok(row.get(0)?), )?; events.collect() } @@ -492,8 +492,7 @@ impl Database { ", )?; - let events = - stmt.query_map(&vec![&(limit as i64)], |row| { Ok(row.get(0)?) })?; + let events = stmt.query_map(&vec![&(limit as i64)], |row| Ok(row.get(0)?))?; events.collect() } } From 46ef3b2b8ba35956f9aeca07320b851ec8c48e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 4 Mar 2020 10:56:24 +0100 Subject: [PATCH 10/33] database: Add propper error handling to the recovery database. --- src/database/recovery.rs | 57 +++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/src/database/recovery.rs b/src/database/recovery.rs index bf60a68..6b64769 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -111,6 +111,12 @@ impl RecoveryDatabase { /// /// After this operation is done, the index can be rebuilt. pub fn delete_the_index(&mut self) -> std::io::Result<()> { + let writer = self.index_writer.take(); + let index = self.index.take(); + + drop(writer); + drop(index); + for entry in fs::read_dir(&self.path)? { let entry = entry?; let path = entry.path(); @@ -148,6 +154,10 @@ impl RecoveryDatabase { } pub fn open_index(&mut self) -> Result<()> { + if !self.index_deleted { + return Err(Error::ReindexError); + } + let index = Index::new(&self.path, &self.config)?; let writer = index.get_writer()?; self.index = Some(index); @@ -160,7 +170,15 @@ impl RecoveryDatabase { &self.recovery_info } - pub fn index_events(&mut self, events: &Vec) -> Result<()> { + /// Re-index a batch of events. + /// + /// # Arguments + /// + /// * `events` - The events that should be reindexed. + /// + /// Returns `ReindexError` if the index wasn't previously deleted and + /// opened. + pub fn index_events(&mut self, events: &[Event]) -> Result<()> { match self.index_writer.as_mut() { Some(writer) => events.iter().map(|e| writer.add_event(e)).collect(), None => panic!("Index wasn't deleted"), @@ -173,12 +191,37 @@ impl RecoveryDatabase { Ok(()) } - /// Commit the recovery database and mark is as reindexed. - pub fn commit(mut self) -> Result<()> { - self.index_writer.as_mut().unwrap().force_commit()?; - self.connection - .execute("UPDATE reindex_needed SET reindex_needed = ?1", &[false])?; - Ok(()) + /// Commit to the index. + /// + /// Returns true if the commit was forwarded, false if not enough events are + /// queued up. + /// + /// Returns `ReindexError` if the index wasn't previously deleted and + /// opened. + pub fn commit(&mut self) -> Result { + match self.index_writer.as_mut() { + Some(writer) => { + let ret = writer.commit()?; + Ok(ret) + } + None => Err(Error::ReindexError), + } + } + + /// Commit the remaining added events and mark the reindex as done. + /// + /// Returns `ReindexError` if the index wasn't previously deleted and + /// opened. + pub fn commit_and_close(mut self) -> Result<()> { + match self.index_writer.as_mut() { + Some(writer) => { + writer.force_commit()?; + self.connection + .execute("UPDATE reindex_needed SET reindex_needed = ?1", &[false])?; + Ok(()) + } + None => Err(Error::ReindexError), + } } } From d3f29967933147ae8de351cb56504a9dfbffc42b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 4 Mar 2020 10:59:48 +0100 Subject: [PATCH 11/33] data: Add a v2 database that needs to be reindexed. --- data/database/v2/.managed.json | 1 + data/database/v2/.tantivy-meta.lock | 0 data/database/v2/.tantivy-writer.lock | 0 .../v2/b653775a48c44546afa249d5f9dc4848.fast | Bin 0 -> 172 bytes ...b653775a48c44546afa249d5f9dc4848.fieldnorm | Bin 0 -> 4195 bytes .../v2/b653775a48c44546afa249d5f9dc4848.idx | Bin 0 -> 4323 bytes .../v2/b653775a48c44546afa249d5f9dc4848.pos | Bin 0 -> 585 bytes .../b653775a48c44546afa249d5f9dc4848.posidx | Bin 0 -> 212 bytes .../v2/b653775a48c44546afa249d5f9dc4848.store | Bin 0 -> 11362 bytes .../v2/b653775a48c44546afa249d5f9dc4848.term | Bin 0 -> 3345 bytes data/database/v2/events.db | Bin 0 -> 667648 bytes data/database/v2/meta.json | 64 ++++++++++++++++++ 12 files changed, 65 insertions(+) create mode 100644 data/database/v2/.managed.json create mode 100644 data/database/v2/.tantivy-meta.lock create mode 100644 data/database/v2/.tantivy-writer.lock create mode 100644 data/database/v2/b653775a48c44546afa249d5f9dc4848.fast create mode 100644 data/database/v2/b653775a48c44546afa249d5f9dc4848.fieldnorm create mode 100644 data/database/v2/b653775a48c44546afa249d5f9dc4848.idx create mode 100644 data/database/v2/b653775a48c44546afa249d5f9dc4848.pos create mode 100644 data/database/v2/b653775a48c44546afa249d5f9dc4848.posidx create mode 100644 data/database/v2/b653775a48c44546afa249d5f9dc4848.store create mode 100644 data/database/v2/b653775a48c44546afa249d5f9dc4848.term create mode 100644 data/database/v2/events.db create mode 100644 data/database/v2/meta.json diff --git a/data/database/v2/.managed.json b/data/database/v2/.managed.json new file mode 100644 index 0000000..188de30 --- /dev/null +++ b/data/database/v2/.managed.json @@ -0,0 +1 @@ +["b653775a48c44546afa249d5f9dc4848.fast","b653775a48c44546afa249d5f9dc4848.pos","meta.json","b653775a48c44546afa249d5f9dc4848.idx","b653775a48c44546afa249d5f9dc4848.posidx","b653775a48c44546afa249d5f9dc4848.store","b653775a48c44546afa249d5f9dc4848.fieldnorm","b653775a48c44546afa249d5f9dc4848.term"] diff --git a/data/database/v2/.tantivy-meta.lock b/data/database/v2/.tantivy-meta.lock new file mode 100644 index 0000000..e69de29 diff --git a/data/database/v2/.tantivy-writer.lock b/data/database/v2/.tantivy-writer.lock new file mode 100644 index 0000000..e69de29 diff --git a/data/database/v2/b653775a48c44546afa249d5f9dc4848.fast b/data/database/v2/b653775a48c44546afa249d5f9dc4848.fast new file mode 100644 index 0000000000000000000000000000000000000000..aa7eedaf87f58644b68332117b8673739c05c600 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jBGtg1U%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tEt%B$gy+ ffCZ7wiZ4qo0_g^-(NV%MQ^`sRVyIH>VxS8F8}B>t literal 0 HcmV?d00001 diff --git a/data/database/v2/b653775a48c44546afa249d5f9dc4848.fieldnorm b/data/database/v2/b653775a48c44546afa249d5f9dc4848.fieldnorm new file mode 100644 index 0000000000000000000000000000000000000000..b5b09ea5d29cb3c0d8c8b260d13d2710dfd27cd2 GIT binary patch literal 4195 zcmZQ(9tEQzFd72GJOmg?~)Z*gI{5&fKh~8_}O1X(y`9(@r20BW)nRy_Vp^=VK kL1IaA23Qc;toX9jB9LyN8XYAJGnK5AAciW{E(W>~0BD?0LjV8( literal 0 HcmV?d00001 diff --git a/data/database/v2/b653775a48c44546afa249d5f9dc4848.idx b/data/database/v2/b653775a48c44546afa249d5f9dc4848.idx new file mode 100644 index 0000000000000000000000000000000000000000..b9d04f7afacd7c4b905c1f7a70e58c754faa9784 GIT binary patch literal 4323 zcmeI!Rg4(gaRy*BGqcxgw%5$e%*?R1*Y+BA?e&`Jeh14bq>w@ix6G7M%8)X*DKn(Z z3`y*pmrBh;)Q3D=^_R}C(b1XF!1<+lPya4&;SHbYkNmMe@uxoE&-}T+@R$C|C;4lC z<8S?)zxNOR(LecT|KgMVtAF$F{=KBNnuqAT6#P7iw0i{A91Fa7vb{TaYO z1~Hf+3}qO@8NsI+$tXrMhOvxeJQJA6B;H{%4NRetsZ3)!GnmONKHY5QFqbCgF`or2 zWD$$`3`ELd)dc+4sein zI>cd)aFk;l=L9D?#c4j<8P0N!^IYH}&0OL#SNI$)T;&?qY2^ktxy5bT_+0JW;VvEA zqm%nQ;31FrJdb(8Q=ajh7rdlP&^725yi50>N6<6q74#1J1bu^kLH}St@c9M?gMz`q zkYH#qEEpb)2u22@f-f*S7!!;Q#s%Yp3Bkl*QZPAa2)@vipfQ*lObez5GlH4HtYCI9 zCkVdC+@L9#7t9Y91Pg;j!Qx;^urzqLWx?`bMX)kh6|4@{1Z#tJ!TR8fZ3s37n}W^3 zmSAhJE!ZCH2zCZvVpp&`*c0px_67Tc1Hr-IP;fZ-Qb&TL!Li_Ya3VMvoC;0{XM(fA zmpK=l4=w~3gXZ8;a5=aVv;K^rozEaPqSJXS|6ZMVyMg5}z(ZFa>6n&M! z(U53pG%Ok(jfh4@qoUE#nCPpGjmAaeqY2T(Xi_veYKW#pjnUVb8cmC)M>C?C(X428 zG$)!HHAP=*UNk>i5G{-rMT?^)(b8yHv^@GcE25Rrs%UkzCR!Vfyd5#5Y#MYp52s6Dz9-Hke;81QL;E$k}OS@CCif)$;#xrtV&iVYm&9ex@3K_A=#L0N;W6o zZA-E>*_Lcib|gEKUCHibPqH`p9{ZC0$${ixaws{R97&EQ$CBeo_FgBFlgX*%baEy+ zo19C|Cl`{7$@gkbE+vHZB{VO~`)O#B5SFIcvzKWR2O>Y+5!wo00v9nc1vt zb~Y!Qn>A(gviaG9Y+?4J7G;aGCE3z!S++b|k*&;DWvjE|$E?ZLX6v%`*@kRmwkg}3 zZOOJ~@3Sr2p6$qXX1lW8*`91~wlCYC{kQ|!!R%0WI6IOZ&5mWqvlH3L>?fScPG@Jb zv)Q@qe0Cwbm^EjYvY&K0yOOnJSF>x`^{h3!k=@L0Wk2P1)|Rzrce1-#M|Lmk%3yOusqGECJi~VnwmCSXHbp))Z@tU$U-PUu-Bg7MqIA z#g<}gv8~u%{IVUz&SF=wyVz6gE%p`rivz{M;#V9h4i`s?qs6h}cyXdQS)3|P7r*LE zake;DoG&gE7mMcNQgOMsQoLVFakaQsTrXOS8^z7yR&l#%D}GITai_RjbQJfB&f+j6TlEQkL-(pj)wAkV^{)Cn+8^c zs=?KeYG^gA8eWa4MpmP$-!i%yQ;n_0RpYA()x>I2HMwf2e%q9)v6@;US-xmRBpPmDQ?hb+x8iTdk|sSHEXNwXxb% zZLYRdTdQr=_G(A9v-*9zs@>I|YHzi#+Fu>04pxV%!_^-+QXQ?1RmZCn)ye8qb-FrJ zovr@Rx$1m%p}JT#SC^{G)s?EHx>~*O<*VJfYu7hk@$2({wLbWvw>Mrd&Tk+5|Ik0C z-}?3$`0GkO(EXLZU*XNS6#vF6>n+uPRQhsGum=oP)A>nnQa zk#~(Q_u888+x2XX{Hq2oLk-R{npAksxV)_u+R-BhuP*AzMBr&ffv#e5~%s|i3 zNY6k=Au}%}wIV((zbH4cM4`-3N1?bRzbG|6IX}0cD7CmaGe6Ht0iyR>wNh?kR(_F^ xm4S{@Ze|{cWoV?MRFGJboBg?wFsmes76N#!%QVBC5WL)wTpo+1OS6qJ>mcW literal 0 HcmV?d00001 diff --git a/data/database/v2/b653775a48c44546afa249d5f9dc4848.store b/data/database/v2/b653775a48c44546afa249d5f9dc4848.store new file mode 100644 index 0000000000000000000000000000000000000000..e65d4295d1c966c284b50df24551b8c0e798091a GIT binary patch literal 11362 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 I+4CFz3sm1Pq5uE@ literal 0 HcmV?d00001 diff --git a/data/database/v2/events.db b/data/database/v2/events.db new file mode 100644 index 0000000000000000000000000000000000000000..54580b1446cac4c432d8dd34449167c42aa406ff GIT binary patch literal 667648 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


6s0QaHJ*N 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%0D_W*OTHf2XRYQ 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

B!tvgf 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 literal 0 HcmV?d00001 diff --git a/data/database/v2/meta.json b/data/database/v2/meta.json new file mode 100644 index 0000000..77fcb0c --- /dev/null +++ b/data/database/v2/meta.json @@ -0,0 +1,64 @@ +{ + "segments": [ + { + "segment_id": "b653775a-48c4-4546-afa2-49d5f9dc4848", + "max_doc": 999, + "deletes": null + } + ], + "schema": [ + { + "name": "body", + "type": "text", + "options": { + "indexing": { + "record": "position", + "tokenizer": "default" + }, + "stored": false + } + }, + { + "name": "topic", + "type": "text", + "options": { + "indexing": { + "record": "position", + "tokenizer": "default" + }, + "stored": false + } + }, + { + "name": "name", + "type": "text", + "options": { + "indexing": { + "record": "position", + "tokenizer": "default" + }, + "stored": false + } + }, + { + "name": "room_id", + "type": "text", + "options": { + "indexing": { + "record": "basic", + "tokenizer": "raw" + }, + "stored": false + } + }, + { + "name": "event_id", + "type": "text", + "options": { + "indexing": null, + "stored": true + } + } + ], + "opstamp": 1000 +} From c6f4df4ed23c79f0de0d906145546be3be8afb82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 19 Feb 2020 13:54:25 +0100 Subject: [PATCH 12/33] database: Add a method to delete events. --- src/database/mod.rs | 87 +++++++++++++++++++++++++++++----- src/database/static_methods.rs | 78 +++++++++++++++++++++++++++++- src/database/writer.rs | 46 ++++++++++++++++-- src/index/mod.rs | 48 +++++++++++++++++-- tests/integration_test.rs | 26 ++++++++++ 5 files changed, 264 insertions(+), 21 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index ccfe25d..2c3495e 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -36,7 +36,7 @@ pub use crate::database::recovery::RecoveryDatabase; pub use crate::database::searcher::{SearchResult, Searcher}; use crate::database::writer::Writer; use crate::error::{Error, Result}; -use crate::events::{CrawlerCheckpoint, Event, HistoricEventsT, Profile}; +use crate::events::{CrawlerCheckpoint, Event, EventId, HistoricEventsT, Profile}; use crate::index::{Index, Writer as IndexWriter}; #[cfg(test)] @@ -49,7 +49,7 @@ use tempfile::tempdir; #[cfg(test)] use crate::events::CheckpointDirection; #[cfg(test)] -use crate::EVENT; +use crate::{EVENT, TOPIC_EVENT}; const DATABASE_VERSION: i64 = 3; const EVENTS_DB_NAME: &str = "events.db"; @@ -58,6 +58,7 @@ pub(crate) enum ThreadMessage { Event((Event, Profile)), HistoricEvents(HistoricEventsT), Write(Sender>, bool), + Delete(Sender>, EventId), } /// The Seshat database. @@ -229,21 +230,21 @@ impl Database { let t_handle = thread::spawn(move || { let mut writer = Writer::new(connection, index_writer); - let mut loaded_uncommitted = false; + let mut loaded_unprocessed = false; while let Ok(message) = rx.recv() { match message { ThreadMessage::Event((event, profile)) => writer.add_event(event, profile), ThreadMessage::Write(sender, force_commit) => { - // We may have events that aren't committed to the index - // but are stored in the db, let us load them from the - // db and commit them to the index now. They will later - // be marked as committed in the database as part of a - // normal write. - if !loaded_uncommitted { - let ret = writer.load_uncommitted_events(); + // We may have events that aren't deleted or committed + // to the index but are stored in the db, let us load + // them from the db and commit them to the index now. + // They will later be marked as committed in the + // database as part of a normal write. + if !loaded_unprocessed { + let ret = writer.load_unprocessed_events(); - loaded_uncommitted = true; + loaded_unprocessed = true; if ret.is_err() { sender.send(ret).unwrap_or(()); @@ -259,6 +260,10 @@ impl Database { let ret = writer.write_historic_events(check, old_check, events, true); sender.send(ret).unwrap_or(()); } + ThreadMessage::Delete(sender, event_id) => { + let ret = writer.delete_event(event_id); + sender.send(ret).unwrap_or(()); + } }; } }); @@ -280,6 +285,22 @@ impl Database { self.tx.send(message).unwrap(); } + /// Delete an event from the database. + /// + /// # Arguments + /// * `event_id` - The event id of the event that will be deleted. + /// + /// Note for the event to be completely removed a commit needs to be done. + /// + /// Returns a receiver that will receive an empty message once the event has + /// been deleted. + pub fn delete_event(&self, event_id: &str) -> Receiver> { + let (sender, receiver): (_, Receiver>) = channel(); + let message = ThreadMessage::Delete(sender, event_id.to_owned()); + self.tx.send(message).unwrap(); + receiver + } + fn commit_helper(&mut self, force: bool) -> Receiver> { let (sender, receiver): (_, Receiver>) = channel(); self.tx.send(ThreadMessage::Write(sender, force)).unwrap(); @@ -885,3 +906,47 @@ fn database_upgrade_v1() { let result = db.search("Hello", &SearchConfig::new()).unwrap(); assert!(!result.is_empty()) } + +#[test] +fn delete_an_event() { + let tmpdir = tempdir().unwrap(); + let mut db = Database::new(tmpdir.path()).unwrap(); + let profile = Profile::new("Alice", ""); + + db.add_event(EVENT.clone(), profile.clone()); + db.add_event(TOPIC_EVENT.clone(), profile); + + db.force_commit().unwrap(); + + assert!(Database::load_undeleted_events(&db.connection) + .unwrap() + .is_empty()); + + let recv = db.delete_event(&EVENT.event_id); + recv.recv().unwrap().unwrap(); + + assert_eq!( + Database::load_undeleted_events(&db.connection) + .unwrap() + .len(), + 1 + ); + + drop(db); + + let mut db = Database::new(tmpdir.path()).unwrap(); + assert_eq!( + Database::load_undeleted_events(&db.connection) + .unwrap() + .len(), + 1 + ); + + db.force_commit().unwrap(); + assert_eq!( + Database::load_undeleted_events(&db.connection) + .unwrap() + .len(), + 0 + ); +} diff --git a/src/database/static_methods.rs b/src/database/static_methods.rs index c656dd8..89e0e7f 100644 --- a/src/database/static_methods.rs +++ b/src/database/static_methods.rs @@ -62,6 +62,62 @@ impl Database { Ok((ret.iter().all(|&x| x), event_ids)) } + pub(crate) fn delete_event_helper( + connection: &mut rusqlite::Connection, + index_writer: &mut IndexWriter, + event_id: EventId, + undeleted_events: &mut Vec, + ) -> Result { + let transaction = connection.transaction()?; + + transaction.execute("DELETE from events WHERE event_id == ?1", &[&event_id])?; + transaction.execute( + "INSERT OR IGNORE INTO undeleted_events (event_id) VALUES (?1)", + &[&event_id], + )?; + transaction.commit().unwrap(); + + index_writer.delete_event(&event_id); + undeleted_events.push(event_id); + + let committed = index_writer.commit()?; + + if committed { + Database::mark_events_as_deleted(connection, undeleted_events)?; + } + + Ok(true) + } + + pub(crate) fn mark_events_as_deleted( + connection: &mut rusqlite::Connection, + events: &mut Vec, + ) -> Result<()> { + if events.is_empty() { + return Ok(()); + } + let transaction = connection.transaction()?; + + for chunk in events.chunks(50) { + let parameter_str = std::iter::repeat(", ?") + .take(chunk.len() - 1) + .collect::(); + + let mut stmt = transaction.prepare(&format!( + "DELETE from undeleted_events + WHERE event_id IN (?{})", + ¶meter_str + ))?; + + stmt.execute(chunk)?; + } + + transaction.commit()?; + events.clear(); + + Ok(()) + } + /// Delete non committed events from the database that were committed pub(crate) fn mark_events_as_indexed( connection: &mut rusqlite::Connection, @@ -102,7 +158,7 @@ impl Database { ), force_commit: bool, uncommitted_events: &mut Vec, - ) -> Result { + ) -> Result<(bool, bool)> { let (new_checkpoint, old_checkpoint, mut events) = message; let transaction = connection.transaction()?; @@ -129,7 +185,7 @@ impl Database { Database::mark_events_as_indexed(connection, uncommitted_events)?; } - Ok(ret) + Ok((ret, committed)) } pub(crate) fn get_version(connection: &mut rusqlite::Connection) -> Result<(i64, bool)> { @@ -252,6 +308,15 @@ impl Database { NO_PARAMS, )?; + conn.execute( + "CREATE TABLE IF NOT EXISTS undeleted_events ( + id INTEGER NOT NULL PRIMARY KEY, + event_id TEXT NOT NULL, + UNIQUE(event_id) + )", + NO_PARAMS, + )?; + conn.execute( "CREATE TABLE IF NOT EXISTS crawlercheckpoints ( id INTEGER NOT NULL PRIMARY KEY, @@ -354,6 +419,15 @@ impl Database { Ok(room_id) } + pub(crate) fn load_undeleted_events( + connection: &rusqlite::Connection, + ) -> rusqlite::Result> { + let mut stmt = connection.prepare("SELECT event_id from undeleted_events")?; + let events = stmt.query_map(NO_PARAMS, |row| Ok(row.get(0)?))?; + + events.collect() + } + pub(crate) fn load_uncommitted_events( connection: &rusqlite::Connection, ) -> rusqlite::Result> { diff --git a/src/database/writer.rs b/src/database/writer.rs index 9fe7ce0..fcf2c9b 100644 --- a/src/database/writer.rs +++ b/src/database/writer.rs @@ -15,7 +15,7 @@ use r2d2_sqlite::SqliteConnectionManager; use crate::error::Result; -use crate::events::{CrawlerCheckpoint, Event, Profile}; +use crate::events::{CrawlerCheckpoint, Event, EventId, Profile}; use crate::index::Writer as IndexWriter; use crate::Database; @@ -24,6 +24,7 @@ pub(crate) struct Writer { connection: r2d2::PooledConnection, events: Vec<(Event, Profile)>, uncommitted_events: Vec, + undeleted_events: Vec, } impl Writer { @@ -36,6 +37,7 @@ impl Writer { connection, events: Vec::new(), uncommitted_events: Vec::new(), + undeleted_events: Vec::new(), } } @@ -43,8 +45,24 @@ impl Writer { self.events.push((event, profile)); } + pub fn delete_event(&mut self, event_id: EventId) -> Result { + Database::delete_event_helper( + &mut self.connection, + &mut self.inner, + event_id, + &mut self.undeleted_events, + ) + } + + fn mark_events_as_deleted(&mut self) -> Result<()> { + if self.undeleted_events.is_empty() { + return Ok(()); + } + Database::mark_events_as_deleted(&mut self.connection, &mut self.undeleted_events) + } + pub fn write_queued_events(&mut self, force_commit: bool) -> Result<()> { - Database::write_events( + let (_, committed) = Database::write_events( &mut self.connection, &mut self.inner, (None, None, &mut self.events), @@ -52,6 +70,10 @@ impl Writer { &mut self.uncommitted_events, )?; + if committed { + self.mark_events_as_deleted()?; + } + Ok(()) } @@ -62,16 +84,22 @@ impl Writer { mut events: Vec<(Event, Profile)>, force_commit: bool, ) -> Result { - Database::write_events( + let (ret, committed) = Database::write_events( &mut self.connection, &mut self.inner, (checkpoint, old_checkpoint, &mut events), force_commit, &mut self.uncommitted_events, - ) + )?; + + if committed { + self.mark_events_as_deleted()?; + } + + Ok(ret) } - pub fn load_uncommitted_events(&mut self) -> Result<()> { + pub fn load_unprocessed_events(&mut self) -> Result<()> { let mut ret = Database::load_uncommitted_events(&self.connection)?; for (id, event) in ret.drain(..) { @@ -79,6 +107,14 @@ impl Writer { self.inner.add_event(&event); } + let ret = Database::load_undeleted_events(&self.connection)?; + + for event_id in &ret { + self.inner.delete_event(&event_id); + } + + self.undeleted_events.extend(ret); + Ok(()) } } diff --git a/src/index/mod.rs b/src/index/mod.rs index 9259942..0de591a 100644 --- a/src/index/mod.rs +++ b/src/index/mod.rs @@ -23,6 +23,8 @@ use std::path::Path; use std::time::Duration; use tantivy as tv; use tantivy::chrono::{NaiveDateTime, Utc}; +use tantivy::tokenizer::Tokenizer; +use tantivy::Term; use crate::config::{Config, Language, SearchConfig}; use crate::events::{Event, EventId, EventType}; @@ -68,7 +70,7 @@ const COMMIT_TIME: Duration = Duration::from_secs(5); use tempfile::TempDir; #[cfg(test)] -use crate::events::{EVENT, JAPANESE_EVENTS}; +use crate::events::{EVENT, JAPANESE_EVENTS, TOPIC_EVENT}; pub(crate) struct Index { index: tv::Index, @@ -147,6 +149,13 @@ impl Writer { self.inner.add_document(doc); self.added_events += 1; } + + /// Delete the event with the given event id from the index. + pub fn delete_event(&mut self, event_id: &str) { + let term = Term::from_field_text(self.event_id_field, &event_id); + self.inner.delete_term(term); + self.inner.commit().unwrap(); + } } pub(crate) struct IndexSearcher { @@ -238,10 +247,12 @@ impl Index { let date_field = schemabuilder.add_date_field("date", tv::schema::INDEXED); - let room_id_field = schemabuilder.add_text_field("room_id", tv::schema::STRING); let sender_field = schemabuilder.add_text_field("sender", tv::schema::STRING); + let room_id_field = + schemabuilder.add_text_field("room_id", tv::schema::STORED | tv::schema::STRING); - let event_id_field = schemabuilder.add_text_field("event_id", tv::schema::STORED); + let event_id_field = + schemabuilder.add_text_field("event_id", tv::schema::STORED | tv::schema::STRING); let schema = schemabuilder.build(); @@ -486,3 +497,34 @@ fn event_count() { writer.force_commit().unwrap(); assert_eq!(writer.added_events, 0); } + +#[test] +fn delete_an_event() { + let tmpdir = TempDir::new().unwrap(); + let config = Config::new().set_language(&Language::English); + let index = Index::new(&tmpdir, &config).unwrap(); + + let mut writer = index.get_writer().unwrap(); + + writer.add_event(&EVENT); + writer.add_event(&TOPIC_EVENT); + writer.force_commit().unwrap(); + index.reload().unwrap(); + + let searcher = index.get_searcher(); + let result = searcher.search("Test", &Default::default()).unwrap(); + + let event_id = &EVENT.event_id; + + assert_eq!(result.len(), 2); + assert_eq!(&result[0].1, event_id); + + writer.delete_event(event_id); + writer.force_commit().unwrap(); + index.reload().unwrap(); + + let searcher = index.get_searcher(); + let result = searcher.search("Test", &Default::default()).unwrap(); + assert_eq!(result.len(), 1); + assert_eq!(&result[0].1, &TOPIC_EVENT.event_id); +} diff --git a/tests/integration_test.rs b/tests/integration_test.rs index db800dd..03e0a27 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -423,3 +423,29 @@ fn load_file_events_directions() { assert_eq!(result[0].0, IMAGE_EVENT.source); assert_eq!(result[1].0, VIDEO_EVENT.source); } + +#[test] +fn delete_events() { + let tmpdir = tempdir().unwrap(); + let mut db = Database::new(tmpdir.path()).unwrap(); + let profile = Profile::new("Alice", ""); + + db.add_event(EVENT.clone(), profile.clone()); + db.add_event(TOPIC_EVENT.clone(), profile); + db.force_commit().unwrap(); + db.reload().unwrap(); + + let searcher = db.get_searcher(); + let result = searcher.search("Test", &SearchConfig::new()).unwrap(); + assert_eq!(result.len(), 2); + + let receiver = db.delete_event(&EVENT.event_id); + let result = receiver.recv().unwrap(); + result.unwrap(); + db.force_commit().unwrap(); + db.reload().unwrap(); + + let result = searcher.search("Test", &SearchConfig::new()).unwrap(); + assert_eq!(result.len(), 1); + assert_eq!(result[0].event_source, TOPIC_EVENT.source); +} From 7f7d7fe169ede3e4ac59039b48e2245736518fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 4 Mar 2020 11:55:49 +0100 Subject: [PATCH 13/33] database: Improve the database recovery test. --- src/database/recovery.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/database/recovery.rs b/src/database/recovery.rs index 6b64769..67f5396 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -227,7 +227,9 @@ impl RecoveryDatabase { #[cfg(test)] mod test { - use crate::{Database, Error, Event, EventType, RecoveryDatabase}; + use crate::{Database, Error, Event, EventType, RecoveryDatabase, SearchConfig}; + use crate::database::DATABASE_VERSION; + use serde_json::Value; use std::path::PathBuf; use std::sync::atomic::Ordering; @@ -280,7 +282,7 @@ mod test { }, } - let mut recovery_db = RecoveryDatabase::new(path).expect("Can't open recovery db"); + let mut recovery_db = RecoveryDatabase::new(&path).expect("Can't open recovery db"); assert_ne!(recovery_db.info().total_events(), 0); recovery_db .delete_the_index() @@ -331,6 +333,17 @@ mod test { 999 ); - recovery_db.commit().unwrap(); + recovery_db.commit_and_close().unwrap(); + + let db = Database::new(&path).unwrap(); + let mut connection = db.get_connection().unwrap(); + + let (version, reindex_needed) = Database::get_version(&mut connection).unwrap(); + + assert_eq!(version, DATABASE_VERSION); + assert_eq!(reindex_needed, false); + + let result = db.search("Hello", &SearchConfig::new()).unwrap(); + assert!(!result.is_empty()) } } From f28220eb383067cc7d73847006cc07a6012424d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 4 Mar 2020 12:59:16 +0100 Subject: [PATCH 14/33] data: Add a v1 database with valid json in the event source field. --- data/database/v1_2/.managed.json | 1 + data/database/v1_2/.tantivy-meta.lock | 0 data/database/v1_2/.tantivy-writer.lock | 0 .../0112d870f836494da5f4c16699878d93.store | 0 .../18dcd68b373940f6844631d851e6139c.fast | Bin 0 -> 172 bytes ...18dcd68b373940f6844631d851e6139c.fieldnorm | Bin 0 -> 1335 bytes .../v1_2/18dcd68b373940f6844631d851e6139c.idx | Bin 0 -> 1278 bytes .../v1_2/18dcd68b373940f6844631d851e6139c.pos | Bin 0 -> 329 bytes .../18dcd68b373940f6844631d851e6139c.posidx | Bin 0 -> 195 bytes .../18dcd68b373940f6844631d851e6139c.store | Bin 0 -> 3459 bytes .../18dcd68b373940f6844631d851e6139c.term | Bin 0 -> 1805 bytes .../3b59e3c0f08646efb6b56192a98ab85f.fast | Bin 0 -> 172 bytes ...3b59e3c0f08646efb6b56192a98ab85f.fieldnorm | Bin 0 -> 200 bytes .../v1_2/3b59e3c0f08646efb6b56192a98ab85f.idx | Bin 0 -> 207 bytes .../v1_2/3b59e3c0f08646efb6b56192a98ab85f.pos | Bin 0 -> 216 bytes .../3b59e3c0f08646efb6b56192a98ab85f.posidx | Bin 0 -> 189 bytes .../3b59e3c0f08646efb6b56192a98ab85f.store | Bin 0 -> 240 bytes .../3b59e3c0f08646efb6b56192a98ab85f.term | Bin 0 -> 406 bytes .../5249de4da76b404098f026f248155bf1.fast | Bin 0 -> 172 bytes ...5249de4da76b404098f026f248155bf1.fieldnorm | Bin 0 -> 1351 bytes .../v1_2/5249de4da76b404098f026f248155bf1.idx | Bin 0 -> 1310 bytes .../v1_2/5249de4da76b404098f026f248155bf1.pos | Bin 0 -> 329 bytes .../5249de4da76b404098f026f248155bf1.posidx | Bin 0 -> 195 bytes .../5249de4da76b404098f026f248155bf1.store | Bin 0 -> 3485 bytes .../5249de4da76b404098f026f248155bf1.term | Bin 0 -> 2262 bytes .../88b4ad3f5a1e430f9ea03e2ef43c39f7.fast | Bin 0 -> 172 bytes ...88b4ad3f5a1e430f9ea03e2ef43c39f7.fieldnorm | Bin 0 -> 200 bytes .../v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.idx | Bin 0 -> 207 bytes .../v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.pos | Bin 0 -> 216 bytes .../88b4ad3f5a1e430f9ea03e2ef43c39f7.posidx | Bin 0 -> 189 bytes .../88b4ad3f5a1e430f9ea03e2ef43c39f7.store | Bin 0 -> 239 bytes .../88b4ad3f5a1e430f9ea03e2ef43c39f7.term | Bin 0 -> 406 bytes .../9883d1a65e92474983c3022fb99ea0da.fast | Bin 0 -> 172 bytes ...9883d1a65e92474983c3022fb99ea0da.fieldnorm | Bin 0 -> 464 bytes .../v1_2/9883d1a65e92474983c3022fb99ea0da.idx | Bin 0 -> 670 bytes .../v1_2/9883d1a65e92474983c3022fb99ea0da.pos | Bin 0 -> 232 bytes .../9883d1a65e92474983c3022fb99ea0da.posidx | Bin 0 -> 190 bytes .../9883d1a65e92474983c3022fb99ea0da.store | Bin 0 -> 1044 bytes .../9883d1a65e92474983c3022fb99ea0da.term | Bin 0 -> 852 bytes .../bf6498b5a1e948d090131605048ecbcd.fast | Bin 0 -> 172 bytes ...bf6498b5a1e948d090131605048ecbcd.fieldnorm | Bin 0 -> 1623 bytes .../v1_2/bf6498b5a1e948d090131605048ecbcd.idx | Bin 0 -> 1854 bytes .../v1_2/bf6498b5a1e948d090131605048ecbcd.pos | Bin 0 -> 345 bytes .../bf6498b5a1e948d090131605048ecbcd.posidx | Bin 0 -> 197 bytes .../bf6498b5a1e948d090131605048ecbcd.store | Bin 0 -> 4270 bytes .../bf6498b5a1e948d090131605048ecbcd.term | Bin 0 -> 2526 bytes .../c7f9f53e463f4d9297d257449d63b8d0.fast | Bin 0 -> 172 bytes ...c7f9f53e463f4d9297d257449d63b8d0.fieldnorm | Bin 0 -> 200 bytes .../v1_2/c7f9f53e463f4d9297d257449d63b8d0.idx | Bin 0 -> 207 bytes .../v1_2/c7f9f53e463f4d9297d257449d63b8d0.pos | Bin 0 -> 216 bytes .../c7f9f53e463f4d9297d257449d63b8d0.posidx | Bin 0 -> 189 bytes .../c7f9f53e463f4d9297d257449d63b8d0.store | Bin 0 -> 239 bytes .../c7f9f53e463f4d9297d257449d63b8d0.term | Bin 0 -> 406 bytes .../d013a4c1859e403093ef8e37d7e88f32.fast | Bin 0 -> 172 bytes ...d013a4c1859e403093ef8e37d7e88f32.fieldnorm | Bin 0 -> 200 bytes .../v1_2/d013a4c1859e403093ef8e37d7e88f32.idx | Bin 0 -> 207 bytes .../v1_2/d013a4c1859e403093ef8e37d7e88f32.pos | Bin 0 -> 216 bytes .../d013a4c1859e403093ef8e37d7e88f32.posidx | Bin 0 -> 189 bytes .../d013a4c1859e403093ef8e37d7e88f32.store | Bin 0 -> 239 bytes .../d013a4c1859e403093ef8e37d7e88f32.term | Bin 0 -> 406 bytes data/database/v1_2/events.db | Bin 0 -> 675840 bytes data/database/v1_2/meta.json | 99 ++++++++++++++++++ 62 files changed, 100 insertions(+) create mode 100644 data/database/v1_2/.managed.json create mode 100644 data/database/v1_2/.tantivy-meta.lock create mode 100644 data/database/v1_2/.tantivy-writer.lock create mode 100644 data/database/v1_2/0112d870f836494da5f4c16699878d93.store create mode 100644 data/database/v1_2/18dcd68b373940f6844631d851e6139c.fast create mode 100644 data/database/v1_2/18dcd68b373940f6844631d851e6139c.fieldnorm create mode 100644 data/database/v1_2/18dcd68b373940f6844631d851e6139c.idx create mode 100644 data/database/v1_2/18dcd68b373940f6844631d851e6139c.pos create mode 100644 data/database/v1_2/18dcd68b373940f6844631d851e6139c.posidx create mode 100644 data/database/v1_2/18dcd68b373940f6844631d851e6139c.store create mode 100644 data/database/v1_2/18dcd68b373940f6844631d851e6139c.term create mode 100644 data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.fast create mode 100644 data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.fieldnorm create mode 100644 data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.idx create mode 100644 data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.pos create mode 100644 data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.posidx create mode 100644 data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.store create mode 100644 data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.term create mode 100644 data/database/v1_2/5249de4da76b404098f026f248155bf1.fast create mode 100644 data/database/v1_2/5249de4da76b404098f026f248155bf1.fieldnorm create mode 100644 data/database/v1_2/5249de4da76b404098f026f248155bf1.idx create mode 100644 data/database/v1_2/5249de4da76b404098f026f248155bf1.pos create mode 100644 data/database/v1_2/5249de4da76b404098f026f248155bf1.posidx create mode 100644 data/database/v1_2/5249de4da76b404098f026f248155bf1.store create mode 100644 data/database/v1_2/5249de4da76b404098f026f248155bf1.term create mode 100644 data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.fast create mode 100644 data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.fieldnorm create mode 100644 data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.idx create mode 100644 data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.pos create mode 100644 data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.posidx create mode 100644 data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.store create mode 100644 data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.term create mode 100644 data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.fast create mode 100644 data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.fieldnorm create mode 100644 data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.idx create mode 100644 data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.pos create mode 100644 data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.posidx create mode 100644 data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.store create mode 100644 data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.term create mode 100644 data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.fast create mode 100644 data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.fieldnorm create mode 100644 data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.idx create mode 100644 data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.pos create mode 100644 data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.posidx create mode 100644 data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.store create mode 100644 data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.term create mode 100644 data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.fast create mode 100644 data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.fieldnorm create mode 100644 data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.idx create mode 100644 data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.pos create mode 100644 data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.posidx create mode 100644 data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.store create mode 100644 data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.term create mode 100644 data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.fast create mode 100644 data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.fieldnorm create mode 100644 data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.idx create mode 100644 data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.pos create mode 100644 data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.posidx create mode 100644 data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.store create mode 100644 data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.term create mode 100644 data/database/v1_2/events.db create mode 100644 data/database/v1_2/meta.json diff --git a/data/database/v1_2/.managed.json b/data/database/v1_2/.managed.json new file mode 100644 index 0000000..2cc3f4d --- /dev/null +++ b/data/database/v1_2/.managed.json @@ -0,0 +1 @@ +["5249de4da76b404098f026f248155bf1.store","88b4ad3f5a1e430f9ea03e2ef43c39f7.fast","88b4ad3f5a1e430f9ea03e2ef43c39f7.fieldnorm","88b4ad3f5a1e430f9ea03e2ef43c39f7.pos","c7f9f53e463f4d9297d257449d63b8d0.posidx","9883d1a65e92474983c3022fb99ea0da.posidx","bf6498b5a1e948d090131605048ecbcd.fieldnorm","3b59e3c0f08646efb6b56192a98ab85f.idx","bf6498b5a1e948d090131605048ecbcd.posidx","5249de4da76b404098f026f248155bf1.term","c7f9f53e463f4d9297d257449d63b8d0.fast","9883d1a65e92474983c3022fb99ea0da.pos","d013a4c1859e403093ef8e37d7e88f32.pos","c7f9f53e463f4d9297d257449d63b8d0.term","5249de4da76b404098f026f248155bf1.posidx","18dcd68b373940f6844631d851e6139c.posidx","0112d870f836494da5f4c16699878d93.store","5249de4da76b404098f026f248155bf1.pos","3b59e3c0f08646efb6b56192a98ab85f.pos","bf6498b5a1e948d090131605048ecbcd.idx","d013a4c1859e403093ef8e37d7e88f32.posidx","c7f9f53e463f4d9297d257449d63b8d0.pos","5249de4da76b404098f026f248155bf1.idx","bf6498b5a1e948d090131605048ecbcd.store","9883d1a65e92474983c3022fb99ea0da.fast","c7f9f53e463f4d9297d257449d63b8d0.fieldnorm","88b4ad3f5a1e430f9ea03e2ef43c39f7.posidx","0112d870f836494da5f4c16699878d93.fast","c7f9f53e463f4d9297d257449d63b8d0.store","9883d1a65e92474983c3022fb99ea0da.term","3b59e3c0f08646efb6b56192a98ab85f.fieldnorm","d013a4c1859e403093ef8e37d7e88f32.fieldnorm","d013a4c1859e403093ef8e37d7e88f32.term","88b4ad3f5a1e430f9ea03e2ef43c39f7.idx","bf6498b5a1e948d090131605048ecbcd.pos","5249de4da76b404098f026f248155bf1.fast","5249de4da76b404098f026f248155bf1.fieldnorm","18dcd68b373940f6844631d851e6139c.fieldnorm","c7f9f53e463f4d9297d257449d63b8d0.idx","meta.json","18dcd68b373940f6844631d851e6139c.term","88b4ad3f5a1e430f9ea03e2ef43c39f7.term","3b59e3c0f08646efb6b56192a98ab85f.term","bf6498b5a1e948d090131605048ecbcd.term","bf6498b5a1e948d090131605048ecbcd.fast","9883d1a65e92474983c3022fb99ea0da.fieldnorm","3b59e3c0f08646efb6b56192a98ab85f.fast","18dcd68b373940f6844631d851e6139c.fast","88b4ad3f5a1e430f9ea03e2ef43c39f7.store","9883d1a65e92474983c3022fb99ea0da.idx","d013a4c1859e403093ef8e37d7e88f32.fast","18dcd68b373940f6844631d851e6139c.idx","9883d1a65e92474983c3022fb99ea0da.store","18dcd68b373940f6844631d851e6139c.store","18dcd68b373940f6844631d851e6139c.pos","3b59e3c0f08646efb6b56192a98ab85f.store","d013a4c1859e403093ef8e37d7e88f32.store","d013a4c1859e403093ef8e37d7e88f32.idx","3b59e3c0f08646efb6b56192a98ab85f.posidx"] diff --git a/data/database/v1_2/.tantivy-meta.lock b/data/database/v1_2/.tantivy-meta.lock new file mode 100644 index 0000000..e69de29 diff --git a/data/database/v1_2/.tantivy-writer.lock b/data/database/v1_2/.tantivy-writer.lock new file mode 100644 index 0000000..e69de29 diff --git a/data/database/v1_2/0112d870f836494da5f4c16699878d93.store b/data/database/v1_2/0112d870f836494da5f4c16699878d93.store new file mode 100644 index 0000000..e69de29 diff --git a/data/database/v1_2/18dcd68b373940f6844631d851e6139c.fast b/data/database/v1_2/18dcd68b373940f6844631d851e6139c.fast new file mode 100644 index 0000000000000000000000000000000000000000..a9cfc669cfa686efccf2d714fd88f4d2acf6f9d5 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jDGuBba%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tNz&B$gy+ jC|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko&`(85>_U>vQC=Rgi3O@=Hv z4kk~5B8O1oP$tmEVNB$3CUFFlsS092bx;#@3OWZ}g04ZgpnK3G=o$11dIz;ZpP+Bh zFX$f(2nGg&g2BO%U}!Kb7#@rWW=<|Y?O3e6Tq~!8Em-*9;9uf@WoBfooJSec7bVnQ zX0dpsZ6o8)D|z**Cms64T*Sb zW=zY3rm@+4I#rC9l8Jbsn9a8|HD}Ygd`qFwn$0xEJ9_6$jMAy`*?iPkpNP_}nF>oL n6HzWzY#tXiHYB1yYc-Wx@|EuLoka8(&8RWz5RE3yDm(lG57>&3 literal 0 HcmV?d00001 diff --git a/data/database/v1_2/18dcd68b373940f6844631d851e6139c.pos b/data/database/v1_2/18dcd68b373940f6844631d851e6139c.pos new file mode 100644 index 0000000000000000000000000000000000000000..7f810efcbcf98463631c58021dba7e67aef6311b GIT binary patch literal 329 zcmZ3rib9~pz_1DlGoXV5|Nk=};r|#wp5gz01a4{o8PFim$PA+RfJ8qdka)u4^|7ru zFR`GYa(78$UP)$Ir9zp3o}rA|)#W9i`mNJP^y!P)DgCu_QS|$;wzq3E8apveY7wZlD?+ SB@8o_tdt;zD%CCqx)1rUnq%(9H}Yd4WVfNZ8b_KE16tFR`GYa(78$UP)$Ir9zp3o}rA|)#W y9i`mNJP^y!P)DgCu_QS|$;wzq3E8apveY7wZlD?+B@8o_tdt;zD%CCqx)1;al06{+ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/18dcd68b373940f6844631d851e6139c.store b/data/database/v1_2/18dcd68b373940f6844631d851e6139c.store new file mode 100644 index 0000000000000000000000000000000000000000..9bb2d6e75cb27a84bcb9ec96d53e908d9aaf5330 GIT binary patch literal 3459 zcmZWsdyHIF89(#b-MhQf%iVHMd&ix@?Yf}d)XRB47AI1`RW^82X5E2qf@Q?g7P=4G zZK1#ti&)!&2o%!-MOyl>q==D!d^8kS&<2In6h%dfwDFagsDuy@sQMd;(Zoq6duR6E zbH4NaUf=wnM94qe30a>tmrXAxPnO8>!xxa-YpWmJTqJny7!XQI>zx?d)LcC^m0mM7 zL3@?;N^5V;(5i{%nzf>rRJ7oDNi~9NuC=q8yYl5^cjsF5wE>5ZQb{$mdTQpPQBqOX zGUc=$!L{braAR1xmyTAX<4kaG(@{dJ6=ylO*7~$c=&KcBm}1uPkuj1uC7rQKj1lS* zEX{?o)kAc;B9&7D|EW*6c0ol>`SNsmH1^II$?I7zc3w!&tM8Hr7H56;4S1)W)5fo+ z%PL-aqnvsF5JDQwj4f{=4|Oi9+&|!iLj{eeNJS{a1U{B6ov2ui+oTt*gKMi56HKq>SUXwz$@eh2+>HZRT_oJ3Pj8?Pqjfi7W4xc8+Yt+FDw!4KHscyB0^u zy#w4R=CeQMD%vpSwHN6YLf0maamIzLUQUmejB_UUR_f5RL^Ecj^Nq*z3GNp{`Pl>L zkvH7p;Ek^k6zmPd#^qP(p~Ry3!iwztTwsATf7Z308kGmnb2z zoT+`9ZY3_aHQ-K;>;n`ITPl$qC5Zu61}mH%>qxi<3eJx#BMCQ7YOS;7`NV6iAX(!~ zK9LM{C{??S9tDEdf-~9ae1ZmH7oK(I6ExO&EgPTAwT_~#QrR3ygcjfq%kFJUI9iNt zYRAX=6Kezq@In_r9AK!?DxTh-r?19%0&J{*JYSJo8ty^oRTPW>Z`!MoCq?WASSTPy1e&?U~j zw(hE1>79$xz*qw&#@Gla6o(2Mu1HX#^D-Jdw&r4qhz zVjXr|JUHnQ`vhvIt%&~;s(Da2?B*YZqCw>0O9T&F7nx+U@`!!Er)8_Xq8xcAaz zGlinGdv7K(d#RWx&l$*k=EMVgKwwya-sI`NgiCFKTeTP03Z3!XG!_Fl)NY*4cIF}o zQK`Kj8GfcS_7)GybUdhTi;NJAT~(ml5&+1h;EnACq87~(nf|aqNAZ8@_2whPtGW`n z4hM6yBSokL%5o6bgSn#7;hmj?&6dlPk&~bmz67r=kem=F`KkkN{XN>d8iOMWr_1PHf}NLgG*(?#SYnFa%7A3rEU_ijr-JRk)qZy2n#^!zw81zy?~&yUHNdZJAhTzuBVqL-Z=s3 zW`-od3fC;Vp%7UPlM~xIbQ~Bhas}~pOV+4HDRBJawhf14IDxS)dlwKo?u2d}=!mW0 z&dY2kgarm`%LkWtk_We)=-V*>p$g3bLOyX^feOC%9kQ#_z+4P$LDW7$zaLpGq-tCO zdxZH2UDfms+>JwOnLPs4!ND{H_y`FH0wThX&Kv#*mXjWCBC_9iqhCTXr)%fw9f^mP zK#h$ZLF_#WI^Whf)Az@BlPbXoLOn7Dv zwhoRSTW@(|eZFXHINVLNxTlk@gU=a(R%L6zEaSb)y*vDTTOzQta~|IUHLF12GiQ&T zTasYQ_&0+H1}eq)RQs296IW-s#KX9p=2>rNY;e2f^%DB$HEhLJkLpVk&cJ2(V=3P% z1!~q@Hmal~l(0)bSHGYgL_^j&K6s*=juF52T%ygda{B8L;z5dVE*kzKgaj9cAI=`6 zqeO=n21OY0>$#HUR))L>Aqdw4xA6LXn+h?sjes(j<>}!V(W|&hFKeS?F`yONkAJ2Ez6cmKtCbNdNN2zx z#g9=edTFc|CR^JUbAz>2dUavLlO?c5=IX=Ox8dYLRMaLjVS>nq3$nqxy6Bb|f&o42 zr`u!X7Pl;Yw4?m%$Re(t`BsTmV{n{1W<~<+;;b~n>*_&lkAXrs$HfZ;>SBopV73Qh zIFx|&-NUa@(|kNo+SdQvUUHJLaBSZ2bA`D-1sG|n1|Esb0ojfC?pd^2)H1v{BCfHc zkYGT-K%xLN(#>-Pvi_lqh}=0vuCm1)FjQEl7{9ycRFm-WTk~XXr9Us}1<z2W*?`$k;1s*PHm#E(1QtvKZt}ijum2OFeBLX`TW1x{n-UYMCGvpcpQF! z56rf(0ZA6N3Crz}Gx z*nv-4r}N6yli}&^`i6OdLradA2KNSKQ^E|R<~EFd2!xbUqVd`BTnw&(>*<*;|EU-V zAninyqZ2U{uf0nbqeIAFr4>(~DED8A^I=XIdLyJZ!W^M^xG?-hAKe~l&T#H?7S>N7 zI3$o1X2iku;miO|To=-50K{eZVy8c!_EvzrF;2+xs2(X{2yzV-mH;N-dtO=7Wk@t1 z*5kqb-EZ`U4$Coe43t2W!pjyE zO7J()yu;sGemc;M&waW6u{^>F!=+3|dh`R4Wz5>fXoT&UWjdQ6gr8arbGss-+hHWg z9L&&n!)Bp;h;rzOfW8A-7;lBl-Yj5VJRH{@Hz~@LzOo7@7b8 literal 0 HcmV?d00001 diff --git a/data/database/v1_2/18dcd68b373940f6844631d851e6139c.term b/data/database/v1_2/18dcd68b373940f6844631d851e6139c.term new file mode 100644 index 0000000000000000000000000000000000000000..77359906c4b8e6eb62526a1c8776045f7f64b63f GIT binary patch literal 1805 zcmZQ#Km!7cnVA^DVwPscMuIE|o+*&0C@U!{$jiyf$iUCf&&UWuvX&O+W~L^_MurB0 zTnwsk75a)GpbrE{3cL`;85rFvCWqE0FVVI%({IVK-VPV(|1sViY4G$OwOQ3*( zATUT67|e|XnUob}B}4>4ZoA5u&ncC{DJA8BYz#;p&?!t1S6P}F3PK$PauSqjVPXJd znwtQf4N+@u3REC1Au7br!^y_PzzBpq4B`w*42KzXf!Ku60_YZ4TqtruEdXhPh5*7S z3p1dpAeR7Xs7uU%o`5Pe16eO6E+PoBh?&8Zk&#DSUS7-86k)s|%y=_nh(YGY2!r4@ zT7s+r8N|oU!OG0Qm{EN4hi8k2vYV1) zQ0F9{86}TYL^PIqc(!_Jhb0{h>Yf&}aE&LHn;NryrvFPmfW z^@*lNfNQ5$S4i-(MNXkpSFMRCeX6Ask$TdrJ1lzJqeG$7*X^nJ`c&H>p_S9SCnEWn zl5^P1O=o75KGQMDSnBEB82TQWZFhEjeWq(saJ19AFQ)j}BIoeAyWZR=eXeIy z@${s3e_ZvqM~B1b@B8!P>vMgF26nET2@hJ>j9q>#JR~H!?uCI{hq>3AiH|0TO+NBt z$uTX5QcdasOvW=uczX3Db_X2C~)t~wW0`R3aog+HJ17X6)er>qcwKMOHY03um?%bJg&ZHH){oZ_Q z(M`R#W?4JJPrse@?nc?=W52iE+x7F^Tl0bg?c8~DK0IkNcK@^U(Iv_C?<~qrZ1;XQ z_tS@IlaK$|^X!#n{(H-s3(vdr=70IK?6dpd{jZp!^gmcN-4H+XZoxN>?ZGGh9(pHL z_5Oo(#{+ks{6#-Rj&Jt(cl49dto0vl`d*a#ykGoF;kxk2e6ZRyyIDW3pLxIRpT+mfC;y-OSM}@tXL&|8CKdw$0fj^d1~w)}IWCq7 z1_BEnIWX|BFq#Rmd=<(nEnjE1ysknIh8K%yU{p|T`JtgSdN zv7n%GcS&MiNoHB4LYaY{p`o6!jzVT$N@_)XT7FS(Vu?bTp^idvNq$jkd~$wnK~ZXP zab|v=l>$WXwQ8l@#H{=xB`X6RrQFOs5X;a|N2wsOBsoLL%2-DU*{t}o)FO~>pc)+| R3^SFilpuyG)h-6Q5CHGq@x1^5 literal 0 HcmV?d00001 diff --git a/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.fast b/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.fast new file mode 100644 index 0000000000000000000000000000000000000000..a9cfc669cfa686efccf2d714fd88f4d2acf6f9d5 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jDGuBba%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tNz&B$gy+ jC|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko)k`LzQY516>FJ8$Un~ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.idx b/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.idx new file mode 100644 index 0000000000000000000000000000000000000000..4f243f10bb1b4a52a65e02c79811f034971785d1 GIT binary patch literal 207 zcmZQ(fPjWZ5M+e$ni@c?hCXHx$qOXtRPHWG%qz((t5hg6&@(jD zGuBba%u7kFh)>He%1ta$C^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZ zpre$VnFnGS8tNz&B$gy+C|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko`R!D+P$&Yt>4*iCOtYN>&Cs xO1YVNAeNz_j#5ElNpgmgm9dTzvRUzEsYM{&Ks7o_7-lM2DM1WXs$C3pApl~DJ+}Y= literal 0 HcmV?d00001 diff --git a/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.posidx b/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.posidx new file mode 100644 index 0000000000000000000000000000000000000000..a9ee6c3eb017f9daa3834e6b67f7420a30981464 GIT binary patch literal 189 zcmZQ#0D`6l5ZTbm3?g}fL_Z^tc%A!WXIpVzVnIRW?vlj3lFYJ7g)##@Lqk1d9fi!i zl+=p&wEUvn#1e%vLmh?UlKi67_~iWDf}+&o;>`R!D+P$&Yt>4*iCOtYN>&CsO1YVN tAeNz_j#5ElNpgmgm9dTzvRUzEsYM{&Ks7o_7-lM2DM1WXs$C3pApi<;KEwb3 literal 0 HcmV?d00001 diff --git a/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.store b/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.store new file mode 100644 index 0000000000000000000000000000000000000000..b5d3e1e7481597baa27e6b7744a4c2eca945019f GIT binary patch literal 240 zcmdO6U|{&q#=ubQml#kG$*91;`?O2}r#m!%egbOY7sC}EhXWTgZ#RH=3`(1id-<4h|6 literal 0 HcmV?d00001 diff --git a/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.term b/data/database/v1_2/3b59e3c0f08646efb6b56192a98ab85f.term new file mode 100644 index 0000000000000000000000000000000000000000..a1f03a2a4684aa3da32b61ac875eff7856c8c589 GIT binary patch literal 406 zcmZQ#Km!6T=g%Kv5SVoS_z@;X21a&<@(eRUW@e}=H7G3)rD5VQLl|KUB$|<#DU{0) zD!_y!0cHv`9y@aG{LxcK&fmOn(sCWQo4!V6XahNISe5klSlx}JOF&aLA zoY}w&B>F)b4muv4(N>(7SWr;8yCgBMB(tniq0B(f&`{4qffhM7uMN)SVpY8L}t2mn*)R-pg@ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/5249de4da76b404098f026f248155bf1.fast b/data/database/v1_2/5249de4da76b404098f026f248155bf1.fast new file mode 100644 index 0000000000000000000000000000000000000000..a9cfc669cfa686efccf2d714fd88f4d2acf6f9d5 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jDGuBba%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tNz&B$gy+ jC|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko?Zg)3dpT1ndfm&c+yjz_Kase=Xo!9(Mw+TidVg6zSq6sO>cSIJKpu4_kG|)ANklP zKJ}T;ec?-A`Pw(W^_}ni;733C*)JCO)o*_Hhd=%0Z~s_mkqTmTppuSsqBC9SN;kUG zgP!!Fir)00FV*y;KLZ%ZAOLgf$8rGzi zBx_N}+N{I6tjGFnK#C37h>h8VP1%gmY|a*J$yRL5Hf+mwY|jqt$WH9cF6_!~?9LeW zU{Cg9Z}wqd_G5nz;6M(dp0T7kmWhP!6M+j1pN|IGi9yD|wEfz_E^G z5^WsCaVB##Q#gjHOj8lWf(}7tFkQ!>Q_wl+5*)8<&@Jd5^ay$ey@IM>hTcJ+-~@ex z>Y!iHKNt`U3}zY>3=W0_LxU3y3x)?Hf|0?fVD{9~GmpiJrCMI?YT=?~qkR8m;eR<) zJXXr5#LOj$6-z3%w49cfK`6Ua6su>HKbvAzsmv-LvS40e%=Fewx}~LUZa$sKHx=6A zh1!~AvZgK(Z_12ooK!zPn`=(zL?VKrUnq%(9H}Yd4WVfNZ8b_KE16tFR`GYa(78$UP)$Ir9zp3o}rA|)#W y9i`mNJP^y!P)DgCu_QS|$;wzq3E8apveY7wZlD?+B@8o_tdt;zD%CCqx)1;al06{+ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/5249de4da76b404098f026f248155bf1.store b/data/database/v1_2/5249de4da76b404098f026f248155bf1.store new file mode 100644 index 0000000000000000000000000000000000000000..50deea89b54e71fd0fd0695f718a61a08226de46 GIT binary patch literal 3485 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 LO?zh#Aj1Cw`S>Cw literal 0 HcmV?d00001 diff --git a/data/database/v1_2/5249de4da76b404098f026f248155bf1.term b/data/database/v1_2/5249de4da76b404098f026f248155bf1.term new file mode 100644 index 0000000000000000000000000000000000000000..c5cfd7a685b22a586958a91df79836718205e446 GIT binary patch literal 2262 zcmZuw2~bm46n#JZ1PI#)k+1{^pGDN5fowmxGz7r_YEcjYQ8uAKWf3ApTQn#ji;CKc zC`%PZZO5f`rb^XOKnP2zSZ8Y0aX}Qs6-2Co8OH>y?2)N!bMGxTfJ_7!SR4CxWLNr~L2=aRC(})PN zkRC4-!iB)B>26MT))ppIfLOWmq)};Km)431p@7fh`oOw$txf^tLsg9te2%3WCwSVU z5C*7GAyTZ#4h~N>lf zR4dGkZb+p7grHAxaGOntgLJlA(v^WC7^tkHp@36R0&u-3nm*v@{cWMAW^mUjARn4) z2Bw02zzKN351mpxsSkh^_Vly>Y)?;ns|&(HXvlNW4NidyIQTHYg|kF}A!JAbe}V+$ z4iZ8+NkI+L48BUys>4liQWShPp{n4VUXR#Q|kd0nJFYhsO!jHyOa zx!8b)i$e>xnA*yES*Ve_R9YZ0u}NqO-CE2fMtfb1uz(WjmIYHh>cvZo%Gi;z2e_$i zQipVFpo5^VY3a6|bMr@5L_+hj^2(UT z(LQ%uPFqP(@gi<=yR*gY z!gtqiw_X3p(@p9g6kNJ2q%xr;{M(~7#Mq_%Ds^LP6uU_W6si5%}>puw++89 zyy?|lcPQ8V+~$r|tuNg-E`0TOS??-S=fipS?f0eg+ehXe`0(oDuEEkpn~!XC|4Z2E z)HNP<{`APa%Hea{hZ_FjJgx}3-~B%I_7|@ws^9i^e|~IY&YNeQmwP7U?-`@c2#tbr zFpL#1mQyJRla7{fFnOO?Zh|5_D|9dv18e+%B@GF-N5$(falfD3#t4bS(W>28Q?f+P zq$7DV(BYpk)}RF7rpQhoH1s+qPxY5iGe?g2qQ^%t@XVmY3u8Sfpx7Fy7G1OB+J6I9 zplH3?)7I76bL(1bYkP0AqNUlTN%ME{P{%o|-x^$#&iWWoUCdVBZ;_J+`Rod^y4)Oo zRgeiauD;CToQ(LatPK}r@fotz+zqT;&Ma^5SzIG5fq*|;xgSN Wo6LqWZ2S{W+!t4o;`xW6!v6rmaStW{ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.fast b/data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.fast new file mode 100644 index 0000000000000000000000000000000000000000..a9cfc669cfa686efccf2d714fd88f4d2acf6f9d5 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jDGuBba%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tNz&B$gy+ jC|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko)k`LzQY516>FJ8$Un~ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.idx b/data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.idx new file mode 100644 index 0000000000000000000000000000000000000000..4f243f10bb1b4a52a65e02c79811f034971785d1 GIT binary patch literal 207 zcmZQ(fPjWZ5M+e$ni@c?hCXHx$qOXtRPHWG%qz((t5hg6&@(jD zGuBba%u7kFh)>He%1ta$C^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZ zpre$VnFnGS8tNz&B$gy+C|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko`R!D+P$&Yt>4*iCOtYN>&Cs xO1YVNAeNz_j#5ElNpgmgm9dTzvRUzEsYM{&Ks7o_7-lM2DM1WXs$C3pApl~DJ+}Y= literal 0 HcmV?d00001 diff --git a/data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.posidx b/data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.posidx new file mode 100644 index 0000000000000000000000000000000000000000..a9ee6c3eb017f9daa3834e6b67f7420a30981464 GIT binary patch literal 189 zcmZQ#0D`6l5ZTbm3?g}fL_Z^tc%A!WXIpVzVnIRW?vlj3lFYJ7g)##@Lqk1d9fi!i zl+=p&wEUvn#1e%vLmh?UlKi67_~iWDf}+&o;>`R!D+P$&Yt>4*iCOtYN>&CsO1YVN tAeNz_j#5ElNpgmgm9dTzvRUzEsYM{&Ks7o_7-lM2DM1WXs$C3pApi<;KEwb3 literal 0 HcmV?d00001 diff --git a/data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.store b/data/database/v1_2/88b4ad3f5a1e430f9ea03e2ef43c39f7.store new file mode 100644 index 0000000000000000000000000000000000000000..b71dbdb68aa768c1e53160a656f4e835ef5fbcf4 GIT binary patch literal 239 zcmdO8U|{&q#=ubQml#kG$tcgj5XL?VKnI_c6(sCWQo4!V6XahNISe5klSlx}JOF&aLA zoY}w&B>F)biZcSfWs7 zsH0F^l3$b>pPZjtP?TC+oSC0zr2x@;ty(EJF)P1F$;v=SDK|3@#4g?wFsmes76N#!%QVBC5WL)wTpo+1OQe!R-^y` literal 0 HcmV?d00001 diff --git a/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.fast b/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.fast new file mode 100644 index 0000000000000000000000000000000000000000..a9cfc669cfa686efccf2d714fd88f4d2acf6f9d5 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jDGuBba%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tNz&B$gy+ jC|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko zC^OJAG}JTJQOL|oNv()a%P-1JEKw*k)KMrd$uCNcPtMORC`v6Z&dkrVQh?~aR;`qq zn3Z3oWM!bEl$)6cVi_9hC>11@BxfjD8S5w^n-yP{S_IM!RHLJWVWyIm62wrY+QmQ@ F0stJQLAC$@ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.idx b/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.idx new file mode 100644 index 0000000000000000000000000000000000000000..6f73d458858bd407dd425697ad7410d1a5327950 GIT binary patch literal 670 zcmd6kIZnf15QRbX93TzWUt3YEbZ$9_Wd$RQL5WGGm}Z7q=9p)JMV45m z%nGZlvCamYY*AsG9d_Acp92m#;+PXoIpdrQF1g~G8*aJdo(CSO^29SQyi((hcj6R( zU;iUTd&6gbd6RrDX5|uvmbkS>QfiJQQEU4u`nK-6*=nHMff;6{FqKr4WLlO?yTj~ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.pos b/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.pos new file mode 100644 index 0000000000000000000000000000000000000000..0db859f417b65aeda53826ac0e32c0eb41d09af5 GIT binary patch literal 232 zcmZ3r3KcLhFfhO{kje1pKRXaJGyH?%rUsB`!v%KtK)Qiybd)g6RI*Zn L7^+me80bO(Zktcf literal 0 HcmV?d00001 diff --git a/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.posidx b/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.posidx new file mode 100644 index 0000000000000000000000000000000000000000..18a334c24240bbd42ae3a2a0d79fee130af26864 GIT binary patch literal 190 zcmZQ#WB`Ju1`yfM#tb5PfkZz@_^IuRn6~1)#Dap#-6e^6C7ETF3S|a*hK72^ItrP2 zDXA6lY57IDi6shUhB^wxCHY0E@yYqQ1x2aF#hLkeRtgZk*Q%9r6SMM*l&lPNlyWok tKrBN;9i@WAlH?2}D`OocWV7PSQj0*kfogP=Fw9i4Qi2$&RJ$1HLI8dhJ>viX literal 0 HcmV?d00001 diff --git a/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.store b/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.store new file mode 100644 index 0000000000000000000000000000000000000000..7bf1ea356605b32a5445b6a24011d303d671d02c GIT binary patch literal 1044 zcmZXTO=x6A5Xbv%f)H3Wtgq#b^9Ea6v_P1@UX~>*jheD-BA6;2Ay54O|a6UR8x*L<(c(nOkb#XHOV5#x&+igi9 zVer`98*NM`S>3$9RDbZTHlkpPzWeMWWJ*S6K!O_Cafy^tjO2!6Qvgc<2z@c7XO9kr zD>03$%Z|li|EejxX7>;VbyJ2Aq9=-dHU$SCC1HcjdrL>!6`3BB(u z7fIAlz~1fjMIk@{J`C?YQ3N1PAcI4bd&d-cc&IwSm{J;iqTZR*8M)da{g$g&ZDjAd z{l?(^*B1k)$8Eic9ufl#zRU{7pu&TI-yofvBv8#o8Rg&QE&dwba+G=G){b)+mpCMoxDs@qN08$hCi}sSEvf96F z>n9_pc=~2vd(9F#V0BlfWP}JYq{fr>=K{UMfHJ%>A1+lYj~iy$D@8xJu#lrplccI{ zsFUkxcy=oXnMUfI=wRKM6$nxL;J$vq-ptu6E#a3I?KmgK5T$Ws@5v)-#W=XOP>@cq z__Y5QJ$6=!1Eaw4JD9(ZE3e%e>cg6^fA>fA{6?mq&!^vi_R7xIXgb~dYBt)MZSL+h zcU=WgVW+vd_4NAlYtKx!$D>(u7dp+I*<^ctO;b*{*LQX{CtKa-vG#`-TI12B$#$#j uI<4{M*8Bv}X-!A7iyN&jc3S_0#ut?(b~Tl?(* literal 0 HcmV?d00001 diff --git a/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.term b/data/database/v1_2/9883d1a65e92474983c3022fb99ea0da.term new file mode 100644 index 0000000000000000000000000000000000000000..f93a4245def85525f84e80c4b160c7beac27e93a GIT binary patch literal 852 zcmZXQ%Wm3G5QhER+;71N34vTNCkY{mxfo+?$UU@=kZuu5sX`?#0z{ium69lBTdA*5 zb=?Q(rb%cbby2#i)Lq}Bn;wHriaHC={~yo!X3nt8WPn;#=2=!3j3!GwXUJTJ=k!CG zS%;Nn;0#3anwsM+MnN`h*5(y?EGf(&s1Gnz8FTXwQp?g7;b4IGd7L(mf#wO4R|&0H z)Y~XoIU}Wcm(fh2r6Z{-i>xjp(v4PD^Y;8dlkw_q!L@I@J8j^%e2C|H77K(yg z4yp=GLq3l}0o&Wy*}?8E_V%#9kAnjo9^&YzNTb*LV?2(XcqBFci@W~!!Pjs7!LJ|v z{{8RkyPNCi7jq*qqukt_d2UjQrkKnr!(N{2;yiK1>B&bw?{vbaOYLp1T`xDAXP-Oe zdZ*ew6T0c7Bqe20sMeoWUY4FUTD5XV=t`o{?lfAJ(n+J%Y*pIrYNK8dMt6U{CbjbO uMvD~EBB@pDx{@T3G|QcnQ&Nyc@-M5@t+e#pv_>TVF-d`ppybU5I^kaeU4r@m literal 0 HcmV?d00001 diff --git a/data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.fast b/data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.fast new file mode 100644 index 0000000000000000000000000000000000000000..a9cfc669cfa686efccf2d714fd88f4d2acf6f9d5 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jDGuBba%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tNz&B$gy+ jC|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko@( zv5UR;Uco=`;*2x+pihoxX74>SyZ6kQ-LuIWXNT%> z!<#lb%v;{}j(5H1aPRxThd%PLBYfghpZVMuj`XFkeC-=Y`PO&7_k$m;_LHCe;#a>p z+V3{mERA%IQH|=?09Uin>*gfnKdWGKMA$>wl z=o|WlhxHEw!oV;nJYsMd5{8ChVbAcW;bBA=8AgT2j1FVM*f1{exba~^c*4XmDNGJi z!qhM=Ob<_*5oU&`%nGx^oG>>$ZC;oka>Ih~jJ&WgEDCE@rM_%>dS$9st*va+=6{Bi z%l`!aznpD6 zqP&ul SO#DSNk(1aenpn9uBtvD~S zprCShNn&0}W?7{|nSq|6p`NjhLS|k{YDIineo<~>i9(s7jzV!seo<QEG8< zW`3TP0z~h%YNg!7to$M+D+3*++{`=>%g|6qsUWc=IYY_HSVsxjtoX9jB9LyN8XYAJ QGnK5AAciW{E(W>~07ibKzW@LL literal 0 HcmV?d00001 diff --git a/data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.posidx b/data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.posidx new file mode 100644 index 0000000000000000000000000000000000000000..365202bfeeb697a75e45f550654179c881985fa2 GIT binary patch literal 197 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 DZS&DY literal 0 HcmV?d00001 diff --git a/data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.term b/data/database/v1_2/bf6498b5a1e948d090131605048ecbcd.term new file mode 100644 index 0000000000000000000000000000000000000000..ad6397bcd12ec0c8aba638a53c95f2088f234514 GIT binary patch literal 2526 zcmZuxdsGuw8oxIQAqff246g(t3?pH&q9%kS6RI}yGNE=4xLXfxZG{Sy*zzc(2>58Q zN$Vm+J)V?BM5>fhN|CDFJ0SzXHh*Nk`@7%w z`+ct&4tV6}!Q*nE6VuZgwF*xFETChK@qoYJ0ra$1ty1ENU;)$XG|^Eg${o?FA4L{3 z)0$|8c_9SRMkyDO=$u0Cv`7a@CjhPTF-3^XN9+lqk3yH2x_#H%Ha)G=YNFLq$RWv{ zRx?LCSD_Ax#sQa&N@HzWtz57*Znm309gXmCDmc)e@D}lbOtuzEWD3<NCr1y^`a!02%Q?SI9sT6(W+bknsqF50e~J!ah*mm_#J-;5r2jfB->Aay8Ha11N=ys%An_QL#?tDBMYp_QjO}5(KgUUt)<^ zB;Y|2_ZlJ;fe!cqB)}yw!U=TGJ_%s^`ubV{R^8XxmI*W92DlP>!W*Cw90pln4ayq= zPc(*S!4;4Un_&v)Jm&#t2X{yId`gs8ma{+rj_{a50a!Qp04(l0BC22iph)lnXAWkr zYg{(#D-;Pm1V*cY%cl&oNte5|b_T)Fp<@A&zRDdN^8285egx4EV z_8*8$wR}T~rI}sEHxh%iL-v$653ebn`eqqM?iZN$8J8te>o-+aZ#-@p3iFLPZ8Ysq zTCw@XmQ4q1w=_)+DWuBw3RC$;byofQKfG1?W?t}i~FGpV1rL_njKipr?Q6E=y@*m^J_usm+Ci|}G zovOjz*Jm$lZH>HU&1g<+zU;uyN4~BY*%bd%{e{4Ro1^0!iW7RCtG;n``u(;~PG3^q ztGS)`l=W57zm7Ui@wo}b4Xuf?#IcD@6(^JAHA83ppKGW8-myhLJ@#tqk?sS#YKK1# z|0vbWhM$`Tdj_(`rwf}-UwQuI__swb zcV4`B!*S35yB#I=&%G|4nwT!XykXa+p=nv?cQbps9y}Rrn}o-Ly4JLeh+|%#DA{*) z`Jp|3o)Z79(D>l;81?Mx?`JFfpZ@Gd{dB-5SGxY)F;16$_5IE&N16DEzs^vd%S?N^ zCx2g8HF^I}qvtoicY1c^S3A4ceKwtOLHEP%x`}~9znr;G-}F2EGt(KaK%U5wtX5Hcu~TZNkz7VtA+v140R`?Z@mwZ&*Ky zSw&0WxfzV~!eEmCcX;8jRf=211niB#4H6$XNaGHPFB~@FHg7*Tk&34+@rU=baexIt zehF^Jq>!k@t+))zPv9gG2qVto4k8FfH{(_xIb7F`8+@0-qyZfG1;fp^ahqQVOuL7t z`IGP!AwdR&!Xg=A51`=Q<%Ctb3?9}Kq$~{9nh3j00qdV3(gMTbIWs{9{SG#j5RRY- z*j7o{^ql_gWdls(YKuJiO6g6%){$y`;3fFgHCvzvQANJ=bC`Dj|!Mt5m90 z>PXU@n~_<(H7lQ|gp3^hke?fwhO@c*^xZNdNm literal 0 HcmV?d00001 diff --git a/data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.fast b/data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.fast new file mode 100644 index 0000000000000000000000000000000000000000..a9cfc669cfa686efccf2d714fd88f4d2acf6f9d5 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jDGuBba%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tNz&B$gy+ jC|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko)k`LzQY516>FJ8$Un~ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.idx b/data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.idx new file mode 100644 index 0000000000000000000000000000000000000000..4f243f10bb1b4a52a65e02c79811f034971785d1 GIT binary patch literal 207 zcmZQ(fPjWZ5M+e$ni@c?hCXHx$qOXtRPHWG%qz((t5hg6&@(jD zGuBba%u7kFh)>He%1ta$C^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZ zpre$VnFnGS8tNz&B$gy+C|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko`R!D+P$&Yt>4*iCOtYN>&Cs xO1YVNAeNz_j#5ElNpgmgm9dTzvRUzEsYM{&Ks7o_7-lM2DM1WXs$C3pApl~DJ+}Y= literal 0 HcmV?d00001 diff --git a/data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.posidx b/data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.posidx new file mode 100644 index 0000000000000000000000000000000000000000..a9ee6c3eb017f9daa3834e6b67f7420a30981464 GIT binary patch literal 189 zcmZQ#0D`6l5ZTbm3?g}fL_Z^tc%A!WXIpVzVnIRW?vlj3lFYJ7g)##@Lqk1d9fi!i zl+=p&wEUvn#1e%vLmh?UlKi67_~iWDf}+&o;>`R!D+P$&Yt>4*iCOtYN>&CsO1YVN tAeNz_j#5ElNpgmgm9dTzvRUzEsYM{&Ks7o_7-lM2DM1WXs$C3pApi<;KEwb3 literal 0 HcmV?d00001 diff --git a/data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.store b/data/database/v1_2/c7f9f53e463f4d9297d257449d63b8d0.store new file mode 100644 index 0000000000000000000000000000000000000000..4f23598e9edfac9b915d03e4421749d678f48e61 GIT binary patch literal 239 zcmdO8U|{&q#=ubQml#kG$tcgjF!TC3jaiK>Kyil2DkcVoCMKo^23G00iJ3Wi$@#gB zosEVdIUs=1j6iljh{)TvcvV|*USdH((sCWQo4!V6XahNISe5klSlx}JOF&aLA zoY}w&B>F)bM8d4n+KTfM3koWCmn7zuWR_Jblo{w58tNJAC}ifPq*lbIL?VK literal 0 HcmV?d00001 diff --git a/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.fast b/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.fast new file mode 100644 index 0000000000000000000000000000000000000000..a9cfc669cfa686efccf2d714fd88f4d2acf6f9d5 GIT binary patch literal 172 zcmZo*WME+E2NACnD$chR=Oq>tRPHWG%qz((t5hg6&@(jDGuBba%u7kFh)>He%1ta$ zC^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZpre$VnFnGS8tNz&B$gy+ jC|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko)k`LzQY516>FJ8$Un~ literal 0 HcmV?d00001 diff --git a/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.idx b/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.idx new file mode 100644 index 0000000000000000000000000000000000000000..4f243f10bb1b4a52a65e02c79811f034971785d1 GIT binary patch literal 207 zcmZQ(fPjWZ5M+e$ni@c?hCXHx$qOXtRPHWG%qz((t5hg6&@(jD zGuBba%u7kFh)>He%1ta$C^OViC@#q_N{vs>&n+lQEiTT?&$Cj1=)G30l$)59U!-JZ zpre$VnFnGS8tNz&B$gy+C|McnC?T5_UzS<~(hXFjql96ml9dv~P^H?%Ko`R!D+P$&Yt>4*iCOtYN>&Cs xO1YVNAeNz_j#5ElNpgmgm9dTzvRUzEsYM{&Ks7o_7-lM2DM1WXs$C3pApl~DJ+}Y= literal 0 HcmV?d00001 diff --git a/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.posidx b/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.posidx new file mode 100644 index 0000000000000000000000000000000000000000..a9ee6c3eb017f9daa3834e6b67f7420a30981464 GIT binary patch literal 189 zcmZQ#0D`6l5ZTbm3?g}fL_Z^tc%A!WXIpVzVnIRW?vlj3lFYJ7g)##@Lqk1d9fi!i zl+=p&wEUvn#1e%vLmh?UlKi67_~iWDf}+&o;>`R!D+P$&Yt>4*iCOtYN>&CsO1YVN tAeNz_j#5ElNpgmgm9dTzvRUzEsYM{&Ks7o_7-lM2DM1WXs$C3pApi<;KEwb3 literal 0 HcmV?d00001 diff --git a/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.store b/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.store new file mode 100644 index 0000000000000000000000000000000000000000..b74cd8b245720f5a9e1ee550b64d6780dd88524e GIT binary patch literal 239 zcmdO8U|{&q#=ubQml#kG$tcgju;N>L+^j|xpg6;16+?4lGXqm|3#-b+jQo7Pg?wFsmes76N#!%QVBC5WL)wTpo+1OT3&NuvM& literal 0 HcmV?d00001 diff --git a/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.term b/data/database/v1_2/d013a4c1859e403093ef8e37d7e88f32.term new file mode 100644 index 0000000000000000000000000000000000000000..ba55336a31592990277e8a18673c5130f8679811 GIT binary patch literal 406 zcmZQ#Km!6T=g%Kv5SVoS_z@;X21a&<@(c?>W@e}=H7G3)rD5VQLl|KUB$|<#DU{0) zD!_y!0cHv`9y@aG{LxcK&fmOn(sCWQo4!V6XahNISe5klSlx}JOF&aLA zoY}w&B>F)b3cvT&wH4C^OJAG}JTJQOL|oNv()a%P-1JEKw*k z)KMrd$uCNcPtMORC`v6Z&dkrVQh?~aR;`qqn3Z3oWM!bEl$)6cVi_9hC>11@BxfjD h8S5w^n-yP{S_IM!RHLJWVWyIm62wrY+QmQ@0sv$jR=5BF literal 0 HcmV?d00001 diff --git a/data/database/v1_2/events.db b/data/database/v1_2/events.db new file mode 100644 index 0000000000000000000000000000000000000000..b5130477274d75d6c11f13016971e722a1ec6aa7 GIT binary patch literal 675840 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

@GI~Cr|a?H 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 ADF6Tf literal 0 HcmV?d00001 diff --git a/data/database/v1_2/meta.json b/data/database/v1_2/meta.json new file mode 100644 index 0000000..0ace26f --- /dev/null +++ b/data/database/v1_2/meta.json @@ -0,0 +1,99 @@ +{ + "segments": [ + { + "segment_id": "bf6498b5-a1e9-48d0-9013-1605048ecbcd", + "max_doc": 356, + "deletes": null + }, + { + "segment_id": "5249de4d-a76b-4040-98f0-26f248155bf1", + "max_doc": 288, + "deletes": null + }, + { + "segment_id": "18dcd68b-3739-40f6-8446-31d851e6139c", + "max_doc": 284, + "deletes": null + }, + { + "segment_id": "9883d1a6-5e92-4749-83c3-022fb99ea0da", + "max_doc": 67, + "deletes": null + }, + { + "segment_id": "3b59e3c0-f086-46ef-b6b5-6192a98ab85f", + "max_doc": 1, + "deletes": null + }, + { + "segment_id": "88b4ad3f-5a1e-430f-9ea0-3e2ef43c39f7", + "max_doc": 1, + "deletes": null + }, + { + "segment_id": "c7f9f53e-463f-4d92-97d2-57449d63b8d0", + "max_doc": 1, + "deletes": null + }, + { + "segment_id": "d013a4c1-859e-4030-93ef-8e37d7e88f32", + "max_doc": 1, + "deletes": null + } + ], + "schema": [ + { + "name": "body", + "type": "text", + "options": { + "indexing": { + "record": "position", + "tokenizer": "default" + }, + "stored": false + } + }, + { + "name": "topic", + "type": "text", + "options": { + "indexing": { + "record": "position", + "tokenizer": "default" + }, + "stored": false + } + }, + { + "name": "name", + "type": "text", + "options": { + "indexing": { + "record": "position", + "tokenizer": "default" + }, + "stored": false + } + }, + { + "name": "room_id", + "type": "text", + "options": { + "indexing": { + "record": "basic", + "tokenizer": "raw" + }, + "stored": false + } + }, + { + "name": "event_id", + "type": "text", + "options": { + "indexing": null, + "stored": true + } + } + ], + "opstamp": 1007 +} From af41adc72db45dcc580f58a4e0000021ae6b8dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 4 Mar 2020 12:59:55 +0100 Subject: [PATCH 15/33] database: Test the new v1 database upgrade. --- src/database/mod.rs | 48 ++++++++++++++++++++++++++++++++++++++-- src/database/recovery.rs | 42 ++++++++++++++++++++--------------- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index 2c3495e..90aa8bf 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -897,9 +897,53 @@ fn database_upgrade_v1() { path.pop(); path.pop(); path.push("data/database/v1"); - let mut db = Database::new(path).unwrap(); - let mut connection = db.get_connection().unwrap(); + let db = Database::new(path); + + // Sadly the v1 database has invalid json in the source field, reindexing it + // won't be possible. Let's check that it's marked for a reindex. + match db { + Ok(_) => panic!("Database doesn't need a reindex."), + Err(e) => match e { + Error::ReindexError => (), + e => panic!("Database doesn't need a reindex: {}", e), + }, + } +} + +#[cfg(test)] +use crate::database::recovery::test::{event_from_json, reindex_loop}; + +#[test] +fn database_upgrade_v1_2() { + let mut path = PathBuf::from(file!()); + path.pop(); + path.pop(); + path.pop(); + path.push("data/database/v1_2"); + let db = Database::new(&path); + match db { + Ok(_) => panic!("Database doesn't need a reindex."), + Err(e) => match e { + Error::ReindexError => (), + e => panic!("Database doesn't need a reindex: {}", e), + }, + } + + let mut recovery_db = RecoveryDatabase::new(&path).expect("Can't open recovery db"); + + recovery_db.delete_the_index().unwrap(); + recovery_db.open_index().unwrap(); + let events = recovery_db.load_events(100, None).unwrap(); + let events: Vec = events.iter().map(|e| event_from_json(e)).collect(); + + recovery_db.index_events(&events).unwrap(); + reindex_loop(&mut recovery_db, events).unwrap(); + recovery_db.commit_and_close().unwrap(); + + let db = Database::new(&path).expect("Can't open the db event after a reindex"); + + let mut connection = db.get_connection().unwrap(); let (version, _) = Database::get_version(&mut connection).unwrap(); assert_eq!(version, DATABASE_VERSION); diff --git a/src/database/recovery.rs b/src/database/recovery.rs index 67f5396..e5540d3 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -226,15 +226,15 @@ impl RecoveryDatabase { } #[cfg(test)] -mod test { - use crate::{Database, Error, Event, EventType, RecoveryDatabase, SearchConfig}; +pub(crate) mod test { + use crate::{Database, Result, Error, Event, EventType, RecoveryDatabase, SearchConfig}; use crate::database::DATABASE_VERSION; use serde_json::Value; use std::path::PathBuf; use std::sync::atomic::Ordering; - fn event_from_json(event_source: &str) -> Event { + pub(crate) fn event_from_json(event_source: &str) -> Event { let object: Value = serde_json::from_str(event_source).expect("Can't deserialize event source"); let content = &object["content"]; @@ -265,6 +265,26 @@ mod test { ) } + pub(crate) fn reindex_loop(db: &mut RecoveryDatabase, initial_events: Vec) -> Result<()> { + let mut events = initial_events; + + loop { + let serialized_events = db.load_events(10, events.last())?; + if serialized_events.is_empty() { + break; + } + + events = serialized_events + .iter() + .map(|e| event_from_json(e)) + .collect(); + + db.index_events(&events)?; + db.commit()?; + } + Ok(()) + } + #[test] fn test_recovery() { let mut path = PathBuf::from(file!()); @@ -309,21 +329,7 @@ mod test { 10 ); - loop { - let serialized_events = recovery_db - .load_events(10, events.last()) - .expect("Can't load events"); - - if serialized_events.is_empty() { - break; - } - - events = serialized_events - .iter() - .map(|e| event_from_json(e)) - .collect(); - recovery_db.index_events(&events).unwrap(); - } + reindex_loop(&mut recovery_db, events).expect("Can't reindex the db"); assert_eq!( recovery_db From e87fb547455a03b0dfb8910e9420a273f4228110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 4 Mar 2020 13:42:01 +0100 Subject: [PATCH 16/33] database: Add missing docs to the recovery database. --- src/database/recovery.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/database/recovery.rs b/src/database/recovery.rs index e5540d3..ca214e1 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -14,6 +14,11 @@ use crate::events::{Event, SerializedEvent}; use crate::index::{Index, Writer}; use crate::Database; +/// Database that can be used to reindex the events. +/// +/// Reindexing the database may be needed if the index schema changes. This may +/// happen occasionally on upgrades or if language settings for the database +/// change. pub struct RecoveryDatabase { path: PathBuf, connection: PooledConnection, @@ -27,16 +32,27 @@ pub struct RecoveryDatabase { } #[derive(Debug, Clone)] +/// Info about the recovery process. +/// +/// This can be used to track the progress of the reindex. +/// +/// `RecoveryInfo` implements `Send` and `Sync` so it can be shared between +/// threads if for example the UI is in a separate thread. pub struct RecoveryInfo { total_event_count: u64, reindexed_events: Arc, } +unsafe impl Send for RecoveryInfo {} +unsafe impl Sync for RecoveryInfo {} + impl RecoveryInfo { + /// The total number of events that the database holds. pub fn total_events(&self) -> u64 { self.total_event_count } + /// The number of events that are processed and reindexed. pub fn reindexed_events(&self) -> &AtomicU64 { &self.reindexed_events } @@ -141,6 +157,10 @@ impl RecoveryDatabase { Ok(()) } + /// Load serialized events from the database. + /// + /// * `limit` - The number of events to load. + /// * `from_event` - The event where to continue loading from. pub fn load_events( &self, limit: usize, @@ -153,6 +173,9 @@ impl RecoveryDatabase { )?) } + /// Create and open a new index. + /// + /// Returns `ReindexError` if the index wasn't deleted first. pub fn open_index(&mut self) -> Result<()> { if !self.index_deleted { return Err(Error::ReindexError); @@ -166,6 +189,7 @@ impl RecoveryDatabase { Ok(()) } + /// Get the recovery info for the database. pub fn info(&self) -> &RecoveryInfo { &self.recovery_info } From ace778c57d5d3002c01c6aba295da85d18af7d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 4 Mar 2020 13:42:23 +0100 Subject: [PATCH 17/33] seshat: Fix some clippy issues. --- src/database/recovery.rs | 2 +- src/events.rs | 1 + src/index/mod.rs | 1 - src/lib.rs | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/database/recovery.rs b/src/database/recovery.rs index ca214e1..d16e7b0 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -342,7 +342,7 @@ pub(crate) mod test { assert!(!events.is_empty()); assert_eq!(events.len(), 10); - let mut events: Vec = events.iter().map(|e| event_from_json(e)).collect(); + let events: Vec = events.iter().map(|e| event_from_json(e)).collect(); recovery_db.index_events(&events).unwrap(); assert_eq!( diff --git a/src/events.rs b/src/events.rs index 1ea592d..15a5789 100644 --- a/src/events.rs +++ b/src/events.rs @@ -155,6 +155,7 @@ impl Event { /// * `room_id` - The unique identifier of the room that the event belongs /// to. /// * `source` - The serialized version of the event. + #[allow(clippy::too_many_arguments)] pub fn new( event_type: EventType, content_value: &str, diff --git a/src/index/mod.rs b/src/index/mod.rs index 0de591a..aab8841 100644 --- a/src/index/mod.rs +++ b/src/index/mod.rs @@ -23,7 +23,6 @@ use std::path::Path; use std::time::Duration; use tantivy as tv; use tantivy::chrono::{NaiveDateTime, Utc}; -use tantivy::tokenizer::Tokenizer; use tantivy::Term; use crate::config::{Config, Language, SearchConfig}; diff --git a/src/lib.rs b/src/lib.rs index 7cc7554..caab719 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,7 @@ //! let result = database.search("test", &SearchConfig::new()).unwrap(); //! ``` -#![warn(missing_docs)] +#![deny(missing_docs)] #[cfg(test)] #[macro_use] From ad3ebfcd5a5094e00915dde702dd5d491598868c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 5 Mar 2020 13:34:36 +0100 Subject: [PATCH 18/33] seshat-node: Add a class to reindex Seshat. --- Cargo.toml | 2 +- seshat-node/lib/index.js | 20 +++++++- seshat-node/native/src/lib.rs | 82 ++++++++++++++++++++++++++------- seshat-node/native/src/tasks.rs | 50 +++++++++++++++++++- seshat-node/native/src/utils.rs | 14 +++--- seshat-node/test/test.js | 2 +- src/database/mod.rs | 2 +- src/database/recovery.rs | 72 +++++++++++++++++++++-------- src/error.rs | 9 ++++ src/lib.rs | 4 +- 10 files changed, 209 insertions(+), 48 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c20c516..83120f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,9 +28,9 @@ pbkdf2 = "0.3.0" rand = "0.7.3" zeroize = "1.1.0" byteorder = "1.3.2" +serde_json = "1.0.48" [dev-dependencies] tempfile = "3.1.0" lazy_static = "1.4.0" fake = "2.2.0" -serde_json = "*" diff --git a/seshat-node/lib/index.js b/seshat-node/lib/index.js index 148c578..13882eb 100644 --- a/seshat-node/lib/index.js +++ b/seshat-node/lib/index.js @@ -393,4 +393,22 @@ class Seshat extends seshat.Seshat { } } -module.exports = Seshat; +class SeshatRecovery extends seshat.SeshatRecovery { + info() { + return super.info(); + } + + async reindex() { + return new Promise((resolve, reject) => { + super.reindex((err, res) => { + if (err) reject(err); + else resolve(res); + }); + }); + } +} + +module.exports = { + Seshat: Seshat, + SeshatRecovery: SeshatRecovery, +} diff --git a/seshat-node/native/src/lib.rs b/seshat-node/native/src/lib.rs index e11fee6..01552b9 100644 --- a/seshat-node/native/src/lib.rs +++ b/seshat-node/native/src/lib.rs @@ -16,35 +16,79 @@ mod tasks; mod utils; use neon::prelude::*; -use seshat::{Config, Database, LoadConfig, LoadDirection, Profile}; +use seshat::{Database, LoadConfig, LoadDirection, Profile, RecoveryDatabase, RecoveryInfo}; +use std::sync::atomic::Ordering; +use std::sync::Mutex; use crate::tasks::*; use crate::utils::*; pub struct SeshatDatabase(Option); - -pub struct DatabaseManager { - path: std::path::PathBuf, - total_events: u64, - completed_events: u64, - config: Config, +pub struct SeshatRecoveryDb { + database: Option, + info: RecoveryInfo, } declare_types! { - pub class Test for DatabaseManager { + pub class SeshatRecovery for SeshatRecoveryDb { init(mut cx) { let db_path: String = cx.argument::(0)?.value(); let args = cx.argument_opt(1); let config = parse_database_config(&mut cx, args)?; + let database = RecoveryDatabase::new_with_config(db_path, &config) + .expect("Can't open recovery database."); + let info = database.info().clone(); + + Ok(SeshatRecoveryDb{ + database: Some(database), + info + }) + } - Ok( - DatabaseManager { - path: db_path.into(), - total_events: 0, - completed_events: 0, - config, - } - ) + method reindex(mut cx) { + let f = cx.argument::(0)?; + let mut this = cx.this(); + + let database = { + let guard = cx.lock(); + let db = &mut this.borrow_mut(&guard).database; + db.take() + }; + + let database = match database { + Some(db) => db, + None => return cx.throw_type_error("A reindex has been already done"), + }; + + let task = ReindexTask { inner: Mutex::new(Some(database)) }; + task.schedule(f); + + Ok(cx.undefined().upcast()) + } + + method info(mut cx) { + let mut this = cx.this(); + + let (total, reindexed) = { + let guard = cx.lock(); + let info = &this.borrow_mut(&guard).info; + + let total = info.total_events(); + let reindexed = info.reindexed_events().load(Ordering::Relaxed); + (total, reindexed) + }; + + let done: f64 = reindexed as f64 / total as f64; + let total = JsNumber::new(&mut cx, total as f64); + let reindexed = JsNumber::new(&mut cx, reindexed as f64); + let done = JsNumber::new(&mut cx, done); + + let info = JsObject::new(&mut cx); + info.set(&mut cx, "totalEvents", total)?; + info.set(&mut cx, "reindexedEvents", reindexed)?; + info.set(&mut cx, "done", done)?; + + Ok(info.upcast()) } } @@ -468,4 +512,8 @@ declare_types! { } } -register_module!(mut cx, { cx.export_class::("Seshat") }); +register_module!(mut cx, { + cx.export_class::("Seshat")?; + cx.export_class::("SeshatRecovery")?; + Ok(()) +}); diff --git a/seshat-node/native/src/tasks.rs b/seshat-node/native/src/tasks.rs index cbf001b..72b0036 100644 --- a/seshat-node/native/src/tasks.rs +++ b/seshat-node/native/src/tasks.rs @@ -14,12 +14,13 @@ use fs_extra::dir; use std::path::PathBuf; +use std::sync::Mutex; use crate::utils::*; use neon::prelude::*; use seshat::{ - CheckpointDirection, Connection, CrawlerCheckpoint, DatabaseStats, LoadConfig, Profile, - Receiver, SearchConfig, SearchResult, Searcher, + CheckpointDirection, Connection, CrawlerCheckpoint, DatabaseStats, Event, LoadConfig, Profile, + Receiver, RecoveryDatabase, SearchConfig, SearchResult, Searcher, }; pub(crate) struct CommitTask { @@ -314,3 +315,48 @@ impl Task for LoadFileEventsTask { Ok(results) } } + +pub(crate) struct ReindexTask { + pub(crate) inner: Mutex>, +} + +impl Task for ReindexTask { + type Output = (); + type Error = seshat::Error; + type JsEvent = JsUndefined; + + fn perform(&self) -> Result { + let mut db = self.inner.lock().unwrap().take().unwrap(); + db.delete_the_index()?; + db.open_index()?; + + let mut events = db.load_events(100, None)?; + db.index_events(&events)?; + + loop { + events = db.load_events(100, events.last())?; + + if events.is_empty() { + break; + } + + db.index_events(&events)?; + db.commit()?; + } + + db.commit_and_close()?; + + Ok(()) + } + + fn complete( + self, + mut cx: TaskContext, + result: Result, + ) -> JsResult { + match result { + Ok(_) => Ok(cx.undefined()), + Err(e) => cx.throw_type_error(e.to_string()), + } + } +} diff --git a/seshat-node/native/src/utils.rs b/seshat-node/native/src/utils.rs index 1f4bd2a..601b32f 100644 --- a/seshat-node/native/src/utils.rs +++ b/seshat-node/native/src/utils.rs @@ -17,8 +17,8 @@ use neon::prelude::*; use neon_serde; use serde_json; use seshat::{ - CheckpointDirection, CrawlerCheckpoint, Event, EventType, Profile, Receiver, SearchConfig, - SearchResult, Config, Language + CheckpointDirection, Config, CrawlerCheckpoint, Event, EventType, Language, Profile, Receiver, + SearchConfig, SearchResult, }; pub(crate) fn parse_database_config( @@ -34,10 +34,12 @@ pub(crate) fn parse_database_config( if let Ok(l) = l.downcast::() { let language = Language::from(l.value().as_ref()); match language { - Language::Unknown => return cx.throw_type_error( - format!("Unsuported language: {}", l.value()) - ), - _ => {config = config.set_language(&language);} + Language::Unknown => { + return cx.throw_type_error(format!("Unsuported language: {}", l.value())) + } + _ => { + config = config.set_language(&language); + } } } } diff --git a/seshat-node/test/test.js b/seshat-node/test/test.js index a68c917..8fcf1ad 100644 --- a/seshat-node/test/test.js +++ b/seshat-node/test/test.js @@ -2,7 +2,7 @@ const fs = require('fs'); const os = require('os'); const path = require('path'); -const Seshat = require('../'); +const {Seshat} = require('../'); const matrixEvent = { type: 'm.room.message', diff --git a/src/database/mod.rs b/src/database/mod.rs index 90aa8bf..2002d20 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -32,7 +32,7 @@ use std::thread::JoinHandle; use crate::config::{Config, SearchConfig}; pub use crate::database::connection::{Connection, DatabaseStats}; -pub use crate::database::recovery::RecoveryDatabase; +pub use crate::database::recovery::{RecoveryDatabase, RecoveryInfo}; pub use crate::database::searcher::{SearchResult, Searcher}; use crate::database::writer::Writer; use crate::error::{Error, Result}; diff --git a/src/database/recovery.rs b/src/database/recovery.rs index d16e7b0..da7b3cb 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -14,6 +14,9 @@ use crate::events::{Event, SerializedEvent}; use crate::index::{Index, Writer}; use crate::Database; +use crate::EventType; +use serde_json::Value; + /// Database that can be used to reindex the events. /// /// Reindexing the database may be needed if the index schema changes. This may @@ -126,7 +129,7 @@ impl RecoveryDatabase { /// Delete the Seshat index, leaving only the events database. /// /// After this operation is done, the index can be rebuilt. - pub fn delete_the_index(&mut self) -> std::io::Result<()> { + pub fn delete_the_index(&mut self) -> Result<()> { let writer = self.index_writer.take(); let index = self.index.take(); @@ -157,20 +160,50 @@ impl RecoveryDatabase { Ok(()) } + fn event_from_json(event_source: &str) -> Event { + let object: Value = + serde_json::from_str(event_source).expect("Can't deserialize event source"); + let content = &object["content"]; + let event_type = &object["type"]; + + let event_type = match event_type.as_str().unwrap() { + "m.room.message" => EventType::Message, + "m.room.name" => EventType::Name, + "m.room.topic" => EventType::Topic, + _ => panic!("Invalid event type"), + }; + + let (content_value, msgtype) = match event_type { + EventType::Message => (content["body"].as_str().unwrap(), Some("m.text")), + EventType::Topic => (content["topic"].as_str().unwrap(), None), + EventType::Name => (content["name"].as_str().unwrap(), None), + }; + + Event::new( + event_type, + content_value, + msgtype, + object["event_id"].as_str().unwrap(), + object["sender"].as_str().unwrap(), + object["origin_server_ts"].as_u64().unwrap() as i64, + object["room_id"].as_str().unwrap(), + &event_source, + ) + } + /// Load serialized events from the database. /// /// * `limit` - The number of events to load. /// * `from_event` - The event where to continue loading from. - pub fn load_events( - &self, - limit: usize, - from_event: Option<&Event>, - ) -> Result> { - Ok(Database::load_all_events( - &self.connection, - limit, - from_event, - )?) + pub fn load_events(&self, limit: usize, from_event: Option<&Event>) -> Result> { + let serialized_events = Database::load_all_events(&self.connection, limit, from_event)?; + + let events = serialized_events + .iter() + .map(|e| RecoveryDatabase::event_from_json(e)) + .collect(); + + Ok(events) } /// Create and open a new index. @@ -251,8 +284,8 @@ impl RecoveryDatabase { #[cfg(test)] pub(crate) mod test { - use crate::{Database, Result, Error, Event, EventType, RecoveryDatabase, SearchConfig}; use crate::database::DATABASE_VERSION; + use crate::{Database, Error, Event, EventType, RecoveryDatabase, Result, SearchConfig}; use serde_json::Value; use std::path::PathBuf; @@ -289,7 +322,10 @@ pub(crate) mod test { ) } - pub(crate) fn reindex_loop(db: &mut RecoveryDatabase, initial_events: Vec) -> Result<()> { + pub(crate) fn reindex_loop( + db: &mut RecoveryDatabase, + initial_events: Vec, + ) -> Result<()> { let mut events = initial_events; loop { @@ -298,10 +334,10 @@ pub(crate) mod test { break; } - events = serialized_events - .iter() - .map(|e| event_from_json(e)) - .collect(); + // events = serialized_events + // .iter() + // .map(|e| event_from_json(e)) + // .collect(); db.index_events(&events)?; db.commit()?; @@ -342,7 +378,7 @@ pub(crate) mod test { assert!(!events.is_empty()); assert_eq!(events.len(), 10); - let events: Vec = events.iter().map(|e| event_from_json(e)).collect(); + // let events: Vec = events.iter().map(|e| event_from_json(e)).collect(); recovery_db.index_events(&events).unwrap(); assert_eq!( diff --git a/src/error.rs b/src/error.rs index a9cfa1d..8b62288 100644 --- a/src/error.rs +++ b/src/error.rs @@ -39,6 +39,9 @@ pub enum Error { /// Error signaling that there was an error while reading from the /// filesystem. FsError(fs_extra::error::Error), + #[fail(display = "IO error: {}", _0)] + /// Error signaling that there was an error while doing a IO operation. + IOError(std::io::Error), /// Error signaling that the database passphrase was incorrect. #[fail(display = "Error unlocking the database: {}", _0)] DatabaseUnlockError(String), @@ -79,3 +82,9 @@ impl From for Error { Error::FsError(err) } } + +impl From for Error { + fn from(err: std::io::Error) -> Self { + Error::IOError(err) + } +} diff --git a/src/lib.rs b/src/lib.rs index caab719..4351281 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,9 @@ mod error; mod events; mod index; -pub use database::{Connection, Database, DatabaseStats, RecoveryDatabase, SearchResult, Searcher}; +pub use database::{ + Connection, Database, DatabaseStats, RecoveryDatabase, RecoveryInfo, SearchResult, Searcher, +}; pub use error::{Error, Result}; From 491be9a14943aff5b0cdb3634f283048217fdbb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 5 Mar 2020 15:06:57 +0100 Subject: [PATCH 19/33] seshat-node: Throw a different error if the database needs to be reindexed. --- seshat-node/native/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/seshat-node/native/src/lib.rs b/seshat-node/native/src/lib.rs index 01552b9..fab2404 100644 --- a/seshat-node/native/src/lib.rs +++ b/seshat-node/native/src/lib.rs @@ -16,7 +16,7 @@ mod tasks; mod utils; use neon::prelude::*; -use seshat::{Database, LoadConfig, LoadDirection, Profile, RecoveryDatabase, RecoveryInfo}; +use seshat::{Database, Error, LoadConfig, LoadDirection, Profile, RecoveryDatabase, RecoveryInfo}; use std::sync::atomic::Ordering; use std::sync::Mutex; @@ -102,8 +102,11 @@ declare_types! { let db = match Database::new_with_config(&db_path, &config) { Ok(db) => db, Err(e) => { - let message = format!("Error opening the database: {:?}", e); - panic!(message) + let error = match e { + Error::ReindexError => cx.throw_range_error("Database needs to be reindexed"), + e => cx.throw_error(format!("Error opening the database: {:?}", e)) + }; + return error; } }; From 3a3453ebba5b44664bd82fe571effdfff3cbf766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 5 Mar 2020 15:07:31 +0100 Subject: [PATCH 20/33] seshat-node: Convert the RangeError into a custom error on the js side. --- seshat-node/lib/index.js | 26 ++++++++++++++++++++++++++ seshat-node/test/test.js | 7 ++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/seshat-node/lib/index.js b/seshat-node/lib/index.js index 13882eb..c62e67c 100644 --- a/seshat-node/lib/index.js +++ b/seshat-node/lib/index.js @@ -76,6 +76,19 @@ const seshat = require('../native'); * @property {number} roomCount The number of rooms the database knows about. */ + +class ReindexError extends Error { + constructor(...params) { + super(...params); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, ReindexError) + } + this.name = 'ReindexError'; + this.message = 'The Seshat database needs to be reindexed.'; + } +} + /** * Seshat database.
* @@ -106,6 +119,18 @@ const seshat = require('../native'); * let results = await db.search('Test'); */ class Seshat extends seshat.Seshat { + constructor(path, config = undefined) { + config = config || {}; + try { + super(path, config); + } catch (e) { + if (e.constructor.name === "RangeError") { + throw new ReindexError(); + } else { + throw e; + } + } + } /** * Add an event to the database. * @@ -411,4 +436,5 @@ class SeshatRecovery extends seshat.SeshatRecovery { module.exports = { Seshat: Seshat, SeshatRecovery: SeshatRecovery, + ReindexError: ReindexError, } diff --git a/seshat-node/test/test.js b/seshat-node/test/test.js index 8fcf1ad..b0c8352 100644 --- a/seshat-node/test/test.js +++ b/seshat-node/test/test.js @@ -2,7 +2,7 @@ const fs = require('fs'); const os = require('os'); const path = require('path'); -const {Seshat} = require('../'); +const {Seshat, ReindexError} = require('../'); const matrixEvent = { type: 'm.room.message', @@ -480,4 +480,9 @@ describe('Database', function() { it('should throw an error when adding events with fields that don\'t typecheck.', function() { expect(() => db.addEvent(badEvent, matrixProfile)).toThrow('Event doesn\'t contain a valid timestamp'); }); + + it('should allow us to reindex a database', async function() { + const dir = '../data/database/v2'; + expect(() => new Seshat(dir)).toThrow(ReindexError); + }); }); From bbbe4c7539464e48406cf8d06b0fd294ebbd715b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 10:55:49 +0100 Subject: [PATCH 21/33] seshat: Make the event deserialization return a Result. --- src/database/recovery.rs | 89 ++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/src/database/recovery.rs b/src/database/recovery.rs index da7b3cb..53c707a 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -3,6 +3,9 @@ use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; +use std::convert::TryInto; +use std::io::{Error as IoError, ErrorKind}; + use r2d2::PooledConnection; use r2d2_sqlite::SqliteConnectionManager; use rusqlite::ToSql; @@ -160,52 +163,104 @@ impl RecoveryDatabase { Ok(()) } - fn event_from_json(event_source: &str) -> Event { - let object: Value = - serde_json::from_str(event_source).expect("Can't deserialize event source"); + fn event_from_json(event_source: &str) -> std::io::Result { + let object: Value = serde_json::from_str(event_source)?; let content = &object["content"]; let event_type = &object["type"]; - let event_type = match event_type.as_str().unwrap() { + let event_type = match event_type.as_str().unwrap_or_default() { "m.room.message" => EventType::Message, "m.room.name" => EventType::Name, "m.room.topic" => EventType::Topic, - _ => panic!("Invalid event type"), + _ => return Err(IoError::new(ErrorKind::Other, "Invalid event type.")), }; let (content_value, msgtype) = match event_type { - EventType::Message => (content["body"].as_str().unwrap(), Some("m.text")), - EventType::Topic => (content["topic"].as_str().unwrap(), None), - EventType::Name => (content["name"].as_str().unwrap(), None), + EventType::Message => ( + content["body"] + .as_str() + .ok_or_else(|| IoError::new(ErrorKind::Other, "No content value found"))?, + Some("m.text"), + ), + EventType::Topic => ( + content["topic"] + .as_str() + .ok_or_else(|| IoError::new(ErrorKind::Other, "No content value found"))?, + None, + ), + EventType::Name => ( + content["name"] + .as_str() + .ok_or_else(|| IoError::new(ErrorKind::Other, "No content value found"))?, + None, + ), }; - Event::new( + let event_id = object["event_id"] + .as_str() + .ok_or_else(|| IoError::new(ErrorKind::Other, "No event id found"))?; + let sender = object["sender"] + .as_str() + .ok_or_else(|| IoError::new(ErrorKind::Other, "No sender found"))?; + let server_ts = object["origin_server_ts"] + .as_u64() + .ok_or_else(|| IoError::new(ErrorKind::Other, "No server timestamp found"))?; + let room_id = object["room_id"] + .as_str() + .ok_or_else(|| IoError::new(ErrorKind::Other, "No room id found"))?; + + Ok(Event::new( event_type, content_value, msgtype, - object["event_id"].as_str().unwrap(), - object["sender"].as_str().unwrap(), - object["origin_server_ts"].as_u64().unwrap() as i64, - object["room_id"].as_str().unwrap(), + event_id, + sender, + server_ts.try_into().map_err(|_e| { + IoError::new(ErrorKind::Other, "Server timestamp out of valid range") + })?, + room_id, &event_source, - ) + )) } - /// Load serialized events from the database. + /// Load deserialized events from the database. /// /// * `limit` - The number of events to load. /// * `from_event` - The event where to continue loading from. - pub fn load_events(&self, limit: usize, from_event: Option<&Event>) -> Result> { - let serialized_events = Database::load_all_events(&self.connection, limit, from_event)?; + /// + /// Events that fail to be deserialized will be filtered out. + pub fn load_events_deserialized( + &self, + limit: usize, + from_event: Option<&Event>, + ) -> Result> { + let serialized_events = self.load_events(limit, from_event)?; let events = serialized_events .iter() .map(|e| RecoveryDatabase::event_from_json(e)) + .filter_map(std::io::Result::ok) .collect(); Ok(events) } + /// Load serialized events from the database. + /// + /// * `limit` - The number of events to load. + /// * `from_event` - The event where to continue loading from. + pub fn load_events( + &self, + limit: usize, + from_event: Option<&Event>, + ) -> Result> { + Ok(Database::load_all_events( + &self.connection, + limit, + from_event, + )?) + } + /// Create and open a new index. /// /// Returns `ReindexError` if the index wasn't deleted first. From 18e747d9cf5cc70650c6a3f3b32bf251ef6593df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 10:56:34 +0100 Subject: [PATCH 22/33] seshat-node: Improve the reindex test. --- seshat-node/test/test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/seshat-node/test/test.js b/seshat-node/test/test.js index b0c8352..989a76d 100644 --- a/seshat-node/test/test.js +++ b/seshat-node/test/test.js @@ -2,7 +2,7 @@ const fs = require('fs'); const os = require('os'); const path = require('path'); -const {Seshat, ReindexError} = require('../'); +const {Seshat, ReindexError, SeshatRecovery} = require('../'); const matrixEvent = { type: 'm.room.message', @@ -484,5 +484,12 @@ describe('Database', function() { it('should allow us to reindex a database', async function() { const dir = '../data/database/v2'; expect(() => new Seshat(dir)).toThrow(ReindexError); + + const recovery = new SeshatRecovery(dir); + await recovery.reindex(); + + const db = new Seshat(dir); + const results = await db.search({search_term: 'Hello'}); + expect(results.count).not.toBe(0); }); }); From 832455f6d7f9f7d2d15cc5c892a7465bad142aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 11:17:49 +0100 Subject: [PATCH 23/33] database: Fix the reindex tests. --- src/database/mod.rs | 5 ++--- src/database/recovery.rs | 45 +++++++--------------------------------- 2 files changed, 9 insertions(+), 41 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index 2002d20..05a2cfe 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -911,7 +911,7 @@ fn database_upgrade_v1() { } #[cfg(test)] -use crate::database::recovery::test::{event_from_json, reindex_loop}; +use crate::database::recovery::test::reindex_loop; #[test] fn database_upgrade_v1_2() { @@ -934,8 +934,7 @@ fn database_upgrade_v1_2() { recovery_db.delete_the_index().unwrap(); recovery_db.open_index().unwrap(); - let events = recovery_db.load_events(100, None).unwrap(); - let events: Vec = events.iter().map(|e| event_from_json(e)).collect(); + let events = recovery_db.load_events_deserialized(100, None).unwrap(); recovery_db.index_events(&events).unwrap(); reindex_loop(&mut recovery_db, events).unwrap(); diff --git a/src/database/recovery.rs b/src/database/recovery.rs index 53c707a..2eddb2c 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -341,42 +341,12 @@ impl RecoveryDatabase { pub(crate) mod test { use crate::database::DATABASE_VERSION; use crate::{Database, Error, Event, EventType, RecoveryDatabase, Result, SearchConfig}; + use crate::events::SerializedEvent; use serde_json::Value; use std::path::PathBuf; use std::sync::atomic::Ordering; - pub(crate) fn event_from_json(event_source: &str) -> Event { - let object: Value = - serde_json::from_str(event_source).expect("Can't deserialize event source"); - let content = &object["content"]; - let event_type = &object["type"]; - - let event_type = match event_type.as_str().unwrap() { - "m.room.message" => EventType::Message, - "m.room.name" => EventType::Name, - "m.room.topic" => EventType::Topic, - _ => panic!("Invalid event type"), - }; - - let (content_value, msgtype) = match event_type { - EventType::Message => (content["body"].as_str().unwrap(), Some("m.text")), - EventType::Topic => (content["topic"].as_str().unwrap(), None), - EventType::Name => (content["name"].as_str().unwrap(), None), - }; - - Event::new( - event_type, - content_value, - msgtype, - object["event_id"].as_str().unwrap(), - object["sender"].as_str().unwrap(), - object["origin_server_ts"].as_u64().unwrap() as i64, - object["room_id"].as_str().unwrap(), - &event_source, - ) - } - pub(crate) fn reindex_loop( db: &mut RecoveryDatabase, initial_events: Vec, @@ -389,10 +359,11 @@ pub(crate) mod test { break; } - // events = serialized_events - // .iter() - // .map(|e| event_from_json(e)) - // .collect(); + events = serialized_events + .iter() + .map(|e| RecoveryDatabase::event_from_json(e)) + .filter_map(std::io::Result::ok) + .collect(); db.index_events(&events)?; db.commit()?; @@ -427,14 +398,12 @@ pub(crate) mod test { .expect("Can't open the new the index"); let events = recovery_db - .load_events(10, None) + .load_events_deserialized(10, None) .expect("Can't load events"); assert!(!events.is_empty()); assert_eq!(events.len(), 10); - // let events: Vec = events.iter().map(|e| event_from_json(e)).collect(); - recovery_db.index_events(&events).unwrap(); assert_eq!( recovery_db From 1ccd8d1326bc3d8e73c53fe3fa1e2bf90ae4f90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 12:07:57 +0100 Subject: [PATCH 24/33] seshat-node: Fix the reindexing. --- seshat-node/native/src/tasks.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/seshat-node/native/src/tasks.rs b/seshat-node/native/src/tasks.rs index 72b0036..7b59cba 100644 --- a/seshat-node/native/src/tasks.rs +++ b/seshat-node/native/src/tasks.rs @@ -19,7 +19,7 @@ use std::sync::Mutex; use crate::utils::*; use neon::prelude::*; use seshat::{ - CheckpointDirection, Connection, CrawlerCheckpoint, DatabaseStats, Event, LoadConfig, Profile, + CheckpointDirection, Connection, CrawlerCheckpoint, DatabaseStats, LoadConfig, Profile, Receiver, RecoveryDatabase, SearchConfig, SearchResult, Searcher, }; @@ -330,11 +330,11 @@ impl Task for ReindexTask { db.delete_the_index()?; db.open_index()?; - let mut events = db.load_events(100, None)?; + let mut events = db.load_events_deserialized(500, None)?; db.index_events(&events)?; loop { - events = db.load_events(100, events.last())?; + events = db.load_events_deserialized(500, events.last())?; if events.is_empty() { break; From fe0ff88bed8f885325febeabe129d47afe8453f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 12:11:49 +0100 Subject: [PATCH 25/33] travis: Reset the test data before running Javascript tests. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index c8f488d..2edd889 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,6 +49,9 @@ install: script: - cargo test - cd seshat-node + # Reset our test data before running the Javascript tests + - rm -r data/database + - git reset --hard HEAD - yarn install - yarn test --coverage - yarn lint From 0029495baef9b750d2080a047bf5f868a3a732de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 12:59:42 +0100 Subject: [PATCH 26/33] database: Remove some unused imports from the tests. --- src/database/recovery.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/database/recovery.rs b/src/database/recovery.rs index 2eddb2c..9b173c2 100644 --- a/src/database/recovery.rs +++ b/src/database/recovery.rs @@ -340,10 +340,8 @@ impl RecoveryDatabase { #[cfg(test)] pub(crate) mod test { use crate::database::DATABASE_VERSION; - use crate::{Database, Error, Event, EventType, RecoveryDatabase, Result, SearchConfig}; - use crate::events::SerializedEvent; + use crate::{Database, Error, Event, RecoveryDatabase, Result, SearchConfig}; - use serde_json::Value; use std::path::PathBuf; use std::sync::atomic::Ordering; From 786fecbf9fa1194b160826987826c3864881292d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 13:00:15 +0100 Subject: [PATCH 27/33] travis: First delete the database folder, then switch folders. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2edd889..042cb95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,10 +48,10 @@ install: script: - cargo test - - cd seshat-node # Reset our test data before running the Javascript tests - rm -r data/database - git reset --hard HEAD + - cd seshat-node - yarn install - yarn test --coverage - yarn lint From 947654b2a8411d4639e26fdcc4051c35301834df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 13:21:39 +0100 Subject: [PATCH 28/33] seshat-node: Add docs and fix lint issues for the new recovery database. --- seshat-node/lib/index.js | 111 ++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 24 deletions(-) diff --git a/seshat-node/lib/index.js b/seshat-node/lib/index.js index c62e67c..34d63a8 100644 --- a/seshat-node/lib/index.js +++ b/seshat-node/lib/index.js @@ -76,13 +76,32 @@ const seshat = require('../native'); * @property {number} roomCount The number of rooms the database knows about. */ +/** + * @typedef recoveryInfo + * @type {Object} + * @property {number} totalEvents The total number of events that the database + * holds. + * @property {number} reindexedEvents The number of events that have been + * reindexed. + * @property {number} done The percentage showing the re-index progress. + */ +/** + * Seshat re-index error.
+ * + * This error will be thrown if a Seshat database can't be opened because it + * needs to be re-indexed. + * + * The database can be opened as a recovery database with the SeshatRecovery + * class. This class provides method to re-index the database. + * + */ class ReindexError extends Error { constructor(...params) { super(...params); if (Error.captureStackTrace) { - Error.captureStackTrace(this, ReindexError) + Error.captureStackTrace(this, ReindexError); } this.name = 'ReindexError'; this.message = 'The Seshat database needs to be reindexed.'; @@ -95,30 +114,33 @@ class ReindexError extends Error { * A Seshat database can be used to store and index Matrix events. A full-text * search can be done on the database retrieving events that match a search * query. - * - * @param {string} path The path where the database should be stored. If a - * database already exist in the given folder the database will be reused. - * @param {object} config Additional configuration for the database. - * database already exist in the given folder the database will be reused. - * @param {string} config.language The language that the database should use - * for indexing. Picking the correct indexing language may improve the search. - * @param {string} config.passphrase The passphrase that should be used to - * encrypt the database. The database is left unencrypted it no passphrase is - * set. - * - * @constructor - * - * @example - * // create a Seshat database in the given folder - * let db = new Seshat("/home/example/database_dir"); - * // Add a Matrix event to the database. - * db.addEvent(textEvent, profile); - * // Commit events waiting in the queue to the database. - * await db.commit(); - * // Search the database for messages containing the word 'Test' - * let results = await db.search('Test'); */ class Seshat extends seshat.Seshat { + /** + * Open an existing or create a new Seshat database. + * + * @param {string} path The path where the database should be stored. If a + * database already exist in the given folder the database will be reused. + * @param {object} config Additional configuration for the database. + * database already exist in the given folder the database will be reused. + * @param {string} config.language The language that the database should use + * for indexing. Picking the correct indexing language may improve the search. + * @param {string} config.passphrase The passphrase that should be used to + * encrypt the database. The database is left unencrypted it no passphrase is + * set. + * + * @constructor + * + * @example + * // create a Seshat database in the given folder + * let db = new Seshat("/home/example/database_dir"); + * // Add a Matrix event to the database. + * db.addEvent(textEvent, profile); + * // Commit events waiting in the queue to the database. + * await db.commit(); + * // Search the database for messages containing the word 'Test' + * let results = await db.search('Test'); + */ constructor(path, config = undefined) { config = config || {}; try { @@ -418,11 +440,52 @@ class Seshat extends seshat.Seshat { } } +/** + * Seshat recovery database.
+ * + * A Seshat recovery database can be used to re-index a Seshat database. + * + * This will be needed if schema changes to the index were required and the + * library has been upgraded. + * + * The recovery database uses the same parameters in the constructor like the + * normal Seshat database. + * + * @param {string} path The path where the database should be stored. If a + * database already exist in the given folder the database will be reused. + * @param {object} config Additional configuration for the database. + * database already exist in the given folder the database will be reused. + * @param {string} config.language The language that the database should use + * for indexing. Picking the correct indexing language may improve the search. + * @param {string} config.passphrase The passphrase that should be used to + * encrypt the database. The database is left unencrypted it no passphrase is + * set. + * + * @constructor + * + * @example + * // open a Seshat recovery database in the given folder + * let recovery = new SeshatRecovery("/home/example/database_dir"); + * // reindex the database + * await recovery.reindex(); + */ class SeshatRecovery extends seshat.SeshatRecovery { + /** + * Get info about the re-index status. + * + * @return {RecoveryInfo} A object that holds the number of total events, + * re-indexed events and the done percentage. + */ info() { return super.info(); } + /** + * Re-index the database. + * + * @return {Promise<>} A promise that will resolve once the database has + * been re-indexed. + */ async reindex() { return new Promise((resolve, reject) => { super.reindex((err, res) => { @@ -437,4 +500,4 @@ module.exports = { Seshat: Seshat, SeshatRecovery: SeshatRecovery, ReindexError: ReindexError, -} +}; From 6aa353fdc500690784f3c75eefa92dd1c9b9f9eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 13:22:21 +0100 Subject: [PATCH 29/33] seshat-node: Explain our re-index error throwing shenanigans. --- seshat-node/lib/index.js | 4 +++- seshat-node/native/src/lib.rs | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/seshat-node/lib/index.js b/seshat-node/lib/index.js index 34d63a8..fff3654 100644 --- a/seshat-node/lib/index.js +++ b/seshat-node/lib/index.js @@ -146,7 +146,9 @@ class Seshat extends seshat.Seshat { try { super(path, config); } catch (e) { - if (e.constructor.name === "RangeError") { + // The Rust side throws a RangeError, this is a bit silly so convert + // it to a custom error. + if (e.constructor.name === 'RangeError') { throw new ReindexError(); } else { throw e; diff --git a/seshat-node/native/src/lib.rs b/seshat-node/native/src/lib.rs index fab2404..04341dc 100644 --- a/seshat-node/native/src/lib.rs +++ b/seshat-node/native/src/lib.rs @@ -102,6 +102,10 @@ declare_types! { let db = match Database::new_with_config(&db_path, &config) { Ok(db) => db, Err(e) => { + // There doesn't seem to be a way to construct custom + // Javascript errors from the Rust side, since we never + // throw a RangeError here, let's hack around this by using + // one here. let error = match e { Error::ReindexError => cx.throw_range_error("Database needs to be reindexed"), e => cx.throw_error(format!("Error opening the database: {:?}", e)) From a3dc17e6f410b9ffbdca1a3f89aee8200e9d82ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 6 Mar 2020 14:00:01 +0100 Subject: [PATCH 30/33] seshat-node: Fix some more lint errors. --- seshat-node/lib/index.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/seshat-node/lib/index.js b/seshat-node/lib/index.js index fff3654..d0c77ba 100644 --- a/seshat-node/lib/index.js +++ b/seshat-node/lib/index.js @@ -97,6 +97,9 @@ const seshat = require('../native'); * */ class ReindexError extends Error { + /** + * Create a new ReindexError + */ constructor(...params) { super(...params); @@ -123,11 +126,11 @@ class Seshat extends seshat.Seshat { * database already exist in the given folder the database will be reused. * @param {object} config Additional configuration for the database. * database already exist in the given folder the database will be reused. - * @param {string} config.language The language that the database should use - * for indexing. Picking the correct indexing language may improve the search. - * @param {string} config.passphrase The passphrase that should be used to - * encrypt the database. The database is left unencrypted it no passphrase is - * set. + * @param {string} config.language The language that the database should + * use for indexing. Picking the correct indexing language may improve the + * search. @param {string} config.passphrase The passphrase that should be + * used to encrypt the database. The database is left unencrypted it no + * passphrase is set. * * @constructor * @@ -485,7 +488,7 @@ class SeshatRecovery extends seshat.SeshatRecovery { /** * Re-index the database. * - * @return {Promise<>} A promise that will resolve once the database has + * @return {Promise} A promise that will resolve once the database has * been re-indexed. */ async reindex() { From 743d44893aa460d405730bb3eec5a711832ce439 Mon Sep 17 00:00:00 2001 From: poljar Date: Tue, 10 Mar 2020 09:19:16 +0100 Subject: [PATCH 31/33] Update src/error.rs Co-Authored-By: J. Ryan Stinnett --- src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index 8b62288..7585ffd 100644 --- a/src/error.rs +++ b/src/error.rs @@ -54,7 +54,7 @@ pub enum Error { /// Error signaling that sqlcipher support is missing. #[fail(display = "Sqlcipher error: {}", _0)] SqlCipherError(String), - /// Error indicating that the index needs to be rebuild. + /// Error indicating that the index needs to be rebuilt. #[fail(display = "Error opening the database, the index needs to be rebuild.")] ReindexError, } From 3b2b9b8ff2d3e849103360c8ec64b62a9290d9dc Mon Sep 17 00:00:00 2001 From: poljar Date: Tue, 10 Mar 2020 09:19:31 +0100 Subject: [PATCH 32/33] Update src/error.rs Co-Authored-By: J. Ryan Stinnett --- src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index 7585ffd..1f6b38d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -55,7 +55,7 @@ pub enum Error { #[fail(display = "Sqlcipher error: {}", _0)] SqlCipherError(String), /// Error indicating that the index needs to be rebuilt. - #[fail(display = "Error opening the database, the index needs to be rebuild.")] + #[fail(display = "Error opening the database, the index needs to be rebuilt.")] ReindexError, } From 48b5d7db8c2d44ae94d686ceed7228ea5592a981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 10 Mar 2020 09:41:27 +0100 Subject: [PATCH 33/33] database: Rename undeleted_events to pending_deletion_events. --- src/database/mod.rs | 8 ++++---- src/database/static_methods.rs | 16 ++++++++-------- src/database/writer.rs | 14 +++++++------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index 05a2cfe..85357e1 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -961,7 +961,7 @@ fn delete_an_event() { db.force_commit().unwrap(); - assert!(Database::load_undeleted_events(&db.connection) + assert!(Database::load_pending_deletion_events(&db.connection) .unwrap() .is_empty()); @@ -969,7 +969,7 @@ fn delete_an_event() { recv.recv().unwrap().unwrap(); assert_eq!( - Database::load_undeleted_events(&db.connection) + Database::load_pending_deletion_events(&db.connection) .unwrap() .len(), 1 @@ -979,7 +979,7 @@ fn delete_an_event() { let mut db = Database::new(tmpdir.path()).unwrap(); assert_eq!( - Database::load_undeleted_events(&db.connection) + Database::load_pending_deletion_events(&db.connection) .unwrap() .len(), 1 @@ -987,7 +987,7 @@ fn delete_an_event() { db.force_commit().unwrap(); assert_eq!( - Database::load_undeleted_events(&db.connection) + Database::load_pending_deletion_events(&db.connection) .unwrap() .len(), 0 diff --git a/src/database/static_methods.rs b/src/database/static_methods.rs index 89e0e7f..61e168c 100644 --- a/src/database/static_methods.rs +++ b/src/database/static_methods.rs @@ -66,24 +66,24 @@ impl Database { connection: &mut rusqlite::Connection, index_writer: &mut IndexWriter, event_id: EventId, - undeleted_events: &mut Vec, + pending_deletion_events: &mut Vec, ) -> Result { let transaction = connection.transaction()?; transaction.execute("DELETE from events WHERE event_id == ?1", &[&event_id])?; transaction.execute( - "INSERT OR IGNORE INTO undeleted_events (event_id) VALUES (?1)", + "INSERT OR IGNORE INTO pending_deletion_events (event_id) VALUES (?1)", &[&event_id], )?; transaction.commit().unwrap(); index_writer.delete_event(&event_id); - undeleted_events.push(event_id); + pending_deletion_events.push(event_id); let committed = index_writer.commit()?; if committed { - Database::mark_events_as_deleted(connection, undeleted_events)?; + Database::mark_events_as_deleted(connection, pending_deletion_events)?; } Ok(true) @@ -104,7 +104,7 @@ impl Database { .collect::(); let mut stmt = transaction.prepare(&format!( - "DELETE from undeleted_events + "DELETE from pending_deletion_events WHERE event_id IN (?{})", ¶meter_str ))?; @@ -309,7 +309,7 @@ impl Database { )?; conn.execute( - "CREATE TABLE IF NOT EXISTS undeleted_events ( + "CREATE TABLE IF NOT EXISTS pending_deletion_events ( id INTEGER NOT NULL PRIMARY KEY, event_id TEXT NOT NULL, UNIQUE(event_id) @@ -419,10 +419,10 @@ impl Database { Ok(room_id) } - pub(crate) fn load_undeleted_events( + pub(crate) fn load_pending_deletion_events( connection: &rusqlite::Connection, ) -> rusqlite::Result> { - let mut stmt = connection.prepare("SELECT event_id from undeleted_events")?; + let mut stmt = connection.prepare("SELECT event_id from pending_deletion_events")?; let events = stmt.query_map(NO_PARAMS, |row| Ok(row.get(0)?))?; events.collect() diff --git a/src/database/writer.rs b/src/database/writer.rs index fcf2c9b..45782f5 100644 --- a/src/database/writer.rs +++ b/src/database/writer.rs @@ -24,7 +24,7 @@ pub(crate) struct Writer { connection: r2d2::PooledConnection, events: Vec<(Event, Profile)>, uncommitted_events: Vec, - undeleted_events: Vec, + pending_deletion_events: Vec, } impl Writer { @@ -37,7 +37,7 @@ impl Writer { connection, events: Vec::new(), uncommitted_events: Vec::new(), - undeleted_events: Vec::new(), + pending_deletion_events: Vec::new(), } } @@ -50,15 +50,15 @@ impl Writer { &mut self.connection, &mut self.inner, event_id, - &mut self.undeleted_events, + &mut self.pending_deletion_events, ) } fn mark_events_as_deleted(&mut self) -> Result<()> { - if self.undeleted_events.is_empty() { + if self.pending_deletion_events.is_empty() { return Ok(()); } - Database::mark_events_as_deleted(&mut self.connection, &mut self.undeleted_events) + Database::mark_events_as_deleted(&mut self.connection, &mut self.pending_deletion_events) } pub fn write_queued_events(&mut self, force_commit: bool) -> Result<()> { @@ -107,13 +107,13 @@ impl Writer { self.inner.add_event(&event); } - let ret = Database::load_undeleted_events(&self.connection)?; + let ret = Database::load_pending_deletion_events(&self.connection)?; for event_id in &ret { self.inner.delete_event(&event_id); } - self.undeleted_events.extend(ret); + self.pending_deletion_events.extend(ret); Ok(()) }