All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.fraunhofer.iosb.ilt.frostserver.modeleditor.LiquibaseTemplates Maven / Gradle / Ivy

/*
 * Copyright (C) 2024 Fraunhofer Institut IOSB, Fraunhoferstr. 1, D 76131
 * Karlsruhe, Germany.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 */
package de.fraunhofer.iosb.ilt.frostserver.modeleditor;

import de.fraunhofer.iosb.ilt.frostserver.model.loader.DefEntityProperty;
import de.fraunhofer.iosb.ilt.frostserver.model.loader.DefModel;
import de.fraunhofer.iosb.ilt.frostserver.persistence.pgjooq.utils.fieldmapper.FieldMapper;
import de.fraunhofer.iosb.ilt.frostserver.persistence.pgjooq.utils.fieldmapper.FieldMapperId;
import de.fraunhofer.iosb.ilt.frostserver.persistence.pgjooq.utils.fieldmapper.FieldMapperManyToMany;
import de.fraunhofer.iosb.ilt.frostserver.persistence.pgjooq.utils.fieldmapper.FieldMapperManyToManyOrdered;
import de.fraunhofer.iosb.ilt.frostserver.persistence.pgjooq.utils.fieldmapper.FieldMapperOneToMany;
import de.fraunhofer.iosb.ilt.frostserver.util.StringHelper;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.CaseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author hylke
 */
public class LiquibaseTemplates {

    private static final Logger LOGGER = LoggerFactory.getLogger(LiquibaseTemplates.class.getName());

    public static final String VAR_NAME_BLOCK_CHANGESETS = "BLOCK_CHANGESETS";
    public static final String VAR_NAME_BLOCK_COLUMNS = "BLOCK_COLUMNS";
    public static final String VAR_NAME_BLOCK_COPYRIGHT = "BLOCK_COPYRIGHT";
    public static final String VAR_NAME_BLOCK_PROPERTIES = "BLOCK_PROPERTIES";
    public static final String VAR_NAME_BLOCK_INCLUDES = "BLOCK_INCLUDES";
    public static final String VAR_NAME_CHANGELOG_AUTHOR = "CHANGELOG_AUTHOR";
    public static final String VAR_NAME_CHANGELOG_DATE = "CHANGELOG_DATE";
    public static final String VAR_NAME_COLUMN_NAME = "COLUMN_NAME";
    public static final String VAR_NAME_COLUMN_NAME_1 = "COLUMN_NAME_1";
    public static final String VAR_NAME_COLUMN_NAME_2 = "COLUMN_NAME_2";
    public static final String VAR_NAME_COLUMN_NAME_OTHER = "COLUMN_NAME_OTHER";
    public static final String VAR_NAME_COLUMN_TYPE = "COLUMN_TYPE";
    public static final String VAR_NAME_COLUMN_TYPE_1 = "COLUMN_TYPE_1";
    public static final String VAR_NAME_COLUMN_TYPE_2 = "COLUMN_TYPE_2";
    public static final String VAR_NAME_ENTITY_NAME = "ENTITY_NAME";
    public static final String VAR_NAME_TABLE_NAME = "TABLE_NAME";
    public static final String VAR_NAME_TABLE_NAME_OTHER = "TABLE_NAME_OTHER";
    public static final String VAR_NAME_TESTCOLUMN_NAME = "TEST_COLUMN_NAME";

    private static final String S_NAME_BLOCK_CHANGESETS = "§{" + VAR_NAME_BLOCK_CHANGESETS + '}';
    private static final String S_NAME_BLOCK_COLUMNS = "§{" + VAR_NAME_BLOCK_COLUMNS + '}';
    private static final String S_NAME_BLOCK_COPYRIGHT = "§{" + VAR_NAME_BLOCK_COPYRIGHT + '}';
    private static final String S_NAME_BLOCK_PROPERTIES = "§{" + VAR_NAME_BLOCK_PROPERTIES + '}';
    private static final String S_NAME_BLOCK_INCLUDES = "§{" + VAR_NAME_BLOCK_INCLUDES + '}';
    private static final String S_NAME_CHANGELOG_AUTHOR = "§{" + VAR_NAME_CHANGELOG_AUTHOR + '}';
    private static final String S_NAME_CHANGELOG_DATE = "§{" + VAR_NAME_CHANGELOG_DATE + '}';
    private static final String S_NAME_COLUMN_NAME = "§{" + VAR_NAME_COLUMN_NAME + '}';
    private static final String S_NAME_COLUMN_NAME_1 = "§{" + VAR_NAME_COLUMN_NAME_1 + '}';
    private static final String S_NAME_COLUMN_NAME_2 = "§{" + VAR_NAME_COLUMN_NAME_2 + '}';
    private static final String S_NAME_COLUMN_NAME_OTHER = "§{" + VAR_NAME_COLUMN_NAME_OTHER + '}';
    private static final String S_NAME_COLUMN_TYPE = "§{" + VAR_NAME_COLUMN_TYPE + '}';
    private static final String S_NAME_COLUMN_TYPE_1 = "§{" + VAR_NAME_COLUMN_TYPE_1 + '}';
    private static final String S_NAME_COLUMN_TYPE_2 = "§{" + VAR_NAME_COLUMN_TYPE_2 + '}';
    private static final String S_NAME_ENTITY_NAME = "§{" + VAR_NAME_ENTITY_NAME + '}';
    private static final String S_NAME_TABLE_NAME = "§{" + VAR_NAME_TABLE_NAME + '}';
    private static final String S_NAME_TABLE_NAME_OTHER = "§{" + VAR_NAME_TABLE_NAME_OTHER + '}';
    private static final String S_NAME_TESTCOLUMN_NAME = "§{" + VAR_NAME_TESTCOLUMN_NAME + '}';

    public static List CreateChangeLogsFor(List models, String date, String author) {
        List clBuilders = new ArrayList<>();
        if (StringHelper.isNullOrEmpty(date)) {
            date = DateTimeFormatter.ISO_LOCAL_DATE.format(ZonedDateTime.now());
        }
        TableChangelogBuilder clForeignKeys = TableChangelogBuilder.start(date)
                .setAuthor(author)
                .setFileName("foreignKeys.xml");
        MainChangeLogBuilder clMain = MainChangeLogBuilder.start();
        for (var model : models) {
            createChangelogFor(model, clMain, date, author, clBuilders, clForeignKeys);
        }
        if (!clForeignKeys.isEmpty()) {
            clBuilders.add(clForeignKeys);
            clMain.addFile(clForeignKeys.getFileName());
        }
        clBuilders.add(clMain);
        return clBuilders;
    }

    private static void createChangelogFor(DefModel model, MainChangeLogBuilder clMain, String date, String author, List clBuilders, TableChangelogBuilder clForeignKeys) {
        for (var et : model.getEntityTypes()) {
            final String etName = et.getName();
            final String tableName = et.getTable();
            final String fileName = "table" + et.getPlural() + ".xml";
            clMain.addFile(fileName);
            clMain.addPropertyIdType(etName);
            TableChangelogBuilder clEntityType = TableChangelogBuilder.start(date, tableName)
                    .setAuthor(author)
                    .setFileName(fileName);
            clBuilders.add(clEntityType);
            ChangesetColumnsBuilder csColumns = ChangesetColumnsBuilder.start();
            String idField = null;
            for (var ep : et.getEntityProperties()) {
                idField = handleEntityProperty(ep, idField, clEntityType, etName, csColumns);
            }
            clEntityType.addChangesetColumnsBuilder(csColumns);

            for (var ep : et.getNavigationProperties()) {
                String otherEntityType = ep.getEntityType();
                for (var handler : ep.getHandlers()) {
                    if (handler instanceof FieldMapperOneToMany fm) {
                        String ourColumn = fm.getField();
                        String otherColumn = fm.getOtherField();
                        String otherTable = fm.getOtherTable();
                        if (ourColumn.equals(idField)) {
                            clEntityType.addChangesetColumnsBuilder(
                                    ChangesetColumnsBuilder.start()
                                            .setTableName(otherTable)
                                            .setTestColumnName(otherColumn)
                                            .prependColumn(otherColumn, idColumnType(etName), !ep.getInverse().isRequired()));
                            clForeignKeys.addChangsetForeignKey(otherTable, otherColumn, tableName, ourColumn);
                            clEntityType.addChangsetIndex(otherTable, otherColumn);
                        } else {
                            csColumns.prependColumn(ourColumn, idColumnType(otherEntityType), !ep.isRequired());
                            if (!csColumns.isTestColumnNameSet()) {
                                csColumns.setTestColumnName(ourColumn);
                            }
                            clForeignKeys.addChangsetForeignKey(tableName, ourColumn, otherTable, otherColumn);
                            clEntityType.addChangsetIndex(ourColumn);
                        }
                    } else if (handler instanceof FieldMapperManyToMany fm) {
                        String ourField = fm.getField();
                        String ourType = idColumnType(etName);
                        String otherType = idColumnType(otherEntityType);
                        String linkTableOurField = fm.getLinkOurField();
                        String linkTable = fm.getLinkTable();
                        String linkTableOtherField = fm.getLinkOtherField();
                        String otherField = fm.getOtherField();
                        String otherTable = fm.getOtherTable();
                        TableChangelogBuilder clLinkTable = TableChangelogBuilder.start(date)
                                .setAuthor(author)
                                .setFileName("table" + CaseUtils.toCamelCase(linkTable, true, '_') + ".xml")
                                .addChangsetLinkTable(linkTable, linkTableOurField, ourType, linkTableOtherField, otherType);
                        clBuilders.add(clLinkTable);
                        clForeignKeys.addChangsetForeignKey(linkTable, linkTableOurField, tableName, ourField);
                        clForeignKeys.addChangsetForeignKey(linkTable, linkTableOtherField, otherTable, otherField);
                        clMain.addFile(clLinkTable.getFileName());
                    } else if (handler instanceof FieldMapperManyToManyOrdered fm) {
                        LOGGER.warn("Unknown Handler Type: {}", handler);
                    }
                }
            }
        }
    }

    private static String handleEntityProperty(DefEntityProperty ep, String idField, TableChangelogBuilder clEntityType, final String etName, ChangesetColumnsBuilder csColumns) {
        for (var handler : ep.getHandlers()) {
            if (handler instanceof FieldMapperId fm) {
                idField = fm.getField();
                clEntityType.addChangeLogsIds(idField, etName);
            } else if (handler instanceof FieldMapper fm) {
                for (var entry : fm.getFieldTypes().entrySet()) {
                    final String colName = entry.getKey();
                    final String colType = entry.getValue();
                    csColumns.addColumn(colName, colType, true);
                    if (!csColumns.isTestColumnNameSet()) {
                        csColumns.setTestColumnName(colName);
                    }
                }
            } else {
                LOGGER.warn("Unknown Handler Type: {}", handler);
            }
        }
        return idField;
    }

    public static interface ChangeLogBuilder {

        public String getFileName();

        public String build();
    }

    public static interface ChangeSetBuilder {

        public boolean isEmpty();

        public String build();
    }

    public static class WrappedSetBuilder implements ChangeSetBuilder {

        private final String data;

        public WrappedSetBuilder(String data) {
            this.data = data;
        }

        @Override
        public boolean isEmpty() {
            return StringUtils.isAllBlank(data);
        }

        @Override
        public String build() {
            return data;
        }

    }

    public static class MainChangeLogBuilder implements ChangeLogBuilder {

        private String fileName = "tables.xml";
        private final List files = new ArrayList<>();
        private final StringBuilder properties = new StringBuilder();

        public static MainChangeLogBuilder start() {
            return new MainChangeLogBuilder();
        }

        public static MainChangeLogBuilder start(String fileName) {
            return new MainChangeLogBuilder()
                    .setFileName(fileName);
        }

        public void addFile(String fileName) {
            files.add(fileName);
        }

        public void addPropertyIdType(String entityTypeName) {
            properties.append("    \n");
            properties.append("    \n");
        }

        @Override
        public String build() {
            StringBuilder includes = new StringBuilder();
            for (String file : files) {
                includes.append("    \n");
            }
            String[] searchList = new String[]{
                S_NAME_BLOCK_COPYRIGHT,
                S_NAME_BLOCK_PROPERTIES,
                S_NAME_BLOCK_INCLUDES
            };
            String[] replacementList = new String[]{
                BLOCK_COPYRIGHT.trim(),
                properties.toString().trim(),
                includes.toString().trim()
            };
            return StringUtils.replaceEach(BLOCK_MAIN_FILE, searchList, replacementList);
        }

        @Override
        public String getFileName() {
            return fileName;
        }

        public MainChangeLogBuilder setFileName(String fileName) {
            this.fileName = fileName;
            return this;
        }

    }

    public static class TableChangelogBuilder implements ChangeLogBuilder {

        private final List changesets = new ArrayList<>();
        private final String base;
        private final String date;
        private final String tableName;
        private String author = "generated";
        private String fileName;

        private TableChangelogBuilder(String date, String tableName) {
            this.date = date;
            this.tableName = tableName;
            String[] searchList = new String[]{
                S_NAME_BLOCK_COPYRIGHT
            };
            String[] replacementList = new String[]{
                BLOCK_COPYRIGHT.trim()
            };
            base = StringUtils.replaceEach(BLOCK_CHANGLOG, searchList, replacementList);
        }

        public static TableChangelogBuilder start(String date) {
            return new TableChangelogBuilder(date, null);
        }

        public static TableChangelogBuilder start(String date, String tableName) {
            return new TableChangelogBuilder(date, tableName);
        }

        @Override
        public String getFileName() {
            return fileName;
        }

        public TableChangelogBuilder setAuthor(String author) {
            this.author = author;
            return this;
        }

        public TableChangelogBuilder setFileName(String fileName) {
            this.fileName = fileName;
            return this;
        }

        public TableChangelogBuilder addChangeLogsIds(String entityName) {
            if (StringHelper.isNullOrEmpty(tableName)) {
                throw new IllegalArgumentException("Table must be set!");
            }
            return addChangeLogsIds(tableName, "id", entityName);
        }

        public TableChangelogBuilder addChangeLogsIds(String columnName, String entityName) {
            if (StringHelper.isNullOrEmpty(tableName)) {
                throw new IllegalArgumentException("Table must be set!");
            }
            return addChangeLogsIds(tableName, columnName, entityName);
        }

        public TableChangelogBuilder addChangeLogsIds(String tableName, String columnName, String entityName) {
            addChangeset(createChangsetLongId(author, date, tableName, columnName, entityName));
            addChangeset(createChangsetStringId(author, date, tableName, columnName, entityName));
            return this;
        }

        public TableChangelogBuilder addChangesetColumnsBuilder(ChangesetColumnsBuilder builder) {
            builder.setAuthor(author);
            builder.setDate(date);
            if (!builder.isTableNameSet()) {
                builder.setTableName(tableName);
            }
            return addChangeset(builder);
        }

        public TableChangelogBuilder addChangsetIndex(String columnName) {
            return addChangsetIndex(tableName, columnName);
        }

        public TableChangelogBuilder addChangsetIndex(String tableName, String columnName) {
            return addChangeset(createChangsetIndex(author, date, tableName, columnName));
        }

        public TableChangelogBuilder addChangsetLinkTable(String columnName1, String columnType1, String columnName2, String columnType2) {
            return addChangsetLinkTable(tableName, columnName1, columnType1, columnName2, columnType2);
        }

        public TableChangelogBuilder addChangsetLinkTable(String tableName, String columnName1, String columnType1, String columnName2, String columnType2) {
            return addChangeset(createChangsetLinkTable(author, date, tableName, columnName1, columnType1, columnName2, columnType2));
        }

        public TableChangelogBuilder addChangsetForeignKey(String columnName, String otherTableName, String otherColumnName) {
            return addChangsetForeignKey(tableName, columnName, otherTableName, otherColumnName);
        }

        public TableChangelogBuilder addChangsetForeignKey(String tableName, String columnName, String otherTableName, String otherColumnName) {
            return addChangeset(createChangsetForeignKey(author, date, tableName, columnName, otherTableName, otherColumnName));
        }

        public TableChangelogBuilder addChangeset(ChangeSetBuilder changeset) {
            changesets.add(changeset);
            return this;
        }

        private TableChangelogBuilder addChangeset(String changeset) {
            changesets.add(new WrappedSetBuilder(changeset));
            return this;
        }

        public boolean isEmpty() {
            return changesets.isEmpty();
        }

        @Override
        public String build() {
            StringBuilder changeSetString = new StringBuilder();
            for (var cs : changesets) {
                if (!cs.isEmpty()) {
                    changeSetString.append(cs.build()).append('\n');
                }
            }
            return StringUtils.replace(base, S_NAME_BLOCK_CHANGESETS, changeSetString.toString().trim());
        }
    }

    public static String createChangsetLongId(String author, String date, String tableName, String columnName, String entityName) {
        String[] searchList = new String[]{
            S_NAME_CHANGELOG_AUTHOR,
            S_NAME_CHANGELOG_DATE,
            S_NAME_TABLE_NAME,
            S_NAME_COLUMN_NAME,
            S_NAME_ENTITY_NAME
        };
        String[] replacementList = new String[]{
            author,
            date,
            tableName,
            columnName,
            entityName
        };
        return StringUtils.replaceEach(BLOCK_CHANGESET_IDLONG, searchList, replacementList);
    }

    public static String createChangsetStringId(String author, String date, String tableName, String columnName, String entityName) {
        String[] searchList = new String[]{
            S_NAME_CHANGELOG_AUTHOR,
            S_NAME_CHANGELOG_DATE,
            S_NAME_TABLE_NAME,
            S_NAME_COLUMN_NAME,
            S_NAME_ENTITY_NAME
        };
        String[] replacementList = new String[]{
            author,
            date,
            tableName,
            columnName,
            entityName
        };
        return StringUtils.replaceEach(BLOCK_CHANGESET_IDSTRING, searchList, replacementList);
    }

    public static class ChangesetColumnsBuilder implements ChangeSetBuilder {

        private final StringBuilder preColumns = new StringBuilder();
        private final StringBuilder columns = new StringBuilder();
        String author;
        String date;
        String tableName;
        String testColumnName;

        public static ChangesetColumnsBuilder start() {
            return new ChangesetColumnsBuilder(null, null, null);
        }

        public static ChangesetColumnsBuilder start(String date, String tableName, String testColumnName) {
            return new ChangesetColumnsBuilder(date, tableName, testColumnName);
        }

        private ChangesetColumnsBuilder(String date, String tableName, String testColumnName) {
            this.date = date;
            this.tableName = tableName;
            this.testColumnName = testColumnName;
        }

        public ChangesetColumnsBuilder setAuthor(String author) {
            this.author = author;
            return this;
        }

        public ChangesetColumnsBuilder setDate(String date) {
            this.date = date;
            return this;
        }

        public boolean isTestColumnNameSet() {
            return !StringHelper.isNullOrEmpty(testColumnName);
        }

        public ChangesetColumnsBuilder setTestColumnName(String testColumnName) {
            this.testColumnName = testColumnName;
            return this;
        }

        public boolean isTableNameSet() {
            return !StringHelper.isNullOrEmpty(tableName);
        }

        public ChangesetColumnsBuilder setTableName(String tableName) {
            this.tableName = tableName;
            return this;
        }

        public ChangesetColumnsBuilder prependColumn(String columnName, String columnType, boolean nullable) {
            preColumns.append(createBlockColumn(columnName, columnType, nullable));
            return this;
        }

        public ChangesetColumnsBuilder addColumn(String columnName, String columnType, boolean nullable) {
            columns.append(createBlockColumn(columnName, columnType, nullable));
            return this;
        }

        public boolean isEmpty() {
            return preColumns.isEmpty() && columns.isEmpty();
        }

        @Override
        public String build() {
            String data = preColumns.toString() + columns.toString();
            if (StringHelper.isNullOrEmpty(date)) {
                throw new IllegalArgumentException("Date must be set!");
            }
            if (StringHelper.isNullOrEmpty(tableName)) {
                throw new IllegalArgumentException("Table must be set!");
            }
            String[] searchList = new String[]{
                S_NAME_CHANGELOG_AUTHOR,
                S_NAME_CHANGELOG_DATE,
                S_NAME_TABLE_NAME,
                S_NAME_TESTCOLUMN_NAME,
                S_NAME_BLOCK_COLUMNS
            };
            String[] replacementList = new String[]{
                author,
                date,
                tableName,
                testColumnName,
                data.trim()
            };
            return StringUtils.replaceEach(BLOCK_CHANGESET_NORMAL_COLUMNS, searchList, replacementList);
        }
    }

    public static String createBlockColumn(String columnName, String columnType, boolean nullable) {
        if (nullable) {
            return createBlockColumn(columnName, columnType);
        } else {
            return createBlockColumnNonNull(columnName, columnType);
        }
    }

    public static String createBlockColumn(String columnName, String columnType) {
        String[] searchList = new String[]{
            S_NAME_COLUMN_NAME,
            S_NAME_COLUMN_TYPE
        };
        String[] replacementList = new String[]{
            columnName,
            columnType
        };
        return StringUtils.replaceEach(BLOCK_CHANGESET_COLUMN, searchList, replacementList);
    }

    public static String createBlockColumnNonNull(String columnName, String columnType) {
        String[] searchList = new String[]{
            S_NAME_COLUMN_NAME,
            S_NAME_COLUMN_TYPE
        };
        String[] replacementList = new String[]{
            columnName,
            columnType
        };
        return StringUtils.replaceEach(BLOCK_CHANGESET_COLUMN_NONNULL, searchList, replacementList);
    }

    public static String createChangsetIndex(String author, String date, String tableName, String columnName) {
        String[] searchList = new String[]{
            S_NAME_CHANGELOG_AUTHOR,
            S_NAME_CHANGELOG_DATE,
            S_NAME_TABLE_NAME,
            S_NAME_COLUMN_NAME
        };
        String[] replacementList = new String[]{
            author,
            date,
            tableName,
            columnName
        };
        return StringUtils.replaceEach(BLOCK_CHANGESET_INDEX, searchList, replacementList);
    }

    public static String createChangsetLinkTable(String author, String date, String tableName, String columnName1, String columnType1, String columnName2, String columnType2) {
        String[] searchList = new String[]{
            S_NAME_CHANGELOG_AUTHOR,
            S_NAME_CHANGELOG_DATE,
            S_NAME_TABLE_NAME,
            S_NAME_COLUMN_NAME_1,
            S_NAME_COLUMN_TYPE_1,
            S_NAME_COLUMN_NAME_2,
            S_NAME_COLUMN_TYPE_2
        };
        String[] replacementList = new String[]{
            author,
            date,
            tableName,
            columnName1,
            columnType1,
            columnName2,
            columnType2
        };
        return StringUtils.replaceEach(BLOCK_CHANGESET_LINKTABLE, searchList, replacementList);
    }

    public static String createChangsetForeignKey(String author, String date, String tableName, String columnName, String otherTableName, String otherColumnName) {
        String[] searchList = new String[]{
            S_NAME_CHANGELOG_AUTHOR,
            S_NAME_CHANGELOG_DATE,
            S_NAME_TABLE_NAME,
            S_NAME_COLUMN_NAME,
            S_NAME_TABLE_NAME_OTHER,
            S_NAME_COLUMN_NAME_OTHER
        };
        String[] replacementList = new String[]{
            author,
            date,
            tableName,
            columnName,
            otherTableName,
            otherColumnName
        };
        return StringUtils.replaceEach(BLOCK_CHANGESET_FKEY, searchList, replacementList);
    }

    public static String idColumnType(String entityType) {
        return "${idType-" + entityType + "}";
    }

    public static final String BLOCK_COPYRIGHT = """
                
            """;

    public static final String BLOCK_CHANGLOG = """
            
            
                §{BLOCK_COPYRIGHT}

                §{BLOCK_CHANGESETS}

            

            """;

    public static final String BLOCK_CHANGESET_IDLONG = """
                
                    
                        
                        
                            
                        
                    
                    
                        
                            
                        
                    
                
            """;

    public static final String BLOCK_CHANGESET_IDSTRING = """
                
                    
                        
                            
                            
                        
                        
                            
                        
                    
                    
                        
                            
                        
                    
                
            """;

    public static final String BLOCK_CHANGESET_NORMAL_COLUMNS = """
                
                    
                        
                            
                        
                    
                    
                        §{BLOCK_COLUMNS}
                    
                
            """;

    public static final String BLOCK_CHANGESET_COLUMN = """
                        
            """;

    public static final String BLOCK_CHANGESET_COLUMN_NONNULL = """
                        
                            
                        
            """;

    public static final String BLOCK_CHANGESET_INDEX = """
                
                    
                        
                            
                        
                    
                    
                        
                    
                
            """;

    public static final String BLOCK_CHANGESET_LINKTABLE = """
                
                    
                        
                            
                        
                    
                    
                        
                            
                        
                        
                            
                        
                    
                    
                    
                        
                    
                    
                        
                    
                
            """;

    public static final String BLOCK_CHANGESET_FKEY = """
                
                    
                        
                            
                        
                    
                    
                
            """;

    public static final String BLOCK_MAIN_FILE = """
            
            
                §{BLOCK_COPYRIGHT}

                §{BLOCK_PROPERTIES}

                §{BLOCK_INCLUDES}

            

            """;

    private LiquibaseTemplates() {
        // Utility class
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy