Compare commits

..

19 Commits

Author SHA1 Message Date
Alexander Krotov
25159e7ed0 Expand tabs into spaces 2019-11-16 13:58:28 +03:00
B. Petersen
d808bfe400 add some tests for me-chat and deaddrop 2019-11-13 22:31:18 +01:00
B. Petersen
1b30078c09 test archive functions 2019-11-13 10:16:57 +01:00
B. Petersen
0278875e03 add device-chat tests 2019-11-13 00:13:32 +01:00
B. Petersen
d0ccf28678 do not add random label for unlabelled device-messages 2019-11-13 00:13:32 +01:00
B. Petersen
5023255ebc fix accidentally called maybe_add_bcc_self_device_msg() 2019-11-13 00:13:32 +01:00
holger krekel
545376875a fix python tests 2019-11-12 16:10:48 +01:00
B. Petersen
a9fe77b62e use separate column for device-msg-labels 2019-11-12 16:10:48 +01:00
B. Petersen
b42d8799b4 add dc_add_device_msg_once() to fii 2019-11-12 16:10:48 +01:00
B. Petersen
a42e197634 add device-message only once 2019-11-12 16:10:48 +01:00
B. Petersen
fc32c85608 add device-msg 'consider enabling bcc_self' if bcc_self is disabled and an autocrypt-setup-message is received 2019-11-12 16:10:48 +01:00
B. Petersen
dabd431b1f change default for bcc_self, preserve values for existing installations 2019-11-12 16:10:48 +01:00
B. Petersen
85b4817a1e restore some comments 2019-11-12 16:10:48 +01:00
B. Petersen
84c6113271 use enum for show_emails 2019-11-12 16:10:48 +01:00
B. Petersen
9506f8c38e use bool for exists_before_update 2019-11-12 16:10:48 +01:00
Friedel Ziegelmayer
d330d890c0 setup minimal github action
Just so we can experiment with it on branches
2019-11-12 14:31:38 +01:00
Alexander Krotov
c6369b1c5a Implement TryFrom instead of TryInto
TryInto is derived automatically and its documentation recommends implementing TryFrom.
2019-11-10 15:38:58 +00:00
Alexander Krotov
bfa0f9d911 Use the first subkey for encryption instead of the primary key 2019-11-10 16:32:09 +01:00
B. Petersen
154cb2db83 add missing DC_STR_DEVICE_MESSAGES 2019-11-10 16:31:12 +01:00
10 changed files with 348 additions and 30 deletions

15
.github/workflows/rust.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: Rust
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose

View File

@@ -1113,6 +1113,28 @@ void dc_set_draft (dc_context_t* context, uint32_t ch
uint32_t dc_add_device_msg (dc_context_t* context, dc_msg_t* msg);
/**
* Add a message only one time to the device-chat.
* The device-message is defined by a name.
* If a message with the same name was added before,
* the message is not added again.
* Use dc_add_device_msg() to add device-messages unconditionally.
*
* Sends the event #DC_EVENT_MSGS_CHANGED on success.
*
* @memberof dc_context_t
* @param context The context as created by dc_context_new().
* @param label A unique name for the message to add.
* The label is typically not displayed to the user and
* must be created from the characters `A-Z`, `a-z`, `0-9`, `_` or `-`.
* @param msg Message to be added to the device-chat.
* The message appears to the user as an incoming message.
* @return The ID of the added message,
* this might be the id of an older message with the same name.
*/
uint32_t dc_add_device_msg_once (dc_context_t* context, const char* label, dc_msg_t* msg);
/**
* Get draft for a chat, if any.
* See dc_set_draft() for more details about drafts.
@@ -4467,7 +4489,8 @@ void dc_array_add_id (dc_array_t*, uint32_t); // depreca
#define DC_STR_MSGLOCATIONDISABLED 65
#define DC_STR_LOCATION 66
#define DC_STR_STICKER 67
#define DC_STR_COUNT 67
#define DC_STR_DEVICE_MESSAGES 68
#define DC_STR_COUNT 68
/*
* @}

View File

@@ -828,6 +828,27 @@ pub unsafe extern "C" fn dc_add_device_msg(context: *mut dc_context_t, msg: *mut
.unwrap_or(0)
}
#[no_mangle]
pub unsafe extern "C" fn dc_add_device_msg_once(
context: *mut dc_context_t,
label: *const libc::c_char,
msg: *mut dc_msg_t,
) -> u32 {
if context.is_null() || label.is_null() || msg.is_null() {
eprintln!("ignoring careless call to dc_add_device_msg_once()");
return 0;
}
let ffi_context = &mut *context;
let ffi_msg = &mut *msg;
ffi_context
.with_inner(|ctx| {
chat::add_device_msg_once(ctx, &to_string_lossy(label), &mut ffi_msg.message)
.unwrap_or_log_default(ctx, "Failed to add device message once")
})
.map(|msg_id| msg_id.to_u32())
.unwrap_or(0)
}
#[no_mangle]
pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32) -> *mut dc_msg_t {
if context.is_null() {

View File

@@ -21,7 +21,7 @@ class TestOfflineAccountBasic:
d = ac1.get_info()
assert d["arch"]
assert d["number_of_chats"] == "0"
assert d["bcc_self"] == "1"
assert d["bcc_self"] == "0"
def test_is_not_configured(self, acfactory):
ac1 = acfactory.get_unconfigured_account()
@@ -43,7 +43,7 @@ class TestOfflineAccountBasic:
def test_has_bccself(self, acfactory):
ac1 = acfactory.get_unconfigured_account()
assert "bcc_self" in ac1.get_config("sys.config_keys").split()
assert ac1.get_config("bcc_self") == "1"
assert ac1.get_config("bcc_self") == "0"
def test_selfcontact_if_unconfigured(self, acfactory):
ac1 = acfactory.get_unconfigured_account()
@@ -405,6 +405,9 @@ class TestOnlineAccount:
wait_successful_IMAP_SMTP_connection(ac1)
wait_configuration_progress(ac1, 1000)
lp.sec("ac1: setting bcc_self=1")
ac1.set_config("bcc_self", "1")
lp.sec("send out message with bcc to ourselves")
msg_out = chat.send_text("message2")
ev = ac1._evlogger.get_matching("DC_EVENT_MSGS_CHANGED")

View File

@@ -1,6 +1,7 @@
use std::path::{Path, PathBuf};
use itertools::Itertools;
use num_traits::FromPrimitive;
use crate::blob::{BlobErrorKind, BlobObject};
use crate::chatlist::*;
@@ -796,7 +797,8 @@ pub fn is_contact_in_chat(context: &Context, chat_id: u32, contact_id: u32) -> b
.unwrap_or_default()
}
// Should return Result
// note that unarchive() is not the same as archive(false) -
// eg. unarchive() does not send events as done for archive(false).
pub fn unarchive(context: &Context, chat_id: u32) -> Result<(), Error> {
sql::execute(
context,
@@ -1012,7 +1014,8 @@ pub fn get_chat_msgs(
Ok(ret)
};
let success = if chat_id == DC_CHAT_ID_DEADDROP {
let show_emails = context.get_config_int(Config::ShowEmails);
let show_emails =
ShowEmails::from_i32(context.get_config_int(Config::ShowEmails)).unwrap_or_default();
context.sql.query_map(
concat!(
"SELECT m.id AS id, m.timestamp AS timestamp",
@@ -1029,7 +1032,7 @@ pub fn get_chat_msgs(
" AND m.msgrmsg>=?",
" ORDER BY m.timestamp,m.id;"
),
params![if show_emails == 2 { 0 } else { 1 }],
params![if show_emails == ShowEmails::All { 0 } else { 1 }],
process_row,
process_rows,
)
@@ -1927,16 +1930,50 @@ pub fn get_chat_id_by_grpid(context: &Context, grpid: impl AsRef<str>) -> (u32,
}
pub fn add_device_msg(context: &Context, msg: &mut Message) -> Result<MsgId, Error> {
add_device_msg_maybe_labelled(context, None, msg)
}
pub fn add_device_msg_once(
context: &Context,
label: &str,
msg: &mut Message,
) -> Result<MsgId, Error> {
add_device_msg_maybe_labelled(context, Some(label), msg)
}
fn add_device_msg_maybe_labelled(
context: &Context,
label: Option<&str>,
msg: &mut Message,
) -> Result<MsgId, Error> {
let (chat_id, _blocked) =
create_or_lookup_by_contact_id(context, DC_CONTACT_ID_DEVICE, Blocked::Not)?;
let rfc724_mid = dc_create_outgoing_rfc724_mid(None, "@device");
// chat_id has an sql-index so it makes sense to add this although redundant
if let Some(label) = label {
if let Ok(msg_id) = context.sql.query_row(
"SELECT id FROM msgs WHERE chat_id=? AND label=?",
params![chat_id, label],
|row| {
let msg_id: MsgId = row.get(0)?;
Ok(msg_id)
},
) {
info!(
context,
"device-message {} already exist as {}", label, msg_id
);
return Ok(msg_id);
}
}
prepare_msg_blob(context, msg)?;
unarchive(context, chat_id)?;
context.sql.execute(
"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,param,rfc724_mid) \
VALUES (?,?,?, ?,?,?, ?,?,?);",
"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,param,rfc724_mid,label) \
VALUES (?,?,?, ?,?,?, ?,?,?,?);",
params![
chat_id,
DC_CONTACT_ID_DEVICE,
@@ -1947,12 +1984,19 @@ pub fn add_device_msg(context: &Context, msg: &mut Message) -> Result<MsgId, Err
msg.text.as_ref().map_or("", String::as_str),
msg.param.to_string(),
rfc724_mid,
label.unwrap_or_default(),
],
)?;
let row_id = sql::get_rowid(context, &context.sql, "msgs", "rfc724_mid", &rfc724_mid);
let msg_id = MsgId::new(row_id);
context.call_cb(Event::IncomingMsg { chat_id, msg_id });
info!(
context,
"device-message {} added as {}",
label.unwrap_or("without label"),
msg_id
);
Ok(msg_id)
}
@@ -2034,4 +2078,164 @@ mod tests {
let added = add_contact_to_chat_ex(&t.ctx, chat_id, DC_CONTACT_ID_SELF, false).unwrap();
assert_eq!(added, false);
}
#[test]
fn test_self_talk() {
let t = dummy_context();
let chat_id = create_by_contact_id(&t.ctx, DC_CONTACT_ID_SELF).unwrap();
assert_eq!(DC_CONTACT_ID_SELF, 1);
assert!(chat_id > DC_CHAT_ID_LAST_SPECIAL);
let chat = Chat::load_from_db(&t.ctx, chat_id).unwrap();
assert_eq!(chat.id, chat_id);
assert!(chat.is_self_talk());
assert!(!chat.archived);
assert!(!chat.is_device_talk());
assert!(chat.can_send());
assert_eq!(chat.name, t.ctx.stock_str(StockMessage::SelfMsg));
}
#[test]
fn test_deaddrop_chat() {
let t = dummy_context();
let chat = Chat::load_from_db(&t.ctx, DC_CHAT_ID_DEADDROP).unwrap();
assert_eq!(DC_CHAT_ID_DEADDROP, 1);
assert_eq!(chat.id, DC_CHAT_ID_DEADDROP);
assert!(!chat.is_self_talk());
assert!(!chat.archived);
assert!(!chat.is_device_talk());
assert!(!chat.can_send());
assert_eq!(chat.name, t.ctx.stock_str(StockMessage::DeadDrop));
}
#[test]
fn test_add_device_msg() {
let t = test_context(Some(Box::new(logging_cb)));
// add two device-messages
let mut msg1 = Message::new(Viewtype::Text);
msg1.text = Some("first message".to_string());
let msg1_id = add_device_msg(&t.ctx, &mut msg1);
assert!(msg1_id.is_ok());
let mut msg2 = Message::new(Viewtype::Text);
msg2.text = Some("second message".to_string());
let msg2_id = add_device_msg(&t.ctx, &mut msg2);
assert!(msg2_id.is_ok());
assert_ne!(msg1_id.as_ref().unwrap(), msg2_id.as_ref().unwrap());
// check added messages
let msg1 = message::Message::load_from_db(&t.ctx, msg1_id.unwrap());
assert!(msg1.is_ok());
let msg1 = msg1.unwrap();
assert_eq!(msg1.text.as_ref().unwrap(), "first message");
assert_eq!(msg1.from_id, DC_CONTACT_ID_DEVICE);
assert_eq!(msg1.to_id, DC_CONTACT_ID_SELF);
assert!(!msg1.is_info());
assert!(!msg1.is_setupmessage());
let msg2 = message::Message::load_from_db(&t.ctx, msg2_id.unwrap());
assert!(msg2.is_ok());
let msg2 = msg2.unwrap();
assert_eq!(msg2.text.as_ref().unwrap(), "second message");
// check device chat
assert_eq!(get_msg_cnt(&t.ctx, msg2.chat_id), 2);
}
#[test]
fn test_add_device_msg_once() {
let t = test_context(Some(Box::new(logging_cb)));
// add two device-messages with the same label (second attempt is not added)
let mut msg1 = Message::new(Viewtype::Text);
msg1.text = Some("first message".to_string());
let msg1_id = add_device_msg_once(&t.ctx, "any-label", &mut msg1);
assert!(msg1_id.is_ok());
let mut msg2 = Message::new(Viewtype::Text);
msg2.text = Some("second message".to_string());
let msg2_id = add_device_msg_once(&t.ctx, "any-label", &mut msg2);
assert!(msg2_id.is_ok());
assert_eq!(msg1_id.as_ref().unwrap(), msg2_id.as_ref().unwrap());
// check added message
let msg2 = message::Message::load_from_db(&t.ctx, msg2_id.unwrap());
assert!(msg2.is_ok());
let msg2 = msg2.unwrap();
assert_eq!(msg1_id.unwrap(), msg2.id);
assert_eq!(msg2.text.as_ref().unwrap(), "first message");
assert_eq!(msg2.from_id, DC_CONTACT_ID_DEVICE);
assert_eq!(msg2.to_id, DC_CONTACT_ID_SELF);
assert!(!msg2.is_info());
assert!(!msg2.is_setupmessage());
// check device chat
let chat_id = msg2.chat_id;
assert_eq!(get_msg_cnt(&t.ctx, chat_id), 1);
assert!(chat_id > DC_CHAT_ID_LAST_SPECIAL);
let chat = Chat::load_from_db(&t.ctx, chat_id);
assert!(chat.is_ok());
let chat = chat.unwrap();
assert!(chat.is_device_talk());
assert!(!chat.is_self_talk());
assert!(!chat.can_send());
assert_eq!(chat.name, t.ctx.stock_str(StockMessage::DeviceMessages));
assert!(chat.get_profile_image(&t.ctx).is_some());
}
fn chatlist_len(ctx: &Context, listflags: usize) -> usize {
Chatlist::try_load(ctx, listflags, None, None)
.unwrap()
.len()
}
#[test]
fn test_archive() {
// create two chats
let t = dummy_context();
let mut msg = Message::new(Viewtype::Text);
msg.text = Some("foo".to_string());
let msg_id = add_device_msg(&t.ctx, &mut msg).unwrap();
let chat_id1 = message::Message::load_from_db(&t.ctx, msg_id)
.unwrap()
.chat_id;
let chat_id2 = create_by_contact_id(&t.ctx, DC_CONTACT_ID_SELF).unwrap();
assert!(chat_id1 > DC_CHAT_ID_LAST_SPECIAL);
assert!(chat_id2 > DC_CHAT_ID_LAST_SPECIAL);
assert_eq!(get_chat_cnt(&t.ctx), 2);
assert_eq!(chatlist_len(&t.ctx, 0), 2);
assert_eq!(chatlist_len(&t.ctx, DC_GCL_NO_SPECIALS), 2);
assert_eq!(chatlist_len(&t.ctx, DC_GCL_ARCHIVED_ONLY), 0);
assert_eq!(DC_GCL_ARCHIVED_ONLY, 0x01);
assert_eq!(DC_GCL_NO_SPECIALS, 0x02);
// archive first chat
assert!(archive(&t.ctx, chat_id1, true).is_ok());
assert!(Chat::load_from_db(&t.ctx, chat_id1).unwrap().is_archived());
assert!(!Chat::load_from_db(&t.ctx, chat_id2).unwrap().is_archived());
assert_eq!(get_chat_cnt(&t.ctx), 2);
assert_eq!(chatlist_len(&t.ctx, 0), 2); // including DC_CHAT_ID_ARCHIVED_LINK now
assert_eq!(chatlist_len(&t.ctx, DC_GCL_NO_SPECIALS), 1);
assert_eq!(chatlist_len(&t.ctx, DC_GCL_ARCHIVED_ONLY), 1);
// archive second chat
assert!(archive(&t.ctx, chat_id2, true).is_ok());
assert!(Chat::load_from_db(&t.ctx, chat_id1).unwrap().is_archived());
assert!(Chat::load_from_db(&t.ctx, chat_id2).unwrap().is_archived());
assert_eq!(get_chat_cnt(&t.ctx), 2);
assert_eq!(chatlist_len(&t.ctx, 0), 1); // only DC_CHAT_ID_ARCHIVED_LINK now
assert_eq!(chatlist_len(&t.ctx, DC_GCL_NO_SPECIALS), 0);
assert_eq!(chatlist_len(&t.ctx, DC_GCL_ARCHIVED_ONLY), 2);
// archive already archived first chat, unarchive second chat two times
assert!(archive(&t.ctx, chat_id1, true).is_ok());
assert!(archive(&t.ctx, chat_id2, false).is_ok());
assert!(archive(&t.ctx, chat_id2, false).is_ok());
assert!(Chat::load_from_db(&t.ctx, chat_id1).unwrap().is_archived());
assert!(!Chat::load_from_db(&t.ctx, chat_id2).unwrap().is_archived());
assert_eq!(get_chat_cnt(&t.ctx), 2);
assert_eq!(chatlist_len(&t.ctx, 0), 2);
assert_eq!(chatlist_len(&t.ctx, DC_GCL_NO_SPECIALS), 1);
assert_eq!(chatlist_len(&t.ctx, DC_GCL_ARCHIVED_ONLY), 1);
}
}

View File

@@ -31,7 +31,7 @@ pub enum Config {
Displayname,
Selfstatus,
Selfavatar,
#[strum(props(default = "1"))]
#[strum(props(default = "0"))]
BccSelf,
#[strum(props(default = "1"))]
E2eeEnabled,

View File

@@ -155,6 +155,11 @@ fn do_initiate_key_transfer(context: &Context) -> Result<String> {
}
}
}
// no maybe_add_bcc_self_device_msg() here.
// the ui shows the dialog with the setup code on this device,
// it would be too much noise to have two things popping up at the same time.
// maybe_add_bcc_self_device_msg() is called on the other device
// once the transfer is completed.
Ok(setup_code)
}
@@ -230,6 +235,21 @@ pub fn create_setup_code(_context: &Context) -> String {
ret
}
fn maybe_add_bcc_self_device_msg(context: &Context) -> Result<()> {
if !context.sql.get_raw_config_bool(context, "bcc_self") {
let mut msg = Message::new(Viewtype::Text);
// TODO: define this as a stockstring once the wording is settled.
msg.text = Some(
"It seems you are using multiple devices with Delta Chat. Great!\n\n\
If you also want to synchronize outgoing messages accross all devices, \
go to the settings and enable \"Send copy to self\"."
.to_string(),
);
chat::add_device_msg_once(context, "bcc-self-hint", &mut msg)?;
}
Ok(())
}
pub fn continue_key_transfer(context: &Context, msg_id: MsgId, setup_code: &str) -> Result<()> {
ensure!(!msg_id.is_special(), "wrong id");
@@ -244,6 +264,7 @@ pub fn continue_key_transfer(context: &Context, msg_id: MsgId, setup_code: &str)
let sc = normalize_setup_code(setup_code);
let armored_key = decrypt_setup_file(context, &sc, file)?;
set_self_key(context, &armored_key, true, true)?;
maybe_add_bcc_self_device_msg(context)?;
Ok(())
} else {

View File

@@ -29,44 +29,44 @@ impl From<SignedSecretKey> for Key {
}
}
impl std::convert::TryInto<SignedSecretKey> for Key {
impl std::convert::TryFrom<Key> for SignedSecretKey {
type Error = ();
fn try_into(self) -> Result<SignedSecretKey, Self::Error> {
match self {
fn try_from(value: Key) -> Result<Self, Self::Error> {
match value {
Key::Public(_) => Err(()),
Key::Secret(key) => Ok(key),
}
}
}
impl<'a> std::convert::TryInto<&'a SignedSecretKey> for &'a Key {
impl<'a> std::convert::TryFrom<&'a Key> for &'a SignedSecretKey {
type Error = ();
fn try_into(self) -> Result<&'a SignedSecretKey, Self::Error> {
match self {
fn try_from(value: &'a Key) -> Result<Self, Self::Error> {
match value {
Key::Public(_) => Err(()),
Key::Secret(key) => Ok(key),
}
}
}
impl std::convert::TryInto<SignedPublicKey> for Key {
impl std::convert::TryFrom<Key> for SignedPublicKey {
type Error = ();
fn try_into(self) -> Result<SignedPublicKey, Self::Error> {
match self {
fn try_from(value: Key) -> Result<Self, Self::Error> {
match value {
Key::Public(key) => Ok(key),
Key::Secret(_) => Err(()),
}
}
}
impl<'a> std::convert::TryInto<&'a SignedPublicKey> for &'a Key {
impl<'a> std::convert::TryFrom<&'a Key> for &'a SignedPublicKey {
type Error = ();
fn try_into(self) -> Result<&'a SignedPublicKey, Self::Error> {
match self {
fn try_from(value: &'a Key) -> Result<Self, Self::Error> {
match value {
Key::Public(key) => Ok(key),
Key::Secret(_) => Err(()),
}

View File

@@ -382,11 +382,11 @@ impl<'a> Peerstate<'a> {
sql::execute(
self.context,
sql,
"UPDATE acpeerstates \
SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, \
public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, \
"UPDATE acpeerstates \
SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, \
public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, \
verified_key=?, verified_key_fingerprint=? \
WHERE addr=?;",
WHERE addr=?;",
params![
self.last_seen,
self.last_seen_autocrypt,

View File

@@ -5,6 +5,7 @@ use std::time::Duration;
use rusqlite::{Connection, OpenFlags, Statement, NO_PARAMS};
use thread_local_object::ThreadLocal;
use crate::constants::ShowEmails;
use crate::context::Context;
use crate::dc_tools::*;
use crate::error::{Error, Result};
@@ -348,7 +349,7 @@ fn open(
}
if !readonly {
let mut exists_before_update = 0;
let mut exists_before_update = false;
let mut dbversion_before_update = 0;
/* Init tables to dbversion=0 */
if !sql.table_exists("config") {
@@ -478,7 +479,7 @@ fn open(
sql.set_raw_config_int(context, "dbversion", 0)?;
}
} else {
exists_before_update = 1;
exists_before_update = true;
dbversion_before_update = sql
.get_raw_config_int(context, "dbversion")
.unwrap_or_default();
@@ -488,6 +489,7 @@ fn open(
// this should be done before updates that use high-level objects that
// rely themselves on the low-level structure.
// --------------------------------------------------------------------
let mut dbversion = dbversion_before_update;
let mut recalc_fingerprints = 0;
let mut update_file_paths = 0;
@@ -588,6 +590,8 @@ fn open(
}
if dbversion < 27 {
info!(context, "[migration] v27");
// chat.id=1 and chat.id=2 are the old deaddrops,
// the current ones are defined by chats.blocked=2
sql.execute("DELETE FROM msgs WHERE chat_id=1 OR chat_id=2;", params![])?;
sql.execute(
"CREATE INDEX chats_contacts_index2 ON chats_contacts (contact_id);",
@@ -653,6 +657,9 @@ fn open(
params![],
)?;
if dbversion_before_update == 34 {
// migrate database from the use of verified-flags to verified_key,
// _only_ version 34 (0.17.0) has the fields public_key_verified and gossip_key_verified
// this block can be deleted in half a year or so (created 5/2018)
sql.execute(
"UPDATE acpeerstates SET verified_key=gossip_key, verified_key_fingerprint=gossip_key_fingerprint WHERE gossip_key_verified=2;",
params![]
@@ -682,6 +689,8 @@ fn open(
}
if dbversion < 42 {
info!(context, "[migration] v42");
// older versions set the txt-field to the filenames, for debugging and fulltext search.
// to allow text+attachment compound messages, we need to reset these fields.
sql.execute("UPDATE msgs SET txt='' WHERE type!=10", params![])?;
dbversion = 42;
sql.set_raw_config_int(context, "dbversion", 42)?;
@@ -735,14 +744,19 @@ fn open(
}
if dbversion < 50 {
info!(context, "[migration] v50");
if 0 != exists_before_update {
sql.set_raw_config_int(context, "show_emails", 2)?;
// installations <= 0.100.1 used DC_SHOW_EMAILS_ALL implicitly;
// keep this default and use DC_SHOW_EMAILS_NO
// only for new installations
if exists_before_update {
sql.set_raw_config_int(context, "show_emails", ShowEmails::All as i32)?;
}
dbversion = 50;
sql.set_raw_config_int(context, "dbversion", 50)?;
}
if dbversion < 53 {
info!(context, "[migration] v53");
// the messages containing _only_ locations
// are also added to the database as _hidden_.
sql.execute(
"CREATE TABLE locations ( id INTEGER PRIMARY KEY AUTOINCREMENT, latitude REAL DEFAULT 0.0, longitude REAL DEFAULT 0.0, accuracy REAL DEFAULT 0.0, timestamp INTEGER DEFAULT 0, chat_id INTEGER DEFAULT 0, from_id INTEGER DEFAULT 0);",
params![]
@@ -790,9 +804,26 @@ fn open(
"ALTER TABLE locations ADD COLUMN independent INTEGER DEFAULT 0;",
params![],
)?;
sql.set_raw_config_int(context, "dbversion", 55)?;
}
if dbversion < 57 {
info!(context, "[migration] v57");
// label is a unique name and is currently used for device-messages only.
// in contrast to rfc724_mid and other fields, the label is generated on the device
// and allows reliable identifications this way.
sql.execute(
"ALTER TABLE msgs ADD COLUMN label TEXT DEFAULT '';",
params![],
)?;
if exists_before_update && sql.get_raw_config_int(context, "bcc_self").is_none() {
sql.set_raw_config_int(context, "bcc_self", 1)?;
}
sql.set_raw_config_int(context, "dbversion", 57)?;
}
// (2) updates that require high-level objects
// (the structure is complete now and all objects are usable)
// --------------------------------------------------------------------
if 0 != recalc_fingerprints {
info!(context, "[migration] recalc fingerprints");