Skip to content
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

Add enrichSequenceWithSchema method #423

Merged
merged 2 commits into from
Jun 23, 2024
Merged
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
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ description = "pg-index-health build"

allprojects {
group = "io.github.mfvanek"
version = "0.12.1"
version = "0.13.0"

repositories {
mavenLocal()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* New "generated as identity" syntax should be used instead.
*
* @author Vadim Khizhin
* @since 0.12.1
* @since 0.13.0
*/
public class PrimaryKeysWithSerialTypesCheckOnHost extends AbstractCheckOnHost<ColumnWithSerialType> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.Locale;

import static io.github.mfvanek.pg.support.AbstractCheckOnHostAssert.assertThat;

class ColumnsWithSerialTypesCheckOnHostTest extends DatabaseAwareTestBase {
Expand All @@ -46,9 +44,9 @@ void onDatabaseWithThem(final String schemaName) {
.hasSize(2)
.containsExactly(
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_account_id"), String.format(Locale.ROOT, "%s.bad_accounts_real_account_id_seq", schemaName)),
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_account_id"), ctx.enrichSequenceWithSchema("bad_accounts_real_account_id_seq")),
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_client_id"), String.format(Locale.ROOT, "%s.bad_accounts_real_client_id_seq", schemaName))
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_client_id"), ctx.enrichSequenceWithSchema("bad_accounts_real_client_id_seq"))
));
}

Expand All @@ -61,7 +59,7 @@ void shouldIgnoreDroppedColumns(final String schemaName) {
.hasSize(1)
.containsExactly(
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_client_id"), String.format(Locale.ROOT, "%s.bad_accounts_real_client_id_seq", schemaName))
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_client_id"), ctx.enrichSequenceWithSchema("bad_accounts_real_client_id_seq"))
));
}

Expand All @@ -83,7 +81,7 @@ void shouldDetectSerialColumnsWithUniqueConstraints(final String schemaName) {
.hasSize(1)
.containsExactly(
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("one_more_table"), "id"), String.format(Locale.ROOT, "%s.one_more_table_id_seq", schemaName))
Column.ofNotNull(ctx.enrichWithSchema("one_more_table"), "id"), ctx.enrichSequenceWithSchema("one_more_table_id_seq"))
));
}

Expand All @@ -96,11 +94,11 @@ void shouldDetectPrimaryKeysThatAreForeignKeysAsWell(final String schemaName) {
.hasSize(3)
.containsExactly(
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("one_more_table"), "id"), String.format(Locale.ROOT, "%s.one_more_table_id_seq", schemaName)),
Column.ofNotNull(ctx.enrichWithSchema("one_more_table"), "id"), ctx.enrichSequenceWithSchema("one_more_table_id_seq")),
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("test_table"), "id"), String.format(Locale.ROOT, "%s.test_table_id_seq", schemaName)),
Column.ofNotNull(ctx.enrichWithSchema("test_table"), "id"), ctx.enrichSequenceWithSchema("test_table_id_seq")),
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("test_table"), "num"), String.format(Locale.ROOT, "%s.test_table_num_seq", schemaName))
Column.ofNotNull(ctx.enrichWithSchema("test_table"), "num"), ctx.enrichSequenceWithSchema("test_table_num_seq"))
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.junit.jupiter.params.provider.ValueSource;

import java.util.List;
import java.util.Locale;

import static io.github.mfvanek.pg.support.AbstractCheckOnHostAssert.assertThat;

Expand Down Expand Up @@ -52,8 +51,7 @@ void onDatabaseWithThem(final String schemaName) {

ExecuteUtils.executeOnDatabase(getDataSource(), statement -> {
for (final Constraint constraint : notValidConstraints) {
statement.execute(String.format(Locale.ROOT, "alter table %s validate constraint %s;",
constraint.getTableName(), constraint.getConstraintName()));
statement.execute(constraint.getValidateSql());
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.Locale;

import static io.github.mfvanek.pg.support.AbstractCheckOnHostAssert.assertThat;

class PrimaryKeysWithSerialTypesCheckOnHostTest extends DatabaseAwareTestBase {
Expand All @@ -45,7 +43,7 @@ void onDatabaseWithThem(final String schemaName) {
.hasSize(1)
.containsExactlyInAnyOrder(
ColumnWithSerialType.of(
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "id"), SerialType.BIG_SERIAL, String.format(Locale.ROOT, "%s.bad_accounts_id_seq", schemaName)
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "id"), SerialType.BIG_SERIAL, ctx.enrichSequenceWithSchema("bad_accounts_id_seq")
)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,11 @@ public String toString() {
}

/**
* Complement the given object name with the specified schema name if it is necessary.
* Complement the given object (table or index) name with the specified schema name if it is necessary.
*
* @param objectName given object name
* @return object name with schema for non default schemas
* @see #enrichSequenceWithSchema
*/
@Nonnull
public String enrichWithSchema(@Nonnull final String objectName) {
Expand All @@ -109,6 +110,25 @@ public String enrichWithSchema(@Nonnull final String objectName) {
return objectName;
}

return enrichWithSchemaIfNeed(objectName);
}

/**
* Complement the given sequence name with the specified schema name if it is necessary.
*
* @param sequenceName given sequence name
* @return sequence name with schema for all schemas
* @see #enrichWithSchema
*/
@Nonnull
public String enrichSequenceWithSchema(@Nonnull final String sequenceName) {
Validators.notBlank(sequenceName, "sequenceName");

return enrichWithSchemaIfNeed(sequenceName);
}

@Nonnull
private String enrichWithSchemaIfNeed(@Nonnull final String objectName) {
final String prefix = schemaName + ".";
if (objectName.toLowerCase(Locale.ROOT).startsWith(prefix)) {
return objectName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.github.mfvanek.pg.model.table.TableNameAware;
import io.github.mfvanek.pg.model.validation.Validators;

import java.util.Locale;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
Expand Down Expand Up @@ -135,6 +136,17 @@ public String toString() {
'}';
}

/**
* Builds and returns sql query to validate current constraint.
*
* @return sql query to validate current constraint
* @see <a href="https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-DESC-VALIDATE-CONSTRAINT">VALIDATE CONSTRAINT</a>
*/
@Nonnull
public String getValidateSql() {
return String.format(Locale.ROOT, "alter table %s validate constraint %s;", tableName, constraintName);
}

/**
* Constructs a {@code Constraint} object with given {@code ConstraintType}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,41 @@ void testToString() {
@Test
void complementWithCustomSchema() {
final PgContext pgContext = PgContext.of("TEST");
assertThat(pgContext.enrichWithSchema("table1")).isEqualTo("test.table1");
assertThat(pgContext.enrichWithSchema("index1")).isEqualTo("test.index1");
assertThat(pgContext.enrichWithSchema("test.table2")).isEqualTo("test.table2");
assertThat(pgContext.enrichWithSchema("TEST.table2")).isEqualTo("TEST.table2");
assertThat(pgContext.enrichWithSchema("table1"))
.isEqualTo("test.table1");
assertThat(pgContext.enrichWithSchema("index1"))
.isEqualTo("test.index1");
assertThat(pgContext.enrichWithSchema("test.table2"))
.isEqualTo("test.table2");
assertThat(pgContext.enrichWithSchema("TEST.table2"))
.isEqualTo("TEST.table2");

assertThat(pgContext.enrichSequenceWithSchema("id_seq"))
.isEqualTo("test.id_seq");
assertThat(pgContext.enrichSequenceWithSchema("test.id_seq"))
.isEqualTo("test.id_seq");
assertThat(pgContext.enrichSequenceWithSchema("TEST.id_seq"))
.isEqualTo("TEST.id_seq");
}

@Test
void complementWithPublicSchema() {
final PgContext pgContext = PgContext.ofPublic();
assertThat(pgContext.enrichWithSchema("table1")).isEqualTo("table1");
assertThat(pgContext.enrichWithSchema("index1")).isEqualTo("index1");
assertThat(pgContext.enrichWithSchema("public.table2")).isEqualTo("public.table2");
assertThat(pgContext.enrichWithSchema("PUBLIC.table2")).isEqualTo("PUBLIC.table2");
assertThat(pgContext.enrichWithSchema("table1"))
.isEqualTo("table1");
assertThat(pgContext.enrichWithSchema("index1"))
.isEqualTo("index1");
assertThat(pgContext.enrichWithSchema("public.table2"))
.isEqualTo("public.table2");
assertThat(pgContext.enrichWithSchema("PUBLIC.table2"))
.isEqualTo("PUBLIC.table2");

assertThat(pgContext.enrichSequenceWithSchema("id_seq"))
.isEqualTo("public.id_seq");
assertThat(pgContext.enrichSequenceWithSchema("public.id_seq"))
.isEqualTo("public.id_seq");
assertThat(pgContext.enrichSequenceWithSchema("PUBLIC.id_seq"))
.isEqualTo("PUBLIC.id_seq");
}

@SuppressWarnings("ConstantConditions")
Expand All @@ -113,5 +135,15 @@ void complementWithSchemaWithInvalidArguments() {
assertThatThrownBy(() -> pgContext.enrichWithSchema(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("objectName cannot be blank");

assertThatThrownBy(() -> pgContext.enrichSequenceWithSchema(null))
.isInstanceOf(NullPointerException.class)
.hasMessage("sequenceName cannot be null");
assertThatThrownBy(() -> pgContext.enrichSequenceWithSchema(""))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("sequenceName cannot be blank");
assertThatThrownBy(() -> pgContext.enrichSequenceWithSchema(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("sequenceName cannot be blank");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ void withInvalidArguments() {
@SuppressWarnings("ConstantConditions")
@Test
void equalsAndHashCode() {
final Constraint first = new Constraint("t", "not_valid_id", ConstraintType.CHECK);
final Constraint theSame = new Constraint("t", "not_valid_id", ConstraintType.CHECK);
final Constraint different = new Constraint("t", "valid_id", ConstraintType.CHECK);
final Constraint constraintTypeDoesntMatter = new Constraint("t", "not_valid_id", ConstraintType.FOREIGN_KEY);
final Constraint third = new Constraint("t1", "not_valid_id", ConstraintType.FOREIGN_KEY);
final Constraint first = Constraint.ofType("t", "not_valid_id", ConstraintType.CHECK);
final Constraint theSame = Constraint.ofType("t", "not_valid_id", ConstraintType.CHECK);
final Constraint different = Constraint.ofType("t", "valid_id", ConstraintType.CHECK);
final Constraint constraintTypeDoesntMatter = Constraint.ofType("t", "not_valid_id", ConstraintType.FOREIGN_KEY);
final Constraint third = Constraint.ofType("t1", "not_valid_id", ConstraintType.FOREIGN_KEY);

assertThat(first.equals(null)).isFalse();
//noinspection EqualsBetweenInconvertibleTypes
Expand Down Expand Up @@ -113,4 +113,12 @@ void equalsHashCodeShouldAdhereContracts() {
.withIgnoredFields("constraintType")
.verify();
}

@Test
void getValidateSqlShouldWork() {
assertThat(Constraint.ofType("t", "not_valid_id", ConstraintType.CHECK).getValidateSql())
.isEqualTo("alter table t validate constraint not_valid_id;");
assertThat(Constraint.ofType("custom_schema.t", "not_valid_id", ConstraintType.CHECK).getValidateSql())
.isEqualTo("alter table custom_schema.t validate constraint not_valid_id;");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* New "generated as identity" syntax should be used instead.
*
* @author Vadim Khizhin
* @since 0.12.1
* @since 0.13.0
*/
public class PrimaryKeysWithSerialTypesCheckOnCluster extends AbstractCheckOnCluster<ColumnWithSerialType> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.Locale;

import static org.assertj.core.api.Assertions.assertThat;

class ColumnsWithSerialTypesCheckOnClusterTest extends DatabaseAwareTestBase {
Expand All @@ -44,9 +42,9 @@ void onDatabaseWithThem(final String schemaName) {
.hasSize(2)
.containsExactly(
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_account_id"), String.format(Locale.ROOT, "%s.bad_accounts_real_account_id_seq", schemaName)),
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_account_id"), ctx.enrichSequenceWithSchema("bad_accounts_real_account_id_seq")),
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_client_id"), String.format(Locale.ROOT, "%s.bad_accounts_real_client_id_seq", schemaName)));
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_client_id"), ctx.enrichSequenceWithSchema("bad_accounts_real_client_id_seq")));

assertThat(check.check(ctx, FilterTablesByNamePredicate.of(ctx.enrichWithSchema("bad_accounts"))))
.isEmpty();
Expand All @@ -61,7 +59,7 @@ void shouldIgnoreDroppedColumns(final String schemaName) {
.hasSize(1)
.containsExactly(
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_client_id"), String.format(Locale.ROOT, "%s.bad_accounts_real_client_id_seq", schemaName))
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "real_client_id"), ctx.enrichSequenceWithSchema("bad_accounts_real_client_id_seq"))
));
}

Expand All @@ -81,7 +79,7 @@ void shouldDetectSerialColumnsWithUniqueConstraints(final String schemaName) {
.hasSize(1)
.containsExactly(
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("one_more_table"), "id"), String.format(Locale.ROOT, "%s.one_more_table_id_seq", schemaName))
Column.ofNotNull(ctx.enrichWithSchema("one_more_table"), "id"), ctx.enrichSequenceWithSchema("one_more_table_id_seq"))
));
}

Expand All @@ -93,11 +91,11 @@ void shouldDetectPrimaryKeysThatAreForeignKeysAsWell(final String schemaName) {
.hasSize(3)
.containsExactly(
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("one_more_table"), "id"), String.format(Locale.ROOT, "%s.one_more_table_id_seq", schemaName)),
Column.ofNotNull(ctx.enrichWithSchema("one_more_table"), "id"), ctx.enrichSequenceWithSchema("one_more_table_id_seq")),
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("test_table"), "id"), String.format(Locale.ROOT, "%s.test_table_id_seq", schemaName)),
Column.ofNotNull(ctx.enrichWithSchema("test_table"), "id"), ctx.enrichSequenceWithSchema("test_table_id_seq")),
ColumnWithSerialType.ofBigSerial(
Column.ofNotNull(ctx.enrichWithSchema("test_table"), "num"), String.format(Locale.ROOT, "%s.test_table_num_seq", schemaName))
Column.ofNotNull(ctx.enrichWithSchema("test_table"), "num"), ctx.enrichSequenceWithSchema("test_table_num_seq"))
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.junit.jupiter.params.provider.ValueSource;

import java.util.List;
import java.util.Locale;

import static org.assertj.core.api.Assertions.assertThat;

Expand Down Expand Up @@ -53,8 +52,7 @@ void onDatabaseWithThem(final String schemaName) {

ExecuteUtils.executeOnDatabase(getDataSource(), statement -> {
for (final Constraint constraint : notValidConstraints) {
statement.execute(String.format(Locale.ROOT, "alter table %s validate constraint %s;",
constraint.getTableName(), constraint.getConstraintName()));
statement.execute(constraint.getValidateSql());
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.Locale;

import static org.assertj.core.api.Assertions.assertThat;

class PrimaryKeysWithSerialTypesCheckOnClusterTest extends DatabaseAwareTestBase {
Expand All @@ -42,7 +40,7 @@ void onDatabaseWithThem(final String schemaName) {
.hasSize(1)
.containsExactlyInAnyOrder(
ColumnWithSerialType.of(
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "id"), SerialType.BIG_SERIAL, String.format(Locale.ROOT, "%s.bad_accounts_id_seq", schemaName)
Column.ofNotNull(ctx.enrichWithSchema("bad_accounts"), "id"), SerialType.BIG_SERIAL, ctx.enrichSequenceWithSchema("bad_accounts_id_seq")
)));
}

Expand Down