Speedup group list even more, implement basic text search

master
Vitaliy Filippov 2016-10-09 18:52:28 +03:00
parent 4ec979569b
commit 6abd931751
1 changed files with 36 additions and 27 deletions

View File

@ -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 });
}