-
Notifications
You must be signed in to change notification settings - Fork 0
/
schema.sql
259 lines (232 loc) · 7.74 KB
/
schema.sql
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
-- Drop triggers if they exist
DROP TRIGGER IF EXISTS before_user_delete;
-- Drop procedures if they exist
DROP PROCEDURE IF EXISTS follow_user;
DROP PROCEDURE IF EXISTS unfollow_user;
DROP PROCEDURE IF EXISTS follow_artist;
DROP PROCEDURE IF EXISTS unfollow_artist;
DROP PROCEDURE IF EXISTS like_song;
DROP PROCEDURE IF EXISTS unlike_song;
DROP PROCEDURE IF EXISTS like_album;
DROP PROCEDURE IF EXISTS unlike_album;
DROP PROCEDURE IF EXISTS like_playlist;
DROP PROCEDURE IF EXISTS unlike_playlist;
-- Drop tables if they exist
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS artists;
DROP TABLE IF EXISTS albums;
DROP TABLE IF EXISTS songs;
DROP TABLE IF EXISTS playlists;
DROP TABLE IF EXISTS user_follow_user;
DROP TABLE IF EXISTS user_follow_artist;
DROP TABLE IF EXISTS liked_songs;
DROP TABLE IF EXISTS liked_albums;
DROP TABLE IF EXISTS liked_playlists;
-- Create Users Table
CREATE TABLE users (
id INT AUTO_INCREMENT,
name VARCHAR(50),
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(20) NOT NULL,
date_created DATETIME,
profile_pic BLOB,
PRIMARY KEY (id)
);
-- Create Artists Table
CREATE TABLE artists (
id INT AUTO_INCREMENT,
name VARCHAR(50),
biography TEXT,
date_created DATE,
profile_pic BLOB,
PRIMARY KEY (id)
);
-- Create Albums Table
CREATE TABLE albums (
id INT AUTO_INCREMENT,
artist_id INT,
title VARCHAR(156) NOT NULL,
release_date DATE NOT NULL,
cover_art BLOB NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (artist_id) REFERENCES artists(id)
);
-- Create Songs Table
CREATE TABLE songs (
id INT AUTO_INCREMENT,
artist_id INT,
album_id INT DEFAULT NULL,
title VARCHAR(50) NOT NULL,
duration TIME NOT NULL,
release_date DATE NOT NULL,
genre VARCHAR(37) NOT NULL,
single BOOLEAN DEFAULT FALSE,
PRIMARY KEY (id),
FOREIGN KEY (artist_id) REFERENCES artists(id),
FOREIGN KEY (album_id) REFERENCES albums(id)
);
-- Create Playlists Table
CREATE TABLE playlists (
id INT AUTO_INCREMENT,
user_id INT,
title VARCHAR(30) NOT NULL,
description TEXT DEFAULT NULL,
date_created DATE NOT NULL,
public BOOL DEFAULT FALSE,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- Create User Follow User Table
CREATE TABLE user_follow_user (
id INT AUTO_INCREMENT,
user1_id INT,
user2_id INT,
since DATETIME,
PRIMARY KEY (id),
FOREIGN KEY (user1_id) REFERENCES users(id),
FOREIGN KEY (user2_id) REFERENCES users(id)
);
-- Create User Follow Artist Table
CREATE TABLE user_follow_artist (
id INT AUTO_INCREMENT,
user_id INT,
artist_id INT,
since DATETIME,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (artist_id) REFERENCES artists(id)
);
-- Create Liked Songs Table
CREATE TABLE liked_songs (
id INT AUTO_INCREMENT,
user_id INT,
song_id INT,
since DATE,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (song_id) REFERENCES songs(id)
);
-- Create Liked Albums Table
CREATE TABLE liked_albums (
id INT AUTO_INCREMENT,
user_id INT,
album_id INT,
since DATE,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (album_id) REFERENCES albums(id)
);
-- Create Liked Playlists Table
CREATE TABLE liked_playlists (
id INT AUTO_INCREMENT,
user_id INT,
playlist_id INT,
since DATE,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (playlist_id) REFERENCES playlists(id)
);
-- Add Indexes to User Follow Tables
CREATE INDEX idx_user1_id ON user_follow_user (user1_id);
CREATE INDEX idx_user2_id ON user_follow_user (user2_id);
CREATE INDEX idx_user_artist_user_id ON user_follow_artist (user_id);
CREATE INDEX idx_user_artist_artist_id ON user_follow_artist (artist_id);
-- Add Indexes to Like Tables
CREATE INDEX idx_liked_songs_user_id ON liked_songs (user_id);
CREATE INDEX idx_liked_songs_song_id ON liked_songs (song_id);
CREATE INDEX idx_liked_albums_user_id ON liked_albums (user_id);
CREATE INDEX idx_liked_albums_album_id ON liked_albums (album_id);
CREATE INDEX idx_liked_playlists_user_id ON liked_playlists (user_id);
CREATE INDEX idx_liked_playlists_playlist_id ON liked_playlists (playlist_id);
-- Set delimiter for triggers and procedures
DELIMITER //
-- Trigger: Before Deleting a User
CREATE TRIGGER before_user_delete
BEFORE DELETE ON users
FOR EACH ROW
BEGIN
-- Delete related records
DELETE FROM user_follow_user WHERE user1_id = OLD.id OR user2_id = OLD.id;
DELETE FROM user_follow_artist WHERE user_id = OLD.id;
DELETE FROM liked_songs WHERE user_id = OLD.id;
DELETE FROM liked_albums WHERE user_id = OLD.id;
DELETE FROM liked_playlists WHERE user_id = OLD.id;
END;
-- Procedure: Follow User with Error Handling
CREATE PROCEDURE follow_user(IN follower_id INT, IN followee_id INT)
BEGIN
-- Check if the follow relationship already exists
IF NOT EXISTS (SELECT 1 FROM user_follow_user WHERE user1_id = follower_id AND user2_id = followee_id) THEN
INSERT INTO user_follow_user (user1_id, user2_id, since)
VALUES (follower_id, followee_id, NOW());
END IF;
END //
-- Procedure: Unfollow User
CREATE PROCEDURE unfollow_user(IN follower_id INT, IN followee_id INT)
BEGIN
DELETE FROM user_follow_user
WHERE user1_id = follower_id AND user2_id = followee_id;
END //
-- Procedure: Follow Artist with Error Handling
CREATE PROCEDURE follow_artist(IN user_ID INT, IN artist_ID INT)
BEGIN
-- Check if the user is already following the artist
IF NOT EXISTS (SELECT 1 FROM user_follow_artist WHERE user_id = user_ID AND artist_id = artist_ID) THEN
INSERT INTO user_follow_artist (user_id, artist_id, since)
VALUES (user_ID, artist_ID, NOW());
END IF;
END //
-- Procedure: Unfollow Artist
CREATE PROCEDURE unfollow_artist(IN user_ID INT, IN artist_ID INT)
BEGIN
DELETE FROM user_follow_artist
WHERE user_id = user_ID AND artist_id = artist_ID;
END //
-- Procedure: Like Song with Error Handling
CREATE PROCEDURE like_song(IN user_ID INT, IN song_ID INT)
BEGIN
-- Check if the song is already liked by the user
IF NOT EXISTS (SELECT 1 FROM liked_songs WHERE user_id = user_ID AND song_id = song_ID) THEN
INSERT INTO liked_songs (user_id, song_id, since)
VALUES (user_ID, song_ID, CURDATE());
END IF;
END //
-- Procedure: Unlike Song
CREATE PROCEDURE unlike_song(IN user_ID INT, IN song_ID INT)
BEGIN
DELETE FROM liked_songs
WHERE user_id = user_ID AND song_id = song_ID;
END //
-- Procedure: Like Album with Error Handling
CREATE PROCEDURE like_album(IN user_ID INT, IN album_ID INT)
BEGIN
-- Check if the album is already liked by the user
IF NOT EXISTS (SELECT 1 FROM liked_albums WHERE user_id = user_ID AND album_id = album_ID) THEN
INSERT INTO liked_albums (user_id, album_id, since)
VALUES (user_ID, album_ID, CURDATE());
END IF;
END //
-- Procedure: Unlike Album
CREATE PROCEDURE unlike_album(IN user_ID INT, IN album_ID INT)
BEGIN
DELETE FROM liked_albums
WHERE user_id = user_ID AND album_id = album_ID;
END //
-- Procedure: Like Playlist with Error Handling
CREATE PROCEDURE like_playlist(IN user_ID INT, IN playlist_ID INT)
BEGIN
-- Check if the playlist is already liked by the user
IF NOT EXISTS (SELECT 1 FROM liked_playlists WHERE user_id = user_ID AND playlist_id = playlist_ID) THEN
INSERT INTO liked_playlists (user_id, playlist_id, since)
VALUES (user_ID, playlist_ID, CURDATE());
END IF;
END //
-- Procedure: Unlike Playlist
CREATE PROCEDURE unlike_playlist(IN user_ID INT, IN playlist_ID INT)
BEGIN
DELETE FROM liked_playlists
WHERE user_id = user_ID AND playlist_id = playlist_ID;
END //
-- Reset delimiter
DELIMITER ;