diff --git a/app/schemas/eu.faircode.email.DB/87.json b/app/schemas/eu.faircode.email.DB/87.json new file mode 100644 index 0000000000..95e73b0b7f --- /dev/null +++ b/app/schemas/eu.faircode.email.DB/87.json @@ -0,0 +1,1799 @@ +{ + "formatVersion": 1, + "database": { + "version": 87, + "identityHash": "54e4606798a2b98908f5ba9b31401294", + "entities": [ + { + "tableName": "identity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `account` INTEGER NOT NULL, `display` TEXT, `color` INTEGER, `signature` TEXT, `auth_type` 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, `realm` TEXT, `use_ip` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `sender_extra` INTEGER NOT NULL, `replyto` TEXT, `bcc` TEXT, `plain_only` INTEGER NOT NULL, `encrypt` INTEGER NOT NULL, `delivery_receipt` INTEGER NOT NULL, `read_receipt` INTEGER NOT NULL, `store_sent` INTEGER NOT NULL, `sent_folder` INTEGER, `tbd` INTEGER, `state` TEXT, `error` TEXT, `last_connected` INTEGER, 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": "account", + "columnName": "account", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "display", + "columnName": "display", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "signature", + "columnName": "signature", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "auth_type", + "columnName": "auth_type", + "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": "realm", + "columnName": "realm", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "use_ip", + "columnName": "use_ip", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "synchronize", + "columnName": "synchronize", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "primary", + "columnName": "primary", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sender_extra", + "columnName": "sender_extra", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "replyto", + "columnName": "replyto", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "bcc", + "columnName": "bcc", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "plain_only", + "columnName": "plain_only", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "encrypt", + "columnName": "encrypt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "delivery_receipt", + "columnName": "delivery_receipt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "read_receipt", + "columnName": "read_receipt", + "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": "tbd", + "columnName": "tbd", + "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": [ + { + "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}` (`order` INTEGER, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `auth_type` INTEGER NOT NULL, `pop` 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, `realm` TEXT, `name` TEXT, `signature` TEXT, `color` INTEGER, `synchronize` INTEGER NOT NULL, `ondemand` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `notify` INTEGER NOT NULL, `browse` INTEGER NOT NULL, `swipe_left` INTEGER, `swipe_right` INTEGER, `poll_interval` INTEGER NOT NULL, `prefix` TEXT, `created` INTEGER, `tbd` INTEGER, `state` TEXT, `warning` TEXT, `error` TEXT, `last_connected` INTEGER)", + "fields": [ + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "auth_type", + "columnName": "auth_type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "pop", + "columnName": "pop", + "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": "realm", + "columnName": "realm", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "signature", + "columnName": "signature", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "synchronize", + "columnName": "synchronize", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ondemand", + "columnName": "ondemand", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "primary", + "columnName": "primary", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notify", + "columnName": "notify", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "browse", + "columnName": "browse", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "swipe_left", + "columnName": "swipe_left", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "swipe_right", + "columnName": "swipe_right", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "poll_interval", + "columnName": "poll_interval", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "prefix", + "columnName": "prefix", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "created", + "columnName": "created", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tbd", + "columnName": "tbd", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "warning", + "columnName": "warning", + "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}` (`order` INTEGER, `id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER, `parent` INTEGER, `name` TEXT NOT NULL, `type` TEXT NOT NULL, `level` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `poll` INTEGER NOT NULL, `download` INTEGER NOT NULL, `subscribed` INTEGER, `sync_days` INTEGER NOT NULL, `keep_days` INTEGER NOT NULL, `auto_delete` INTEGER NOT NULL, `display` TEXT, `hide` INTEGER NOT NULL, `collapsed` INTEGER NOT NULL, `unified` INTEGER NOT NULL, `navigation` INTEGER NOT NULL, `notify` INTEGER NOT NULL, `total` INTEGER, `keywords` TEXT, `initialize` INTEGER NOT NULL, `tbc` INTEGER, `tbd` INTEGER, `state` TEXT, `sync_state` TEXT, `read_only` INTEGER NOT NULL, `error` TEXT, `last_sync` INTEGER, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "account", + "columnName": "account", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "parent", + "columnName": "parent", + "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": "download", + "columnName": "download", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subscribed", + "columnName": "subscribed", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "sync_days", + "columnName": "sync_days", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "keep_days", + "columnName": "keep_days", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "auto_delete", + "columnName": "auto_delete", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "display", + "columnName": "display", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "hide", + "columnName": "hide", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "collapsed", + "columnName": "collapsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unified", + "columnName": "unified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "navigation", + "columnName": "navigation", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notify", + "columnName": "notify", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "total", + "columnName": "total", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "keywords", + "columnName": "keywords", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "initialize", + "columnName": "initialize", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tbc", + "columnName": "tbc", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tbd", + "columnName": "tbd", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sync_state", + "columnName": "sync_state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "read_only", + "columnName": "read_only", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "last_sync", + "columnName": "last_sync", + "affinity": "INTEGER", + "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, `receipt_request` INTEGER, `receipt_to` TEXT, `dkim` INTEGER, `spf` INTEGER, `dmarc` INTEGER, `avatar` TEXT, `sender` TEXT, `from` TEXT, `to` TEXT, `cc` TEXT, `bcc` TEXT, `reply` TEXT, `list_post` TEXT, `headers` TEXT, `raw` INTEGER, `subject` TEXT, `size` INTEGER, `content` INTEGER NOT NULL, `plain_only` INTEGER, `preview` TEXT, `sent` INTEGER, `received` INTEGER NOT NULL, `stored` INTEGER NOT NULL, `seen` INTEGER NOT NULL, `answered` INTEGER NOT NULL, `flagged` INTEGER NOT NULL, `flags` TEXT, `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, `ui_snoozed` INTEGER, `color` INTEGER, `revision` INTEGER, `revisions` INTEGER, `warning` TEXT, `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": "receipt_request", + "columnName": "receipt_request", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "receipt_to", + "columnName": "receipt_to", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "dkim", + "columnName": "dkim", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "spf", + "columnName": "spf", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "dmarc", + "columnName": "dmarc", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "avatar", + "columnName": "avatar", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sender", + "columnName": "sender", + "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": "list_post", + "columnName": "list_post", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "headers", + "columnName": "headers", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "raw", + "columnName": "raw", + "affinity": "INTEGER", + "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": "plain_only", + "columnName": "plain_only", + "affinity": "INTEGER", + "notNull": false + }, + { + "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": "flags", + "columnName": "flags", + "affinity": "TEXT", + "notNull": false + }, + { + "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": "ui_snoozed", + "columnName": "ui_snoozed", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "revision", + "columnName": "revision", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "revisions", + "columnName": "revisions", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "warning", + "columnName": "warning", + "affinity": "TEXT", + "notNull": false + }, + { + "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_folder_uid", + "unique": true, + "columnNames": [ + "folder", + "uid" + ], + "createSql": "CREATE UNIQUE INDEX `index_message_folder_uid` ON `${TABLE_NAME}` (`folder`, `uid`)" + }, + { + "name": "index_message_msgid", + "unique": false, + "columnNames": [ + "msgid" + ], + "createSql": "CREATE INDEX `index_message_msgid` ON `${TABLE_NAME}` (`msgid`)" + }, + { + "name": "index_message_thread", + "unique": false, + "columnNames": [ + "thread" + ], + "createSql": "CREATE INDEX `index_message_thread` ON `${TABLE_NAME}` (`thread`)" + }, + { + "name": "index_message_sender", + "unique": false, + "columnNames": [ + "sender" + ], + "createSql": "CREATE INDEX `index_message_sender` ON `${TABLE_NAME}` (`sender`)" + }, + { + "name": "index_message_received", + "unique": false, + "columnNames": [ + "received" + ], + "createSql": "CREATE INDEX `index_message_received` ON `${TABLE_NAME}` (`received`)" + }, + { + "name": "index_message_subject", + "unique": false, + "columnNames": [ + "subject" + ], + "createSql": "CREATE INDEX `index_message_subject` ON `${TABLE_NAME}` (`subject`)" + }, + { + "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`)" + }, + { + "name": "index_message_ui_snoozed", + "unique": false, + "columnNames": [ + "ui_snoozed" + ], + "createSql": "CREATE INDEX `index_message_ui_snoozed` ON `${TABLE_NAME}` (`ui_snoozed`)" + } + ], + "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, `disposition` TEXT, `cid` TEXT, `encryption` INTEGER, `size` INTEGER, `progress` INTEGER, `available` INTEGER NOT NULL, `error` TEXT, 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": "disposition", + "columnName": "disposition", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "cid", + "columnName": "cid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryption", + "columnName": "encryption", + "affinity": "INTEGER", + "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 + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + } + ], + "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": false, + "columnNames": [ + "message", + "cid" + ], + "createSql": "CREATE 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, `account` INTEGER, `folder` INTEGER NOT NULL, `message` INTEGER, `name` TEXT NOT NULL, `args` TEXT NOT NULL, `created` INTEGER NOT NULL, `state` TEXT, `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": "account", + "columnName": "account", + "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": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_operation_account", + "unique": false, + "columnNames": [ + "account" + ], + "createSql": "CREATE INDEX `index_operation_account` ON `${TABLE_NAME}` (`account`)" + }, + { + "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`)" + }, + { + "name": "index_operation_name", + "unique": false, + "columnNames": [ + "name" + ], + "createSql": "CREATE INDEX `index_operation_name` ON `${TABLE_NAME}` (`name`)" + }, + { + "name": "index_operation_state", + "unique": false, + "columnNames": [ + "state" + ], + "createSql": "CREATE INDEX `index_operation_state` ON `${TABLE_NAME}` (`state`)" + } + ], + "foreignKeys": [ + { + "table": "folder", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "folder" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "message", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "message" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "contact", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER NOT NULL, `type` INTEGER NOT NULL, `email` TEXT NOT NULL, `name` TEXT, `avatar` TEXT, `times_contacted` INTEGER NOT NULL, `first_contacted` INTEGER NOT NULL, `last_contacted` INTEGER NOT NULL, `state` INTEGER NOT NULL, 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": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatar", + "columnName": "avatar", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "times_contacted", + "columnName": "times_contacted", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "first_contacted", + "columnName": "first_contacted", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "last_contacted", + "columnName": "last_contacted", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_contact_account_type_email", + "unique": true, + "columnNames": [ + "account", + "type", + "email" + ], + "createSql": "CREATE UNIQUE INDEX `index_contact_account_type_email` ON `${TABLE_NAME}` (`account`, `type`, `email`)" + }, + { + "name": "index_contact_email", + "unique": false, + "columnNames": [ + "email" + ], + "createSql": "CREATE INDEX `index_contact_email` ON `${TABLE_NAME}` (`email`)" + }, + { + "name": "index_contact_name", + "unique": false, + "columnNames": [ + "name" + ], + "createSql": "CREATE INDEX `index_contact_name` ON `${TABLE_NAME}` (`name`)" + }, + { + "name": "index_contact_avatar", + "unique": false, + "columnNames": [ + "avatar" + ], + "createSql": "CREATE INDEX `index_contact_avatar` ON `${TABLE_NAME}` (`avatar`)" + }, + { + "name": "index_contact_times_contacted", + "unique": false, + "columnNames": [ + "times_contacted" + ], + "createSql": "CREATE INDEX `index_contact_times_contacted` ON `${TABLE_NAME}` (`times_contacted`)" + }, + { + "name": "index_contact_last_contacted", + "unique": false, + "columnNames": [ + "last_contacted" + ], + "createSql": "CREATE INDEX `index_contact_last_contacted` ON `${TABLE_NAME}` (`last_contacted`)" + }, + { + "name": "index_contact_state", + "unique": false, + "columnNames": [ + "state" + ], + "createSql": "CREATE INDEX `index_contact_state` ON `${TABLE_NAME}` (`state`)" + } + ], + "foreignKeys": [ + { + "table": "account", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "answer", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `hide` INTEGER NOT NULL, `text` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "hide", + "columnName": "hide", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "text", + "columnName": "text", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "rule", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `folder` INTEGER NOT NULL, `name` TEXT NOT NULL, `order` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `stop` INTEGER NOT NULL, `condition` TEXT NOT NULL, `action` TEXT NOT NULL, FOREIGN KEY(`folder`) REFERENCES `folder`(`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": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stop", + "columnName": "stop", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "condition", + "columnName": "condition", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "action", + "columnName": "action", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_rule_folder", + "unique": false, + "columnNames": [ + "folder" + ], + "createSql": "CREATE INDEX `index_rule_folder` ON `${TABLE_NAME}` (`folder`)" + }, + { + "name": "index_rule_order", + "unique": false, + "columnNames": [ + "order" + ], + "createSql": "CREATE INDEX `index_rule_order` ON `${TABLE_NAME}` (`order`)" + } + ], + "foreignKeys": [ + { + "table": "folder", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "folder" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "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": [] + } + ], + "views": [ + { + "viewName": "accountprop", + "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT id, name, color, synchronize, `primary`, notify, browse, swipe_left, swipe_right, created, `order` FROM account" + }, + { + "viewName": "folderprop", + "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT id, account, name, type, download, display, unified, notify FROM folder" + }, + { + "viewName": "attachmentprop", + "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT id, message, name FROM attachment" + }, + { + "viewName": "operationprop", + "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT id, folder, message, name FROM operation" + } + ], + "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, '54e4606798a2b98908f5ba9b31401294')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/faircode/email/DB.java b/app/src/main/java/eu/faircode/email/DB.java index aea2cedec8..7eca0246bf 100644 --- a/app/src/main/java/eu/faircode/email/DB.java +++ b/app/src/main/java/eu/faircode/email/DB.java @@ -54,7 +54,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory; // https://developer.android.com/topic/libraries/architecture/room.html @Database( - version = 86, + version = 87, entities = { EntityIdentity.class, EntityAccount.class, @@ -68,7 +68,10 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory; EntityLog.class }, views = { - EntityFolderView.class + EntityAccountProp.class, + EntityFolderProp.class, + EntityAttachmentProp.class, + EntityOperationProp.class } ) @@ -863,6 +866,21 @@ public abstract class DB extends RoomDatabase { db.execSQL("CREATE VIEW `folderview` AS SELECT id, account, name, type, display, unified FROM folder"); } }) + .addMigrations(new Migration(86, 87) { + @Override + public void migrate(SupportSQLiteDatabase db) { + Log.i("DB migration from version " + startVersion + " to " + endVersion); + db.execSQL("DROP VIEW `folderview`"); + db.execSQL("CREATE VIEW `accountprop` AS " + + "SELECT id, name, color, synchronize, `primary`, notify, browse, swipe_left, swipe_right, created, `order` FROM account"); + db.execSQL("CREATE VIEW `folderprop` AS " + + "SELECT id, account, name, type, download, display, unified, notify FROM folder"); + db.execSQL("CREATE VIEW `attachmentprop` AS " + + "SELECT id, message, name FROM attachment"); + db.execSQL("CREATE VIEW `operationprop` AS " + + "SELECT id, folder, message, name FROM operation"); + } + }) .build(); } diff --git a/app/src/main/java/eu/faircode/email/DaoAccount.java b/app/src/main/java/eu/faircode/email/DaoAccount.java index 963b2613d9..6064531924 100644 --- a/app/src/main/java/eu/faircode/email/DaoAccount.java +++ b/app/src/main/java/eu/faircode/email/DaoAccount.java @@ -46,7 +46,7 @@ public interface DaoAccount { @Query("SELECT account.*" + ", (SELECT COUNT(message.id)" + " FROM message" + - " JOIN folder ON folder.id = message.folder" + + " JOIN folderprop AS folder ON folder.id = message.folder" + " WHERE message.account = account.id" + " AND folder.type <> '" + EntityFolder.ARCHIVE + "'" + " AND folder.type <> '" + EntityFolder.TRASH + "'" + @@ -60,7 +60,7 @@ public interface DaoAccount { " AND identity.synchronize) AS identities" + ", CASE WHEN drafts.id IS NULL THEN 0 ELSE 1 END AS drafts" + " FROM account" + - " LEFT JOIN folder AS drafts ON drafts.account = account.id AND drafts.type = '" + EntityFolder.DRAFTS + "'" + + " LEFT JOIN folderprop AS drafts ON drafts.account = account.id AND drafts.type = '" + EntityFolder.DRAFTS + "'" + " WHERE :all OR account.synchronize" + " GROUP BY account.id" + " ORDER BY CASE WHEN :all THEN 0 ELSE account.`order` END" + @@ -84,16 +84,16 @@ public interface DaoAccount { " (SELECT COUNT(account.id) FROM account" + " WHERE synchronize" + " AND state = 'connected') AS accounts" + - ", (SELECT COUNT(operation.id) FROM operation" + - " JOIN folder ON folder.id = operation.folder" + - " JOIN account ON account.id = folder.account" + // not outbox + ", (SELECT COUNT(operation.id) FROM operationprop AS operation" + + " JOIN folderprop AS folder ON folder.id = operation.folder" + + " JOIN accountprop AS account ON account.id = folder.account" + // not outbox " WHERE account.synchronize) AS operations") LiveData liveStats(); @Query("SELECT account.id, l.id AS swipe_left, l.type AS left_type, r.id AS swipe_right, r.type AS right_type" + - " FROM account" + - " LEFT JOIN folder l ON l.id = account.swipe_left" + - " LEFT JOIN folder r ON r.id = account.swipe_right") + " FROM accountprop AS account" + + " LEFT JOIN folderprop AS l ON l.id = account.swipe_left" + + " LEFT JOIN folderprop r ON r.id = account.swipe_right") LiveData> liveAccountSwipes(); @Insert diff --git a/app/src/main/java/eu/faircode/email/DaoContact.java b/app/src/main/java/eu/faircode/email/DaoContact.java index 9673700d48..a57547221a 100644 --- a/app/src/main/java/eu/faircode/email/DaoContact.java +++ b/app/src/main/java/eu/faircode/email/DaoContact.java @@ -37,7 +37,7 @@ public interface DaoContact { @Query("SELECT contact.*, account.name AS accountName" + " FROM contact" + - " JOIN account ON account.id = contact.account" + + " JOIN accountprop AS account ON account.id = contact.account" + " ORDER BY times_contacted DESC, last_contacted DESC") LiveData> liveContacts(); diff --git a/app/src/main/java/eu/faircode/email/DaoFolder.java b/app/src/main/java/eu/faircode/email/DaoFolder.java index 07aeac5042..9ef8f3e501 100644 --- a/app/src/main/java/eu/faircode/email/DaoFolder.java +++ b/app/src/main/java/eu/faircode/email/DaoFolder.java @@ -45,13 +45,13 @@ public interface DaoFolder { List getFoldersEx(long account); @Query("SELECT folder.* FROM folder" + - " JOIN account ON account.id = folder.account" + + " JOIN accountprop AS account ON account.id = folder.account" + " WHERE account.synchronize" + " AND folder.synchronize AND unified") List getFoldersSynchronizingUnified(); @Query("SELECT folder.* FROM folder" + - " JOIN account ON account.id = folder.account" + + " JOIN accountprop AS account ON account.id = folder.account" + " WHERE folder.id = :folder" + " AND (:search OR (account.synchronize AND account.browse))") EntityFolder getBrowsableFolder(long folder, boolean search); @@ -59,7 +59,7 @@ public interface DaoFolder { @Query("SELECT folder.*" + ", account.`order` AS accountOrder, account.name AS accountName" + " FROM folder" + - " JOIN account ON account.id = folder.account" + + " JOIN accountprop AS account ON account.id = folder.account" + " WHERE account.`synchronize`") List getSortedFolders(); @@ -99,7 +99,7 @@ public interface DaoFolder { ", (SELECT COUNT(operation.id) FROM operation WHERE operation.folder = folder.id) AS operations" + ", (SELECT COUNT(operation.id) FROM operation WHERE operation.folder = folder.id AND operation.state = 'executing') AS executing" + " FROM folder" + - " LEFT JOIN account ON account.id = folder.account" + + " LEFT JOIN accountprop AS account ON account.id = folder.account" + " LEFT JOIN message ON message.folder = folder.id AND NOT message.ui_hide" + " WHERE account.id IS NULL" + " OR (account.`synchronize` AND folder.navigation)" + @@ -107,7 +107,7 @@ public interface DaoFolder { LiveData> liveNavigation(); @Query("SELECT folder.* FROM folder" + - " JOIN account ON account.id = folder.account" + + " JOIN accountprop AS account ON account.id = folder.account" + " WHERE account.synchronize" + " AND account.`primary`" + " AND folder.type = '" + EntityFolder.DRAFTS + "'") @@ -149,19 +149,19 @@ public interface DaoFolder { EntityFolder getFolderByType(long account, String type); @Query("SELECT folder.* FROM folder" + - " JOIN account ON account.id = folder.account" + + " JOIN accountprop AS account ON account.id = folder.account" + " WHERE `primary` AND type = '" + EntityFolder.DRAFTS + "'") EntityFolder getPrimaryDrafts(); @Query("SELECT folder.* FROM folder" + - " JOIN account ON account.id = folder.account" + + " JOIN accountprop AS account ON account.id = folder.account" + " WHERE `primary` AND type = '" + EntityFolder.ARCHIVE + "'") EntityFolder getPrimaryArchive(); @Query("SELECT * FROM folder WHERE type = '" + EntityFolder.OUTBOX + "'") EntityFolder getOutbox(); - @Query("SELECT download FROM folder WHERE id = :id") + @Query("SELECT download FROM folderprop WHERE id = :id") boolean getFolderDownload(long id); @Insert diff --git a/app/src/main/java/eu/faircode/email/DaoIdentity.java b/app/src/main/java/eu/faircode/email/DaoIdentity.java index 66510ebf19..12748a8ad9 100644 --- a/app/src/main/java/eu/faircode/email/DaoIdentity.java +++ b/app/src/main/java/eu/faircode/email/DaoIdentity.java @@ -30,13 +30,13 @@ import java.util.List; @Dao public interface DaoIdentity { @Query("SELECT identity.*, account.name AS accountName FROM identity" + - " JOIN account ON account.id = identity.account" + + " JOIN accountprop AS account ON account.id = identity.account" + " WHERE NOT :synchronize OR account.synchronize") LiveData> liveIdentities(boolean synchronize); @Query("SELECT identity.*, account.name AS accountName FROM identity" + - " JOIN account ON account.id = identity.account" + - " JOIN folder ON folder.account = identity.account AND folder.type = '" + EntityFolder.DRAFTS + "'" + + " JOIN accountprop AS account ON account.id = identity.account" + + " JOIN folderprop AS folder ON folder.account = identity.account AND folder.type = '" + EntityFolder.DRAFTS + "'" + " WHERE (:account IS NULL OR identity.account = :account)" + " AND identity.synchronize" + " AND account.synchronize" + @@ -45,8 +45,8 @@ public interface DaoIdentity { List getComposableIdentities(Long account); @Query("SELECT identity.*, account.name AS accountName FROM identity" + - " JOIN account ON account.id = identity.account" + - " JOIN folder ON folder.account = identity.account AND folder.type = '" + EntityFolder.DRAFTS + "'" + + " JOIN accountprop AS account ON account.id = identity.account" + + " JOIN folderprop AS folder ON folder.account = identity.account AND folder.type = '" + EntityFolder.DRAFTS + "'" + " WHERE (:account IS NULL OR identity.account = :account)" + " AND identity.synchronize" + " AND account.synchronize") diff --git a/app/src/main/java/eu/faircode/email/DaoMessage.java b/app/src/main/java/eu/faircode/email/DaoMessage.java index c33965770c..2ea4c23cb1 100644 --- a/app/src/main/java/eu/faircode/email/DaoMessage.java +++ b/app/src/main/java/eu/faircode/email/DaoMessage.java @@ -48,15 +48,15 @@ public interface DaoMessage { ", COUNT(message.id) AS count" + ", " + unseen_unified + " AS unseen" + ", " + unflagged_unified + " AS unflagged" + - ", (SELECT COUNT(a.id) FROM attachment a WHERE a.message = message.id) AS attachments" + + ", (SELECT COUNT(a.id) FROM attachmentprop a WHERE a.message = message.id) AS attachments" + ", SUM(CASE WHEN folder.type = '" + EntityFolder.DRAFTS + "' THEN 1 ELSE 0 END) AS drafts" + ", COUNT(DISTINCT CASE WHEN message.msgid IS NULL THEN message.id ELSE message.msgid END) AS visible" + ", SUM(message.size) AS totalSize" + ", MAX(CASE WHEN :found OR folder.unified THEN message.received ELSE 0 END) AS dummy" + " FROM message" + - " JOIN account ON account.id = message.account" + + " JOIN accountprop AS account ON account.id = message.account" + " LEFT JOIN identity ON identity.id = message.identity" + - " JOIN folderview AS folder ON folder.id = message.folder" + + " JOIN folderprop AS folder ON folder.id = message.folder" + " WHERE account.`synchronize`" + " AND (NOT message.ui_hide OR :debug)" + " AND (NOT :found OR ui_found = :found)" + @@ -94,16 +94,16 @@ public interface DaoMessage { ", COUNT(message.id) AS count" + ", " + unseen_folder + " AS unseen" + ", " + unflagged_folder + " AS unflagged" + - ", (SELECT COUNT(a.id) FROM attachment a WHERE a.message = message.id) AS attachments" + + ", (SELECT COUNT(a.id) FROM attachmentprop a WHERE a.message = message.id) AS attachments" + ", SUM(CASE WHEN folder.type = '" + EntityFolder.DRAFTS + "' THEN 1 ELSE 0 END) AS drafts" + ", COUNT(DISTINCT CASE WHEN message.msgid IS NULL THEN message.id ELSE message.msgid END) AS visible" + ", SUM(message.size) AS totalSize" + ", MAX(CASE WHEN folder.id = :folder THEN message.received ELSE 0 END) AS dummy" + " FROM message" + - " JOIN account ON account.id = message.account" + + " JOIN accountprop AS account ON account.id = message.account" + " LEFT JOIN identity ON identity.id = message.identity" + - " JOIN folderview AS folder ON folder.id = message.folder" + - " JOIN folderview AS f ON f.id = :folder" + + " JOIN folderprop AS folder ON folder.id = message.folder" + + " JOIN folderprop AS f ON f.id = :folder" + " WHERE (message.account = f.account OR " + is_outbox + ")" + " AND (NOT message.ui_hide OR :debug)" + " AND (NOT :found OR ui_found = :found)" + @@ -137,14 +137,14 @@ public interface DaoMessage { ", 1 AS count" + ", CASE WHEN message.ui_seen THEN 0 ELSE 1 END AS unseen" + ", CASE WHEN message.ui_flagged THEN 0 ELSE 1 END AS unflagged" + - ", (SELECT COUNT(a.id) FROM attachment a WHERE a.message = message.id) AS attachments" + + ", (SELECT COUNT(a.id) FROM attachmentprop a WHERE a.message = message.id) AS attachments" + ", CASE WHEN folder.type = '" + EntityFolder.DRAFTS + "' THEN 1 ELSE 0 END AS drafts" + ", 1 AS visible" + ", message.size AS totalSize" + " FROM message" + - " JOIN account ON account.id = message.account" + + " JOIN accountprop AS account ON account.id = message.account" + " LEFT JOIN identity ON identity.id = message.identity" + - " JOIN folderview AS folder ON folder.id = message.folder" + + " JOIN folderprop AS folder ON folder.id = message.folder" + " WHERE message.account = :account" + " AND message.thread = :thread" + " AND (:id IS NULL OR message.id = :id)" + @@ -157,7 +157,7 @@ public interface DaoMessage { ", COUNT(message.id) AS count" + ", SUM(message.ui_seen) AS seen" + " FROM message" + - " JOIN account ON account.id = message.account" + + " JOIN accountprop AS account ON account.id = message.account" + " WHERE message.account = :account" + " AND message.thread = :thread" + " AND (:id IS NULL OR message.id = :id)" + @@ -165,7 +165,7 @@ public interface DaoMessage { " GROUP BY account.id") LiveData liveThreadStats(long account, String thread, Long id); - @Query("SELECT message.id FROM folder" + + @Query("SELECT message.id FROM folderprop AS folder" + " JOIN message ON message.folder = folder.id" + " WHERE CASE WHEN :folder IS NULL THEN folder.unified ELSE folder.id = :folder END" + " AND ui_hide") @@ -208,7 +208,7 @@ public interface DaoMessage { List getMessageIdsByFolder(Long folder); @Query("SELECT message.id" + - " FROM folder" + + " FROM folderprop AS folder" + " JOIN message ON message.folder = folder.id" + " WHERE CASE WHEN :folder IS NULL THEN folder.unified ELSE folder.id = :folder END" + " AND NOT ui_hide" + @@ -243,14 +243,14 @@ public interface DaoMessage { ", 1 AS count" + ", CASE WHEN message.ui_seen THEN 0 ELSE 1 END AS unseen" + ", CASE WHEN message.ui_flagged THEN 0 ELSE 1 END AS unflagged" + - ", (SELECT COUNT(a.id) FROM attachment a WHERE a.message = message.id) AS attachments" + + ", (SELECT COUNT(a.id) FROM attachmentprop a WHERE a.message = message.id) AS attachments" + ", CASE WHEN folder.type = '" + EntityFolder.DRAFTS + "' THEN 1 ELSE 0 END AS drafts" + ", 1 AS visible" + ", message.size AS totalSize" + " FROM message" + - " JOIN account ON account.id = message.account" + + " JOIN accountprop AS account ON account.id = message.account" + " LEFT JOIN identity ON identity.id = message.identity" + - " JOIN folder ON folder.id = message.folder" + + " JOIN folderprop AS folder ON folder.id = message.folder" + " WHERE message.id = :id") LiveData liveMessage(long id); @@ -266,9 +266,9 @@ public interface DaoMessage { ", 1 AS visible" + ", message.size AS totalSize" + " FROM message" + - " JOIN account ON account.id = message.account" + + " JOIN accountprop AS account ON account.id = message.account" + " LEFT JOIN identity ON identity.id = message.identity" + - " JOIN folder ON folder.id = message.folder" + + " JOIN folderprop AS folder ON folder.id = message.folder" + " WHERE account.`synchronize`" + " AND folder.notify" + " AND (account.created IS NULL OR message.received > account.created)" + @@ -279,8 +279,8 @@ public interface DaoMessage { LiveData> liveUnseenNotify(); @Query("SELECT COUNT(message.id) FROM message" + - " JOIN account ON account.id = message.account" + - " JOIN folder ON folder.id = message.folder" + + " JOIN accountprop AS account ON account.id = message.account" + + " JOIN folderprop AS folder ON folder.id = message.folder" + " WHERE account.`synchronize`" + " AND folder.unified" + " AND (account.created IS NULL OR message.received > account.created)" + @@ -298,7 +298,7 @@ public interface DaoMessage { List getUids(long folder, Long received); @Query("SELECT message.* FROM message" + - " JOIN folder on folder.id = message.folder" + + " JOIN folderprop AS folder on folder.id = message.folder" + " WHERE message.account = :account" + " AND folder.type = '" + EntityFolder.OUTBOX + "'" + " AND sent IS NOT NULL") @@ -398,7 +398,7 @@ public interface DaoMessage { @Query("UPDATE message SET ui_ignored = 1" + " WHERE NOT ui_ignored" + - " AND folder IN (SELECT id FROM folder WHERE type = '" + EntityFolder.INBOX + "')") + " AND folder IN (SELECT id FROM folderprop WHERE type = '" + EntityFolder.INBOX + "')") int ignoreAll(); @Query("UPDATE message SET ui_found = 1" + @@ -436,7 +436,7 @@ public interface DaoMessage { " WHERE folder = :folder" + " AND uid IS NULL" + " AND NOT EXISTS" + - " (SELECT * FROM operation" + + " (SELECT * FROM operationprop AS operation" + " WHERE operation.message = message.id" + " AND operation.name = '" + EntityOperation.ADD + "')") int deleteOrphans(long folder); diff --git a/app/src/main/java/eu/faircode/email/DaoOperation.java b/app/src/main/java/eu/faircode/email/DaoOperation.java index a20012791b..883babe697 100644 --- a/app/src/main/java/eu/faircode/email/DaoOperation.java +++ b/app/src/main/java/eu/faircode/email/DaoOperation.java @@ -32,9 +32,9 @@ public interface DaoOperation { " ,((account.synchronize IS NULL OR account.synchronize)" + " AND (NOT folder.account IS NULL OR identity.synchronize IS NULL OR identity.synchronize)) AS synchronize" + " FROM operation" + - " JOIN folder ON folder.id = operation.folder" + + " JOIN folderprop AS folder ON folder.id = operation.folder" + " LEFT JOIN message ON message.id = operation.message" + - " LEFT JOIN account ON account.id = message.account OR account.id = folder.account" + + " LEFT JOIN accountprop AS account ON account.id = message.account OR account.id = folder.account" + " LEFT JOIN identity ON identity.id = message.identity" + " ORDER BY" + " CASE WHEN operation.name = '" + EntityOperation.SYNC + "' THEN" + @@ -45,9 +45,9 @@ public interface DaoOperation { LiveData> liveOperations(); String GET_OPS_FOLDER = "SELECT operation.* FROM operation" + - " JOIN folder ON folder.id = operation.folder" + + " JOIN folderprop AS folder ON folder.id = operation.folder" + " LEFT JOIN message ON message.id = operation.message" + - " LEFT JOIN account ON account.id = message.account" + + " LEFT JOIN accountprop AS account ON account.id = message.account" + " LEFT JOIN identity ON identity.id = message.identity" + " WHERE operation.folder = :folder" + " AND (account.synchronize IS NULL OR account.synchronize)" + @@ -70,7 +70,7 @@ public interface DaoOperation { " FROM operation") LiveData liveStats(); - @Query("SELECT COUNT(operation.id) FROM operation" + + @Query("SELECT COUNT(operation.id) FROM operationprop AS operation" + " WHERE operation.name = '" + EntityOperation.SEND + "'") LiveData liveUnsent(); @@ -83,12 +83,12 @@ public interface DaoOperation { @Query("SELECT * FROM operation WHERE error IS NOT NULL") List getOperationsError(); - @Query("SELECT COUNT(id) FROM operation" + + @Query("SELECT COUNT(id) FROM operationprop AS operation" + " WHERE folder = :folder" + " AND (:name IS NULL OR operation.name = :name)") int getOperationCount(long folder, String name); - @Query("SELECT COUNT(id) FROM operation" + + @Query("SELECT COUNT(id) FROM operationprop" + " WHERE folder = :folder" + " AND message = :message") int getOperationCount(long folder, long message); diff --git a/app/src/main/java/eu/faircode/email/DaoRule.java b/app/src/main/java/eu/faircode/email/DaoRule.java index 6562824ff7..512a14f4b5 100644 --- a/app/src/main/java/eu/faircode/email/DaoRule.java +++ b/app/src/main/java/eu/faircode/email/DaoRule.java @@ -41,14 +41,14 @@ public interface DaoRule { List getEnabledRules(long folder); @Query("SELECT rule.*, folder.account, folder.name AS folderName, account.name AS accountName FROM rule" + - " JOIN folder ON folder.id = rule.folder" + - " JOIN account ON account.id = folder.account" + + " JOIN folderprop AS folder ON folder.id = rule.folder" + + " JOIN accountprop AS account ON account.id = folder.account" + " WHERE rule.id = :id") TupleRuleEx getRule(long id); @Query("SELECT rule.*, folder.account, folder.name AS folderName, account.name AS accountName FROM rule" + - " JOIN folder ON folder.id = rule.folder" + - " JOIN account ON account.id = folder.account" + + " JOIN folderprop AS folder ON folder.id = rule.folder" + + " JOIN accountprop AS account ON account.id = folder.account" + " WHERE rule.folder = :folder" + " ORDER BY `order`, name COLLATE NOCASE") LiveData> liveRules(long folder); diff --git a/app/src/main/java/eu/faircode/email/EntityAccountProp.java b/app/src/main/java/eu/faircode/email/EntityAccountProp.java new file mode 100644 index 0000000000..491ba451af --- /dev/null +++ b/app/src/main/java/eu/faircode/email/EntityAccountProp.java @@ -0,0 +1,44 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import androidx.annotation.NonNull; +import androidx.room.DatabaseView; + +@DatabaseView( + viewName = "accountprop", + value = "SELECT id, name, color, synchronize, `primary`, notify, browse, swipe_left, swipe_right, created, `order` FROM account") +public class EntityAccountProp { + public Long id; + public String name; + public Integer color; + @NonNull + public Boolean synchronize; + @NonNull + public Boolean primary; + @NonNull + public Boolean notify; + @NonNull + public Boolean browse = true; + public Long swipe_left; + public Long swipe_right; + public Long created; + public Integer order; +} diff --git a/app/src/main/java/eu/faircode/email/EntityAttachmentProp.java b/app/src/main/java/eu/faircode/email/EntityAttachmentProp.java new file mode 100644 index 0000000000..6aac4e3fea --- /dev/null +++ b/app/src/main/java/eu/faircode/email/EntityAttachmentProp.java @@ -0,0 +1,33 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import androidx.annotation.NonNull; +import androidx.room.DatabaseView; + +@DatabaseView( + viewName = "attachmentprop", + value = "SELECT id, message, name FROM attachment") +public class EntityAttachmentProp { + public Long id; + @NonNull + public Long message; + public String name; +} diff --git a/app/src/main/java/eu/faircode/email/EntityFolderView.java b/app/src/main/java/eu/faircode/email/EntityFolderProp.java similarity index 80% rename from app/src/main/java/eu/faircode/email/EntityFolderView.java rename to app/src/main/java/eu/faircode/email/EntityFolderProp.java index 6d27126039..ed3812f919 100644 --- a/app/src/main/java/eu/faircode/email/EntityFolderView.java +++ b/app/src/main/java/eu/faircode/email/EntityFolderProp.java @@ -22,18 +22,21 @@ package eu.faircode.email; import androidx.annotation.NonNull; import androidx.room.DatabaseView; - @DatabaseView( - viewName = "folderview", - value = "SELECT id, account, name, type, display, unified FROM folder") -public class EntityFolderView { + viewName = "folderprop", + value = "SELECT id, account, name, type, download, display, unified, notify FROM folder") +public class EntityFolderProp { public Long id; public Long account; @NonNull public String name; @NonNull public String type; + @NonNull + public Boolean download = true; public String display; @NonNull public Boolean unified = false; + @NonNull + public Boolean notify = false; } diff --git a/app/src/main/java/eu/faircode/email/EntityOperationProp.java b/app/src/main/java/eu/faircode/email/EntityOperationProp.java new file mode 100644 index 0000000000..76dcf5e523 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/EntityOperationProp.java @@ -0,0 +1,35 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import androidx.annotation.NonNull; +import androidx.room.DatabaseView; + +@DatabaseView( + viewName = "operationprop", + value = "SELECT id, folder, message, name FROM operation") +public class EntityOperationProp { + public Long id; + @NonNull + public Long folder; + public Long message; + @NonNull + public String name; +}