Repair TIME projection and DOC enum migrations

This commit is contained in:
trifonovt 2026-05-18 14:02:54 +02:00
parent 253845e9ea
commit 142b0a5809
5 changed files with 224 additions and 30 deletions

View File

@ -80,10 +80,10 @@ public class TimeEntrySearchProjection {
@Column(name = "time_recording_mcl_id", length = 255)
private String timeRecordingMclId;
@Column(name = "time_recording_desc", length = 255)
@Column(name = "time_recording_desc", columnDefinition = "TEXT")
private String timeRecordingDesc;
@Column(name = "time_recording_remark", length = 255)
@Column(name = "time_recording_remark", columnDefinition = "TEXT")
private String timeRecordingRemark;
@Column(name = "time_recording_url", length = 1000)

View File

@ -44,34 +44,6 @@ BEGIN
END
$$;
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM pg_enum e
JOIN pg_type t ON t.oid = e.enumtypid
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE n.nspname = 'doc' AND t.typname = 'doc_document_type' AND e.enumlabel = 'TIME_ENTRY'
) THEN
ALTER TYPE doc.doc_document_type ADD VALUE 'TIME_ENTRY';
END IF;
END
$$;
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM pg_enum e
JOIN pg_type t ON t.oid = e.enumtypid
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE n.nspname = 'doc' AND t.typname = 'doc_document_family' AND e.enumlabel = 'TIME'
) THEN
ALTER TYPE doc.doc_document_family ADD VALUE 'TIME';
END IF;
END
$$;
CREATE TABLE IF NOT EXISTS "time".time_entry (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
document_id UUID NOT NULL UNIQUE REFERENCES doc.doc_document(id) ON DELETE CASCADE,

View File

@ -0,0 +1,7 @@
-- Align TIME projection source text fields with real Leitstand payload lengths.
ALTER TABLE "time".time_entry_search_projection
ALTER COLUMN time_recording_desc TYPE TEXT;
ALTER TABLE "time".time_entry_search_projection
ALTER COLUMN time_recording_remark TYPE TEXT;

View File

@ -0,0 +1,80 @@
-- Repair DOC document enum/check alignment for TIME documents on databases
-- that still carry the pre-TIME family/type constraints.
DO $$
BEGIN
IF EXISTS (
SELECT 1
FROM pg_type t
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE n.nspname = 'doc'
AND t.typname = 'doc_document_type'
) THEN
ALTER TYPE DOC.doc_document_type ADD VALUE IF NOT EXISTS 'TED_PACKAGE';
ALTER TYPE DOC.doc_document_type ADD VALUE IF NOT EXISTS 'TED_NOTICE_LOT';
ALTER TYPE DOC.doc_document_type ADD VALUE IF NOT EXISTS 'TIME_ENTRY';
END IF;
END
$$;
DO $$
BEGIN
IF EXISTS (
SELECT 1
FROM pg_type t
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE n.nspname = 'doc'
AND t.typname = 'doc_document_family'
) THEN
ALTER TYPE DOC.doc_document_family ADD VALUE IF NOT EXISTS 'TIME';
END IF;
END
$$;
DO $$
BEGIN
IF EXISTS (
SELECT 1
FROM information_schema.tables
WHERE table_schema = 'doc'
AND table_name = 'doc_document'
) THEN
ALTER TABLE DOC.doc_document DROP CONSTRAINT IF EXISTS doc_document_document_type_check;
ALTER TABLE DOC.doc_document
ADD CONSTRAINT doc_document_document_type_check
CHECK (
document_type IN (
'TED_PACKAGE',
'TED_NOTICE',
'TED_NOTICE_LOT',
'TIME_ENTRY',
'EMAIL',
'MIME_MESSAGE',
'PDF',
'DOCX',
'HTML',
'XML_GENERIC',
'TEXT',
'MARKDOWN',
'ZIP_ARCHIVE',
'GENERIC_BINARY',
'UNKNOWN'
)
);
ALTER TABLE DOC.doc_document DROP CONSTRAINT IF EXISTS doc_document_document_family_check;
ALTER TABLE DOC.doc_document
ADD CONSTRAINT doc_document_document_family_check
CHECK (
document_family IN (
'PROCUREMENT',
'TIME',
'MAIL',
'ATTACHMENT',
'KNOWLEDGE',
'GENERIC'
)
);
END IF;
END
$$;

View File

@ -0,0 +1,135 @@
package at.procon.dip.migration;
import static org.assertj.core.api.Assertions.assertThat;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.MigrationVersion;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@Testcontainers
class DocDocumentTimeEnumConstraintRepairMigrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("dip_migration_test")
.withUsername("test")
.withPassword("test");
@Test
void repairMigrationExpandsLegacyDocDocumentChecksForTimeDocuments() throws SQLException {
createLegacyDocDocumentState();
Flyway.configure()
.dataSource(postgres.getJdbcUrl(), postgres.getUsername(), postgres.getPassword())
.locations("filesystem:src/main/resources/db/migration")
.schemas("doc")
.defaultSchema("doc")
.baselineOnMigrate(true)
.baselineVersion(MigrationVersion.fromVersion("42"))
.load()
.migrate();
try (Connection connection = openConnection();
Statement statement = connection.createStatement()) {
statement.executeUpdate("""
INSERT INTO doc.doc_document (id, document_type, document_family)
VALUES ('709e388b-19d9-4c21-8d06-82b295b33505', 'TIME_ENTRY', 'TIME')
""");
}
try (Connection connection = openConnection();
var preparedStatement = connection.prepareStatement("""
SELECT pg_get_constraintdef(oid)
FROM pg_constraint
WHERE conrelid = 'doc.doc_document'::regclass
AND conname = ?
""")) {
preparedStatement.setString(1, "doc_document_document_family_check");
try (var resultSet = preparedStatement.executeQuery()) {
assertThat(resultSet.next()).isTrue();
assertThat(resultSet.getString(1)).contains("TIME");
}
}
}
private void createLegacyDocDocumentState() throws SQLException {
try (Connection connection = openConnection();
Statement statement = connection.createStatement()) {
statement.execute("CREATE SCHEMA doc");
statement.execute("""
CREATE TYPE doc.doc_document_type AS ENUM (
'TED_NOTICE',
'EMAIL',
'MIME_MESSAGE',
'PDF',
'DOCX',
'HTML',
'XML_GENERIC',
'TEXT',
'MARKDOWN',
'ZIP_ARCHIVE',
'GENERIC_BINARY',
'UNKNOWN'
)
""");
statement.execute("""
CREATE TYPE doc.doc_document_family AS ENUM (
'PROCUREMENT',
'MAIL',
'ATTACHMENT',
'KNOWLEDGE',
'GENERIC'
)
""");
statement.execute("""
CREATE TABLE doc.doc_document (
id UUID PRIMARY KEY,
document_type doc.doc_document_type NOT NULL,
document_family doc.doc_document_family NOT NULL,
CONSTRAINT doc_document_document_type_check
CHECK (
document_type IN (
'TED_NOTICE',
'EMAIL',
'MIME_MESSAGE',
'PDF',
'DOCX',
'HTML',
'XML_GENERIC',
'TEXT',
'MARKDOWN',
'ZIP_ARCHIVE',
'GENERIC_BINARY',
'UNKNOWN'
)
),
CONSTRAINT doc_document_document_family_check
CHECK (
document_family IN (
'PROCUREMENT',
'MAIL',
'ATTACHMENT',
'KNOWLEDGE',
'GENERIC'
)
)
)
""");
}
}
private Connection openConnection() throws SQLException {
return DriverManager.getConnection(
postgres.getJdbcUrl(),
postgres.getUsername(),
postgres.getPassword()
);
}
}