Skip to content

User specified database cleanup #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions src/main/java/com/exasol/dbcleaner/CleanRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.exasol.dbcleaner;

/**
* A request enabling the user to enable or disable the drop of certain database objects
* while using {@link ExasolDatabaseCleaner}.
*/
public final class CleanRequest {
private final boolean cleanObjects;
private final boolean cleanConnections;
private final boolean cleanUsers;
private final boolean cleanRoles;

/**
* Create an instance of {@link CleanRequestBuilder}
* @return instance of {@link CleanRequestBuilder}
*/
public static CleanRequestBuilder builder() {
return new CleanRequestBuilder();
}

CleanRequest(final boolean cleanObjects, final boolean cleanConnections, final boolean cleanUsers, final boolean cleanRoles) {
this.cleanObjects = cleanObjects;
this.cleanConnections = cleanConnections;
this.cleanUsers = cleanUsers;
this.cleanRoles = cleanRoles;
}

/**
* Should all database objects be dropped?
* @return true if all objects should be dropped
*/
public boolean isCleanObjects() {
return cleanObjects;
}

/**
* Should all connections be dropped?
* @return true if all connections should be dropped
*/
public boolean isCleanConnections() {
return cleanConnections;
}

/**
* Should all user be dropped?
* @return true if users should be dropped
*/
public boolean isCleanUsers() {
return cleanUsers;
}

/**
* Should all roles be dropped?
* @return true if all roles should be dropped
*/
public boolean isCleanRoles() {
return cleanRoles;
}

/**
* Should everything be dropped?
* @return true if everything should be dropped
*/
public boolean isCleanAll() {
return cleanObjects && cleanConnections && cleanUsers && cleanRoles;
}
}
62 changes: 62 additions & 0 deletions src/main/java/com/exasol/dbcleaner/CleanRequestBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.exasol.dbcleaner;

/**
* Builder to create instances of {@link CleanRequest}.
*/
public class CleanRequestBuilder {
private boolean cleanObjects = true;
private boolean cleanConnections = true;
private boolean cleanUsers = true;
private boolean cleanRoles = true;

CleanRequestBuilder() {
}

/**
* Set whether database objects should be dropped
* @param cleanObjects true if all database objects should be dropped
* @return itself to enable chaining
*/
public CleanRequestBuilder setCleanObjects(final boolean cleanObjects) {
this.cleanObjects = cleanObjects;
return this;
}

/**
* Set whether connections should be dropped
* @param cleanConnections true if all connections should be dropped
* @return itself to enable chaining
*/
public CleanRequestBuilder setCleanConnections(final boolean cleanConnections) {
this.cleanConnections = cleanConnections;
return this;
}

/**
* Set whether users should be dropped
* @param cleanUsers true if all users should be dropped
* @return itself to enable chaining
*/
public CleanRequestBuilder setCleanUsers(final boolean cleanUsers) {
this.cleanUsers = cleanUsers;
return this;
}

/**
* Set whether roles should be dropped
* @param cleanRoles true if all roles should be dropped
* @return itself to enable chaining
*/
public CleanRequestBuilder setCleanRoles(final boolean cleanRoles) {
this.cleanRoles = cleanRoles;
return this;
}

/**
* Build the instance of {@link CleanRequest}.
* @return the instance of {@link CleanRequest}.
*/
public CleanRequest build() {
return new CleanRequest(cleanObjects, cleanConnections, cleanUsers, cleanRoles);
}
}
35 changes: 33 additions & 2 deletions src/main/java/com/exasol/dbcleaner/ExasolDatabaseCleaner.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.exasol.dbcleaner;

import java.sql.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Logger;

Expand All @@ -13,7 +15,7 @@ public class ExasolDatabaseCleaner {

/**
* Create a new instance of {@link ExasolDatabaseCleaner}.
*
*
* @param statement SQL statement to the Exasol database
*/
public ExasolDatabaseCleaner(final Statement statement) {
Expand All @@ -32,6 +34,35 @@ public void cleanDatabase() throws SQLException {
purgeRoles();
}

/**
* Drop all database objects request in {@link CleanRequest}.
*
* @param cleanRequest instance of {@link CleanRequest} the defines which objects to drop
* @throws SQLException if failed to delete an object
*/
public void cleanDatabase(final CleanRequest cleanRequest) throws SQLException {
if (cleanRequest.isCleanAll()) {
cleanDatabase();
} else {
cleanDatabaseAsRequested(cleanRequest);
}
}

private void cleanDatabaseAsRequested(final CleanRequest cleanRequest) throws SQLException {
if (cleanRequest.isCleanObjects()) {
purgeObjects();
}
if (cleanRequest.isCleanConnections()) {
purgeConnections();
}
if (cleanRequest.isCleanUsers()) {
purgeUsers();
}
if (cleanRequest.isCleanRoles()) {
purgeRoles();
}
}

private void purgeConnections() throws SQLException {
try (final ResultSet resultSet = this.statement
.executeQuery("SELECT CONNECTION_NAME FROM EXA_ALL_CONNECTIONS")) {
Expand Down
24 changes: 24 additions & 0 deletions src/test/java/com/exasol/dbcleaner/CleanRequestBuilderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.exasol.dbcleaner;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertFalse;

class CleanRequestBuilderTest {

@Test
Comment on lines +8 to +9

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Test
@Test

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

void test_build() {
final CleanRequest underTest = CleanRequest.builder()
.setCleanConnections(false)
.setCleanObjects(false)
.setCleanUsers(false)
.setCleanRoles(false)
.build();

assertFalse(underTest.isCleanConnections());
assertFalse(underTest.isCleanAll());
assertFalse(underTest.isCleanObjects());
assertFalse(underTest.isCleanRoles());
assertFalse(underTest.isCleanUsers());
}
}
104 changes: 103 additions & 1 deletion src/test/java/com/exasol/dbcleaner/ExasolDatabaseCleanerIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import java.sql.SQLException;
import java.sql.Statement;

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

Expand Down Expand Up @@ -39,6 +41,22 @@ void testPurgeSchema() throws SQLException {
assertDoesNotThrow(this::createSchema);
}

@Test
void testPurgeSchema_userSpecified() throws SQLException {
createSchema();

final CleanRequest request = CleanRequest.builder()
.setCleanConnections(false)
.setCleanRoles(false)
.setCleanUsers(false)
.setCleanConnections(false)
.setCleanObjects(true)
.build();

CLEANER.cleanDatabase(request);
assertDoesNotThrow(this::createSchema);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tests only if the object is deleted, not if the other ones are untouched. 50% done. :-)

}

@Test
void testPurgeTable() throws SQLException {
createSchema();
Expand All @@ -48,27 +66,95 @@ void testPurgeTable() throws SQLException {
assertDoesNotThrow(this::createTable);
}

@Test
void testPurgeTable_userSpecified() throws SQLException {
createSchema();
createTable();

final CleanRequest request = CleanRequest.builder()
.setCleanConnections(false)
.setCleanRoles(false)
.setCleanUsers(false)
.setCleanConnections(false)
.setCleanObjects(true)
.build();

CLEANER.cleanDatabase(request);

createSchema();
assertDoesNotThrow(this::createTable);
}

@Test
void testPurgeConnection() throws SQLException {
createConnection();
CLEANER.cleanDatabase();
assertDoesNotThrow(this::createConnection);
}

@Test
void testPurgeConnection_userSpecified() throws SQLException {
createConnection();

final CleanRequest request = CleanRequest.builder()
.setCleanConnections(true)
.setCleanRoles(false)
.setCleanUsers(false)
.setCleanConnections(false)
.setCleanObjects(false)
.build();

CLEANER.cleanDatabase(request);
assertDoesNotThrow(this::createConnection);
}

@Test
void testPurgeUser() throws SQLException {
createUser();
CLEANER.cleanDatabase();
assertDoesNotThrow(this::createUser);
}

@Test
void testPurgeUser_userSpecified() throws SQLException {
createUser();

final CleanRequest request = CleanRequest.builder()
.setCleanConnections(false)
.setCleanRoles(false)
.setCleanUsers(true)
.setCleanConnections(false)
.setCleanObjects(false)
.build();

CLEANER.cleanDatabase(request);
assertDoesNotThrow(this::createUser);
}

@Test
void testPurgeRole() throws SQLException {
createRole();
CLEANER.cleanDatabase();
assertDoesNotThrow(this::createRole);
}

@Test
void testPurgeRole_userSpecified() throws SQLException {
createRole();

final CleanRequest request = CleanRequest.builder()
.setCleanConnections(false)
.setCleanRoles(true)
.setCleanUsers(false)
.setCleanConnections(false)
.setCleanObjects(false)
.build();

CLEANER.cleanDatabase(request);

assertDoesNotThrow(this::createRole);
}

@Test
void testPurgeFunction() throws SQLException {
createFunction("S1");
Expand All @@ -84,6 +170,22 @@ void testPurgeFunctionWithNonImplicitSchemaName() throws SQLException {
assertDoesNotThrow(() -> createFunction("S1"));
}

@Test
void testPurgeFunction_userSpecified() throws SQLException {
createFunction("S1");

final CleanRequest request = CleanRequest.builder()
.setCleanConnections(false)
.setCleanRoles(false)
.setCleanUsers(false)
.setCleanConnections(false)
.setCleanObjects(true)
.build();

CLEANER.cleanDatabase(request);
assertDoesNotThrow(() -> createFunction("S1"));
}

private void createFunction(final String schemaName) throws SQLException {
STATEMENT.executeUpdate("CREATE SCHEMA " + schemaName + ";");
STATEMENT.executeUpdate("CREATE FUNCTION " + schemaName
Expand Down