mirror of
https://github.com/chatmail/core.git
synced 2026-06-20 06:36:39 +03:00
Compare commits
1 Commits
v2.53.0
...
iequidoo/d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
974e32dd76 |
37
src/chat.rs
37
src/chat.rs
@@ -3738,17 +3738,19 @@ pub(crate) async fn update_chat_contacts_table(
|
|||||||
id: ChatId,
|
id: ChatId,
|
||||||
contacts: &BTreeSet<ContactId>,
|
contacts: &BTreeSet<ContactId>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
// See add_to_chat_contacts_table() for reasoning.
|
||||||
|
let limit = cmp::max(time().saturating_add(TIMESTAMP_SENT_TOLERANCE), timestamp);
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.transaction(move |transaction| {
|
.transaction(move |transaction| {
|
||||||
// Bump `remove_timestamp` to at least `now`
|
// Bump `remove_timestamp` even for members from `contacts`.
|
||||||
// even for members from `contacts`.
|
|
||||||
// We add members from `contacts` back below.
|
// We add members from `contacts` back below.
|
||||||
transaction.execute(
|
transaction.execute(
|
||||||
"UPDATE chats_contacts
|
"UPDATE chats_contacts SET
|
||||||
SET remove_timestamp=MAX(add_timestamp+1, ?)
|
add_timestamp=MIN(add_timestamp, ?1),
|
||||||
|
remove_timestamp=MAX(MIN(remove_timestamp,?1), MIN(add_timestamp,?1)+1, ?)
|
||||||
WHERE chat_id=?",
|
WHERE chat_id=?",
|
||||||
(timestamp, id),
|
(limit, timestamp, id),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if !contacts.is_empty() {
|
if !contacts.is_empty() {
|
||||||
@@ -3760,9 +3762,8 @@ pub(crate) async fn update_chat_contacts_table(
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
for contact_id in contacts {
|
for contact_id in contacts {
|
||||||
// We bumped `add_timestamp` for existing rows above,
|
// We bumped `remove_timestamp` for existing rows above,
|
||||||
// so on conflict it is enough to set `add_timestamp = remove_timestamp`
|
// so on conflict it is enough to set `add_timestamp = remove_timestamp`.
|
||||||
// and this guarantees that `add_timestamp` is no less than `timestamp`.
|
|
||||||
statement.execute((id, contact_id, timestamp))?;
|
statement.execute((id, contact_id, timestamp))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3779,17 +3780,24 @@ pub(crate) async fn add_to_chat_contacts_table(
|
|||||||
chat_id: ChatId,
|
chat_id: ChatId,
|
||||||
contact_ids: &[ContactId],
|
contact_ids: &[ContactId],
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
// Our clock may be slow, so limit stored timestamps with `timestamp` if it's bigger. This way
|
||||||
|
// we only cap remote timestamps if, in addition, remote changes arrive reordered or we do local
|
||||||
|
// changes. Also allow some tolerance, moreover, previous removals might lend time from the
|
||||||
|
// future.
|
||||||
|
let limit = cmp::max(time().saturating_add(TIMESTAMP_SENT_TOLERANCE), timestamp);
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.transaction(move |transaction| {
|
.transaction(move |transaction| {
|
||||||
let mut add_statement = transaction.prepare(
|
let mut add_statement = transaction.prepare(
|
||||||
"INSERT INTO chats_contacts (chat_id, contact_id, add_timestamp) VALUES(?1, ?2, ?3)
|
"INSERT INTO chats_contacts (chat_id, contact_id, add_timestamp) VALUES(?1, ?2, ?3)
|
||||||
ON CONFLICT (chat_id, contact_id)
|
ON CONFLICT (chat_id, contact_id)
|
||||||
DO UPDATE SET add_timestamp=MAX(remove_timestamp, ?3)",
|
DO UPDATE SET
|
||||||
|
remove_timestamp=MIN(remove_timestamp, ?4),
|
||||||
|
add_timestamp=MIN(MAX(add_timestamp,remove_timestamp,?3), ?4)",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
for contact_id in contact_ids {
|
for contact_id in contact_ids {
|
||||||
add_statement.execute((chat_id, contact_id, timestamp))?;
|
add_statement.execute((chat_id, contact_id, timestamp, limit))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@@ -3808,13 +3816,16 @@ pub(crate) async fn remove_from_chat_contacts_table(
|
|||||||
contact_id: ContactId,
|
contact_id: ContactId,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
let now = time();
|
let now = time();
|
||||||
|
// See add_to_chat_contacts_table() for reasoning.
|
||||||
|
let limit = now.saturating_add(TIMESTAMP_SENT_TOLERANCE);
|
||||||
let is_past_member = context
|
let is_past_member = context
|
||||||
.sql
|
.sql
|
||||||
.execute(
|
.execute(
|
||||||
"UPDATE chats_contacts
|
"UPDATE chats_contacts SET
|
||||||
SET remove_timestamp=MAX(add_timestamp+1, ?)
|
add_timestamp=MIN(add_timestamp, ?1),
|
||||||
|
remove_timestamp=MAX(MIN(remove_timestamp,?1), MIN(add_timestamp,?1)+1, ?)
|
||||||
WHERE chat_id=? AND contact_id=?",
|
WHERE chat_id=? AND contact_id=?",
|
||||||
(now, chat_id, contact_id),
|
(limit, now, chat_id, contact_id),
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
> 0;
|
> 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user