summaryrefslogtreecommitdiff
path: root/tools/sql/schema.txt
blob: 634447007eeec58c00a3446339e2fbdd64348b1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
CREATE TABLE IF NOT EXISTS users (
	user_id INTEGER PRIMARY KEY,
	name TEXT UNIQUE COLLATE NOCASE,
	mail TEXT UNIQUE COLLATE NOCASE,
	about TEXT,
	password TEXT,
	salt TEXT,
	ctime TIMESTAMP,
	cip TEXT,
	atime TIMESTAMP,
	aip TEXT,
	notifications INTEGER
);

CREATE TABLE IF NOT EXISTS notifications (
	user_id INTEGER,
	game_id INTEGER,
	time TIMESTAMP,
	UNIQUE ( user_id, game_id )
);

CREATE TABLE IF NOT EXISTS tokens (
	user_id INTEGER PRIMARY KEY,
	token TEXT,
	time TIMESTAMP
);

CREATE TABLE IF NOT EXISTS blacklist_ip ( ip TEXT PRIMARY KEY );
CREATE TABLE IF NOT EXISTS blacklist_mail ( mail TEXT PRIMARY KEY );

CREATE TABLE IF NOT EXISTS titles (
	title_id TEXT UNIQUE,
	title_name TEXT,
	bgg INTEGER
);

CREATE TABLE IF NOT EXISTS roles (
	title_id TEXT,
	role TEXT,
	UNIQUE ( title_id, role )
);

CREATE TABLE IF NOT EXISTS games (
	game_id INTEGER PRIMARY KEY,
	title_id TEXT,
	scenario TEXT,
	options TEXT,
	owner_id INTEGER,
	private BOOLEAN,
	random BOOLEAN,
	description TEXT,
	ctime TIMESTAMP,
	mtime TIMESTAMP,
	status INTEGER,
	result TEXT,
	active TEXT,
	state TEXT
);

CREATE TABLE IF NOT EXISTS replay (
	game_id INTEGER,
	time TIMESTAMP,
	role TEXT,
	action TEXT,
	arguments TEXT
);

CREATE TABLE IF NOT EXISTS chats (
	game_id INTEGER PRIMARY KEY,
	time TIMESTAMP,
	chat TEXT
);

CREATE TABLE IF NOT EXISTS players (
	user_id INTEGER,
	game_id INTEGER,
	role TEXT,
	UNIQUE ( game_id, role )
);

CREATE TABLE IF NOT EXISTS forums (
	forum_id INTEGER PRIMARY KEY,
	title TEXT
);

CREATE TABLE IF NOT EXISTS threads (
	thread_id INTEGER PRIMARY KEY,
	forum_id INTEGER DEFAULT 1,
	author_id INTEGER,
	subject TEXT,
	ctime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	mtime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	post_count INTEGER DEFAULT 0,
	locked BOOLEAN DEFAULT 0
	-- or first_post_id and last_post_id ?
);

CREATE TABLE IF NOT EXISTS posts (
	post_id INTEGER PRIMARY KEY,
	thread_id INTEGER,
	author_id INTEGER,
	ctime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	mtime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	body TEXT
);

CREATE TABLE IF NOT EXISTS messages (
	message_id INTEGER PRIMARY KEY,
	from_id INTEGER,
	to_id INTEGER,
	time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	subject TEXT,
	body TEXT,
	read BOOLEAN DEFAULT 0,
	deleted_from_inbox BOOLEAN DEFAULT 0,
	deleted_from_outbox BOOLEAN DEFAULT 0
);

DROP TRIGGER IF EXISTS update_reply_count;
CREATE TRIGGER update_reply_count AFTER INSERT ON posts
BEGIN
	UPDATE threads
		SET
			post_count = ( SELECT COUNT(*) FROM posts WHERE posts.thread_id = new.thread_id ),
			mtime = datetime('now')
		WHERE threads.thread_id = new.thread_id
	;
END;

DROP TRIGGER IF EXISTS update_reply_time;
CREATE TRIGGER update_reply_time AFTER UPDATE ON posts
BEGIN
	UPDATE threads SET mtime = datetime('now') WHERE threads.thread_id = new.thread_id ;
END;

DROP TRIGGER IF EXISTS no_part_on_active_game;
CREATE TRIGGER no_part_on_active_game BEFORE DELETE ON players
BEGIN
	SELECT CASE
	WHEN ( SELECT status FROM games WHERE game_id = old.game_id ) > 0
	THEN RAISE(ABORT, "Cannot remove players from started games.")
	END;
END;

DROP TRIGGER IF EXISTS no_join_on_active_game;
CREATE TRIGGER no_join_on_active_game BEFORE INSERT ON players
BEGIN
	SELECT CASE
	WHEN ( SELECT status FROM games WHERE game_id = new.game_id ) > 0
	THEN RAISE(ABORT, "Cannot add players to started games.")
	END;
END;

DROP TRIGGER IF EXISTS must_be_valid_role;
CREATE TRIGGER must_be_valid_role BEFORE INSERT ON players
BEGIN
	SELECT CASE
	WHEN ( SELECT COUNT(*) FROM roles, games WHERE
		roles.title_id = games.title_id AND
		games.game_id = new.game_id AND
		roles.role = new.role ) <> 1
	AND new.role <> 'Random 1'
	AND new.role <> 'Random 2'
	AND new.role <> 'Random 3'
	AND new.role <> 'Random 4'
	AND new.role <> 'Random 5'
	AND new.role <> 'Random 6'
	THEN RAISE(ABORT, "Invalid role for that title.")
	END;
END;

DROP TRIGGER IF EXISTS purge_players;
CREATE TRIGGER purge_players AFTER DELETE ON games
BEGIN
	DELETE FROM players WHERE game_id = old.game_id;
	DELETE FROM notifications WHERE game_id = old.game_id;
	DELETE FROM chats WHERE game_id = old.game_id;
	DELETE FROM replay WHERE game_id = old.game_id;
END;

DROP VIEW IF EXISTS player_view;
DROP VIEW IF EXISTS player_list_view;
DROP VIEW IF EXISTS game_view;

CREATE VIEW player_view AS
	SELECT players.game_id
		, players.role AS role
		, players.user_id AS user_id
		, users.name AS user_name
	FROM players
	JOIN users ON players.user_id = users.user_id
	;

CREATE VIEW player_list_view AS
	SELECT game_id
		, group_concat(name, ', ') AS player_names
		, COUNT(DISTINCT user_id) AS user_count
		, COUNT(user_id) AS role_count
	FROM players
	JOIN users USING ( user_id )
	GROUP BY game_id
	;

CREATE VIEW game_view AS
	SELECT games.game_id
		, games.title_id
		, titles.title_name
		, games.scenario
		, games.options
		, games.owner_id
		, owner.name AS owner_name
		, players.player_names
		, players.user_count = 1 AS is_solo
		, players.user_count <> players.role_count AS is_shared
		, games.private
		, games.random
		, games.description
		, games.ctime
		, games.mtime
		, games.status
		, games.result
		, games.active AS active_role
		-- , games.state
	FROM games
	JOIN titles USING ( title_id )
	JOIN users AS owner ON games.owner_id = owner.user_id
	LEFT JOIN player_list_view AS players USING ( game_id )
	;

DROP VIEW IF EXISTS thread_view;
CREATE VIEW thread_view AS
	SELECT threads.thread_id
		, threads.author_id
		, author.name AS author_name
		, threads.post_count - 1 AS reply_count
		, threads.ctime
		, threads.mtime
		, threads.subject
	FROM threads
	JOIN users AS author ON threads.author_id = author.user_id
	;

DROP VIEW IF EXISTS post_view;
CREATE VIEW post_view AS
	SELECT posts.post_id
		, posts.thread_id
		, posts.author_id
		, author.name AS author_name
		, posts.ctime
		, posts.mtime
		, posts.body
	FROM posts
	JOIN users AS author ON posts.author_id = author.user_id
	;

DROP VIEW IF EXISTS message_view;
CREATE VIEW message_view AS
	SELECT messages.message_id
		, messages.from_id
		, users_from.name AS from_name
		, messages.to_id
		, users_to.name AS to_name
		, messages.time
		, messages.subject
		, messages.body
		, messages.read
		, messages.deleted_from_inbox
		, messages.deleted_from_outbox
	FROM messages
	JOIN users AS users_from ON messages.from_id = users_from.user_id
	JOIN users AS users_to ON messages.to_id = users_to.user_id
	;