Skip to content

Commit

Permalink
Removed MessageDaoSource.updateMsgsByUID(), MessageDaoSource.getRawMI…
Browse files Browse the repository at this point in the history
…ME(). Refactored code.| #793
  • Loading branch information
DenBond7 committed Dec 24, 2019
1 parent 4ed68e2 commit dff864f
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ interface BaseDao<T> {
@Update
suspend fun updateSuspend(entity: T): Int

@Update
fun update(entities: Collection<T>): Int

@Update
suspend fun updateSuspend(entities: Collection<T>): Int

@Delete
fun delete(entity: T): Int

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import com.flowcrypt.email.api.email.JavaEmailConstants
import com.flowcrypt.email.database.MessageState
import com.flowcrypt.email.database.entity.MessageEntity
import java.util.*
import javax.mail.Flags
import kotlin.collections.ArrayList

/**
* This class describes available methods for [MessageEntity]
Expand All @@ -31,6 +33,9 @@ abstract class MessagesDao : BaseDao<MessageEntity> {
@Query("SELECT * FROM messages WHERE email = :account AND folder = :folder")
abstract fun getMessages(account: String, folder: String): LiveData<MessageEntity>

@Query("SELECT * FROM messages WHERE email = :account AND folder = :folder AND uid IN (:msgsUID)")
abstract fun getMsgsByUids(account: String?, folder: String?, msgsUID: Collection<Long>?): List<MessageEntity>

@Query("SELECT * FROM messages WHERE email = :account AND folder = :folder ORDER BY received_date DESC")
abstract fun getMessagesDataSourceFactory(account: String, folder: String): DataSource
.Factory<Int, MessageEntity>
Expand All @@ -44,8 +49,8 @@ abstract class MessagesDao : BaseDao<MessageEntity> {
@Query("SELECT * FROM messages WHERE email = :account AND folder = :label AND state NOT IN (:msgStates)")
abstract fun getOutboxMessages(account: String?, label: String = JavaEmailConstants.FOLDER_OUTBOX,
msgStates: Collection<Int> = listOf(
MessageState.SENDING.value,
MessageState.SENT_WITHOUT_LOCAL_COPY.value)): List<MessageEntity>
MessageState.SENDING.value,
MessageState.SENT_WITHOUT_LOCAL_COPY.value)): List<MessageEntity>

@Query("SELECT * FROM messages WHERE email = :account AND folder = :label AND state NOT IN (:msgStateValue)")
abstract fun getOutboxMessages(account: String?, label: String = JavaEmailConstants.FOLDER_OUTBOX,
Expand Down Expand Up @@ -77,4 +82,25 @@ abstract class MessagesDao : BaseDao<MessageEntity> {
}
}
}

@Transaction
open fun updateFlags(email: String?, label: String?, flagsMap: Map<Long, Flags>) {
val msgEntities = getMsgsByUids(account = email, folder = label, msgsUID = flagsMap.keys)
val modifiedMsgEntities = ArrayList<MessageEntity>()

for (msgEntity in msgEntities) {
val flags = flagsMap[msgEntity.uid]
flags?.let {
val modifiedMsgEntity = if (it.contains(Flags.Flag.SEEN)) {
msgEntity.copy(flags = it.toString().toUpperCase(Locale
.getDefault()), isNew = false)
} else {
msgEntity.copy(flags = it.toString().toUpperCase(Locale.getDefault()))
}
modifiedMsgEntities.add(modifiedMsgEntity)
}
}

update(modifiedMsgEntities)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ import com.flowcrypt.email.api.email.model.MessageFlag
import com.flowcrypt.email.database.FlowCryptRoomDatabase
import com.flowcrypt.email.database.MessageState
import com.flowcrypt.email.database.dao.source.BaseDaoSource
import com.sun.mail.imap.IMAPFolder
import java.util.*
import javax.mail.Flags
import javax.mail.Message
import javax.mail.internet.AddressException
import javax.mail.internet.InternetAddress

Expand All @@ -44,42 +42,6 @@ class MessageDaoSource : BaseDaoSource() {

override val tableName: String = TABLE_NAME_MESSAGES

/**
* This method update cached messages.
*
* @param context Interface to global information about an application environment.
* @param email The email that the message linked.
* @param label The folder label.
* @param folder The [IMAPFolder] object which contains information about a
* remote folder.
* @param msgs The messages array.
* @return the [ContentProviderResult] array.
*/
fun updateMsgsByUID(context: Context, email: String?, label: String?,
folder: IMAPFolder, msgs: Array<Message>?): Array<ContentProviderResult> {
val contentResolver = context.contentResolver
if (email != null && label != null && contentResolver != null && msgs != null && msgs.isNotEmpty()) {

val ops = ArrayList<ContentProviderOperation>()
for (message in msgs) {
val selection = "$COL_EMAIL= ? AND $COL_FOLDER = ? AND $COL_UID = ? "

val builder = ContentProviderOperation.newUpdate(baseContentUri)
.withValue(COL_FLAGS, message.flags.toString().toUpperCase(Locale.getDefault()))
.withSelection(selection, arrayOf(email, label, folder.getUID(message).toString()))
.withYieldAllowed(true)

if (message.flags.contains(Flags.Flag.SEEN)) {
builder.withValue(COL_IS_NEW, false)
}

ops.add(builder.build())
}
return contentResolver.applyBatch(baseContentUri.authority!!, ops)
} else
return emptyArray()
}

/**
* Update some message by the given parameters.
*
Expand Down Expand Up @@ -382,34 +344,6 @@ class MessageDaoSource : BaseDaoSource() {
return details
}

/**
* Get the raw MIME content of some message.
*
* @param context Interface to global information about an application environment.
* @param email The user email.
* @param label The label name.
* @param uid The uid of the message.
* @return the raw MIME message
*/
fun getRawMIME(context: Context, email: String, label: String, uid: Long): String? {
val contentResolver = context.contentResolver
val selection = "$COL_EMAIL= ? AND $COL_FOLDER = ? AND $COL_UID = ? "
val selectionArgs = arrayOf(email, label, uid.toString())
val cursor = contentResolver.query(baseContentUri, null, selection, selectionArgs, null)

var rawMimeMsg: String? = null

if (cursor != null) {
if (cursor.moveToFirst()) {
rawMimeMsg = cursor.getString(cursor.getColumnIndex(COL_RAW_MESSAGE_WITHOUT_ATTACHMENTS))

}
cursor.close()
}

return rawMimeMsg
}

/**
* Get the last UID of a message in the database for some label.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ class MessagesSenderJobService : JobService() {
val atts = attDaoSource.getAttInfoList(context, email,
JavaEmailConstants.FOLDER_OUTBOX, details.uid)

val mimeMsg = createMimeMsg(context, sess, msgDaoSource, details, atts)
val mimeMsg = createMimeMsg(context, sess, details, atts)
val isMsgSaved = saveCopyOfSentMsg(account, store, context, mimeMsg)

if (!isMsgSaved) {
Expand Down Expand Up @@ -348,7 +348,7 @@ class MessagesSenderJobService : JobService() {

private fun sendMsg(context: Context, account: AccountDao, msgDaoSource: MessageDaoSource,
details: MessageEntity, atts: List<AttachmentInfo>): Boolean {
val mimeMsg = createMimeMsg(context, sess, msgDaoSource, details, atts)
val mimeMsg = createMimeMsg(context, sess, details, atts)
val detEmail = details.email
val detLabel = details.folder

Expand Down Expand Up @@ -422,10 +422,8 @@ class MessagesSenderJobService : JobService() {
* @throws IOException
* @throws MessagingException
*/
private fun createMimeMsg(context: Context, sess: Session?, msgDaoSource: MessageDaoSource,
details: MessageEntity, atts: List<AttachmentInfo>): MimeMessage {
val rawMime = msgDaoSource.getRawMIME(context, details.email, details.folder, details.uid)
val stream = IOUtils.toInputStream(rawMime, StandardCharsets.UTF_8)
private fun createMimeMsg(context: Context, sess: Session?, details: MessageEntity, atts: List<AttachmentInfo>): MimeMessage {
val stream = IOUtils.toInputStream(details.rawMessageWithoutAttachments, StandardCharsets.UTF_8)
val mimeMsg = MimeMessage(sess, stream)

if (mimeMsg.content is MimeMultipart && !CollectionUtils.isEmpty(atts)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,12 @@ class SyncJobService : JobService(), SyncListener {
val deleteCandidatesUIDs = EmailUtil.genDeleteCandidates(uidSet, remoteFolder, updateMsgs)

val generalMsgDetailsBeforeUpdate = msgDaoSource.getNewMsgs(applicationContext, account.email, folderName)
val roomDatabase = FlowCryptRoomDatabase.getDatabase(applicationContext)
roomDatabase.msgDao().deleteByUIDs(account.email, folderName, deleteCandidatesUIDs)

FlowCryptRoomDatabase.getDatabase(applicationContext).msgDao().deleteByUIDs(account.email, folderName, deleteCandidatesUIDs)

msgDaoSource.updateMsgsByUID(applicationContext, account.email, folderName, remoteFolder,
EmailUtil.genUpdateCandidates(mapOfUIDsAndMsgsFlags, remoteFolder, updateMsgs))
val updateCandidates = EmailUtil.genUpdateCandidates(mapOfUIDsAndMsgsFlags, remoteFolder,
updateMsgs).map { remoteFolder.getUID(it) to it.flags }.toMap()
roomDatabase.msgDao().updateFlags(account.email, folderName, updateCandidates)

val detailsAfterUpdate = msgDaoSource.getNewMsgs(applicationContext,
account.email, folderName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,13 @@ class EmailSyncService : BaseService(), SyncListener {

try {
val msgsDaoSource = MessageDaoSource()
val roomDatabase = FlowCryptRoomDatabase.getDatabase(applicationContext)

val mapOfUIDAndMsgFlags = msgsDaoSource.getMapOfUIDAndMsgFlags(this, email, folderName)
val msgsUIDs = HashSet(mapOfUIDAndMsgFlags.keys)
val deleteCandidatesUIDs = EmailUtil.genDeleteCandidates(msgsUIDs, remoteFolder, updateMsgs)

FlowCryptRoomDatabase.getDatabase(context).msgDao().deleteByUIDs(account.email, folderName, deleteCandidatesUIDs)
roomDatabase.msgDao().deleteByUIDs(account.email, folderName, deleteCandidatesUIDs)

val folderType = FoldersManager.getFolderType(localFolder)
if (!GeneralUtil.isAppForegrounded() && folderType === FoldersManager.FolderType.INBOX) {
Expand Down Expand Up @@ -414,14 +415,15 @@ class EmailSyncService : BaseService(), SyncListener {
areAllMsgsEncrypted = isEncryptedModeEnabled
)

FlowCryptRoomDatabase.getDatabase(context).msgDao().insert(msgEntities)
roomDatabase.msgDao().insert(msgEntities)

if (!isEncryptedModeEnabled) {
emailSyncManager.identifyEncryptedMsgs(ownerKey, R.id.syns_identify_encrypted_messages, localFolder)
}

val msgs = EmailUtil.genUpdateCandidates(mapOfUIDAndMsgFlags, remoteFolder, updateMsgs)
msgsDaoSource.updateMsgsByUID(this, email, folderName, remoteFolder, msgs)
val updateCandidates = EmailUtil.genUpdateCandidates(mapOfUIDAndMsgFlags, remoteFolder, updateMsgs)
.map { remoteFolder.getUID(it) to it.flags }.toMap()
roomDatabase.msgDao().updateFlags(account.email, folderName, updateCandidates)

if (newMsgs.isNotEmpty() || updateMsgs.isNotEmpty()) {
sendReply(ownerKey, requestCode, REPLY_RESULT_CODE_NEED_UPDATE)
Expand Down

0 comments on commit dff864f

Please sign in to comment.