From be7cee2c37875746ed374d282edaf6e1bb366317 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Sun, 7 Feb 2021 20:54:40 +0100 Subject: [PATCH] Avoid ChatId::is_unset when querying location sending Avoid using the 0 ChatID as a special value, use Options instead. For get_range() also do this for contact_id. --- deltachat-ffi/src/lib.rs | 22 +++++++++++++---- examples/repl/cmdline.rs | 8 +++---- src/location.rs | 51 +++++++++++++++++++++++++++++----------- src/mimefactory.rs | 2 +- 4 files changed, 59 insertions(+), 24 deletions(-) diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index bfd1cc7e7..a06961ba0 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -1943,11 +1943,13 @@ pub unsafe extern "C" fn dc_is_sending_locations_to_chat( return 0; } let ctx = &*context; + let chat_id = if chat_id == 0 { + None + } else { + Some(ChatId::new(chat_id)) + }; - block_on(location::is_sending_locations_to_chat( - &ctx, - ChatId::new(chat_id), - )) as libc::c_int + block_on(location::is_sending_locations_to_chat(&ctx, chat_id)) as libc::c_int } #[no_mangle] @@ -1979,11 +1981,21 @@ pub unsafe extern "C" fn dc_get_locations( return ptr::null_mut(); } let ctx = &*context; + let chat_id = if chat_id == 0 { + None + } else { + Some(ChatId::new(chat_id)) + }; + let contact_id = if contact_id == 0 { + None + } else { + Some(contact_id) + }; block_on(async move { let res = location::get_range( &ctx, - ChatId::new(chat_id), + chat_id, contact_id, timestamp_begin as i64, timestamp_end as i64, diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 5524eea5d..23d38b22d 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -573,7 +573,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu ); } } - if location::is_sending_locations_to_chat(&context, ChatId::new(0)).await { + if location::is_sending_locations_to_chat(&context, None).await { println!("Location streaming enabled."); } println!("{} chats", cnt); @@ -735,7 +735,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu contacts.len(), location::is_sending_locations_to_chat( &context, - sel_chat.as_ref().unwrap().get_id() + Some(sel_chat.as_ref().unwrap().get_id()) ) .await, ); @@ -743,10 +743,10 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu "getlocations" => { ensure!(sel_chat.is_some(), "No chat selected."); - let contact_id = arg1.parse().unwrap_or_default(); + let contact_id: Option = arg1.parse().ok(); let locations = location::get_range( &context, - sel_chat.as_ref().unwrap().get_id(), + Some(sel_chat.as_ref().unwrap().get_id()), contact_id, 0, 0, diff --git a/src/location.rs b/src/location.rs index a751fbb6b..576634a72 100644 --- a/src/location.rs +++ b/src/location.rs @@ -193,7 +193,8 @@ impl Kml { pub async fn send_locations_to_chat(context: &Context, chat_id: ChatId, seconds: i64) { let now = time(); if !(seconds < 0 || chat_id.is_special()) { - let is_sending_locations_before = is_sending_locations_to_chat(context, chat_id).await; + let is_sending_locations_before = + is_sending_locations_to_chat(context, Some(chat_id)).await; if context .sql .execute( @@ -249,15 +250,29 @@ async fn schedule_maybe_send_locations(context: &Context, force_schedule: bool) }; } -pub async fn is_sending_locations_to_chat(context: &Context, chat_id: ChatId) -> bool { - context - .sql - .exists( - "SELECT id FROM chats WHERE (? OR id=?) AND locations_send_until>?;", - paramsv![if chat_id.is_unset() { 1 } else { 0 }, chat_id, time()], - ) - .await - .unwrap_or_default() +/// Returns whether `chat_id` or any chat is sending locations. +/// +/// If `chat_id` is `Some` only that chat is checked, otherwise returns `true` if any chat +/// is sending locations. +pub async fn is_sending_locations_to_chat(context: &Context, chat_id: Option) -> bool { + match chat_id { + Some(chat_id) => context + .sql + .exists( + "SELECT id FROM chats WHERE id=? AND locations_send_until>?;", + paramsv![chat_id, time()], + ) + .await + .unwrap_or_default(), + None => context + .sql + .exists( + "SELECT id FROM chats WHERE locations_send_until>?;", + paramsv![time()], + ) + .await + .unwrap_or_default(), + } } pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64) -> bool { @@ -305,14 +320,22 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64 pub async fn get_range( context: &Context, - chat_id: ChatId, - contact_id: u32, + chat_id: Option, + contact_id: Option, timestamp_from: i64, mut timestamp_to: i64, ) -> Vec { if timestamp_to == 0 { timestamp_to = time() + 10; } + let (disable_chat_id, chat_id) = match chat_id { + Some(chat_id) => (0, chat_id), + None => (1, ChatId::new(0)), // this ChatId is unused + }; + let (disable_contact_id, contact_id) = match contact_id { + Some(contact_id) => (0, contact_id), + None => (1, 0), // this contact_id is unused + }; context .sql .query_map( @@ -323,9 +346,9 @@ pub async fn get_range( AND (l.independent=1 OR (l.timestamp>=? AND l.timestamp<=?)) \ ORDER BY l.timestamp DESC, l.id DESC, msg_id DESC;", paramsv![ - if chat_id.is_unset() { 1 } else { 0 }, + disable_chat_id, chat_id, - if contact_id == 0 { 1 } else { 0 }, + disable_contact_id, contact_id as i32, timestamp_from, timestamp_to, diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 2b9a6a5bd..2a092fdd8 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -978,7 +978,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> { parts.push(msg_kml_part); } - if location::is_sending_locations_to_chat(context, self.msg.chat_id).await { + if location::is_sending_locations_to_chat(context, Some(self.msg.chat_id)).await { match self.get_location_kml_part().await { Ok(part) => parts.push(part), Err(err) => {