Skip to content

Commit

Permalink
Merge pull request #291 from tumugin/migrate-to-postgres
Browse files Browse the repository at this point in the history
Migrated to Postgres
  • Loading branch information
tumugin authored Oct 9, 2023
2 parents 2fe5b20 + 9c74804 commit 9f6c040
Show file tree
Hide file tree
Showing 20 changed files with 167 additions and 134 deletions.
4 changes: 2 additions & 2 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DB_JDBC_URL=jdbc:p6spy:mysql://localhost:3306/aisu?createDatabaseIfNotExist=true&connectionTimeZone=UTC
DB_USERNAME=root
DB_JDBC_URL=jdbc:p6spy:postgresql://localhost:5432/aisu
DB_USERNAME=aisu
DB_PASSWORD=4ab4008b362142c391cc9e1ab98addc6b25f00f5
REDIS_CONNECTION_URL=redis://localhost:6379
APP_ENV=local
Expand Down
4 changes: 2 additions & 2 deletions .env.testing
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DB_JDBC_URL=jdbc:mysql://localhost:3306/aisu_test?createDatabaseIfNotExist=true
DB_USERNAME=root
DB_JDBC_URL=jdbc:postgresql://localhost:5432/aisu_test
DB_USERNAME=aisu
DB_PASSWORD=4ab4008b362142c391cc9e1ab98addc6b25f00f5

# h2で動くようになったらコレに変える
Expand Down
13 changes: 6 additions & 7 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@ jobs:
runs-on: ubuntu-latest
services:
db:
image: mariadb:10.11.5
image: postgres:16.0
ports:
- 3306:3306
- 5432:5432
env:
MYSQL_ROOT_PASSWORD: 4ab4008b362142c391cc9e1ab98addc6b25f00f5
MYSQL_DATABASE: aisu
MYSQL_USER: aisu
MYSQL_PASSWORD: 4ab4008b362142c391cc9e1ab98addc6b25f00f5
POSTGRES_DB: aisu_test
POSTGRES_USER: aisu
POSTGRES_PASSWORD: 4ab4008b362142c391cc9e1ab98addc6b25f00f5
options: >-
--health-cmd "mysqladmin ping"
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ aisu is a cheki management application backend made with Kotlin.

## Requirements
- Java 19 or newer
- MySQL 8.0.29 or newer(MariaDB 10.7.3 or newer)
- PostgreSQL 15 or newer
- Redis 7.0.0 or newer
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ dependencies {
implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
implementation("mysql:mysql-connector-java:8.0.33")
implementation("org.postgresql:postgresql:42.6.0")
implementation("com.zaxxer:HikariCP:5.0.1")
implementation("io.insert-koin:koin-core:$koinVersion")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.1")
Expand Down
17 changes: 8 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
version: "3.9"
services:
mysql:
image: mariadb:10.11.5
postgres:
image: postgres:16.0
ports:
- "3306:3306"
- "5432:5432"
volumes:
- mysql_data:/var/lib/mysql
- postgres_data:/var/lib/postgresql/data
environment:
- MYSQL_DATABASE=aisu
- MYSQL_ROOT_PASSWORD=4ab4008b362142c391cc9e1ab98addc6b25f00f5
- MYSQL_USER=aisu
- MYSQL_PASSWORD=4ab4008b362142c391cc9e1ab98addc6b25f00f5
- POSTGRES_DB=aisu
- POSTGRES_USER=aisu
- POSTGRES_PASSWORD=4ab4008b362142c391cc9e1ab98addc6b25f00f5
redis:
image: redis:7.2.1
ports:
Expand All @@ -26,5 +25,5 @@ services:
environment:
SWAGGER_JSON: /oas3/openapi.yaml
volumes:
mysql_data:
postgres_data:
redis_data:
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package com.tumugin.aisu.infra.repository.exposed
import kotlinx.datetime.*
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.vendors.*
import java.sql.ResultSet
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter

class DataTimeWithTimeZoneColumnType : ColumnType(), IDateColumnType {
Expand All @@ -19,11 +22,8 @@ class DataTimeWithTimeZoneColumnType : ColumnType(), IDateColumnType {
return when (value) {
is Instant -> value
is java.time.Instant -> value.toKotlinInstant()
// タイムゾーン情報を付けられないMySQLのようなDBの場合には強制的にタイムゾーンをUTCとして扱う
is LocalDateTime -> value.toInstant(UtcOffset.ZERO)
is java.time.LocalDateTime -> value.toKotlinLocalDateTime().toInstant(UtcOffset.ZERO)
is java.sql.Timestamp -> value.toLocalDateTime().toKotlinLocalDateTime().toInstant(UtcOffset.ZERO)
else -> error("$value is not Instant or LocalDateTime!")
is OffsetDateTime -> value.toInstant().toKotlinInstant()
else -> error("$value is not Instant or OffsetDateTime!")
}
}

Expand All @@ -35,7 +35,13 @@ class DataTimeWithTimeZoneColumnType : ColumnType(), IDateColumnType {
// タイムゾーン情報を付けられないMySQLのようなDBの場合には強制的にタイムゾーンをUTCとして扱う
return value.toLocalDateTime(TimeZone.UTC).toJavaLocalDateTime()
}
return value.toJavaInstant()

// see here for pgsql: https://jdbc.postgresql.org/documentation/query/#table51-supportedjava-8-date-and-time-classes
return value.toJavaInstant().atOffset(ZoneOffset.UTC)
}

override fun readObject(rs: ResultSet, index: Int): Any? {
return rs.getObject(index, OffsetDateTime::class.java)
}

private fun currentDBSupportsTimeZone(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,36 @@ import org.jetbrains.exposed.sql.CharColumnType
import org.jetbrains.exposed.sql.ExpressionWithColumnType
import org.jetbrains.exposed.sql.QueryBuilder
import org.jetbrains.exposed.sql.append
import org.jetbrains.exposed.sql.vendors.MysqlDialect
import org.jetbrains.exposed.sql.vendors.PostgreSQLDialect
import org.jetbrains.exposed.sql.vendors.currentDialect

class DateFormatWithTZFunction<T : ExpressionWithColumnType<Instant>>(
private val exp: T, private val format: String, private val fromTZ: TimeZone, private val toTZ: TimeZone
) : org.jetbrains.exposed.sql.Function<String>(CharColumnType()) {
override fun toQueryBuilder(queryBuilder: QueryBuilder) = queryBuilder {
append("DATE_FORMAT(CONVERT_TZ(", exp, ", '${toOffsetString(fromTZ)}', '${toOffsetString(toTZ)}'), '${format}')")
when (currentDialect.name) {
PostgreSQLDialect.dialectName -> {
append(
"TO_CHAR(",
exp,
" AT TIME ZONE INTERVAL '${toOffsetString(toTZ)}'",
", '${format}')"
)
}

MysqlDialect.dialectName -> {
append(
"DATE_FORMAT(CONVERT_TZ(",
exp,
", '${toOffsetString(fromTZ)}', '${toOffsetString(toTZ)}'), '${format}')"
)
}

else -> {
error("${currentDialect.name} is unsupported database for DateFormatWithTZFunction.")
}
}
}

private fun toOffsetString(tz: TimeZone): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ class ChekiRepositoryImpl : ChekiRepository {
return transaction {
val yearConvertFunc = DateFormatWithTZFunction(
Chekis.shotAt,
"%Y",
"yyyy",
TimeZone.of("UTC"),
baseTimezone
)
val monthConvertFunc = DateFormatWithTZFunction(
Chekis.shotAt,
"%c",
"mm",
TimeZone.of("UTC"),
baseTimezone
)
Expand Down
11 changes: 0 additions & 11 deletions src/main/resources/db/migration/V1__create_users.sql

This file was deleted.

107 changes: 107 additions & 0 deletions src/main/resources/db/migration/V1__initial_create_postgres.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
create table "users"
(
"id" bigserial primary key not null,
"name" varchar(255) not null,
"email" varchar(255) unique,
"password" varchar(255),
"email_verified_at" timestamptz,
"force_logout_generation" integer default 0,
"created_at" timestamptz not null,
"updated_at" timestamptz not null
);

create table "groups"
(
"id" bigserial primary key not null,
"user_id" bigint,
"name" varchar(255) not null,
"status" varchar(255) not null,
"created_at" timestamptz not null,
"updated_at" timestamptz not null,
constraint fk_user_id foreign key ("user_id") references "users" ("id") on delete set null
);

create table "idols"
(
"id" bigserial primary key not null,
"user_id" bigint,
"name" varchar(255) not null,
"status" varchar(255) not null,
"created_at" timestamptz not null,
"updated_at" timestamptz not null,
constraint fk_user_id foreign key ("user_id") references "users" ("id") on delete set null
);

create table "regulations"
(
"id" bigserial primary key not null,
"group_id" bigint not null,
"user_id" bigint,
"name" varchar(255) not null,
"comment" text not null,
"unit_price" integer not null,
"status" varchar(255) not null,
"created_at" timestamptz not null,
"updated_at" timestamptz not null,
constraint fk_group_id foreign key ("group_id") references "groups" ("id") on delete cascade,
constraint fk_user_id foreign key ("user_id") references "users" ("id") on delete set null
);

create table "chekis"
(
"id" bigserial primary key not null,
"user_id" bigint not null,
"idol_id" bigint,
"regulation_id" bigint,
"quantity" integer not null,
"shot_at" timestamptz not null,
"created_at" timestamptz not null,
"updated_at" timestamptz not null,
constraint fk_user_id foreign key ("user_id") references "users" ("id") on delete cascade,
constraint fk_idol_id foreign key ("idol_id") references "idols" ("id") on delete set null,
constraint fk_regulation_id foreign key ("regulation_id") references "regulations" ("id") on delete set null
);

create table "favorite_groups"
(
"id" bigserial primary key not null,
"user_id" bigint not null,
"group_id" bigint not null,
"created_at" timestamptz not null,
"updated_at" timestamptz not null,
constraint fk_user_id foreign key ("user_id") references "users" ("id") on delete cascade,
constraint fk_group_id foreign key ("group_id") references "groups" ("id") on delete cascade
);

create table "group_idols"
(
"id" bigserial primary key not null,
"group_id" bigint not null,
"idol_id" bigint not null,
"created_at" timestamptz not null,
"updated_at" timestamptz not null,
constraint fk_group_id foreign key ("group_id") references "groups" ("id") on delete cascade,
constraint fk_idol_id foreign key ("idol_id") references "idols" ("id") on delete cascade,
unique ("group_id", "idol_id")
);

create table "admin_users"
(
"id" bigserial primary key not null,
"name" varchar(255) not null,
"email" varchar(255) unique,
"password" varchar(255),
"force_logout_generation" integer default 0,
"created_at" timestamptz not null,
"updated_at" timestamptz not null
);

create table "auth0_users"
(
"id" bigserial primary key not null,
"user_id" bigint not null unique,
"auth0_user_id" varchar(255) not null unique,
"created_at" timestamptz not null,
"updated_at" timestamptz not null,
constraint fk_user_id foreign key ("user_id") references "users" ("id") on delete cascade
);
10 changes: 0 additions & 10 deletions src/main/resources/db/migration/V2__create_groups.sql

This file was deleted.

10 changes: 0 additions & 10 deletions src/main/resources/db/migration/V3__create_idols.sql

This file was deleted.

14 changes: 0 additions & 14 deletions src/main/resources/db/migration/V4__create_regulations.sql

This file was deleted.

14 changes: 0 additions & 14 deletions src/main/resources/db/migration/V5__create_chekis.sql

This file was deleted.

10 changes: 0 additions & 10 deletions src/main/resources/db/migration/V6__favorite_groups.sql

This file was deleted.

11 changes: 0 additions & 11 deletions src/main/resources/db/migration/V7__create_group_idols.sql

This file was deleted.

10 changes: 0 additions & 10 deletions src/main/resources/db/migration/V8__create_admin_users.sql

This file was deleted.

9 changes: 0 additions & 9 deletions src/main/resources/db/migration/V9__create_auth0_users.sql

This file was deleted.

Loading

0 comments on commit 9f6c040

Please sign in to comment.