diff --git a/SyncerWeb.js b/SyncerWeb.js index c7793f3..0323149 100644 --- a/SyncerWeb.js +++ b/SyncerWeb.js @@ -101,21 +101,30 @@ function ymd(dt) SyncerWeb.prototype.msgSearchCond = function(query) { - var p; + var p = []; if (query.folderId) - p = this.pg.sql.eq('m.folder_id', query.folderId); + p.push(this.pg.sql.eq('m.folder_id', query.folderId)); else if (query.folderType == 'unread') - p = this.pg.sql('(flags @> array[\'unread\']::varchar(255)[])'); + p.push(this.pg.sql('(flags @> array[\'unread\']::varchar(255)[])')); else if (query.folderType == 'pinned') - p = this.pg.sql('(flags @> array[\'flagged\']::varchar(255)[])'); + p.push(this.pg.sql('(flags @> array[\'flagged\']::varchar(255)[])')); else if (query.folderType == 'inbox') - p = this.pg.sql('(flags @> array[\'in\']::varchar(255)[])'); + { + var folders = []; + for (var id in this.syncer.accounts) + { + n = this.syncer.accounts[id].settings.folders.spam; + if (n) + folders.push(this.pg.sql.and({ 'f.name': n, 'f.account_id': id })); + } + p.push(this.pg.sql.not(this.pg.sql.or.apply(this.pg.sql, folders))); + p.push(this.pg.sql('(flags @> array[\'in\']::varchar(255)[])')); + } else if (query.folderType == 'out') - p = this.pg.sql('(flags @> array[\'out\']::varchar(255)[])'); + p.push(this.pg.sql('(flags @> array[\'out\']::varchar(255)[])')); else if (query.folderType == 'outbox') { // TODO это какая-то хитрая метапапка, которая не живёт на IMAP'е? - p = null; } else if (query.folderType == 'drafts' || query.folderType == 'spam' || query.folderType == 'trash') { @@ -127,11 +136,13 @@ SyncerWeb.prototype.msgSearchCond = function(query) if (n) folders.push(this.pg.sql.and({ 'f.name': n, 'f.account_id': id })); } - p = this.pg.sql.or.apply(this.pg.sql.or, folders); + p.push(this.pg.sql.or.apply(this.pg.sql, folders)); } - if (p && query.accountId) - p = this.pg.sql.and(p, this.pg.sql.eq('f.account_id', query.accountId)); - return p; + if (typeof query.search == 'string' && query.search.trim()) + p.push(this.pg.sql('messages_fulltext(m) @@ plainto_tsquery($1)', query.search.trim())); + if (query.accountId) + p.push(this.pg.sql.and(p, this.pg.sql.eq('f.account_id', query.accountId))); + return p.length ? this.pg.sql.and.apply(this.pg.sql, p) : null; } SyncerWeb.prototype.get_groups = function*(req, res) @@ -159,29 +170,27 @@ SyncerWeb.prototype.get_groups = function*(req, res) { intervals.push({ date: ymd(new Date(i)), name: 'd'+d }); } + for (var i = today.getFullYear()-1; i >= 1970; i--) + { + intervals.unshift({ date: i+'-01-01', name: ''+i }); + } intervals.push({ date: ymd(today), name: 't' }); for (var i = 0; i < intervals.length-1; i++) { intervals[i].date_end = intervals[i+1].date; } - intervals[i].date_end = '100000-12-31'; // it's faster than (is null or <) + intervals[intervals.length-1].date_end = '100000-12-31'; // it's faster than (is null or <) var [ groups ] = yield this.pg - .select('d.name, d.date, count(*) count') - .from('messages m') - .innerJoin('folders f', this.pg.sql('f.id=m.folder_id')) - .innerJoin(this.pg.sql.values(intervals).as('d').columns(), - this.pg.sql('m.time >= d.date::date and m.time < d.date_end::date')) - .where(cond) - .groupBy('1, 2') - .union( - this.pg.select('y::text as name, y||\'-01-01\' date, ('+ - this.pg.select('count(*)').from('messages m') - .innerJoin('folders f', this.pg.sql('f.id=m.folder_id')) - .where(cond).where(this.pg.sql('m.time >= (t.y||\'-01-01\')::date and m.time <= (t.y||\'-12-31\')::date')) - +') count') - .from('generate_series(1970, '+(today.getFullYear()-1)+') as t (y)') - ) + .select('d.name, d.date, ('+ + this.pg.select('count(*)') + .from('messages m') + .innerJoin('folders f', this.pg.sql('f.id=m.folder_id')) + .where(cond) + .where(this.pg.sql('m.time >= d.date::date and m.time < d.date_end::date')) + +') count') + .from(this.pg.sql.values(intervals).as('d').columns()) .orderBy('date desc').rows(gen.ef()); + groups = groups.filter(g => g.count > 0); return res.send({ groups: groups }); }