Skip to content

Commit 2babb20

Browse files
committed
Migrate db migration to flyway, use lowercase email
1 parent 8a817b6 commit 2babb20

File tree

12 files changed

+76
-53
lines changed

12 files changed

+76
-53
lines changed

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ dependencies {
2929
implementation 'org.springframework.boot:spring-boot-starter-security'
3030
implementation 'org.springframework.boot:spring-boot-starter-validation'
3131
implementation 'org.springframework.boot:spring-boot-starter-web'
32+
implementation 'org.flywaydb:flyway-core:11.13.0'
33+
implementation 'org.flywaydb:flyway-database-postgresql:11.13.0'
3234

3335
runtimeOnly 'org.postgresql:postgresql'
3436

db/000-init.sql

Lines changed: 0 additions & 5 deletions
This file was deleted.

db/schema/course.sql

Lines changed: 0 additions & 10 deletions
This file was deleted.

db/schema/enrollment.sql

Lines changed: 0 additions & 8 deletions
This file was deleted.

db/schema/instructor.sql

Lines changed: 0 additions & 8 deletions
This file was deleted.

db/schema/student.sql

Lines changed: 0 additions & 8 deletions
This file was deleted.

db/schema/user_account.sql

Lines changed: 0 additions & 10 deletions
This file was deleted.

docker-compose.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ services:
22
postgres:
33
image: postgres:17
44
container_name: postgres
5-
volumes:
6-
- ./db:/docker-entrypoint-initdb.d
75
environment:
86
POSTGRES_USER: course_user
97
POSTGRES_PASSWORD: course_user_password

src/main/java/net/hackyourfuture/coursehub/repository/UserAccountRepository.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public UserAccountEntity findByUserId(Integer userId) {
3131

3232
@Nullable
3333
public UserAccountEntity findByEmailAddress(String emailAddress) {
34-
String sql = "SELECT * FROM user_account WHERE email_address = :emailAddress";
34+
String sql = "SELECT * FROM user_account WHERE lower(email_address) = lower(:emailAddress)";
3535
try {
3636
return jdbcTemplate.queryForObject(sql, Map.of("emailAddress", emailAddress), USER_ACCOUNT_ROW_MAPPER);
3737
} catch (EmptyResultDataAccessException e) {
@@ -60,7 +60,7 @@ public UserAccountEntity insertUserAccount(String emailAddress, String passwordH
6060

6161
@Nullable
6262
public Integer findUserIdByEmail(String emailAddress) {
63-
String sql = "SELECT user_id FROM user_account WHERE email_address = :emailAddress";
63+
String sql = "SELECT user_id FROM user_account WHERE lower(email_address) = lower(:emailAddress)";
6464
try {
6565
return jdbcTemplate.queryForObject(sql, Map.of("emailAddress", emailAddress), Integer.class);
6666
} catch (EmptyResultDataAccessException e) {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
-- User account (used for user authentication and authorization)
2+
CREATE TYPE role AS ENUM ('instructor', 'student');
3+
4+
CREATE TABLE user_account
5+
(
6+
user_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
7+
password_hash VARCHAR(60) NOT NULL,
8+
email_address VARCHAR(100) NOT NULL,
9+
role role NOT NULL
10+
);
11+
12+
-- preserve original email case for display, but enforce case-insensitive uniqueness
13+
CREATE UNIQUE INDEX idx_email_unique
14+
ON user_account (lower(email_address));
15+
16+
-- A student is a user who can enroll in courses.
17+
CREATE TABLE student
18+
(
19+
student_id INTEGER PRIMARY KEY,
20+
first_name VARCHAR NOT NULL,
21+
last_name VARCHAR NOT NULL,
22+
enrollment_date DATE NOT NULL DEFAULT current_date,
23+
FOREIGN KEY (student_id) REFERENCES user_account (user_id) ON DELETE CASCADE
24+
);
25+
26+
-- An instructor is a user who can create and manage courses.
27+
CREATE TABLE instructor
28+
(
29+
instructor_id INTEGER PRIMARY KEY,
30+
first_name VARCHAR NOT NULL,
31+
last_name VARCHAR NOT NULL,
32+
hire_date DATE NOT NULL DEFAULT current_date,
33+
FOREIGN KEY (instructor_id) REFERENCES user_account (user_id) ON DELETE CASCADE
34+
);
35+
36+
-- A course is taught by an instructor and can have many students enrolled.
37+
CREATE TABLE course
38+
(
39+
course_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
40+
name VARCHAR(255) NOT NULL,
41+
description TEXT,
42+
instructor_id INTEGER REFERENCES instructor (instructor_id) ON DELETE SET NULL,
43+
start_date DATE,
44+
end_date DATE,
45+
max_enrollments INT CHECK (max_enrollments > 0)
46+
);
47+
48+
-- An enrollment is a student taking a course.
49+
CREATE TABLE enrollment
50+
(
51+
enrollment_id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
52+
student_id INTEGER REFERENCES student (student_id) ON DELETE CASCADE,
53+
course_id INTEGER REFERENCES course (course_id) ON DELETE CASCADE,
54+
enrollment_date DATE DEFAULT current_date
55+
);

0 commit comments

Comments
 (0)