Skip to content

Commit

Permalink
[BE] Truncate 를 위한 DatabaseCleanup 구현 (#118)
Browse files Browse the repository at this point in the history
* [Docs] GitHub Issue 및 PR Template 설정 (#37)

* chore: .gitignore 추가

* chore: GitHub PR 및 Issue Template

* Revert "chore: GitHub PR 및 Issue Template"

This reverts commit 65915f7.

* Revert "chore: .gitignore 추가"

This reverts commit 1e1865a.

* chore: .gitignore 추가

* chore: GitHub Issue 및 PR Template 추가

* [Docs] GitHub Issue Template 파일명 오류 수정 (#39)

* chore: .gitignore 추가

* chore: GitHub PR 및 Issue Template

* Revert "chore: GitHub PR 및 Issue Template"

This reverts commit 65915f7.

* Revert "chore: .gitignore 추가"

This reverts commit 1e1865a.

* chore: .gitignore 추가

* chore: GitHub Issue 및 PR Template 추가

* chore: GitHub Issue 및 PR Template 추가

* test : Database Truncate 위한 DatabaseCleanup 구현

* style : 코드 컨벤션으로 인한 개행 추가

* refactor : @service -> @component 및 guava 의존성 제거

* fix: guava import 문 제거

* refactor: 메서드, 변수 분리

* refactor: disable/enable Referential query 상수로 변환

---------

Co-authored-by: 준팍(junpak) <[email protected]>
  • Loading branch information
kpeel5839 and junpakPark authored Aug 1, 2023
1 parent 5053383 commit c88b86e
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 3 deletions.
98 changes: 98 additions & 0 deletions backend/src/test/java/com/mapbefine/mapbefine/DatabaseCleanup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.mapbefine.mapbefine;

import jakarta.persistence.Entity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.metamodel.EntityType;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class DatabaseCleanup implements InitializingBean {

private static final String TRUNCATE_SQL_MESSAGE = "TRUNCATE TABLE %s";
private static final String ID_RESET_SQL_MESSAGE = "ALTER TABLE %s ALTER COLUMN ID RESTART WITH 1";
private static final String SET_REFERENTIAL_INTEGRITY_SQL_MESSAGE = "SET REFERENTIAL_INTEGRITY %s";
private static final String UNDERSCORE = "_";
private static final String DISABLE_REFERENTIAL_QUERY = String.format(SET_REFERENTIAL_INTEGRITY_SQL_MESSAGE, false);
private static final String ENABLE_REFERENTIAL_QUERY = String.format(SET_REFERENTIAL_INTEGRITY_SQL_MESSAGE, true);

@PersistenceContext
private EntityManager entityManager;

private List<String> tableNames;

@Override
public void afterPropertiesSet() {
Set<EntityType<?>> entities = entityManager.getMetamodel()
.getEntities();

tableNames = entities.stream()
.filter(this::isEntity)
.map(this::convertTableNameFromCamelCaseToSnakeCase)
.toList();
}

private boolean isEntity(final EntityType<?> entityType) {
return entityType.getJavaType()
.getAnnotation(Entity.class) != null;
}

private String convertTableNameFromCamelCaseToSnakeCase(EntityType<?> entityType) {
StringBuilder tableNameSnake = new StringBuilder();
String classNameOfEntity = entityType.getName();

for (char letter : classNameOfEntity.toCharArray()) {
addUnderScoreForCapitalLetter(tableNameSnake, letter);
tableNameSnake.append(letter);
}

return tableNameSnake.substring(1).toLowerCase();
}

private void addUnderScoreForCapitalLetter(StringBuilder tableNameSnake, char letter) {
if (Character.isUpperCase(letter)) {
tableNameSnake.append(UNDERSCORE);
}
}

@Transactional
public void execute() {
executeSqlWithReferentialIntegrityDisabled(this::executeTruncate);
}

private void executeSqlWithReferentialIntegrityDisabled(Runnable sqlExecutor) {
disableReferentialIntegrity();
sqlExecutor.run();
enableReferentialIntegrity();
}

private void disableReferentialIntegrity() {
entityManager.flush();

entityManager.createNativeQuery(DISABLE_REFERENTIAL_QUERY)
.executeUpdate();
}

private void enableReferentialIntegrity() {

entityManager.createNativeQuery(ENABLE_REFERENTIAL_QUERY)
.executeUpdate();
}

private void executeTruncate() {
for (String tableName : tableNames) {
String TRUNCATE_QUERY = String.format(TRUNCATE_SQL_MESSAGE, tableName);
String ID_RESET_QUERY = String.format(ID_RESET_SQL_MESSAGE, tableName);

entityManager.createNativeQuery(TRUNCATE_QUERY)
.executeUpdate();
entityManager.createNativeQuery(ID_RESET_QUERY)
.executeUpdate();
}
}

}
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
package com.mapbefine.mapbefine.integration;

import com.mapbefine.mapbefine.DatabaseCleanup;
import io.restassured.RestAssured;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.context.jdbc.Sql;

@Sql("/initialization.sql")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class IntegrationTest {

@LocalServerPort
int port;
private int port;

@Autowired
private DatabaseCleanup databaseCleanup;

@BeforeEach
public void setUp() {
RestAssured.port = port;
}

@AfterEach
public void tearDown() {
databaseCleanup.execute();
}

}

0 comments on commit c88b86e

Please sign in to comment.