Skip to content

Commit

Permalink
Merge pull request #155 from bas-kirill/feature/migrate-jdbc-to-jooq
Browse files Browse the repository at this point in the history
feat(persistence): migrate jdbc to jooq
  • Loading branch information
bas-kirill authored Sep 2, 2024
2 parents 104e8f9 + e10594b commit e45a660
Show file tree
Hide file tree
Showing 34 changed files with 425 additions and 90 deletions.
31 changes: 19 additions & 12 deletions client/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export const I18N_INSTRUMENT_DATE_TO = "instrument.date.to";
export const I18N_INSTRUMENT_CARD_SHOW_BUTTON = "instrument.card.show.button";
export const I18N_INSTRUMENT_CARD_REMOVE_BUTTON = "instrument.remove.button";
export const I18N_INSTRUMENT_CARD_EDIT_BUTTON = "instrument.edit.button";
export const I18N_INSTRUMENT_CARD_FAVORITE_BUTTON = "instrument.favorite.button";
export const I18N_INSTRUMENT_CARD_FAVORITE_BUTTON =
"instrument.favorite.button";

export const I18N_LOGIN_INPUT = "login.login.input";
export const I18N_LOGIN_PASSWORD_INPUT = "login.login.password";
Expand Down Expand Up @@ -63,9 +64,12 @@ const resources = {
[I18N_HOME_SEARCH_BAR_INPUT]: "What instrument?",
[I18N_HOME_SEARCH_BAR_BUTTON]: "Search",
[I18N_REASONS_H1]: "Why Choose Us for Your Musical Needs",
[I18N_REASONS_FIRST]: "We offer a wide range of high-quality instruments for all skill levels",
[I18N_REASONS_SECOND]: "Our expert staff provides personalized advice and service",
[I18N_REASONS_THIRD]: "Enjoy competitive prices and exclusive deals on top brands",
[I18N_REASONS_FIRST]:
"We offer a wide range of high-quality instruments for all skill levels",
[I18N_REASONS_SECOND]:
"Our expert staff provides personalized advice and service",
[I18N_REASONS_THIRD]:
"Enjoy competitive prices and exclusive deals on top brands",
[I18N_TRENDS_H1]: "Trending Instruments",
[I18N_INSTRUMENT_TYPE_FILTER]: "Type",
[I18N_INSTRUMENT_CARD_MANUFACTURER]: "Manufacturer",
Expand Down Expand Up @@ -98,7 +102,7 @@ const resources = {
[I18N_NAVBAR_NEXT]: "Next",

[I18N_FAVORITE_H1]: "Favorite",
}
},
},
ru: {
translation: {
Expand All @@ -111,9 +115,12 @@ const resources = {
[I18N_HOME_SEARCH_BAR_INPUT]: "Какой инструмент?",
[I18N_HOME_SEARCH_BAR_BUTTON]: "Поиск",
[I18N_REASONS_H1]: "Почему вы выберете нас",
[I18N_REASONS_FIRST]: "Мы предлагаем широкий ассортимент высококачественных инструментов для всех уровней квалификации",
[I18N_REASONS_SECOND]: "Наш квалифицированный персонал предоставляет индивидуальные консультации и обслуживание",
[I18N_REASONS_THIRD]: "Наслаждайтесь конкурентоспособными ценами и эксклюзивными предложениями от ведущих брендов",
[I18N_REASONS_FIRST]:
"Мы предлагаем широкий ассортимент высококачественных инструментов для всех уровней квалификации",
[I18N_REASONS_SECOND]:
"Наш квалифицированный персонал предоставляет индивидуальные консультации и обслуживание",
[I18N_REASONS_THIRD]:
"Наслаждайтесь конкурентоспособными ценами и эксклюзивными предложениями от ведущих брендов",
[I18N_TRENDS_H1]: "Тренды",
[I18N_INSTRUMENT_TYPE_FILTER]: "Тип",
[I18N_INSTRUMENT_CARD_MANUFACTURER]: "Производитель",
Expand Down Expand Up @@ -144,8 +151,8 @@ const resources = {
[I18N_LOGOUT_BUTTON]: "Выйти",

[I18N_FAVORITE_H1]: "Любимое",
}
}
},
},
};

i18n
Expand All @@ -155,8 +162,8 @@ i18n
lng: window.navigator.language,
fallbackLng: "en",
interpolation: {
escapeValue: false // react already safes from xss
}
escapeValue: false, // react already safes from xss
},
});

export default i18n;
27 changes: 15 additions & 12 deletions client/src/pages/home/ui/Home.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,46 @@ import {
I18N_HOME_SEARCH_BAR_BUTTON,
I18N_HOME_SEARCH_BAR_INPUT,
I18N_REASONS_FIRST,
I18N_REASONS_H1, I18N_REASONS_SECOND, I18N_REASONS_THIRD, I18N_TRENDS_H1
I18N_REASONS_H1,
I18N_REASONS_SECOND,
I18N_REASONS_THIRD,
I18N_TRENDS_H1,
} from "../../../i18n";

const images = [
{
image: saxophone,
caption: "Saxophone"
caption: "Saxophone",
},
{
image: guitar,
caption: "Guitar"
caption: "Guitar",
},
{
image: rock_guitar,
caption: "Rock Guitar"
caption: "Rock Guitar",
},
{
image: violin,
caption: "Violin"
}
caption: "Violin",
},
];

const trendingInstrumentsResponsiveSettings = [
{
breakpoint: 571,
settings: {
slidesToShow: 3,
slidesToScroll: 1
}
slidesToScroll: 1,
},
},
{
breakpoint: 570,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
slidesToScroll: 1,
},
},
];

export function HomePage() {
Expand All @@ -66,7 +69,7 @@ export function HomePage() {
<div
className={styles.home_logo}
style={{
background: `url(${homeLogo}) no-repeat center, linear-gradient(blue, cyan)`
background: `url(${homeLogo}) no-repeat center, linear-gradient(blue, cyan)`,
}}
>
<form
Expand Down
2 changes: 1 addition & 1 deletion client/src/pages/login/ui/Login.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
I18N_LOGIN_BUTTON,
I18N_LOGIN_INPUT,
I18N_LOGIN_PASSWORD_INPUT,
I18N_REGISTRATION_BUTTON
I18N_REGISTRATION_BUTTON,
} from "../../../i18n";

export function LoginPage() {
Expand Down
2 changes: 1 addition & 1 deletion client/src/pages/profile/ui/Profile.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
I18N_DARK_MODE_BUTTON,
I18N_LOGOUT_BUTTON,
I18N_PROFILE_NAME_SPAN,
I18N_PROFILE_ROLE_SPAN
I18N_PROFILE_ROLE_SPAN,
} from "../../../i18n";
import { useTranslation } from "react-i18next";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import React, { useEffect, useRef } from "react";
import React, { useEffect, useState } from "react";
import styles from "./styles/Favorite.button.module.css";
import actionBtnStyle from "./styles/Action.button.module.css";
import { useState } from "react";
import {
AddFavoriteApi,
ListFavoriteApi,
RemoveFavoriteApi,
} from "generated/api";
import { InstrumentId } from "generated/model";
import Jwt from "domain/model/jwt";
import { COOKIE_JWT_KEY } from "shared/config/frontend";
import { getCookie } from "shared/cookie/cookie";
import { apiConfig } from "shared/config/api";
import { useTranslation } from "react-i18next";
import { I18N_HEADER_FAVORITE_BUTTON, I18N_INSTRUMENT_CARD_REMOVE_BUTTON } from "../../../i18n";
import { I18N_HEADER_FAVORITE_BUTTON } from "../../../i18n";

interface Props {
instrumentId: InstrumentId;
Expand All @@ -25,7 +22,6 @@ const addFavorite = new AddFavoriteApi(apiConfig);

export const FavoriteButton = (props: Props) => {
const { t } = useTranslation();
const jwt = useRef<string | undefined>(getCookie(COOKIE_JWT_KEY));
const [favorite, setFavorite] = useState<boolean>();

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useDarkMode } from "shared/dark-mode/use-dark-mode";
import { apiConfig } from "shared/config/api";
import Jwt from "domain/model/jwt";
import { DeleteInstrumentByIdApi } from "generated/api/delete-instrument-by-id-api";
import { I18N_INSTRUMENT_CARD_EDIT_BUTTON, I18N_INSTRUMENT_CARD_REMOVE_BUTTON } from "../../../i18n";
import { I18N_INSTRUMENT_CARD_REMOVE_BUTTON } from "../../../i18n";
import { useTranslation } from "react-i18next";

interface Props {
Expand Down
3 changes: 2 additions & 1 deletion client/src/widgets/header/ui/Header.widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
I18N_HEADER_CATALOGUE_BUTTON,
I18N_HEADER_FAVORITE_BUTTON,
I18N_HEADER_HOME_BUTTON,
I18N_HEADER_LOGIN_BUTTON, I18N_HEADER_PROFILE_BUTTON
I18N_HEADER_LOGIN_BUTTON,
I18N_HEADER_PROFILE_BUTTON,
} from "../../../i18n";
import { useTranslation } from "react-i18next";

Expand Down
50 changes: 49 additions & 1 deletion server/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import io.gitlab.arturbosch.detekt.Detekt
import org.jooq.meta.jaxb.Property

val rootProjectDir = "$projectDir/../.."

Expand All @@ -13,8 +14,11 @@ plugins {
id("org.sonarqube") version "5.0.0.4638"
id("org.openapi.generator") version "7.8.0"
id("info.solidsoft.pitest") version "1.15.0"
id("nu.studer.jooq") version "6.0.1"
}

val schemaVersion by extra { "1" }

group = "mu.muse"
version = "1.0.0-SNAPSHOT"

Expand All @@ -38,6 +42,7 @@ springBoot {
}

repositories {
mavenLocal()
mavenCentral()
}

Expand All @@ -61,14 +66,16 @@ dependencies {
implementation("jakarta.validation:jakarta.validation-api:3.1.0") // `useSpringBoot3` param requires it
implementation("org.postgresql:postgresql")
implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
implementation("org.jooq:jooq:3.19.11")
jooqGenerator("org.jooq:jooq-meta-extensions:3.19.11")
}

tasks.named<Test>("test") {
useJUnitPlatform()
}

configure<org.jlleitschuh.gradle.ktlint.KtlintExtension> {
debug.set(true)
debug = true
verbose.set(true)
ignoreFailures.set(false)

Expand Down Expand Up @@ -145,3 +152,44 @@ pitest {
targetClasses = setOf("mu.muse.*")
timestampedReports = false
}

jooq {
version.set("3.19.11")
configurations {
create("main") {
jooqConfiguration.apply {
logging = org.jooq.meta.jaxb.Logging.WARN
generator.apply {
name = "org.jooq.codegen.KotlinGenerator"
database.apply {
name = "org.jooq.meta.extensions.ddl.DDLDatabase"
properties.apply {
add(Property().apply {
key = "scripts"
value = "./src/main/resources/db/schema.sql"
})
add(Property().apply {
key = "defaultNameCase"
value = "lower"
})
}
}

generate.apply {
isPojos = true
isPojosAsKotlinDataClasses = true
isImmutablePojos = true
isImmutableInterfaces = true
isGeneratedAnnotation = true
isGeneratedAnnotationDate = true
isInterfaces = true
}

target.apply {
packageName = "mu.muse.codegen.jooq"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package mu.muse.rest.dto

import java.util.Objects
import com.fasterxml.jackson.annotation.JsonProperty
import jakarta.validation.constraints.DecimalMax
import jakarta.validation.constraints.DecimalMin
import jakarta.validation.constraints.Email
import jakarta.validation.constraints.Max
import jakarta.validation.constraints.Min
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Pattern
import jakarta.validation.constraints.Size
import jakarta.validation.Valid

/**
*
* @param i18nCode
* @param localizedMessage
*/
data class ManufactureType(

@get:JsonProperty("i18n_code", required = true) val i18nCode: kotlin.String,

@get:JsonProperty("localized_message") val localizedMessage: kotlin.String? = null
) {

}

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import mu.muse.domain.user.UserId
import mu.muse.domain.user.Username
import mu.muse.usecase.access.instrument.InstrumentPersister
import mu.muse.usecase.access.user.UserPersister
import org.jooq.DSLContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ package mu.muse.application.muse

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import mu.muse.persistence.instrument.postgres.PostgresInstrumentIdGenerator
import mu.muse.persistence.instrument.postgres.PostgresInstrumentRepository
import mu.muse.persistence.user.postgres.PostgresUserIdGenerator
import mu.muse.persistence.user.postgres.PostgresUserRepository
import mu.muse.persistence.instrument.jooq.JooqPostgresInstrumentIdGenerator
import mu.muse.persistence.instrument.jooq.JooqPostgresInstrumentRepository
import mu.muse.persistence.user.jooq.JooqPostgresUserIdGenerator
import mu.muse.persistence.user.jooq.JooqPostgresUserRepository
import org.jooq.DSLContext
import org.jooq.SQLDialect
import org.jooq.impl.DSL
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
import javax.sql.DataSource

@Configuration
Expand Down Expand Up @@ -38,25 +40,25 @@ class PersistenceConfiguration {
}

@Bean
fun dataSource(hikariConfig: HikariConfig): DataSource = with(HikariDataSource(hikariConfig)) {
maximumPoolSize = MAXIMUM_POOL_SIZE
this
}
fun dataSource(hikariConfig: HikariConfig): DataSource =
with(HikariDataSource(hikariConfig)) {
maximumPoolSize = MAXIMUM_POOL_SIZE
this
}

@Bean
fun namedTemplate(dataSource: DataSource) = NamedParameterJdbcTemplate(dataSource)
fun dslContext(dataSource: DataSource): DSLContext = DSL.using(dataSource, SQLDialect.POSTGRES)

@Bean
fun userIdGenerator(namedTemplate: NamedParameterJdbcTemplate) = PostgresUserIdGenerator(namedTemplate)
fun userIdGenerator(dslContext: DSLContext) = JooqPostgresUserIdGenerator(dslContext)

@Bean
fun userRepository(namedTemplate: NamedParameterJdbcTemplate) = PostgresUserRepository(namedTemplate)
fun userRepository(dslContext: DSLContext) = JooqPostgresUserRepository(dslContext)

@Bean
fun instrumentIdGenerator(namedTemplate: NamedParameterJdbcTemplate) = PostgresInstrumentIdGenerator(namedTemplate)
fun instrumentIdGenerator(dslContext: DSLContext) = JooqPostgresInstrumentIdGenerator(dslContext)

@Bean
fun instrumentRepository(namedTemplate: NamedParameterJdbcTemplate) = PostgresInstrumentRepository(namedTemplate)

fun instrumentRepository(dslContext: DSLContext) = JooqPostgresInstrumentRepository(dslContext)

}
Loading

0 comments on commit e45a660

Please sign in to comment.