Automated schema migration
This commit is contained in:
@@ -8,7 +8,6 @@ pub mod cache;
|
||||
pub mod identity;
|
||||
pub mod mailbox;
|
||||
pub mod message;
|
||||
pub mod migration;
|
||||
pub mod push;
|
||||
pub mod sieve;
|
||||
pub mod submission;
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use super::{
|
||||
index::{MAX_ID_LENGTH, MAX_SORT_FIELD_LENGTH, TrimTextValue, VisitText},
|
||||
ingest::{EmailIngest, IngestedEmail, ThreadResult},
|
||||
metadata::{MessageData, MessageMetadata},
|
||||
};
|
||||
use crate::mailbox::UidMailbox;
|
||||
use common::{Server, auth::ResourceToken, storage::index::ObjectIndexBuilder};
|
||||
use jmap_proto::{
|
||||
error::set::SetError,
|
||||
@@ -23,14 +29,6 @@ use store::{
|
||||
};
|
||||
use trc::AddContext;
|
||||
|
||||
use crate::{cache::MessageCacheFetch, mailbox::UidMailbox};
|
||||
|
||||
use super::{
|
||||
index::{MAX_ID_LENGTH, MAX_SORT_FIELD_LENGTH, TrimTextValue, VisitText},
|
||||
ingest::{EmailIngest, IngestedEmail, ThreadResult},
|
||||
metadata::{MessageData, MessageMetadata},
|
||||
};
|
||||
|
||||
pub trait EmailCopy: Sync + Send {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn copy_message(
|
||||
@@ -145,10 +143,10 @@ impl EmailCopy for Server {
|
||||
ThreadResult::Id(thread_id) => (false, thread_id),
|
||||
ThreadResult::Create => (
|
||||
true,
|
||||
self.get_cached_messages(account_id)
|
||||
self.store()
|
||||
.assign_document_ids(account_id, Collection::Thread, 1)
|
||||
.await
|
||||
.caused_by(trc::location!())?
|
||||
.assign_thread_id(subject.as_bytes(), message_id.as_bytes()),
|
||||
.caused_by(trc::location!())?,
|
||||
),
|
||||
ThreadResult::Skip => unreachable!(),
|
||||
};
|
||||
|
||||
@@ -330,13 +330,10 @@ impl EmailIngest for Server {
|
||||
ThreadResult::Id(thread_id) => thread_id,
|
||||
ThreadResult::Create => {
|
||||
log_thread_create = true;
|
||||
self.get_cached_messages(account_id)
|
||||
self.store()
|
||||
.assign_document_ids(account_id, Collection::Thread, 1)
|
||||
.await
|
||||
.caused_by(trc::location!())?
|
||||
.assign_thread_id(
|
||||
subject.as_bytes(),
|
||||
message_id.as_deref().unwrap_or_default().as_bytes(),
|
||||
)
|
||||
}
|
||||
ThreadResult::Skip => {
|
||||
// Duplicate message
|
||||
|
||||
@@ -24,7 +24,7 @@ use std::{borrow::Cow, collections::VecDeque};
|
||||
use store::{SERIALIZE_MESSAGE_DATA_V1, SERIALIZE_MESSAGE_METADATA_V1, SerializedVersion};
|
||||
use utils::BlobHash;
|
||||
|
||||
#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Debug)]
|
||||
#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Debug, Default)]
|
||||
pub struct MessageData {
|
||||
pub mailboxes: Vec<UidMailbox>,
|
||||
pub keywords: Vec<Keyword>,
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
use common::Server;
|
||||
use jmap_proto::types::collection::Collection;
|
||||
|
||||
async fn migrate_email(server: &Server, account_id: u32) -> trc::Result<()> {
|
||||
// Obtain email ids
|
||||
let document_ids = server
|
||||
.get_document_ids(account_id, Collection::Email)
|
||||
.await?
|
||||
.unwrap_or_default();
|
||||
|
||||
//TODO remove tombstones
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
pub mod email;
|
||||
@@ -19,16 +19,17 @@ use common::{
|
||||
use directory::{Permission, QueryBy};
|
||||
use jmap_proto::types::{collection::Collection, id::Id, keyword::Keyword, property::Property};
|
||||
use mail_parser::MessageParser;
|
||||
use rkyv::util::AlignedVec;
|
||||
use sieve::{Envelope, Event, Input, Mailbox, Recipient, Sieve};
|
||||
use std::future::Future;
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
use store::{
|
||||
Serialize, SerializeInfallible,
|
||||
Deserialize, Serialize, SerializeInfallible,
|
||||
ahash::AHashMap,
|
||||
dispatch::lookup::KeyValue,
|
||||
query::Filter,
|
||||
write::{Archiver, BatchBuilder, BlobOp},
|
||||
write::{
|
||||
AlignedBytes, Archiver, BatchBuilder, BlobOp, UnversionedArchive, UnversionedArchiver,
|
||||
},
|
||||
};
|
||||
use trc::{AddContext, SieveEvent};
|
||||
use utils::config::utils::ParseValue;
|
||||
@@ -636,9 +637,10 @@ impl SieveScriptIngest for Server {
|
||||
|
||||
// Obtain the precompiled script
|
||||
if let Some(script) = script_bytes.get(script_offset..).and_then(|bytes| {
|
||||
let mut abytes = AlignedVec::<16>::with_capacity(bytes.len());
|
||||
abytes.extend_from_slice(bytes);
|
||||
rkyv::from_bytes::<Sieve, rkyv::rancor::Error>(&abytes).ok()
|
||||
<UnversionedArchive<AlignedBytes> as Deserialize>::deserialize(bytes)
|
||||
.ok()?
|
||||
.deserialize::<Sieve>()
|
||||
.ok()
|
||||
}) {
|
||||
Ok(CompiledScript {
|
||||
script,
|
||||
@@ -657,9 +659,8 @@ impl SieveScriptIngest for Server {
|
||||
) {
|
||||
Ok(sieve) => {
|
||||
// Store updated compiled sieve script
|
||||
let compiled_bytes = rkyv::to_bytes::<rkyv::rancor::Error>(&sieve)
|
||||
.map_err(Into::into)
|
||||
.caused_by(trc::location!())?;
|
||||
let sieve = UnversionedArchiver::new(sieve);
|
||||
let compiled_bytes = sieve.serialize().caused_by(trc::location!())?;
|
||||
let mut updated_sieve_bytes =
|
||||
Vec::with_capacity(script_offset + compiled_bytes.len());
|
||||
updated_sieve_bytes.extend_from_slice(&script_bytes[0..script_offset]);
|
||||
@@ -700,7 +701,7 @@ impl SieveScriptIngest for Server {
|
||||
.caused_by(trc::location!())?;
|
||||
|
||||
Ok(CompiledScript {
|
||||
script: sieve,
|
||||
script: sieve.into_inner(),
|
||||
name: new_archive.into_inner().name,
|
||||
hash,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user