Skip to content
Snippets Groups Projects

Platform 2035484 new liquibase structure

Merged Lukas Werner requested to merge platform_2035484_newLiquibaseStructure into beta
All threads resolved!
1 file
+ 0
141
Compare changes
  • Side-by-side
  • Inline
+ 0
141
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs"
import { randomUUID } from "crypto"
import { GenerateChangeLogCommandAttributes, Liquibase, LiquibaseConfig } from "liquibase"
const path = require('path');
//Alias und Tabellen anpassen!
let database = "adito_data";
let targetAlias = "Workflow_alias";
let tables = [
"standard_workflow",
"workflowsignal",
"workflowstartconfig"
];
let classpath = path.join(__dirname, '..', 'node_modules', 'liquibase', 'dist', 'drivers', 'mariadb-java-client-2.5.3.jar')
let url = "jdbc:mariadb://localhost:3306/" + database;
let pathToAlias = path.join(__dirname, "..", '.liquibase', targetAlias)
let pathToChangelog = path.join(pathToAlias, "1.0.0")
let pathToAliasInAliasDefinition = path.join(__dirname, "..", 'aliasDefinition', targetAlias);
if(!existsSync(pathToAliasInAliasDefinition))
throw Error("Alias does not exist: " + pathToAliasInAliasDefinition);
mkdirSync(pathToAlias, {recursive: true})
mkdirSync(path.join(pathToChangelog, "csv"), {recursive: true})
const createTablePrecondition: string = `\t\t<preConditions onFail="MARK_RAN">
\t\t\t<not>
\t\t\t\t<tableExists tableName="$2"/>
\t\t\t</not>
\t\t</preConditions>
\t\t$1`.replace(/\t/g, " ")
const createIndexPrecondition = `\t\t<preConditions onFail="MARK_RAN">
\t\t\t<not>
\t\t\t\t<indexExists indexName="$2"/>
\t\t\t</not>
\t\t</preConditions>
\t\t$1`.replace(/\t/g, " ")
function createLoadDataPrecondition(tableName: string, columns: string[]): string{
let loadDataPreconditionColumns = columns.map(column => `\t\t\t\t<columnExists tableName="${tableName}" columnName="${column}"/>`).join("\r\n");
let loadDataPrecondition = `<preConditions onFail="MARK_RAN">
\t\t\t<and>
\t\t\t\t<tableExists tableName="${tableName}"/>
\t\t\t\t<sqlCheck expectedResult="0">
\t\t\t\t\tSELECT COUNT(1) FROM ${tableName}
\t\t\t\t</sqlCheck>
${loadDataPreconditionColumns}
\t\t\t</and>
\t\t</preConditions>`.replace(/\t/g, " ")
return loadDataPrecondition;
}
generateChangesets().then(() => generateChangelogXMLs());
async function generateChangesets(){
//@ts-ignore Missing parameter changeLogFile is set in for loop
let config: LiquibaseConfig = {
classpath: classpath,
url: url,
username: "adito",
password: "adito"
}
//@ts-ignore Missing mandatory parameter causes error
const changeLogParams: GenerateChangeLogCommandAttributes = {
dataOutputDirectory: path.join(pathToChangelog, "csv")
}
const liquibase = new Liquibase(config);
for(const table of tables)
{
let changelogFilename: string = "create_"+ table +".xml";
let changelogFilePath: string = path.join(pathToChangelog, changelogFilename)
//Ignoring enclosure so we don't need to create a new Liquibase Object for every table, also the includedObjects param is currently missing for the config
//@ts-ignore
liquibase.config.changeLogFile = path.join(pathToChangelog, "create_"+ table +".xml");
//@ts-ignore
liquibase.config.includeObjects = table;
console.log("Generating ", changelogFilename)
await liquibase.generateChangeLog(changeLogParams)
.then(() => {
let file = readFileSync(changelogFilePath, "utf-8");
file = file.replace(/.*(<createTable tableName="(.*?)">).*/g, createTablePrecondition);
file = file.replace(/.*(<createIndex indexName="(.*?)" tableName="(.*?)">).*/g, createIndexPrecondition);
let loadDatas: RegExpMatchArray[] = Array.from(file.matchAll(/<loadData.*?>(.*?)<\/loadData>/gms))
for(let i =0; i<loadDatas.length; i++)
{
let tableName: string | null = (loadDatas[i][0].match(/tableName="(.*?)"/) ?? [ , null])[1]
let columnsMatches = loadDatas[i][0].matchAll(/<column header="(.*?)"/g);
let columnNames: string[] = Array.from(columnsMatches).map(column => column[1]);
if(!tableName)
{
throw new Error("Tablename not found!")
}
let precondition: string = createLoadDataPrecondition(tableName, columnNames);
file = file.replace(loadDatas[i][0], precondition + '\r\n\t' + loadDatas[i][0])
}
file = file.replace(/(<loadData.*?file=").*?(".*?tableName="(.*?)".*?>)/g, '$1csv/$3.csv" relativeToChangelogFile="true$2')
file = file.replace(/id=".*?"/g, () => 'id="' + randomUUID() + '"')
writeFileSync(changelogFilePath, file, {encoding: "utf-8", flag: "w"});
})
.catch((err: Error) => {
if(err.message.indexOf("existiert bereits") != -1)
console.warn(changelogFilePath, " already exists! -> Skipped");
else
throw err;
});
};
}
function generateChangelogXMLs(){
let rootChangelog: string = `<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
\txmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
\txsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
\t<include relativeToChangelogFile="true" file="1.0.0/changelog.xml"/>
</databaseChangeLog>`
let changelogFilenames: string[] = tables.map(table => `create_${table}.xml`);
let changesets: string = changelogFilenames.map(changesetFilename => `\t<include relativeToChangelogFile="true" file="${changesetFilename}"/>`).join('\r\n')
let initChangelog: string = `<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
\txmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
\txsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
${changesets}
</databaseChangeLog>`
writeFileSync(path.join(pathToAlias, "changelog.xml"), rootChangelog, {encoding: "utf-8", flag: "w"})
writeFileSync(path.join(pathToChangelog, "changelog.xml"), initChangelog, {encoding: "utf-8", flag: "w"})
}
\ No newline at end of file
Loading