diff --git a/app/schemas/eu.faircode.email.DB/17.json b/app/schemas/eu.faircode.email.DB/17.json new file mode 100644 index 0000000000..1be00892d0 --- /dev/null +++ b/app/schemas/eu.faircode.email.DB/17.json @@ -0,0 +1,1178 @@ +{ + "formatVersion": 1, + "database": { + "version": 17, + "identityHash": "ecce26622382a152074082389d41d354", + "entities": [ + { + "tableName": "identity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `replyto` TEXT, `account` INTEGER NOT NULL, `host` TEXT NOT NULL, `starttls` INTEGER NOT NULL, `insecure` INTEGER NOT NULL, `port` INTEGER NOT NULL, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `auth_type` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `color` INTEGER, `signature` TEXT, `synchronize` INTEGER NOT NULL, `store_sent` INTEGER NOT NULL, `sent_folder` INTEGER, `state` TEXT, `error` TEXT, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "replyto", + "columnName": "replyto", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "account", + "columnName": "account", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "host", + "columnName": "host", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "starttls", + "columnName": "starttls", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "insecure", + "columnName": "insecure", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "port", + "columnName": "port", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "user", + "columnName": "user", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "auth_type", + "columnName": "auth_type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "primary", + "columnName": "primary", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "signature", + "columnName": "signature", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "synchronize", + "columnName": "synchronize", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "store_sent", + "columnName": "store_sent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sent_folder", + "columnName": "sent_folder", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_identity_account", + "unique": false, + "columnNames": [ + "account" + ], + "createSql": "CREATE INDEX `index_identity_account` ON `${TABLE_NAME}` (`account`)" + }, + { + "name": "index_identity_account_email", + "unique": false, + "columnNames": [ + "account", + "email" + ], + "createSql": "CREATE INDEX `index_identity_account_email` ON `${TABLE_NAME}` (`account`, `email`)" + } + ], + "foreignKeys": [ + { + "table": "account", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "account", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `signature` TEXT, `host` TEXT NOT NULL, `starttls` INTEGER NOT NULL, `insecure` INTEGER NOT NULL, `port` INTEGER NOT NULL, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `auth_type` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `color` INTEGER, `notify` INTEGER NOT NULL, `poll_interval` INTEGER NOT NULL, `created` INTEGER, `state` TEXT, `error` TEXT, `last_connected` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "signature", + "columnName": "signature", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "host", + "columnName": "host", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "starttls", + "columnName": "starttls", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "insecure", + "columnName": "insecure", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "port", + "columnName": "port", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "user", + "columnName": "user", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "auth_type", + "columnName": "auth_type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "synchronize", + "columnName": "synchronize", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "primary", + "columnName": "primary", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notify", + "columnName": "notify", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "poll_interval", + "columnName": "poll_interval", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "created", + "columnName": "created", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "last_connected", + "columnName": "last_connected", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "folder", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER, `name` TEXT NOT NULL, `type` TEXT NOT NULL, `level` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `poll` INTEGER NOT NULL, `sync_days` INTEGER NOT NULL, `keep_days` INTEGER NOT NULL, `display` TEXT, `hide` INTEGER NOT NULL, `unified` INTEGER NOT NULL, `keywords` TEXT, `state` TEXT, `sync_state` TEXT, `error` TEXT, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "account", + "columnName": "account", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "level", + "columnName": "level", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "synchronize", + "columnName": "synchronize", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "poll", + "columnName": "poll", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sync_days", + "columnName": "sync_days", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "keep_days", + "columnName": "keep_days", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "display", + "columnName": "display", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "hide", + "columnName": "hide", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unified", + "columnName": "unified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "keywords", + "columnName": "keywords", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sync_state", + "columnName": "sync_state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_folder_account_name", + "unique": true, + "columnNames": [ + "account", + "name" + ], + "createSql": "CREATE UNIQUE INDEX `index_folder_account_name` ON `${TABLE_NAME}` (`account`, `name`)" + }, + { + "name": "index_folder_account", + "unique": false, + "columnNames": [ + "account" + ], + "createSql": "CREATE INDEX `index_folder_account` ON `${TABLE_NAME}` (`account`)" + }, + { + "name": "index_folder_name", + "unique": false, + "columnNames": [ + "name" + ], + "createSql": "CREATE INDEX `index_folder_name` ON `${TABLE_NAME}` (`name`)" + }, + { + "name": "index_folder_type", + "unique": false, + "columnNames": [ + "type" + ], + "createSql": "CREATE INDEX `index_folder_type` ON `${TABLE_NAME}` (`type`)" + }, + { + "name": "index_folder_unified", + "unique": false, + "columnNames": [ + "unified" + ], + "createSql": "CREATE INDEX `index_folder_unified` ON `${TABLE_NAME}` (`unified`)" + } + ], + "foreignKeys": [ + { + "table": "account", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "message", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER NOT NULL, `folder` INTEGER NOT NULL, `identity` INTEGER, `extra` TEXT, `replying` INTEGER, `forwarding` INTEGER, `uid` INTEGER, `msgid` TEXT, `references` TEXT, `deliveredto` TEXT, `inreplyto` TEXT, `thread` TEXT, `avatar` TEXT, `from` TEXT, `to` TEXT, `cc` TEXT, `bcc` TEXT, `reply` TEXT, `headers` TEXT, `subject` TEXT, `size` INTEGER, `content` INTEGER NOT NULL, `preview` TEXT, `sent` INTEGER, `received` INTEGER NOT NULL, `stored` INTEGER NOT NULL, `seen` INTEGER NOT NULL, `answered` INTEGER NOT NULL, `flagged` INTEGER NOT NULL, `keywords` TEXT, `ui_seen` INTEGER NOT NULL, `ui_answered` INTEGER NOT NULL, `ui_flagged` INTEGER NOT NULL, `ui_hide` INTEGER NOT NULL, `ui_found` INTEGER NOT NULL, `ui_ignored` INTEGER NOT NULL, `ui_browsed` INTEGER NOT NULL, `error` TEXT, `last_attempt` INTEGER, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`identity`) REFERENCES `identity`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL , FOREIGN KEY(`replying`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL , FOREIGN KEY(`forwarding`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "account", + "columnName": "account", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "folder", + "columnName": "folder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "identity", + "columnName": "identity", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "extra", + "columnName": "extra", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "replying", + "columnName": "replying", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "forwarding", + "columnName": "forwarding", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "msgid", + "columnName": "msgid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "references", + "columnName": "references", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deliveredto", + "columnName": "deliveredto", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "inreplyto", + "columnName": "inreplyto", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thread", + "columnName": "thread", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatar", + "columnName": "avatar", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "from", + "columnName": "from", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "to", + "columnName": "to", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "cc", + "columnName": "cc", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "bcc", + "columnName": "bcc", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "reply", + "columnName": "reply", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "headers", + "columnName": "headers", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "size", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "preview", + "columnName": "preview", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sent", + "columnName": "sent", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "received", + "columnName": "received", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stored", + "columnName": "stored", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "seen", + "columnName": "seen", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "answered", + "columnName": "answered", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "flagged", + "columnName": "flagged", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "keywords", + "columnName": "keywords", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ui_seen", + "columnName": "ui_seen", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ui_answered", + "columnName": "ui_answered", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ui_flagged", + "columnName": "ui_flagged", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ui_hide", + "columnName": "ui_hide", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ui_found", + "columnName": "ui_found", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ui_ignored", + "columnName": "ui_ignored", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ui_browsed", + "columnName": "ui_browsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "last_attempt", + "columnName": "last_attempt", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_message_account", + "unique": false, + "columnNames": [ + "account" + ], + "createSql": "CREATE INDEX `index_message_account` ON `${TABLE_NAME}` (`account`)" + }, + { + "name": "index_message_folder", + "unique": false, + "columnNames": [ + "folder" + ], + "createSql": "CREATE INDEX `index_message_folder` ON `${TABLE_NAME}` (`folder`)" + }, + { + "name": "index_message_identity", + "unique": false, + "columnNames": [ + "identity" + ], + "createSql": "CREATE INDEX `index_message_identity` ON `${TABLE_NAME}` (`identity`)" + }, + { + "name": "index_message_replying", + "unique": false, + "columnNames": [ + "replying" + ], + "createSql": "CREATE INDEX `index_message_replying` ON `${TABLE_NAME}` (`replying`)" + }, + { + "name": "index_message_forwarding", + "unique": false, + "columnNames": [ + "forwarding" + ], + "createSql": "CREATE INDEX `index_message_forwarding` ON `${TABLE_NAME}` (`forwarding`)" + }, + { + "name": "index_message_folder_uid", + "unique": true, + "columnNames": [ + "folder", + "uid" + ], + "createSql": "CREATE UNIQUE INDEX `index_message_folder_uid` ON `${TABLE_NAME}` (`folder`, `uid`)" + }, + { + "name": "index_message_msgid_folder", + "unique": true, + "columnNames": [ + "msgid", + "folder" + ], + "createSql": "CREATE UNIQUE INDEX `index_message_msgid_folder` ON `${TABLE_NAME}` (`msgid`, `folder`)" + }, + { + "name": "index_message_thread", + "unique": false, + "columnNames": [ + "thread" + ], + "createSql": "CREATE INDEX `index_message_thread` ON `${TABLE_NAME}` (`thread`)" + }, + { + "name": "index_message_received", + "unique": false, + "columnNames": [ + "received" + ], + "createSql": "CREATE INDEX `index_message_received` ON `${TABLE_NAME}` (`received`)" + }, + { + "name": "index_message_ui_seen", + "unique": false, + "columnNames": [ + "ui_seen" + ], + "createSql": "CREATE INDEX `index_message_ui_seen` ON `${TABLE_NAME}` (`ui_seen`)" + }, + { + "name": "index_message_ui_flagged", + "unique": false, + "columnNames": [ + "ui_flagged" + ], + "createSql": "CREATE INDEX `index_message_ui_flagged` ON `${TABLE_NAME}` (`ui_flagged`)" + }, + { + "name": "index_message_ui_hide", + "unique": false, + "columnNames": [ + "ui_hide" + ], + "createSql": "CREATE INDEX `index_message_ui_hide` ON `${TABLE_NAME}` (`ui_hide`)" + }, + { + "name": "index_message_ui_found", + "unique": false, + "columnNames": [ + "ui_found" + ], + "createSql": "CREATE INDEX `index_message_ui_found` ON `${TABLE_NAME}` (`ui_found`)" + }, + { + "name": "index_message_ui_ignored", + "unique": false, + "columnNames": [ + "ui_ignored" + ], + "createSql": "CREATE INDEX `index_message_ui_ignored` ON `${TABLE_NAME}` (`ui_ignored`)" + }, + { + "name": "index_message_ui_browsed", + "unique": false, + "columnNames": [ + "ui_browsed" + ], + "createSql": "CREATE INDEX `index_message_ui_browsed` ON `${TABLE_NAME}` (`ui_browsed`)" + } + ], + "foreignKeys": [ + { + "table": "account", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "folder", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "folder" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "identity", + "onDelete": "SET NULL", + "onUpdate": "NO ACTION", + "columns": [ + "identity" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "message", + "onDelete": "SET NULL", + "onUpdate": "NO ACTION", + "columns": [ + "replying" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "message", + "onDelete": "SET NULL", + "onUpdate": "NO ACTION", + "columns": [ + "forwarding" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "attachment", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` INTEGER NOT NULL, `sequence` INTEGER NOT NULL, `name` TEXT, `type` TEXT NOT NULL, `cid` TEXT, `size` INTEGER, `progress` INTEGER, `available` INTEGER NOT NULL, FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "message", + "columnName": "message", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sequence", + "columnName": "sequence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "cid", + "columnName": "cid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "size", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "progress", + "columnName": "progress", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "available", + "columnName": "available", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_attachment_message", + "unique": false, + "columnNames": [ + "message" + ], + "createSql": "CREATE INDEX `index_attachment_message` ON `${TABLE_NAME}` (`message`)" + }, + { + "name": "index_attachment_message_sequence", + "unique": true, + "columnNames": [ + "message", + "sequence" + ], + "createSql": "CREATE UNIQUE INDEX `index_attachment_message_sequence` ON `${TABLE_NAME}` (`message`, `sequence`)" + }, + { + "name": "index_attachment_message_cid", + "unique": true, + "columnNames": [ + "message", + "cid" + ], + "createSql": "CREATE UNIQUE INDEX `index_attachment_message_cid` ON `${TABLE_NAME}` (`message`, `cid`)" + } + ], + "foreignKeys": [ + { + "table": "message", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "message" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "operation", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `folder` INTEGER NOT NULL, `message` INTEGER, `name` TEXT NOT NULL, `args` TEXT NOT NULL, `created` INTEGER NOT NULL, `error` TEXT, FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "folder", + "columnName": "folder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "message", + "columnName": "message", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "args", + "columnName": "args", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "created", + "columnName": "created", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_operation_folder", + "unique": false, + "columnNames": [ + "folder" + ], + "createSql": "CREATE INDEX `index_operation_folder` ON `${TABLE_NAME}` (`folder`)" + }, + { + "name": "index_operation_message", + "unique": false, + "columnNames": [ + "message" + ], + "createSql": "CREATE INDEX `index_operation_message` ON `${TABLE_NAME}` (`message`)" + } + ], + "foreignKeys": [ + { + "table": "folder", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "folder" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "message", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "message" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "answer", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `text` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "text", + "columnName": "text", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "log", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `time` INTEGER NOT NULL, `data` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "data", + "columnName": "data", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_log_time", + "unique": false, + "columnNames": [ + "time" + ], + "createSql": "CREATE INDEX `index_log_time` ON `${TABLE_NAME}` (`time`)" + } + ], + "foreignKeys": [] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"ecce26622382a152074082389d41d354\")" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index f240dc6a32..875222def1 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -411,7 +411,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB if (archive == null) throw new IllegalArgumentException(getString(R.string.title_no_primary_archive)); - db.message().deleteFoundMessages(); + db.message().resetSearch(); return archive.id; } @@ -1162,7 +1162,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB args.putLong("account", intent.getLongExtra("account", -1)); args.putString("thread", intent.getStringExtra("thread")); args.putLong("id", intent.getLongExtra("id", -1)); - args.putBoolean("found", intent.getBooleanExtra("found", false)); FragmentMessages fragment = new FragmentMessages(); fragment.setArguments(args); diff --git a/app/src/main/java/eu/faircode/email/AdapterFolder.java b/app/src/main/java/eu/faircode/email/AdapterFolder.java index d2ee6eaa08..e05fbdb498 100644 --- a/app/src/main/java/eu/faircode/email/AdapterFolder.java +++ b/app/src/main/java/eu/faircode/email/AdapterFolder.java @@ -323,7 +323,7 @@ public class AdapterFolder extends RecyclerView.Adapter messages = db.message().getMessageByThread( - message.account, message.thread, threading && thread ? null : id, message.folder, message.ui_found); + message.account, message.thread, threading && thread ? null : id, message.folder); for (EntityMessage threaded : messages) EntityOperation.queue(db, threaded, EntityOperation.FLAG, flagged); diff --git a/app/src/main/java/eu/faircode/email/AdapterOperation.java b/app/src/main/java/eu/faircode/email/AdapterOperation.java index 3264fbb9cc..70c218c7c0 100644 --- a/app/src/main/java/eu/faircode/email/AdapterOperation.java +++ b/app/src/main/java/eu/faircode/email/AdapterOperation.java @@ -134,8 +134,7 @@ public class AdapterOperation extends RecyclerView.Adapter liveFolderEx(long id); diff --git a/app/src/main/java/eu/faircode/email/DaoMessage.java b/app/src/main/java/eu/faircode/email/DaoMessage.java index 203702d33f..ae1dd6cff4 100644 --- a/app/src/main/java/eu/faircode/email/DaoMessage.java +++ b/app/src/main/java/eu/faircode/email/DaoMessage.java @@ -57,7 +57,6 @@ public interface DaoMessage { " JOIN folder ON folder.id = message.folder" + " WHERE account.`synchronize`" + " AND (NOT message.ui_hide OR :debug)" + - " AND NOT ui_found" + " GROUP BY account.id, CASE WHEN message.thread IS NULL OR NOT :threading THEN message.id ELSE message.thread END" + " HAVING SUM(unified) > 0" + " ORDER BY CASE" + @@ -90,7 +89,7 @@ public interface DaoMessage { " JOIN folder f ON f.id = :folder" + " WHERE (message.account = f.account OR folder.type = '" + EntityFolder.OUTBOX + "')" + " AND (NOT message.ui_hide OR :debug)" + - " AND ui_found = :found" + + " AND (NOT :found OR ui_found = :found)" + " GROUP BY CASE WHEN message.thread IS NULL OR NOT :threading THEN message.id ELSE message.thread END" + " HAVING SUM(CASE WHEN folder.id = :folder THEN 1 ELSE 0 END) > 0" + " ORDER BY CASE" + @@ -126,14 +125,13 @@ public interface DaoMessage { " WHERE message.account = :account" + " AND message.thread = :thread" + " AND (:id IS NULL OR message.id = :id)" + - " AND ui_found = :found" + " AND (NOT message.ui_hide OR :debug)" + " ORDER BY CASE" + " WHEN 'unread' = :sort THEN NOT message.ui_seen" + " WHEN 'starred' = :sort THEN message.ui_flagged" + " ELSE 0" + " END DESC, message.received DESC") - DataSource.Factory pagedThread(long account, String thread, Long id, boolean found, String sort, boolean debug); + DataSource.Factory pagedThread(long account, String thread, Long id, String sort, boolean debug); @Query("SELECT COUNT(id)" + " FROM message" + @@ -148,38 +146,33 @@ public interface DaoMessage { @Query("SELECT *" + " FROM message" + " WHERE folder = :folder" + - " AND uid = :uid" + - " AND ui_found = :found") - EntityMessage getMessageByUid(long folder, long uid, boolean found); + " AND uid = :uid") + EntityMessage getMessageByUid(long folder, long uid); @Query("SELECT id" + " FROM message" + " WHERE folder = :folder" + - " AND ui_found = :found" + " ORDER BY message.received DESC") - List getMessageByFolder(long folder, boolean found); + List getMessageByFolder(long folder); @Query("SELECT *" + " FROM message" + " WHERE account = :account" + " AND thread = :thread" + " AND (:id IS NULL OR message.id = :id)" + - " AND (:folder IS NULL OR message.folder = :folder)" + - " AND ui_found = :found") - List getMessageByThread(long account, String thread, Long id, Long folder, boolean found); + " AND (:folder IS NULL OR message.folder = :folder)") + List getMessageByThread(long account, String thread, Long id, Long folder); @Query("SELECT message.* FROM message" + " JOIN folder ON folder.id = message.folder" + " WHERE message.account = :account" + - " AND message.msgid = :msgid" + - " AND ui_found = :found") - List getMessageByMsgId(long account, String msgid, boolean found); + " AND message.msgid = :msgid") + List getMessageByMsgId(long account, String msgid); @Query("SELECT * FROM message" + " WHERE folder = :folder" + - " AND ui_seen" + - " AND ui_found = :found") - List getMessageSeen(long folder, boolean found); + " AND ui_seen") + List getMessageSeen(long folder); @Query("SELECT id FROM message" + " WHERE content" + @@ -218,7 +211,6 @@ public interface DaoMessage { " AND (account.created IS NULL OR message.received > account.created)" + " AND NOT message.ui_seen" + " AND NOT message.ui_hide" + - " AND NOT message.ui_found" + " AND NOT message.ui_ignored" + " ORDER BY message.received") LiveData> liveUnseenUnified(); @@ -230,7 +222,6 @@ public interface DaoMessage { " AND folder.unified" + " AND NOT message.ui_seen" + " AND NOT message.ui_hide" + - " AND NOT message.ui_found" + " AND NOT message.ui_ignored" + " ORDER BY message.received") int getUnseenUnified(); @@ -238,8 +229,7 @@ public interface DaoMessage { @Query("SELECT uid FROM message" + " WHERE folder = :folder" + " AND received >= :received" + - " AND NOT uid IS NULL" + - " AND NOT ui_found" /* keep found messages */) + " AND NOT uid IS NULL") List getUids(long folder, long received); @Insert @@ -298,6 +288,14 @@ public interface DaoMessage { " AND folder IN (SELECT id FROM folder WHERE type = '" + EntityFolder.INBOX + "')") int ignoreAll(); + @Query("UPDATE message SET ui_found = 1" + + " WHERE account = :account" + + " AND thread = :thread") + int setMessageFound(long account, String thread); + + @Query("UPDATE message SET ui_found = 0") + int resetSearch(); + @Query("DELETE FROM message WHERE id = :id") int deleteMessage(long id); @@ -323,7 +321,4 @@ public interface DaoMessage { " AND (NOT ui_browsed OR :browsed)" + " AND NOT ui_flagged") int deleteMessagesBefore(long folder, long received, boolean browsed); - - @Query("DELETE FROM message WHERE ui_found") - int deleteFoundMessages(); } \ No newline at end of file diff --git a/app/src/main/java/eu/faircode/email/EntityMessage.java b/app/src/main/java/eu/faircode/email/EntityMessage.java index 211ae5c085..f5c86db012 100644 --- a/app/src/main/java/eu/faircode/email/EntityMessage.java +++ b/app/src/main/java/eu/faircode/email/EntityMessage.java @@ -69,8 +69,8 @@ import static androidx.room.ForeignKey.SET_NULL; @Index(value = {"identity"}), @Index(value = {"replying"}), @Index(value = {"forwarding"}), - @Index(value = {"folder", "uid", "ui_found"}, unique = true), - @Index(value = {"msgid", "folder", "ui_found"}, unique = true), + @Index(value = {"folder", "uid"}, unique = true), + @Index(value = {"msgid", "folder"}, unique = true), @Index(value = {"thread"}), @Index(value = {"received"}), @Index(value = {"ui_seen"}), diff --git a/app/src/main/java/eu/faircode/email/EntityOperation.java b/app/src/main/java/eu/faircode/email/EntityOperation.java index e92bf2f74c..e362824c25 100644 --- a/app/src/main/java/eu/faircode/email/EntityOperation.java +++ b/app/src/main/java/eu/faircode/email/EntityOperation.java @@ -84,17 +84,17 @@ public class EntityOperation { queue(db, message.folder, message.id, name, jargs); if (SEEN.equals(name)) { - for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid, message.ui_found)) { + for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid)) { db.message().setMessageUiSeen(similar.id, (boolean) value); db.message().setMessageUiIgnored(similar.id, true); } } else if (FLAG.equals(name)) - for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid, message.ui_found)) + for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid)) db.message().setMessageUiFlagged(similar.id, (boolean) value); else if (ANSWERED.equals(name)) - for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid, message.ui_found)) + for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid)) db.message().setMessageUiAnswered(similar.id, (boolean) value); else if (MOVE.equals(name)) diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index 0df2a9dc38..925faba4cc 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -94,7 +94,6 @@ public class FragmentMessages extends FragmentEx { private boolean outgoing = false; private String thread = null; private long id = -1; - private boolean found = false; private String search = null; private boolean threading = true; @@ -136,7 +135,6 @@ public class FragmentMessages extends FragmentEx { outgoing = args.getBoolean("outgoing", false); thread = args.getString("thread"); id = args.getLong("id", -1); - found = args.getBoolean("found", false); search = args.getString("search"); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); @@ -548,7 +546,7 @@ public class FragmentMessages extends FragmentEx { result.target = target; List messages = db.message().getMessageByThread( - message.account, message.thread, threading && thread ? null : id, message.folder, message.ui_found); + message.account, message.thread, threading && thread ? null : id, message.folder); for (EntityMessage threaded : messages) { result.ids.add(threaded.id); db.message().setMessageUiHide(threaded.id, true); @@ -606,7 +604,6 @@ public class FragmentMessages extends FragmentEx { Bundle args = new Bundle(); args.putLong("account", account); args.putString("thread", thread); - args.putBoolean("found", found); args.putString("folderType", folderType); new SimpleTask() { @@ -614,7 +611,6 @@ public class FragmentMessages extends FragmentEx { protected MessageTarget onLoad(Context context, Bundle args) { long account = args.getLong("account"); String thread = args.getString("thread"); - boolean found = args.getBoolean("found"); String folderType = args.getString("folderType"); MessageTarget result = new MessageTarget(); @@ -626,7 +622,7 @@ public class FragmentMessages extends FragmentEx { result.target = db.folder().getFolderByType(account, folderType); List messages = db.message().getMessageByThread( - account, thread, threading ? null : id, null, found); + account, thread, threading ? null : id, null); for (EntityMessage threaded : messages) if (!result.target.id.equals(threaded.folder)) { result.ids.add(threaded.id); @@ -659,8 +655,7 @@ public class FragmentMessages extends FragmentEx { new Intent(ActivityView.ACTION_VIEW_THREAD) .putExtra("account", target.account) .putExtra("thread", target.thread) - .putExtra("id", target.id) - .putExtra("found", target.found)); + .putExtra("id", target.id)); } }); @@ -851,7 +846,7 @@ public class FragmentMessages extends FragmentEx { EntityMessage message = db.message().getMessage(id); if (message.ui_seen != seen) { List messages = db.message().getMessageByThread( - message.account, message.thread, threading ? null : id, message.folder, message.ui_found); + message.account, message.thread, threading ? null : id, message.folder); for (EntityMessage threaded : messages) EntityOperation.queue(db, threaded, EntityOperation.SEEN, seen); } @@ -893,7 +888,7 @@ public class FragmentMessages extends FragmentEx { EntityMessage message = db.message().getMessage(id); if (message.ui_flagged != flagged) { List messages = db.message().getMessageByThread( - message.account, message.thread, threading ? null : id, message.folder, message.ui_found); + message.account, message.thread, threading ? null : id, message.folder); for (EntityMessage threaded : messages) EntityOperation.queue(db, threaded, EntityOperation.FLAG, flagged); } @@ -950,7 +945,7 @@ public class FragmentMessages extends FragmentEx { for (long id : ids) { EntityMessage message = db.message().getMessage(id); List messages = db.message().getMessageByThread( - message.account, message.thread, threading ? null : id, message.folder, message.ui_found); + message.account, message.thread, threading ? null : id, message.folder); for (EntityMessage threaded : messages) { if (threaded.uid == null && !TextUtils.isEmpty(threaded.error)) // outbox db.message().deleteMessage(threaded.id); @@ -1003,7 +998,7 @@ public class FragmentMessages extends FragmentEx { for (long id : ids) { EntityMessage message = db.message().getMessage(id); List messages = db.message().getMessageByThread( - message.account, message.thread, threading ? null : id, message.folder, message.ui_found); + message.account, message.thread, threading ? null : id, message.folder); for (EntityMessage threaded : messages) { result.ids.add(threaded.id); db.message().setMessageUiHide(threaded.id, true); @@ -1092,7 +1087,7 @@ public class FragmentMessages extends FragmentEx { for (long id : ids) { EntityMessage message = db.message().getMessage(id); List messages = db.message().getMessageByThread( - message.account, message.thread, threading ? null : id, message.folder, message.ui_found); + message.account, message.thread, threading ? null : id, message.folder); for (EntityMessage threaded : messages) { result.ids.add(threaded.id); db.message().setMessageUiHide(threaded.id, true); @@ -1363,7 +1358,7 @@ public class FragmentMessages extends FragmentEx { new SimpleTask() { @Override protected Void onLoad(Context context, Bundle args) { - DB.getInstance(context).message().deleteFoundMessages(); + DB.getInstance(context).message().resetSearch(); return null; } @@ -1485,7 +1480,7 @@ public class FragmentMessages extends FragmentEx { try { db.beginTransaction(); - for (EntityMessage message : db.message().getMessageSeen(outbox, false)) { + for (EntityMessage message : db.message().getMessageSeen(outbox)) { EntityIdentity identity = db.identity().getIdentity(message.identity); EntityFolder sent = db.folder().getFolderByType(identity.account, EntityFolder.SENT); if (sent != null) { @@ -1574,7 +1569,7 @@ public class FragmentMessages extends FragmentEx { case THREAD: messages = new LivePagedListBuilder<>( - db.message().pagedThread(account, thread, threading ? null : id, found, sort, debug), LOCAL_PAGE_SIZE).build(); + db.message().pagedThread(account, thread, threading ? null : id, sort, debug), LOCAL_PAGE_SIZE).build(); break; } } else { diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index 9ab1a77d93..5fedcc0089 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -926,13 +926,12 @@ public class ServiceSynchronize extends LifecycleService { for (Message imessage : e.getMessages()) try { - long id; + EntityMessage message; try { db.beginTransaction(); - id = synchronizeMessage( + message = synchronizeMessage( ServiceSynchronize.this, - folder, ifolder, (IMAPMessage) imessage, - false, false, false); + folder, ifolder, (IMAPMessage) imessage, false, false); db.setTransactionSuccessful(); } finally { db.endTransaction(); @@ -940,7 +939,9 @@ public class ServiceSynchronize extends LifecycleService { try { db.beginTransaction(); - downloadMessage(ServiceSynchronize.this, folder, ifolder, (IMAPMessage) imessage, id); + downloadMessage( + ServiceSynchronize.this, + folder, ifolder, (IMAPMessage) imessage, message.id); db.setTransactionSuccessful(); } finally { db.endTransaction(); @@ -1006,13 +1007,12 @@ public class ServiceSynchronize extends LifecycleService { fp.add(IMAPFolder.FetchProfileItem.FLAGS); ifolder.fetch(new Message[]{e.getMessage()}, fp); - long id; + EntityMessage message; try { db.beginTransaction(); - id = synchronizeMessage( + message = synchronizeMessage( ServiceSynchronize.this, - folder, ifolder, (IMAPMessage) e.getMessage(), - false, false, false); + folder, ifolder, (IMAPMessage) e.getMessage(), false, false); db.setTransactionSuccessful(); } finally { db.endTransaction(); @@ -1020,7 +1020,7 @@ public class ServiceSynchronize extends LifecycleService { try { db.beginTransaction(); - downloadMessage(ServiceSynchronize.this, folder, ifolder, (IMAPMessage) e.getMessage(), id); + downloadMessage(ServiceSynchronize.this, folder, ifolder, (IMAPMessage) e.getMessage(), message.id); db.setTransactionSuccessful(); } finally { db.endTransaction(); @@ -1948,7 +1948,7 @@ public class ServiceSynchronize extends LifecycleService { List full = new ArrayList<>(); for (Message imessage : isub) { long uid = ifolder.getUID(imessage); - EntityMessage message = db.message().getMessageByUid(folder.id, uid, false); + EntityMessage message = db.message().getMessageByUid(folder.id, uid); if (message == null) full.add(imessage); } @@ -1962,10 +1962,10 @@ public class ServiceSynchronize extends LifecycleService { for (int j = isub.length - 1; j >= 0 && state.running(); j--) try { db.beginTransaction(); - ids[from + j] = synchronizeMessage( + EntityMessage message = synchronizeMessage( this, - folder, ifolder, (IMAPMessage) isub[j], - false, false, true); + folder, ifolder, (IMAPMessage) isub[j], false, true); + ids[from + j] = message.id; db.setTransactionSuccessful(); Thread.sleep(20); } catch (MessageRemovedException ex) { @@ -2036,10 +2036,10 @@ public class ServiceSynchronize extends LifecycleService { } } - static Long synchronizeMessage( + static EntityMessage synchronizeMessage( Context context, EntityFolder folder, IMAPFolder ifolder, IMAPMessage imessage, - boolean found, boolean browsed, boolean full) throws MessagingException, IOException { + boolean browsed, boolean full) throws MessagingException, IOException { long uid = ifolder.getUID(imessage); if (imessage.isExpunged()) { @@ -2060,7 +2060,7 @@ public class ServiceSynchronize extends LifecycleService { DB db = DB.getInstance(context); // Find message by uid (fast, no headers required) - EntityMessage message = db.message().getMessageByUid(folder.id, uid, found); + EntityMessage message = db.message().getMessageByUid(folder.id, uid); // Find message by Message-ID (slow, headers required) // - messages in inbox have same id as message sent to self @@ -2069,7 +2069,7 @@ public class ServiceSynchronize extends LifecycleService { // Will fetch headers within database transaction String msgid = helper.getMessageID(); Log.i(Helper.TAG, "Searching for " + msgid); - for (EntityMessage dup : db.message().getMessageByMsgId(folder.account, msgid, found)) { + for (EntityMessage dup : db.message().getMessageByMsgId(folder.account, msgid)) { EntityFolder dfolder = db.folder().getFolder(dup.folder); boolean outbox = EntityFolder.OUTBOX.equals(dfolder.type); Log.i(Helper.TAG, folder.name + " found as id=" + dup.id + "/" + dup.uid + @@ -2162,7 +2162,7 @@ public class ServiceSynchronize extends LifecycleService { message.ui_answered = answered; message.ui_flagged = flagged; message.ui_hide = false; - message.ui_found = found; + message.ui_found = false; message.ui_ignored = false; message.ui_browsed = browsed; message.getAvatar(context); @@ -2243,7 +2243,7 @@ public class ServiceSynchronize extends LifecycleService { db.folder().setFolderKeywords(folder.id, DB.Converters.fromStringArray(fkeywords.toArray(new String[0]))); } - return message.id; + return message; } private static void downloadMessage(Context context, EntityFolder folder, IMAPFolder ifolder, IMAPMessage imessage, long id) throws MessagingException, IOException { diff --git a/app/src/main/java/eu/faircode/email/ViewModelBrowse.java b/app/src/main/java/eu/faircode/email/ViewModelBrowse.java index f8fce8b49c..1eb71b3a3b 100644 --- a/app/src/main/java/eu/faircode/email/ViewModelBrowse.java +++ b/app/src/main/java/eu/faircode/email/ViewModelBrowse.java @@ -90,7 +90,7 @@ public class ViewModelBrowse extends ViewModel { db.beginTransaction(); if (state.messages == null) - state.messages = db.message().getMessageByFolder(state.fid, false); + state.messages = db.message().getMessageByFolder(state.fid); int matched = 0; for (int i = state.local; i < state.messages.size() && matched < state.pageSize; i++) { @@ -115,17 +115,8 @@ public class ViewModelBrowse extends ViewModel { if (!match && message.content) match = body.toLowerCase().contains(find); - if (match) { - EntityMessage exists = db.message().getMessageByUid(state.fid, message.uid, state.search != null); - if (exists == null) { - matched++; - message.id = null; - message.ui_found = true; - message.id = db.message().insertMessage(message); - if (message.content) - message.write(state.context, body); - } - } + if (match) + db.message().setMessageFound(message.account, message.thread); } db.setTransactionSuccessful(); @@ -202,14 +193,14 @@ public class ViewModelBrowse extends ViewModel { try { long uid = state.ifolder.getUID(isub[j]); Log.i(Helper.TAG, "Boundary sync uid=" + uid); - EntityMessage message = db.message().getMessageByUid(state.fid, uid, state.search != null); + EntityMessage message = db.message().getMessageByUid(state.fid, uid); if (message == null) { - ServiceSynchronize.synchronizeMessage( + message = ServiceSynchronize.synchronizeMessage( state.context, - folder, state.ifolder, (IMAPMessage) isub[j], - state.search != null, state.search == null, false); + folder, state.ifolder, (IMAPMessage) isub[j], true, false); count++; } + db.message().setMessageFound(message.account, message.thread); } catch (MessageRemovedException ex) { Log.w(Helper.TAG, "Boundary " + ex + "\n" + Log.getStackTraceString(ex)); } catch (FolderClosedException ex) {