From 37bcd22719d5f5d2b1eeb4cd3d7db376be3d8909 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Thu, 16 May 2019 21:29:58 +0300 Subject: [PATCH] Remove varchar's --- Syncer.js | 4 ++-- SyncerWeb.js | 18 ++++++++++-------- database-patches/2019-05-16-text.sql | 8 ++++++++ db.sql => database/db.sql | 16 ++++++++-------- operetta.js | 9 +++------ 5 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 database-patches/2019-05-16-text.sql rename db.sql => database/db.sql (91%) diff --git a/Syncer.js b/Syncer.js index 6569ee3..d8ff341 100644 --- a/Syncer.js +++ b/Syncer.js @@ -283,7 +283,7 @@ class Syncer { let updated = await SQL.update( this.pg, { m: 'messages', t: SQL.values(updateFlags) }, - [ 'flags = t.flags::varchar(255)[]' ], + [ 'flags = t.flags::text[]' ], { 'm.folder_id': boxId, 'm.uid = t.uid::int': [] }, checkMissing ? { returning: 'm.uid' } : null ); @@ -502,7 +502,7 @@ class Syncer { threadId = await SQL.select( this.pg, 'messages', 'MAX(thread_id)', - { 'refs @> array[?]::varchar(1000)[]': msgrow.messageid }, null, SQL.MS_VALUE + { 'refs @> array[?]': msgrow.messageid }, null, SQL.MS_VALUE ); if (threadId) { diff --git a/SyncerWeb.js b/SyncerWeb.js index dcdaf2c..689610c 100644 --- a/SyncerWeb.js +++ b/SyncerWeb.js @@ -75,13 +75,13 @@ class SyncerWeb 'select id, name, email, settings->\'folders\' folderMap,'+ ' (select count(*) from messages m, folders f'+ ' where m.folder_id=f.id and f.account_id=a.id'+ - ' and (flags @> array[\'pinned\',\'unread\']::varchar(255)[])) pinned_unread_count'+ + ' and (flags @> array[\'pinned\',\'unread\'])) pinned_unread_count'+ ' from accounts a' )).rows; const folders = (await this.pg.query( 'select id, account_id, name,'+ ' (select count(*) from messages m where m.folder_id=f.id) total_count,'+ - ' (select count(*) from messages m where m.folder_id=f.id and (flags @> array[\'unread\']::varchar(255)[])) unread_count'+ + ' (select count(*) from messages m where m.folder_id=f.id and (flags @> array[\'unread\'])) unread_count'+ ' from folders f order by account_id, name' )).rows; let fh = {}; @@ -106,11 +106,11 @@ class SyncerWeb } else if (query.folderType == 'unread') { - p['(flags @> array[\'unread\']::varchar(255)[])'] = []; + p['(flags @> array[\'unread\'])'] = []; } else if (query.folderType == 'pinned') { - p['(flags @> array[\'flagged\']::varchar(255)[])'] = []; + p['(flags @> array[\'flagged\'])'] = []; } else if (query.folderType == 'inbox') { @@ -119,15 +119,16 @@ class SyncerWeb .filter(f => f[1]); p['(f.account_id, f.name) NOT IN ('+folders.map(f => '(?, ?)').join(', ')+')'] = [].concat.apply([], folders); - p['(flags @> array[\'in\']::varchar(255)[])'] = []; + p['(flags @> array[\'in\'])'] = []; } - else if (query.folderType == 'out') + else if (query.folderType == 'sent') { - p['(flags @> array[\'out\']::varchar(255)[])'] = []; + // Все отправленные + p['(flags @> array[\'out\'])'] = []; } else if (query.folderType == 'outbox') { - // TODO это какая-то хитрая метапапка, которая не живёт на IMAP'е? + // FIXME это "папка" для локально составленных сообщений, не сохранённых в IMAP } else if (query.folderType == 'drafts' || query.folderType == 'spam' || query.folderType == 'trash') { @@ -350,6 +351,7 @@ function sanitizeHtml(html) styles = ''; } html = htmlawed.sanitize(html||'', { safe: 1, elements: '* +style', keep_bad: 0, comment: 1 }); + html = html.replace(/]+)>/i, (m, m1) => ''); html = html.replace(/]*>([\s\S]*)<\/style\s*>/ig, function(m, m1) { let ast = css.parse(m1, { silent: true }); diff --git a/database-patches/2019-05-16-text.sql b/database-patches/2019-05-16-text.sql new file mode 100644 index 0000000..18a68ab --- /dev/null +++ b/database-patches/2019-05-16-text.sql @@ -0,0 +1,8 @@ +alter table accounts alter name type text; +alter table accounts alter email type text; +alter table folders alter name type text; +alter table folders alter kind type text; +alter table messages alter messageid type text; +alter table messages alter inreplyto type text; +alter table messages alter refs type text[]; +alter table messages alter flags type text[]; diff --git a/db.sql b/database/db.sql similarity index 91% rename from db.sql rename to database/db.sql index 447c174..7770318 100644 --- a/db.sql +++ b/database/db.sql @@ -2,8 +2,8 @@ create extension if not exists btree_gin; create table accounts ( id serial not null primary key, - name varchar(255) not null, - email varchar(255) not null, + name text not null, + email text not null, settings jsonb not null -- настройки: replyto, cc, bcc, imap, smtp, folders ); @@ -13,9 +13,9 @@ create table folders ( id serial not null primary key, uidvalidity int not null, account_id int not null, - name varchar(255) not null, + name text not null, highestmodseq int not null default 0, - kind varchar(255) not null, + kind text not null, foreign key (account_id) references accounts (id) on delete cascade on update cascade ); create unique index folders_name on folders (account_id, name); @@ -25,9 +25,9 @@ create table messages ( thread_id int, folder_id int not null, uid int, - messageid varchar(1000) not null, - inreplyto varchar(1000) not null, - refs varchar(1000)[] not null, + messageid text not null, + inreplyto text not null, + refs text[] not null, subject text not null, props jsonb not null, body_html text not null default '', @@ -35,7 +35,7 @@ create table messages ( body_html_text text not null default '', time timestamptz not null, size int not null, - flags varchar(255)[] not null, + flags text[] not null, foreign key (folder_id) references folders (id) on delete cascade on update cascade ); create unique index messages_unique on messages (folder_id, uid); diff --git a/operetta.js b/operetta.js index e14cd17..c56805a 100644 --- a/operetta.js +++ b/operetta.js @@ -1,6 +1,6 @@ /** * TODO: - * - исправить параллелизм запросов и sync'а + * - пометка прочитанным, просмотренным (seen) * - фоновая индексация всех текстов сообщений в ящике * - скачивание вложений * - написание сообщений @@ -37,11 +37,8 @@ * функционал самого почтового сервера. Но шо ж с ним поделаешь, если он "ни ф силах"... * Ведь по сути-то, MTA от такой штуки нужен только 1 метод: "добавить сообщение в папку". * - * Блин, IMAP - кривой протокол - * - sequence number-ы это какая-то жопа - * - обновления идут по sequence number-ам - * - обновления идут только по активному mailbox-у - * - а ещё есть какие-то сраные неймспейсы + * Но для сохранения совместимости с IMAP тут два пути - либо тащить всё к себе и потом + * делать свой IMAP сервер, либо всё-таки мучаться и дублировать функционал. */ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";