1/*
2 Copyright (C) 1999-2004, IC & S  dbmail@ic-s.nl
3 Copyright (c) 2004-2014, NFG Net Facilities Group BV, support@nfg.nl
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20/*
21*/
22
23BEGIN TRANSACTION;
24
25CREATE SEQUENCE dbmail_alias_idnr_seq;
26CREATE TABLE dbmail_aliases (
27    alias_idnr INT8 DEFAULT nextval('dbmail_alias_idnr_seq'),
28    alias VARCHAR(100) NOT NULL,
29    deliver_to VARCHAR(250) NOT NULL,
30    client_idnr INT8 DEFAULT '0' NOT NULL,
31    PRIMARY KEY (alias_idnr)
32);
33CREATE INDEX dbmail_aliases_alias_idx ON dbmail_aliases(alias);
34CREATE INDEX dbmail_aliases_alias_low_idx ON dbmail_aliases(lower(alias));
35
36CREATE SEQUENCE dbmail_authlog_id_seq;
37CREATE TABLE dbmail_authlog (
38  id INT8 DEFAULT nextval('dbmail_authlog_id_seq'),
39  userid VARCHAR(100),
40  service VARCHAR(32),
41  login_time TIMESTAMP WITHOUT TIME ZONE,
42  logout_time TIMESTAMP WITHOUT TIME ZONE,
43  src_ip VARCHAR(40),
44  src_port INT8,
45  dst_ip VARCHAR(40),
46  dst_port INT8,
47  status VARCHAR(32) DEFAULT 'active',
48  bytes_rx INT8 DEFAULT '0' NOT NULL,
49  bytes_tx INT8 DEFAULT '0' NOT NULL,
50  PRIMARY KEY (id)
51);
52
53
54
55CREATE SEQUENCE dbmail_user_idnr_seq;
56CREATE TABLE dbmail_users (
57   user_idnr INT8 DEFAULT nextval('dbmail_user_idnr_seq'),
58   userid VARCHAR(100) NOT NULL,
59   passwd VARCHAR(130) NOT NULL,
60   client_idnr INT8 DEFAULT '0' NOT NULL,
61   maxmail_size INT8 DEFAULT '0' NOT NULL,
62   curmail_size INT8 DEFAULT '0' NOT NULL,
63   maxsieve_size INT8 DEFAULT '0' NOT NULL,
64   cursieve_size INT8 DEFAULT '0' NOT NULL,
65   encryption_type VARCHAR(20) DEFAULT '' NOT NULL,
66   last_login TIMESTAMP DEFAULT '1979-11-03 22:05:58' NOT NULL,
67   PRIMARY KEY (user_idnr)
68);
69
70CREATE UNIQUE INDEX dbmail_users_name_idx ON dbmail_users(userid);
71CREATE INDEX dbmail_users_2 ON dbmail_users (lower(userid));
72
73CREATE TABLE dbmail_usermap (
74  login VARCHAR(100) NOT NULL,
75  sock_allow varchar(100) NOT NULL,
76  sock_deny varchar(100) NOT NULL,
77  userid varchar(100) NOT NULL
78);
79CREATE UNIQUE INDEX usermap_idx_1 ON dbmail_usermap(login, sock_allow, userid);
80
81CREATE SEQUENCE dbmail_mailbox_idnr_seq;
82CREATE TABLE dbmail_mailboxes (
83   mailbox_idnr INT8 DEFAULT nextval('dbmail_mailbox_idnr_seq'),
84   owner_idnr INT8 REFERENCES dbmail_users(user_idnr) ON DELETE CASCADE ON UPDATE CASCADE,
85   name VARCHAR(255) NOT NULL,
86   seen_flag INT2 DEFAULT '0' NOT NULL,
87   answered_flag INT2 DEFAULT '0' NOT NULL,
88   deleted_flag INT2 DEFAULT '0' NOT NULL,
89   flagged_flag INT2 DEFAULT '0' NOT NULL,
90   recent_flag INT2 DEFAULT '0' NOT NULL,
91   draft_flag INT2 DEFAULT '0' NOT NULL,
92   no_inferiors INT2 DEFAULT '0' NOT NULL,
93   no_select INT2 DEFAULT '0' NOT NULL,
94   permission INT2 DEFAULT '2' NOT NULL,
95   seq INT8 DEFAULT '0' NOT NULL,
96   PRIMARY KEY (mailbox_idnr)
97);
98CREATE INDEX dbmail_mailboxes_owner_idx ON dbmail_mailboxes(owner_idnr);
99CREATE INDEX dbmail_mailboxes_name_idx ON dbmail_mailboxes(name);
100CREATE INDEX dbmail_mailboxes_seq ON dbmail_mailboxes(seq);
101CREATE UNIQUE INDEX dbmail_mailboxes_owner_name_idx
102	ON dbmail_mailboxes(owner_idnr, name);
103
104CREATE TABLE dbmail_subscription (
105   user_id INT8 REFERENCES dbmail_users(user_idnr) ON DELETE CASCADE ON UPDATE CASCADE,
106   mailbox_id INT8 REFERENCES dbmail_mailboxes(mailbox_idnr)
107	ON DELETE CASCADE ON UPDATE CASCADE,
108   PRIMARY KEY (user_id, mailbox_id)
109);
110
111CREATE TABLE dbmail_acl (
112    user_id INT8 REFERENCES dbmail_users(user_idnr) ON DELETE CASCADE ON UPDATE CASCADE,
113    mailbox_id INT8 REFERENCES dbmail_mailboxes(mailbox_idnr)
114	ON DELETE CASCADE ON UPDATE CASCADE,
115    lookup_flag INT2 DEFAULT '0' NOT NULL,
116    read_flag INT2 DEFAULT '0' NOT NULL,
117    seen_flag INT2 DEFAULT '0' NOT NULL,
118    write_flag INT2 DEFAULT '0' NOT NULL,
119    insert_flag INT2 DEFAULT '0' NOT NULL,
120    post_flag INT2 DEFAULT '0' NOT NULL,
121    create_flag INT2 DEFAULT '0' NOT NULL,
122    delete_flag INT2 DEFAULT '0' NOT NULL,
123    deleted_flag INT2 DEFAULT '0' NOT NULL,
124    expunge_flag INT2 DEFAULT '0' NOT NULL,
125    administer_flag INT2 DEFAULT '0' NOT NULL,
126    PRIMARY KEY (user_id, mailbox_id)
127);
128
129CREATE SEQUENCE dbmail_physmessage_id_seq;
130CREATE TABLE dbmail_physmessage (
131   id INT8 DEFAULT nextval('dbmail_physmessage_id_seq'),
132   messagesize INT8 DEFAULT '0' NOT NULL,
133   rfcsize INT8 DEFAULT '0' NOT NULL,
134   internal_date TIMESTAMP WITHOUT TIME ZONE,
135   PRIMARY KEY(id)
136);
137
138CREATE SEQUENCE dbmail_message_idnr_seq;
139CREATE TABLE dbmail_messages (
140   message_idnr INT8 DEFAULT nextval('dbmail_message_idnr_seq'),
141   mailbox_idnr INT8 REFERENCES dbmail_mailboxes(mailbox_idnr)
142	ON DELETE CASCADE ON UPDATE CASCADE,
143   physmessage_id INT8 REFERENCES dbmail_physmessage(id)
144	ON DELETE CASCADE ON UPDATE CASCADE,
145   seen_flag INT2 DEFAULT '0' NOT NULL,
146   answered_flag INT2 DEFAULT '0' NOT NULL,
147   deleted_flag INT2 DEFAULT '0' NOT NULL,
148   flagged_flag INT2 DEFAULT '0' NOT NULL,
149   recent_flag INT2 DEFAULT '0' NOT NULL,
150   draft_flag INT2 DEFAULT '0' NOT NULL,
151   unique_id varchar(70) NOT NULL,
152   status INT2 DEFAULT '0' NOT NULL,
153   PRIMARY KEY (message_idnr)
154);
155CREATE INDEX dbmail_messages_1 ON dbmail_messages(mailbox_idnr);
156CREATE INDEX dbmail_messages_2 ON dbmail_messages(physmessage_id);
157CREATE INDEX dbmail_messages_3 ON dbmail_messages(seen_flag);
158CREATE INDEX dbmail_messages_4 ON dbmail_messages(unique_id);
159CREATE INDEX dbmail_messages_5 ON dbmail_messages(status);
160CREATE INDEX dbmail_messages_6 ON dbmail_messages(status) WHERE status < '2';
161CREATE INDEX dbmail_messages_7 ON dbmail_messages(mailbox_idnr,status,seen_flag);
162CREATE INDEX dbmail_messages_8 ON dbmail_messages(mailbox_idnr,status,recent_flag);
163
164CREATE SEQUENCE dbmail_messageblk_idnr_seq;
165CREATE TABLE dbmail_messageblks (
166   messageblk_idnr INT8 DEFAULT nextval('dbmail_messageblk_idnr_seq'),
167   physmessage_id INT8 REFERENCES dbmail_physmessage(id)
168	ON DELETE CASCADE ON UPDATE CASCADE,
169   messageblk BYTEA NOT NULL,
170   blocksize INT8 DEFAULT '0' NOT NULL,
171   is_header INT2 DEFAULT '0' NOT NULL,
172   PRIMARY KEY (messageblk_idnr)
173);
174CREATE INDEX dbmail_messageblks_physmessage_idx
175	ON dbmail_messageblks(physmessage_id);
176CREATE INDEX dbmail_messageblks_physmessage_is_header_idx
177	ON dbmail_messageblks(physmessage_id, is_header);
178
179
180
181CREATE TABLE dbmail_auto_notifications (
182   user_idnr INT8 REFERENCES dbmail_users(user_idnr) ON DELETE CASCADE ON UPDATE CASCADE,
183   notify_address VARCHAR(100),
184   PRIMARY KEY (user_idnr)
185);
186
187CREATE TABLE dbmail_auto_replies (
188   user_idnr INT8 REFERENCES dbmail_users (user_idnr) ON DELETE CASCADE ON UPDATE CASCADE,
189   start_date timestamp without time zone not null,
190   stop_date timestamp without time zone not null,
191   reply_body TEXT,
192   PRIMARY KEY (user_idnr)
193);
194
195CREATE SEQUENCE dbmail_seq_pbsp_id;
196CREATE TABLE dbmail_pbsp (
197  idnr INT8 NOT NULL DEFAULT NEXTVAL('dbmail_seq_pbsp_id'),
198  since TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:00',
199  ipnumber INET NOT NULL DEFAULT '0.0.0.0',
200  PRIMARY KEY (idnr)
201);
202CREATE UNIQUE INDEX dbmail_idx_ipnumber ON dbmail_pbsp (ipnumber);
203CREATE INDEX dbmail_idx_since ON dbmail_pbsp (since);
204
205--- Create the user for the delivery chain:
206INSERT INTO dbmail_users (userid, passwd, encryption_type)
207	VALUES ('__@!internal_delivery_user!@__', '', 'md5');
208--- Create the 'anyone' user which is used for ACLs.
209INSERT INTO dbmail_users (userid, passwd, encryption_type)
210	VALUES ('anyone', '', 'md5');
211--- Create the user to own #Public mailboxes
212INSERT INTO dbmail_users (userid, passwd, encryption_type)
213	VALUES ('__public__', '', 'md5');
214
215
216CREATE SEQUENCE dbmail_headervalue_id_seq;
217CREATE TABLE dbmail_headervalue (
218        id INT8 NOT NULL DEFAULT nextval('dbmail_headervalue_id_seq'),
219	hash VARCHAR(256) NOT NULL,
220        headervalue   TEXT NOT NULL DEFAULT '',
221        sortfield     VARCHAR(255) DEFAULT NULL,
222        datefield     TIMESTAMP WITHOUT TIME ZONE,
223        PRIMARY KEY (id)
224);
225
226CREATE INDEX dbmail_headervalue_1 ON dbmail_headervalue USING btree (hash);
227CREATE INDEX dbmail_headervalue_2 ON dbmail_headervalue USING btree (sortfield);
228CREATE INDEX dbmail_headervalue_3 ON dbmail_headervalue USING btree (datefield);
229
230CREATE SEQUENCE dbmail_headername_id_seq;
231CREATE TABLE dbmail_headername (
232        id  INT8 NOT NULL DEFAULT nextval('dbmail_headername_id_seq'),
233        headername    VARCHAR(100) NOT NULL DEFAULT 'BROKEN_HEADER',
234        PRIMARY KEY (id)
235);
236CREATE UNIQUE INDEX dbmail_headername_1 on dbmail_headername(lower(headername));
237
238CREATE TABLE dbmail_header (
239        physmessage_id      INT8 NOT NULL
240		REFERENCES dbmail_physmessage(id)
241                ON UPDATE CASCADE ON DELETE CASCADE,
242        headername_id  INT8 NOT NULL
243                REFERENCES dbmail_headername(id)
244                ON UPDATE CASCADE ON DELETE CASCADE,
245        headervalue_id      INT8 NOT NULL
246                REFERENCES dbmail_headervalue(id)
247                ON UPDATE CASCADE ON DELETE CASCADE,
248        PRIMARY KEY (physmessage_id,headername_id,headervalue_id)
249);
250
251CREATE INDEX dbmail_header_headername_id_key on dbmail_header(headername_id);
252CREATE INDEX dbmail_header_headervalue_id_key on dbmail_header(headervalue_id);
253CREATE INDEX dbmail_header_physmessage_id_key on dbmail_header(physmessage_id);
254
255
256CREATE SEQUENCE dbmail_referencesfield_idnr_seq;
257CREATE TABLE dbmail_referencesfield (
258        physmessage_id  INT8 NOT NULL
259			REFERENCES dbmail_physmessage(id)
260			ON UPDATE CASCADE ON DELETE CASCADE,
261	id		INT8 DEFAULT nextval('dbmail_referencesfield_idnr_seq'),
262	referencesfield	VARCHAR(255) NOT NULL DEFAULT '',
263	PRIMARY KEY (id)
264);
265CREATE UNIQUE INDEX dbmail_referencesfield_1 ON dbmail_referencesfield(physmessage_id, referencesfield);
266
267
268CREATE TABLE dbmail_replycache (
269    to_addr character varying(100) DEFAULT ''::character varying NOT NULL,
270    from_addr character varying(100) DEFAULT ''::character varying NOT NULL,
271    handle    character varying(100) DEFAULT ''::character varying,
272    lastseen timestamp without time zone NOT NULL
273);
274CREATE UNIQUE INDEX replycache_1 ON dbmail_replycache USING btree (to_addr, from_addr, handle);
275
276CREATE SEQUENCE dbmail_sievescripts_idnr_seq;
277CREATE TABLE dbmail_sievescripts (
278	id		INT8 DEFAULT nextval('dbmail_sievescripts_idnr_seq'),
279        owner_idnr	INT8 NOT NULL
280			REFERENCES dbmail_users(user_idnr)
281			ON UPDATE CASCADE ON DELETE CASCADE,
282	active		INT2 DEFAULT '0' NOT NULL,
283	name		VARCHAR(100) NOT NULL DEFAULT '',
284	script		TEXT NOT NULL DEFAULT '',
285	PRIMARY KEY	(id)
286);
287
288CREATE UNIQUE INDEX dbmail_sievescripts_1 on dbmail_sievescripts(owner_idnr,name);
289CREATE INDEX dbmail_sievescripts_2 on dbmail_sievescripts(owner_idnr,active);
290
291CREATE SEQUENCE dbmail_envelope_idnr_seq;
292CREATE TABLE dbmail_envelope (
293        physmessage_id  INT8 NOT NULL
294			REFERENCES dbmail_physmessage(id)
295			ON UPDATE CASCADE ON DELETE CASCADE,
296	id		INT8 DEFAULT nextval('dbmail_envelope_idnr_seq'),
297	envelope	TEXT NOT NULL DEFAULT '',
298	PRIMARY KEY (id)
299);
300CREATE UNIQUE INDEX dbmail_envelope_1 ON dbmail_envelope(physmessage_id);
301CREATE UNIQUE INDEX dbmail_envelope_2 ON dbmail_envelope(physmessage_id, id);
302
303CREATE SEQUENCE dbmail_mimeparts_id_seq;
304CREATE TABLE dbmail_mimeparts (
305    id bigint NOT NULL DEFAULT nextval('dbmail_mimeparts_id_seq'),
306    hash character(256) NOT NULL,
307    data bytea NOT NULL,
308    size bigint NOT NULL,
309    PRIMARY KEY (id)
310);
311
312CREATE INDEX dbmail_mimeparts_1 ON dbmail_mimeparts USING btree (hash);
313
314CREATE TABLE dbmail_partlists (
315    physmessage_id bigint NOT NULL,
316    is_header smallint DEFAULT (0)::smallint NOT NULL,
317    part_key integer DEFAULT 0 NOT NULL,
318    part_depth integer DEFAULT 0 NOT NULL,
319    part_order integer DEFAULT 0 NOT NULL,
320    part_id bigint NOT NULL
321);
322
323CREATE INDEX dbmail_partlists_1 ON dbmail_partlists USING btree (physmessage_id);
324CREATE INDEX dbmail_partlists_2 ON dbmail_partlists USING btree (part_id);
325CREATE UNIQUE INDEX message_parts ON dbmail_partlists(physmessage_id, part_key, part_depth, part_order);
326
327ALTER TABLE ONLY dbmail_partlists
328    ADD CONSTRAINT dbmail_partlists_part_id_fkey FOREIGN KEY (part_id) REFERENCES dbmail_mimeparts(id) ON UPDATE CASCADE ON DELETE CASCADE;
329
330ALTER TABLE ONLY dbmail_partlists
331    ADD CONSTRAINT dbmail_partlists_physmessage_id_fkey FOREIGN KEY (physmessage_id) REFERENCES dbmail_physmessage(id) ON UPDATE CASCADE ON DELETE CASCADE;
332
333CREATE TABLE dbmail_keywords (
334	message_idnr bigint NOT NULL,
335	keyword varchar(64) NOT NULL
336);
337ALTER TABLE ONLY dbmail_keywords
338    ADD CONSTRAINT dbmail_keywords_pkey PRIMARY KEY (message_idnr, keyword);
339ALTER TABLE ONLY dbmail_keywords
340    ADD CONSTRAINT dbmail_keywords_fkey FOREIGN KEY (message_idnr) REFERENCES dbmail_messages (message_idnr) ON DELETE CASCADE ON UPDATE CASCADE;
341
342CREATE SEQUENCE dbmail_filters_id_seq;
343CREATE TABLE dbmail_filters (
344	user_id      INT8 REFERENCES dbmail_users(user_idnr) ON DELETE CASCADE ON UPDATE CASCADE,
345	id           INT8 NOT NULL DEFAULT nextval('dbmail_filters_id_seq'),
346	headername   varchar(128) NOT NULL,
347	headervalue  varchar(255) NOT NULL,
348	mailbox      varchar(100) NOT NULL,
349	PRIMARY KEY (user_id, id)
350);
351
352CREATE VIEW dbmail_fromfield AS
353        SELECT physmessage_id,sortfield AS fromfield
354        FROM dbmail_messages m
355        JOIN dbmail_header h USING (physmessage_id)
356        JOIN dbmail_headername n ON h.headername_id = n.id
357        JOIN dbmail_headervalue v ON h.headervalue_id = v.id
358WHERE n.headername='from';
359
360CREATE VIEW dbmail_ccfield AS
361        SELECT physmessage_id,sortfield AS ccfield
362        FROM dbmail_messages m
363        JOIN dbmail_header h USING (physmessage_id)
364        JOIN dbmail_headername n ON h.headername_id = n.id
365        JOIN dbmail_headervalue v ON h.headervalue_id = v.id
366WHERE n.headername='cc';
367
368CREATE VIEW dbmail_tofield AS
369        SELECT physmessage_id,sortfield AS tofield
370        FROM dbmail_messages m
371        JOIN dbmail_header h USING (physmessage_id)
372        JOIN dbmail_headername n ON h.headername_id = n.id
373        JOIN dbmail_headervalue v ON h.headervalue_id = v.id
374WHERE n.headername='to';
375
376CREATE VIEW dbmail_subjectfield AS
377        SELECT physmessage_id,headervalue AS subjectfield
378        FROM dbmail_messages m
379        JOIN dbmail_header h USING (physmessage_id)
380        JOIN dbmail_headername n ON h.headername_id = n.id
381        JOIN dbmail_headervalue v ON h.headervalue_id = v.id
382WHERE n.headername='subject';
383
384CREATE VIEW dbmail_datefield AS
385        SELECT physmessage_id,datefield,sortfield
386        FROM dbmail_messages m
387        JOIN dbmail_header h USING (physmessage_id)
388        JOIN dbmail_headername n ON h.headername_id = n.id
389        JOIN dbmail_headervalue v ON h.headervalue_id = v.id
390WHERE n.headername='date';
391
392
393COMMIT;
394