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, settings jsonb not null -- настройки: replyto, cc, bcc, in_server, in_port, out_server, out_port, login, password -- sent_folder, trash_folder, spam_folder, drafts_folder -- in_server varchar(255) not null, -- out_server varchar(255) not null, -- reply_to ); create unique index accounts_email on accounts (email); create table folders ( id serial not null primary key, uidvalidity int not null, account_id int not null, name varchar(255) not null, highestmodseq int not null default 0, kind varchar(255) 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); create table messages ( id serial not null primary key, 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, subject text not null, props jsonb not null, body_html text not null default '', body_text text not null default '', body_html_text text not null default '', time timestamptz not null, size int not null, flags varchar(255)[] 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); create index messages_flags on messages using gin (folder_id, flags); create index messages_messageid on messages (messageid); create index messages_refs on messages using gin (refs); create index messages_time on messages (folder_id, time); create or replace function messages_fulltext(msg messages) returns tsvector language plpgsql immutable as $$ begin return setweight(to_tsvector('russian', regexp_replace( coalesce(msg.props->>'from', '') || ' ' || coalesce(msg.props->>'replyto', '') || ' ' || coalesce(msg.props->>'to', '') || ' ' || coalesce(msg.props->>'cc', '') || ' ' || coalesce(msg.props->>'bcc', '') || ' ' || coalesce(msg.props->>'attachments', '') || ' ' || msg.subject, '\W+', ' ', 'g' )), 'A') || setweight(to_tsvector('russian', msg.body_html_text || ' ' || msg.body_text), 'B'); end $$; create index messages_text on messages using gin (messages_fulltext(messages)); create table threads ( id serial not null primary key, first_msg int, msg_count int not null default 1, foreign key (first_msg) references messages (id) on delete restrict on update cascade ); create index threads_first_msg on threads (first_msg); alter table messages add foreign key (thread_id) references threads (id) on delete restrict on update cascade; alter table accounts owner to operetta; alter table folders owner to operetta; alter table messages owner to operetta; alter table threads owner to operetta;