mirror of
https://github.com/chatmail/core.git
synced 2026-04-18 14:06:29 +03:00
feat: Case-insensitive search for non-ASCII chat and contact names (#7477)
This makes `Contact::get_all()` and `Chatlist::try_load()` case-insensitive for non-ASCII chat and
contact names as well. The same approach as in f6f4ccc6ea "feat:
Case-insensitive search for non-ASCII messages (#5052)" is used: `chats.name_normalized` and
`contacts.name_normalized` colums are added which store lowercased/normalized names (for a contact,
if the name is unset, it's a normalized authname). If a normalized name is the same as the
chat/contact name, it's not stored to reduce the db size. A db migration is added for 10000 random
chats and the same number of the most recently seen contacts, for users it will probably migrate all
chats/contacts and for bots which may have more data it's not important.
This commit is contained in:
@@ -19,7 +19,7 @@ use crate::log::warn;
|
||||
use crate::message::MsgId;
|
||||
use crate::provider::get_provider_info;
|
||||
use crate::sql::Sql;
|
||||
use crate::tools::{Time, inc_and_check, time_elapsed};
|
||||
use crate::tools::{Time, inc_and_check, normalize_text, time_elapsed};
|
||||
use crate::transport::ConfiguredLoginParam;
|
||||
|
||||
const DBVERSION: i32 = 68;
|
||||
@@ -1454,6 +1454,56 @@ CREATE INDEX imap_sync_index ON imap_sync(transport_id, folder);
|
||||
.await?;
|
||||
}
|
||||
|
||||
inc_and_check(&mut migration_version, 143)?;
|
||||
if dbversion < migration_version {
|
||||
let trans_fn = |t: &mut rusqlite::Transaction| {
|
||||
t.execute_batch(
|
||||
"
|
||||
ALTER TABLE chats ADD COLUMN name_normalized TEXT;
|
||||
ALTER TABLE contacts ADD COLUMN name_normalized TEXT;
|
||||
",
|
||||
)?;
|
||||
|
||||
let mut stmt = t.prepare("UPDATE chats SET name_normalized=? WHERE id=?")?;
|
||||
for res in t
|
||||
.prepare("SELECT id, name FROM chats LIMIT 10000")?
|
||||
.query_map((), |row| {
|
||||
let id: u32 = row.get(0)?;
|
||||
let name: String = row.get(1)?;
|
||||
Ok((id, name))
|
||||
})?
|
||||
{
|
||||
let (id, name) = res?;
|
||||
if let Some(name_normalized) = normalize_text(&name) {
|
||||
stmt.execute((name_normalized, id))?;
|
||||
}
|
||||
}
|
||||
|
||||
let mut stmt = t.prepare("UPDATE contacts SET name_normalized=? WHERE id=?")?;
|
||||
for res in t
|
||||
.prepare(
|
||||
"
|
||||
SELECT id, IIF(name='', authname, name) FROM contacts
|
||||
ORDER BY last_seen DESC LIMIT 10000
|
||||
",
|
||||
)?
|
||||
.query_map((), |row| {
|
||||
let id: u32 = row.get(0)?;
|
||||
let name: String = row.get(1)?;
|
||||
Ok((id, name))
|
||||
})?
|
||||
{
|
||||
let (id, name) = res?;
|
||||
if let Some(name_normalized) = normalize_text(&name) {
|
||||
stmt.execute((name_normalized, id))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
sql.execute_migration_transaction(trans_fn, migration_version)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let new_version = sql
|
||||
.get_raw_config_int(VERSION_CFG)
|
||||
.await?
|
||||
|
||||
@@ -160,9 +160,7 @@ async fn test_key_contacts_migration_verified() -> Result<()> {
|
||||
"#,
|
||||
)?)).await?;
|
||||
|
||||
STOP_MIGRATIONS_AT
|
||||
.scope(133, t.sql.run_migrations(&t))
|
||||
.await?;
|
||||
t.sql.run_migrations(&t).await?;
|
||||
|
||||
// Hidden address-contact can't be looked up.
|
||||
assert!(
|
||||
|
||||
Reference in New Issue
Block a user