package liquibase.serializer.core.formattedsql; import liquibase.change.Change; import liquibase.changelog.ChangeLogChild; import liquibase.changelog.ChangeSet; import liquibase.configuration.GlobalConfiguration; import liquibase.configuration.LiquibaseConfiguration; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.serializer.ChangeLogSerializer; import liquibase.serializer.LiquibaseSerializable; import liquibase.sql.Sql; import liquibase.sqlgenerator.SqlGeneratorFactory; import java.io.*; import java.util.*; import java.util.regex.*; public class FormattedSqlChangeLogSerializer implements ChangeLogSerializer { private static Pattern fileNamePatter = Pattern.compile(".*\\.(\\w+)\\.sql"); @Override public String[] getValidFileExtensions() { return new String[] { "sql" }; } @Override public String serialize(LiquibaseSerializable object, boolean pretty) { if (object instanceof ChangeSet) { StringBuilder builder = new StringBuilder(); ChangeSet changeSet = (ChangeSet) object; Database database = getTargetDatabase(changeSet); String author = (changeSet.getAuthor()).replaceAll("\\s+", "_"); author = author.replace("_(generated)",""); builder.append("--changeset ").append(author).append(":").append(changeSet.getId()).append("\n"); for (Change change : changeSet.getChanges()) { Sql[] sqls = SqlGeneratorFactory.getInstance().generateSql(change.generateStatements(database), database); if (sqls != null) { for (Sql sql : sqls) { builder.append(sql.toSql()).append(sql.getEndDelimiter()).append("\n"); } } } return builder.toString(); } else { throw new UnexpectedLiquibaseException("Cannot serialize object type: "+object.getClass().getName()); } } protected Database getTargetDatabase(ChangeSet changeSet) { String filePath = changeSet.getFilePath(); if (filePath == null) { throw new UnexpectedLiquibaseException("You must specify the changelog file name as filename.DB_TYPE.sql. Example: changelog.mysql.sql"); } Matcher matcher = fileNamePatter.matcher(filePath); if (!matcher.matches()) { throw new UnexpectedLiquibaseException("Serializing changelog as sql requires a file name in the format *.databaseType.sql. Example: changelog.h2.sql. Passed: "+filePath); } String shortName = matcher.replaceFirst("$1"); Database database = DatabaseFactory.getInstance().getDatabase(shortName); if (database == null) { throw new UnexpectedLiquibaseException("Serializing changelog as sql requires a file name in the format *.databaseType.sql. Example: changelog.h2.sql. Unknown databaes type: "+shortName); } return database; } @Override public <T extends ChangeLogChild> void write(List<T> children, OutputStream out) throws IOException { StringBuilder builder = new StringBuilder(); builder.append("--liquibase formatted sql\n\n"); for (T child : children) { builder.append(serialize(child, true)); builder.append("\n"); } out.write(builder.toString().getBytes(LiquibaseConfiguration.getInstance().getConfiguration(GlobalConfiguration.class).getOutputEncoding())); } @Override public void append(ChangeSet changeSet, File changeLogFile) throws IOException { } @Override public int getPriority() { return PRIORITY_DEFAULT; } }