RelationalDesign: buildboard-ddl.sql

File buildboard-ddl.sql, 7.1 KB (added by 226026, 3 weeks ago)
Line 
1---- DROP TABLES
2DROP TABLE IF EXISTS users CASCADE;
3DROP TABLE IF EXISTS moderator CASCADE;
4DROP TABLE IF EXISTS developer CASCADE;
5DROP TABLE IF EXISTS project_manager CASCADE;
6DROP TABLE IF EXISTS thread CASCADE;
7DROP TABLE IF EXISTS likes CASCADE;
8DROP TABLE IF EXISTS topic_threads_moderators CASCADE;
9DROP TABLE IF EXISTS tag CASCADE;
10DROP TABLE IF EXISTS tag_threads CASCADE;
11DROP TABLE IF EXISTS topic_thread CASCADE;
12DROP TABLE IF EXISTS topic_belongs_to_project CASCADE;
13DROP TABLE IF EXISTS topic_blacklist CASCADE;
14DROP TABLE IF EXISTS project_thread CASCADE;
15DROP TABLE IF EXISTS discussion_thread CASCADE;
16DROP TABLE IF EXISTS developer_associated_with_project CASCADE;
17DROP TABLE IF EXISTS permissions CASCADE;
18DROP TABLE IF EXISTS project_roles CASCADE;
19DROP TABLE IF EXISTS users_project_roles CASCADE;
20DROP TABLE IF EXISTS project_roles_permissions CASCADE;
21DROP TABLE IF EXISTS project_request CASCADE;
22DROP TABLE IF EXISTS report CASCADE;
23DROP TABLE IF EXISTS channel CASCADE;
24DROP TABLE IF EXISTS messages CASCADE;
25DROP TABLE IF EXISTS threads_moderators CASCADE;
26DROP TABLE IF EXISTS blacklisted_user CASCADE;
27DROP TYPE IF EXISTS status;
28DROP FUNCTION IF EXISTS add_child_topic;
29DROP FUNCTION IF EXISTS validate_same_parent;
30DROP FUNCTION IF EXISTS validate_topic_title;
31---- DDL
32CREATE TABLE users
33(
34 id SERIAL PRIMARY KEY,
35 username VARCHAR(32) UNIQUE NOT NULL,
36 is_activate bool,
37 password VARCHAR(72) NOT NULL,
38 description VARCHAR(200),
39 registered_at TIMESTAMP,
40 sex VARCHAR(1)
41);
42CREATE TABLE moderator
43(
44) INHERITS (users);
45CREATE TABLE developer
46(
47) INHERITS (users);
48CREATE TABLE project_manager
49(
50) INHERITS (users);
51CREATE TABLE thread
52(
53 id SERIAL PRIMARY KEY,
54 content TEXT,
55 user_id INT REFERENCES users (id) NOT NULL
56);
57CREATE TABLE likes
58(
59 user_id INT REFERENCES users (id),
60 thread_id INT REFERENCES thread (id),
61 PRIMARY KEY (user_id, thread_id)
62);
63CREATE TABLE topic_threads_moderators
64(
65 thread_id INT REFERENCES thread (id) ON DELETE CASCADE,
66 user_id INT REFERENCES users (id) ON DELETE CASCADE,
67 PRIMARY KEY (thread_id, user_id)
68);
69CREATE TABLE tag
70(
71 name VARCHAR(64) PRIMARY KEY
72);
73CREATE TABLE tag_threads
74(
75 thread_id INT REFERENCES thread (id),
76 tag_name VARCHAR(64) REFERENCES tag (name),
77 PRIMARY KEY (thread_id, tag_name)
78);
79CREATE TABLE topic_thread
80(
81 title VARCHAR(32) NOT NULL,
82 guidelines jsonb,
83 parent_topic_id INT REFERENCES thread (id)
84) INHERITS (thread);
85CREATE TABLE topic_belongs_to_project
86(
87 topic_id INT REFERENCES thread (id) ON DELETE CASCADE,
88 project_id INT REFERENCES thread (id) ON DELETE CASCADE,
89 PRIMARY KEY (topic_id, project_id)
90);
91CREATE TABLE blacklisted_user
92(
93 topic_id INT REFERENCES thread (id) ON DELETE CASCADE,
94 user_id INT REFERENCES users (id) ON DELETE CASCADE,
95 moderator_id INT REFERENCES users (id) ON DELETE CASCADE,
96 start_date TIMESTAMP,
97 end_date TIMESTAMP,
98 reason TEXT,
99 PRIMARY KEY (user_id, moderator_id, topic_id, start_date)
100);
101CREATE TABLE project_thread
102(
103 title VARCHAR(32) NOT NULL,
104 repo_url TEXT
105) INHERITS (thread);
106CREATE TABLE discussion_thread
107(
108 user_id INT REFERENCES users (id),
109 reply_discussion_id INT REFERENCES thread (id),
110 topic_id INT REFERENCES thread (id) NOT NULL
111) INHERITS (thread);
112CREATE TABLE developer_associated_with_project
113(
114 project_id INT REFERENCES thread (id),
115 developer_id INT REFERENCES users (id),
116 started_at TIMESTAMP,
117 ended_at TIMESTAMP,
118 PRIMARY KEY (project_id, developer_id, started_at)
119);
120CREATE TABLE permissions
121(
122 name VARCHAR(32) PRIMARY KEY
123);
124CREATE TABLE project_roles
125(
126 name VARCHAR(32),
127 project_id INT REFERENCES thread (id) ON DELETE CASCADE,
128 description TEXT,
129 PRIMARY KEY (name, project_id)
130);
131CREATE TABLE users_project_roles
132(
133 user_id INT REFERENCES users (id),
134 project_id INT,
135 role_name VARCHAR(32),
136 FOREIGN KEY (role_name, project_id)
137 REFERENCES project_roles (name, project_id),
138 PRIMARY KEY (user_id, project_id, role_name)
139);
140CREATE TABLE project_roles_permissions
141(
142 permission_name VARCHAR(32) REFERENCES permissions (name),
143 role_name VARCHAR(32),
144 project_id INT,
145 PRIMARY KEY (permission_name, role_name, project_id),
146 FOREIGN KEY (role_name, project_id)
147 REFERENCES project_roles (name, project_id)
148);
149CREATE TYPE status AS ENUM ('ACCEPTED', 'DENIED', 'PENDING');
150CREATE TABLE project_request
151(
152 id SERIAL PRIMARY KEY,
153 description VARCHAR(200) ,
154 status status NOT NULL,
155 user_id INT REFERENCES users (id) NOT NULL,
156 project_id INT REFERENCES thread (id) NOT NULL
157);
158CREATE TABLE report
159(
160 id SERIAL,
161 created_at TIMESTAMP,
162 description VARCHAR(200) NOT NULL,
163 status status,
164 thread_id INT REFERENCES thread (id),
165 for_user_id INT REFERENCES users (id),
166 by_user_id INT REFERENCES users (id),
167 PRIMARY KEY (id, thread_id, for_user_id, by_user_id)
168);
169CREATE TABLE channel
170(
171 name VARCHAR(64),
172 description VARCHAR(200),
173 project_id INT REFERENCES thread (id) ON DELETE CASCADE,
174 developer_id INT REFERENCES users (id),
175 PRIMARY KEY (name, project_id)
176);
177CREATE TABLE messages
178(
179 sent_at TIMESTAMP,
180 content VARCHAR(200) NOT NULL,
181 sent_by INT REFERENCES users (id),
182 project_id INT,
183 channel_name VARCHAR(64),
184 FOREIGN KEY (channel_name, project_id)
185 REFERENCES channel (name, project_id) ON DELETE CASCADE,
186 PRIMARY KEY (channel_name, project_id, sent_at, sent_by)
187);
188-------------------------- FUNCTIONS ----------------------
189CREATE FUNCTION validate_topic_title()
190 RETURNS TRIGGER
191 LANGUAGE plpgsql
192AS
193$$
194BEGIN
195 IF new.title IN
196 (SELECT title
197 FROM topic_thread
198 AS t
199 WHERE t.parent_topic_id = new.parent_topic_id)
200 THEN
201 RAISE EXCEPTION 'There already exists a topic with title % in parent topic with id %',new.title,new.parent_topic_id;
202 END IF;
203 RETURN new;
204END;
205$$;
206CREATE FUNCTION add_child_topic()
207 RETURNS TRIGGER
208 LANGUAGE plpgsql
209AS
210$$
211DECLARE
212 project_id INT;
213BEGIN
214 SELECT t.project_id
215 INTO project_id
216 FROM topic_belongs_to_project AS t
217 WHERE new.id = t.topic_id;
218 INSERT INTO topic_belongs_to_project VALUES (new.id, project_id);
219END;
220$$;
221CREATE FUNCTION validate_same_parent()
222 RETURNS TRIGGER
223 LANGUAGE plpgsql
224AS
225$$
226BEGIN
227 IF NOT EXISTS (SELECT 1
228 FROM discussion_thread
229 AS dt
230 WHERE new.reply_discussion_id = dt.id
231 AND dt.topic_id = new.topic_id) THEN
232 RAISE EXCEPTION 'Can not reply to a discussion that is not in the same topic';
233 END IF;
234 RETURN new;
235END;
236$$;
237
238-------------------------- TRIGGERS ----------------------
239
240CREATE OR REPLACE TRIGGER check_topic_name
241 BEFORE INSERT OR UPDATE
242 ON topic_thread
243 FOR EACH ROW
244EXECUTE FUNCTION validate_topic_title();
245
246CREATE OR REPLACE TRIGGER project_insert_child_topic
247 AFTER INSERT
248 ON topic_thread
249 FOR EACH ROW
250EXECUTE FUNCTION add_child_topic();
251
252CREATE OR REPLACE TRIGGER check_same_parent
253 BEFORE INSERT
254 ON discussion_thread
255 FOR EACH ROW
256EXECUTE FUNCTION validate_same_parent();
257
258
259