add migrationtest sql-dump-checksum-assertions to prevent accidental changes (#204)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/204 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
@@ -7,39 +7,29 @@ import lombok.SneakyThrows;
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
|
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
import org.junit.jupiter.api.extension.TestWatcher;
|
import org.junit.jupiter.api.extension.TestWatcher;
|
||||||
import org.opentest4j.AssertionFailedError;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.core.io.AbstractResource;
|
|
||||||
import org.springframework.core.io.ClassPathResource;
|
|
||||||
import org.springframework.core.io.FileSystemResource;
|
|
||||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.validation.ValidationException;
|
import jakarta.validation.ValidationException;
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -50,7 +40,6 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.mapper.Array.emptyArray;
|
import static net.hostsharing.hsadminng.mapper.Array.emptyArray;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
@@ -122,26 +111,6 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
return stream(lines.getFirst()).map(String::trim).toArray(String[]::new);
|
return stream(lines.getFirst()).map(String::trim).toArray(String[]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull AbstractResource resourceOf(final String sqlFile) {
|
|
||||||
return new File(sqlFile).exists()
|
|
||||||
? new FileSystemResource(sqlFile)
|
|
||||||
: new ClassPathResource(sqlFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Reader resourceReader(@NotNull final String resourcePath) {
|
|
||||||
try {
|
|
||||||
return new InputStreamReader(requireNonNull(resourceOf(resourcePath).getInputStream()));
|
|
||||||
} catch (final Exception exc) {
|
|
||||||
throw new AssertionFailedError("cannot open '" + resourcePath + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
protected String resourceAsString(final Resource resource) {
|
|
||||||
final var lines = Files.readAllLines(resource.getFile().toPath(), StandardCharsets.UTF_8);
|
|
||||||
return String.join("\n", lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected List<String[]> withoutHeader(final List<String[]> records) {
|
protected List<String[]> withoutHeader(final List<String[]> records) {
|
||||||
return records.subList(1, records.size());
|
return records.subList(1, records.size());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.migration;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.hostsharing.hsadminng.rbac.context.Context;
|
|
||||||
import net.hostsharing.hsadminng.hash.HashGenerator;
|
import net.hostsharing.hsadminng.hash.HashGenerator;
|
||||||
import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm;
|
import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm;
|
||||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||||
@@ -19,6 +18,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
|||||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityValidatorRegistry;
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityValidatorRegistry;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator;
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator;
|
||||||
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import org.apache.commons.collections4.ListUtils;
|
import org.apache.commons.collections4.ListUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -84,6 +84,9 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQ
|
|||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_INSTANCE;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_INSTANCE;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_USER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_USER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER;
|
||||||
|
import static net.hostsharing.hsadminng.hs.migration.ResourceUtil.resourceAsString;
|
||||||
|
import static net.hostsharing.hsadminng.hs.migration.ResourceUtil.resourceOf;
|
||||||
|
import static net.hostsharing.hsadminng.hs.migration.ResourceUtil.resourceReader;
|
||||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||||
@@ -143,6 +146,18 @@ public class ImportHostingAssets extends CsvDataImport {
|
|||||||
@Value("${HSADMINNG_OFFICE_DATA_SQL_FILE:/db/released-prod-schema-with-import-test-data.sql}")
|
@Value("${HSADMINNG_OFFICE_DATA_SQL_FILE:/db/released-prod-schema-with-import-test-data.sql}")
|
||||||
String officeSchemaAndDataSqlFile;
|
String officeSchemaAndDataSqlFile;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(10000)
|
||||||
|
@SneakyThrows
|
||||||
|
void baseSchemaDumpIsUnchanged() {
|
||||||
|
ResourceUtil.assertResourceHash(
|
||||||
|
officeSchemaAndDataSqlFile,
|
||||||
|
// Never change this hash!
|
||||||
|
// Except if you deliberately updated the reference SQL dump, e.g. after a prod release.
|
||||||
|
// It protects you from accidentally making changes, e.g. with search&replace.
|
||||||
|
"41e6e3ad7f2ba5de507219582d76fd33ebc93bef148f2ee2c25ae9b5b8c0f53b");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(11000)
|
@Order(11000)
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@@ -1961,6 +1976,7 @@ public class ImportHostingAssets extends CsvDataImport {
|
|||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private void executeSqlScript(final String sqlFile) {
|
private void executeSqlScript(final String sqlFile) {
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
|
|||||||
+16
-1
@@ -1,5 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.migration;
|
package net.hostsharing.hsadminng.hs.migration;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import org.junit.jupiter.api.Tag;
|
import org.junit.jupiter.api.Tag;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -43,9 +44,12 @@ import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TE
|
|||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@ActiveProfiles("liquibase-migration-test")
|
@ActiveProfiles("liquibase-migration-test")
|
||||||
@Import(LiquibaseConfig.class)
|
@Import(LiquibaseConfig.class)
|
||||||
@Sql(value = "/db/released-prod-schema-with-test-data.sql", executionPhase = BEFORE_TEST_CLASS) // release-schema
|
@Sql(value =
|
||||||
|
LiquibaseCompatibilityIntegrationTest.DB_RELEASED_PROD_SCHEMA_RESOURCE_WITH_TEST_DATA_SQL,
|
||||||
|
executionPhase = BEFORE_TEST_CLASS)
|
||||||
public class LiquibaseCompatibilityIntegrationTest {
|
public class LiquibaseCompatibilityIntegrationTest {
|
||||||
|
|
||||||
|
public static final String DB_RELEASED_PROD_SCHEMA_RESOURCE_WITH_TEST_DATA_SQL = "/db/released-prod-schema-with-test-data.sql";
|
||||||
private static final String EXPECTED_CHANGESET_ONLY_AFTER_NEW_MIGRATION = "hs-global-liquibase-migration-test";
|
private static final String EXPECTED_CHANGESET_ONLY_AFTER_NEW_MIGRATION = "hs-global-liquibase-migration-test";
|
||||||
private static final int EXPECTED_LIQUIBASE_CHANGELOGS_IN_PROD_SCHEMA_DUMP = 299;
|
private static final int EXPECTED_LIQUIBASE_CHANGELOGS_IN_PROD_SCHEMA_DUMP = 299;
|
||||||
|
|
||||||
@@ -55,6 +59,17 @@ public class LiquibaseCompatibilityIntegrationTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private LiquibaseMigration liquibase;
|
private LiquibaseMigration liquibase;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SneakyThrows
|
||||||
|
void baseSchemaDumpIsUnchanged() {
|
||||||
|
ResourceUtil.assertResourceHash(
|
||||||
|
DB_RELEASED_PROD_SCHEMA_RESOURCE_WITH_TEST_DATA_SQL,
|
||||||
|
// Never change this hash!
|
||||||
|
// Except, if you deliberately updated the reference SQL dump, e.g. after a prod release.
|
||||||
|
// It protects you from accidentally making changes, e.g. with search&replace.
|
||||||
|
"512216e4baeed3f5d988766ff79a79c2885c8c04fa54c61009bde3d4f4708d72");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void migrationWorksBasedOnAPreviouslyPopulatedSchema() {
|
void migrationWorksBasedOnAPreviouslyPopulatedSchema() {
|
||||||
// check the initial status from the @Sql-annotation
|
// check the initial status from the @Sql-annotation
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.migration;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import lombok.val;
|
||||||
|
import org.opentest4j.AssertionFailedError;
|
||||||
|
import org.springframework.core.io.AbstractResource;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.util.FileCopyUtils.copyToByteArray;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class ResourceUtil {
|
||||||
|
|
||||||
|
public void assertResourceHash(final String givenResourceOrFileName, final String expectedHash) throws IOException,
|
||||||
|
NoSuchAlgorithmException {
|
||||||
|
try (val inputStream = resourceOf(givenResourceOrFileName).getInputStream()) {
|
||||||
|
val fileContent = copyToByteArray(inputStream);
|
||||||
|
val digest = MessageDigest.getInstance("SHA-256");
|
||||||
|
val hashBytes = digest.digest(fileContent);
|
||||||
|
val hashHex = bytesToHex(hashBytes);
|
||||||
|
assertThat(hashHex).isEqualTo(expectedHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String bytesToHex(byte[] bytes) {
|
||||||
|
val result = new StringBuilder();
|
||||||
|
for (byte b : bytes) {
|
||||||
|
result.append(String.format("%02x", b));
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull AbstractResource resourceOf(final String sqlFile) {
|
||||||
|
return new File(sqlFile).exists()
|
||||||
|
? new FileSystemResource(sqlFile)
|
||||||
|
: new ClassPathResource(sqlFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Reader resourceReader(@NotNull final String resourcePath) {
|
||||||
|
try {
|
||||||
|
return new InputStreamReader(requireNonNull(resourceOf(resourcePath).getInputStream()));
|
||||||
|
} catch (final Exception exc) {
|
||||||
|
throw new AssertionFailedError("cannot open '" + resourcePath + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static String resourceAsString(final Resource resource) {
|
||||||
|
final var lines = Files.readAllLines(resource.getFile().toPath(), StandardCharsets.UTF_8);
|
||||||
|
return String.join("\n", lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12750,7 +12750,7 @@ INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, ordere
|
|||||||
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('rbactest-domain-rbac-update-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/2-rbactest/203-rbactest-domain/2033-rbactest-domain-rbac.sql', '2025-06-06 10:23:06.53273', 309, 'RERAN', '9:4d2cdd1bc08df6985622d0c5953bf4ba', 'sql', '', NULL, '4.29.2', '!without-test-data', NULL, '9198184942');
|
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('rbactest-domain-rbac-update-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/2-rbactest/203-rbactest-domain/2033-rbactest-domain-rbac.sql', '2025-06-06 10:23:06.53273', 309, 'RERAN', '9:4d2cdd1bc08df6985622d0c5953bf4ba', 'sql', '', NULL, '4.29.2', '!without-test-data', NULL, '9198184942');
|
||||||
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-contact-rbac-insert-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/5-hs-office/501-contact/5013-hs-office-contact-rbac.sql', '2025-06-06 10:23:06.581665', 310, 'RERAN', '9:b29cf6087a2225d235637a187b5946c2', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-contact-rbac-insert-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/5-hs-office/501-contact/5013-hs-office-contact-rbac.sql', '2025-06-06 10:23:06.581665', 310, 'RERAN', '9:b29cf6087a2225d235637a187b5946c2', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
||||||
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-person-rbac-insert-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/5-hs-office/502-person/5023-hs-office-person-rbac.sql', '2025-06-06 10:23:06.611557', 311, 'RERAN', '9:9adfbff372bce3de87410eb7582869f2', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-person-rbac-insert-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/5-hs-office/502-person/5023-hs-office-person-rbac.sql', '2025-06-06 10:23:06.611557', 311, 'RERAN', '9:9adfbff372bce3de87410eb7582869f2', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
||||||
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-person-TEST-DATA-GENERATION-FOR-CREDENTIALS', 'michael.hoennig', 'db/changelog/5-hs-office/502-person/5028-hs-office-person-test-data-for-accounts.sql', '2025-06-06 10:23:06.727793', 312, 'EXECUTED', '9:cf05c4705d539d4ea7b0199921f8cc78', 'sql', '', NULL, '4.29.2', '!without-test-data AND !without-test-data', NULL, '9198184942');
|
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-person-TEST-DATA-GENERATION-FOR-CREDENTIALS', 'michael.hoennig', 'db/changelog/5-hs-office/502-person/5028-hs-office-person-test-data-for-credentials.sql', '2025-06-06 10:23:06.727793', 312, 'EXECUTED', '9:cf05c4705d539d4ea7b0199921f8cc78', 'sql', '', NULL, '4.29.2', '!without-test-data AND !without-test-data', NULL, '9198184942');
|
||||||
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-relation-debitor-anchor-CONSTRAINT-BY-TRIGGER', 'marc.sandlus', 'db/changelog/5-hs-office/503-relation/5030-hs-office-relation.sql', '2025-06-06 10:23:06.759158', 313, 'EXECUTED', '9:0623a018f7494b53f87b01d88bc3fa41', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-relation-debitor-anchor-CONSTRAINT-BY-TRIGGER', 'marc.sandlus', 'db/changelog/5-hs-office/503-relation/5030-hs-office-relation.sql', '2025-06-06 10:23:06.759158', 313, 'EXECUTED', '9:0623a018f7494b53f87b01d88bc3fa41', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
||||||
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-relation-rbac-insert-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/5-hs-office/503-relation/5033-hs-office-relation-rbac.sql', '2025-06-06 10:23:06.7945', 314, 'RERAN', '9:6fc1a046dcd803edfb0ce77cd127b576', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-relation-rbac-insert-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/5-hs-office/503-relation/5033-hs-office-relation-rbac.sql', '2025-06-06 10:23:06.7945', 314, 'RERAN', '9:6fc1a046dcd803edfb0ce77cd127b576', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
||||||
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-relation-rbac-update-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/5-hs-office/503-relation/5033-hs-office-relation-rbac.sql', '2025-06-06 10:23:06.835025', 315, 'RERAN', '9:6737dfa739a4b9036f3e9e8224019276', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
INSERT INTO public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) VALUES ('hs-office-relation-rbac-update-trigger', 'RolesGrantsAndPermissionsGenerator', 'db/changelog/5-hs-office/503-relation/5033-hs-office-relation-rbac.sql', '2025-06-06 10:23:06.835025', 315, 'RERAN', '9:6737dfa739a4b9036f3e9e8224019276', 'sql', '', NULL, '4.29.2', NULL, NULL, '9198184942');
|
||||||
|
|||||||
Reference in New Issue
Block a user