From 2e8f302a48aa6755c0cc9bf774051a6fccaaa16d Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 18 Dec 2018 10:55:26 -0800 Subject: [PATCH] Fix support for the `has: attachment` search query #1260 --- .../thread-search/lib/search-bar-util.es6 | 6 ++++++ app/spec/models/thread-spec.es6 | 2 +- app/src/flux/models/thread.es6 | 2 ++ app/src/flux/models/utils.es6 | 3 +++ app/src/services/search/search-query-backend-local.es6 | 7 ++++++- app/src/services/search/search-query-parser.es6 | 3 ++- mailsync | 2 +- 7 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/internal_packages/thread-search/lib/search-bar-util.es6 b/app/internal_packages/thread-search/lib/search-bar-util.es6 index c4f43aabc..8415afc17 100644 --- a/app/internal_packages/thread-search/lib/search-bar-util.es6 +++ b/app/internal_packages/thread-search/lib/search-bar-util.es6 @@ -105,6 +105,12 @@ export const TokenSuggestions = [ description: 'unread, starred', termSuggestions: ['unread', 'starred'], }, + { + token: 'has', + term: '', + description: 'attachment', + termSuggestions: ['attachment'], + }, { token: 'subject', term: '', diff --git a/app/spec/models/thread-spec.es6 b/app/spec/models/thread-spec.es6 index a8fa2e965..5d436d2bb 100644 --- a/app/spec/models/thread-spec.es6 +++ b/app/spec/models/thread-spec.es6 @@ -7,7 +7,7 @@ describe('Thread', function() { xit('1,000,000 iterations', function() { let iterations = 0; const json = - '[{"client_id":"local-76c370af-65de","server_id":"f0vkowp7zxt7djue7ifylb940","__cls":"Thread","account_id":"1r6w6qiq3sb0o9fiwin6v87dd","snippet":"http://itunestandc.tumblr.com/tagged/itunes-terms-and-conditions/chrono _______________________________________________ http://www.macgroup.com/mailman/listinfo/smartfriends-chat","subject":"iTunes Terms And Conditions as you\'ve never seen them before","unread":true,"starred":false,"version":1,"folders":[],"labels":[{"server_id":"8cf4fn20k9pjjhjawrv3xrxo0","name":"all","display_name":"All Mail","id":"8cf4fn20k9pjjhjawrv3xrxo0"},{"server_id":"f1lq8faw8vv06m67y8f3xdf84","name":"inbox","display_name":"Inbox","id":"f1lq8faw8vv06m67y8f3xdf84"}],"participants":[{"name":"Andrew Stadler","email":"stadler@gmail.com","thirdPartyData":{}},{"name":"Smart Friends™ Chat","email":"smartfriends-chat@macgroup.com","thirdPartyData":{}}],"has_attachments":false,"lastMessageReceivedTimestamp":1446600615,"id":"f0vkowp7zxt7djue7ifylb940"}]'; + '[{"client_id":"local-76c370af-65de","server_id":"f0vkowp7zxt7djue7ifylb940","__cls":"Thread","account_id":"1r6w6qiq3sb0o9fiwin6v87dd","snippet":"http://itunestandc.tumblr.com/tagged/itunes-terms-and-conditions/chrono _______________________________________________ http://www.macgroup.com/mailman/listinfo/smartfriends-chat","subject":"iTunes Terms And Conditions as you\'ve never seen them before","unread":true,"starred":false,"version":1,"folders":[],"labels":[{"server_id":"8cf4fn20k9pjjhjawrv3xrxo0","name":"all","display_name":"All Mail","id":"8cf4fn20k9pjjhjawrv3xrxo0"},{"server_id":"f1lq8faw8vv06m67y8f3xdf84","name":"inbox","display_name":"Inbox","id":"f1lq8faw8vv06m67y8f3xdf84"}],"participants":[{"name":"Andrew Stadler","email":"stadler@gmail.com","thirdPartyData":{}},{"name":"Smart Friends™ Chat","email":"smartfriends-chat@macgroup.com","thirdPartyData":{}}],"attachmentCount":0,"lastMessageReceivedTimestamp":1446600615,"id":"f0vkowp7zxt7djue7ifylb940"}]'; const start = Date.now(); while (iterations < 1000000) { var data; diff --git a/app/src/flux/models/thread.es6 b/app/src/flux/models/thread.es6 index 5e9766edb..99f78a698 100644 --- a/app/src/flux/models/thread.es6 +++ b/app/src/flux/models/thread.es6 @@ -98,6 +98,8 @@ export default class Thread extends ModelWithMetadata { itemClass: Contact, }), + // Note: Attachment count only includes non-inline files and inline files > 12kb. + // (Attachments that would trigger the display of the attachment icon.) attachmentCount: Attributes.Number({ modelKey: 'attachmentCount', }), diff --git a/app/src/flux/models/utils.es6 b/app/src/flux/models/utils.es6 index 3c627b3ea..fcc2deb0d 100644 --- a/app/src/flux/models/utils.es6 +++ b/app/src/flux/models/utils.es6 @@ -35,6 +35,9 @@ module.exports = Utils = { if (!(files instanceof Array)) { return false; } + // TODO BG: This code has been duplicated into the mailsync core. The + // Thread.attachmentCount property is now the number of attachments that + // meet these two criteria so this function can be removed soon. return files.find(f => !f.contentId || f.size > 12 * 1024); }, diff --git a/app/src/services/search/search-query-backend-local.es6 b/app/src/services/search/search-query-backend-local.es6 index c8b5ca125..41ea7c27a 100644 --- a/app/src/services/search/search-query-backend-local.es6 +++ b/app/src/services/search/search-query-backend-local.es6 @@ -223,7 +223,12 @@ class StructuredSearchQueryVisitor extends SearchQueryExpressionVisitor { } visitHasAttachment(/* node */) { - this._result = `(\`${this._className}\`.\`data\` LIKE '%"has_attachments":true%')`; + /* + TODO BG: On Dec. 18th 2018 I fixed the sync engine to populate the `hasAttachment` column + with a valid attachment count. After DB CURRENT_VERSION > 4, we should switch to using + that field rather than this slow LIKE clause. + */ + this._result = `(\`${this._className}\`.\`data\` NOT LIKE '%"attachmentCount":0%')`; } visitDate(node) { diff --git a/app/src/services/search/search-query-parser.es6 b/app/src/services/search/search-query-parser.es6 index 132dc34d1..508d50bcc 100644 --- a/app/src/services/search/search-query-parser.es6 +++ b/app/src/services/search/search-query-parser.es6 @@ -223,7 +223,8 @@ const parseHasQuery = text => { } const tokText = tok.s.toUpperCase(); switch (tokText) { - case 'ATTACHMENT': { + case 'ATTACHMENT': + case 'ATTACHMENTS': { return [new HasAttachmentQueryExpression(), afterTok]; } default: diff --git a/mailsync b/mailsync index ce250cd2f..59a41e8b0 160000 --- a/mailsync +++ b/mailsync @@ -1 +1 @@ -Subproject commit ce250cd2fcfc1fd030bf1d1b1ea8ec1f478a7a0b +Subproject commit 59a41e8b00e7d99aa101b4734917b64c53b910c8