use of liquibase.changelog.DatabaseChangeLog in project liquibase by liquibase.
the class ConvertCommand method run.
@Override
protected CommandResult run() throws Exception {
List<ResourceAccessor> openers = new ArrayList<ResourceAccessor>();
openers.add(new FileSystemResourceAccessor());
openers.add(new ClassLoaderResourceAccessor());
if (classpath != null) {
openers.add(new FileSystemResourceAccessor(classpath));
}
ResourceAccessor resourceAccessor = new CompositeResourceAccessor(openers);
ChangeLogParser sourceParser = ChangeLogParserFactory.getInstance().getParser(src, resourceAccessor);
ChangeLogSerializer outSerializer = ChangeLogSerializerFactory.getInstance().getSerializer(out);
DatabaseChangeLog changeLog = sourceParser.parse(src, new ChangeLogParameters(), resourceAccessor);
File outFile = new File(out);
if (!outFile.exists()) {
outFile.getParentFile().mkdirs();
}
FileOutputStream outputStream = new FileOutputStream(outFile);
try {
outSerializer.write(changeLog.getChangeSets(), outputStream);
} finally {
outputStream.flush();
outputStream.close();
}
return new CommandResult("Converted successfully");
}
use of liquibase.changelog.DatabaseChangeLog in project liquibase by liquibase.
the class FormattedSqlChangeLogParser method parse.
@Override
public DatabaseChangeLog parse(String physicalChangeLogLocation, ChangeLogParameters changeLogParameters, ResourceAccessor resourceAccessor) throws ChangeLogParseException {
DatabaseChangeLog changeLog = new DatabaseChangeLog();
changeLog.setChangeLogParameters(changeLogParameters);
changeLog.setPhysicalFilePath(physicalChangeLogLocation);
try (BufferedReader reader = new BufferedReader(StreamUtil.readStreamWithReader(openChangeLogFile(physicalChangeLogLocation, resourceAccessor), null))) {
StringBuilder currentSql = new StringBuilder();
StringBuilder currentRollbackSql = new StringBuilder();
ChangeSet changeSet = null;
RawSQLChange change = null;
Pattern changeLogPattern = Pattern.compile("\\-\\-\\s*liquibase formatted.*", Pattern.CASE_INSENSITIVE);
Pattern propertyPattern = Pattern.compile("\\s*\\-\\-[\\s]*property\\s+(.*:.*)\\s+(.*:.*).*", Pattern.CASE_INSENSITIVE);
Pattern changeSetPattern = Pattern.compile("\\s*\\-\\-[\\s]*changeset\\s+(\"[^\"]+\"|[^:]+):\\s*(\"[^\"]+\"|\\S+).*", Pattern.CASE_INSENSITIVE);
Pattern rollbackPattern = Pattern.compile("\\s*\\-\\-[\\s]*rollback (.*)", Pattern.CASE_INSENSITIVE);
Pattern preconditionsPattern = Pattern.compile("\\s*\\-\\-[\\s]*preconditions(.*)", Pattern.CASE_INSENSITIVE);
Pattern preconditionPattern = Pattern.compile("\\s*\\-\\-[\\s]*precondition\\-([a-zA-Z0-9-]+) (.*)", Pattern.CASE_INSENSITIVE);
Pattern stripCommentsPattern = Pattern.compile(".*stripComments:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern splitStatementsPattern = Pattern.compile(".*splitStatements:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern rollbackSplitStatementsPattern = Pattern.compile(".*rollbackSplitStatements:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern endDelimiterPattern = Pattern.compile(".*endDelimiter:(\\S*).*", Pattern.CASE_INSENSITIVE);
Pattern rollbackEndDelimiterPattern = Pattern.compile(".*rollbackEndDelimiter:(\\S*).*", Pattern.CASE_INSENSITIVE);
Pattern commentPattern = Pattern.compile("\\-\\-[\\s]*comment:? (.*)", Pattern.CASE_INSENSITIVE);
Pattern validCheckSumPattern = Pattern.compile("\\-\\-[\\s]*validCheckSum:? (.*)", Pattern.CASE_INSENSITIVE);
Pattern ignoreLinesPattern = Pattern.compile("\\-\\-[\\s]*ignoreLines:(\\w+)", Pattern.CASE_INSENSITIVE);
Pattern runWithPattern = Pattern.compile(".*runWith:([\\w\\$\\{\\}]+).*", Pattern.CASE_INSENSITIVE);
Pattern runOnChangePattern = Pattern.compile(".*runOnChange:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern runAlwaysPattern = Pattern.compile(".*runAlways:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern contextPattern = Pattern.compile(".*context:(\".*\"|\\S*).*", Pattern.CASE_INSENSITIVE);
Pattern logicalFilePathPattern = Pattern.compile(".*logicalFilePath:(\\S*).*", Pattern.CASE_INSENSITIVE);
Pattern changeLogIdPattern = Pattern.compile(".*changeLogId:(\\S*).*", Pattern.CASE_INSENSITIVE);
Pattern labelsPattern = Pattern.compile(".*labels:(\\S*).*", Pattern.CASE_INSENSITIVE);
Pattern runInTransactionPattern = Pattern.compile(".*runInTransaction:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern dbmsPattern = Pattern.compile(".*dbms:([^,][\\w!,]+).*", Pattern.CASE_INSENSITIVE);
Pattern failOnErrorPattern = Pattern.compile(".*failOnError:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern onFailPattern = Pattern.compile(".*onFail:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern onErrorPattern = Pattern.compile(".*onError:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern onUpdateSqlPattern = Pattern.compile(".*onUpdateSQL:(\\w+).*", Pattern.CASE_INSENSITIVE);
Matcher rollbackSplitStatementsPatternMatcher = null;
boolean rollbackSplitStatements = true;
String rollbackEndDelimiter = null;
String line;
while ((line = reader.readLine()) != null) {
Matcher propertyPatternMatcher = propertyPattern.matcher(line);
if (propertyPatternMatcher.matches()) {
handleProperty(changeLogParameters, changeLog, propertyPatternMatcher);
continue;
}
Matcher changeLogPatterMatcher = changeLogPattern.matcher(line);
if (changeLogPatterMatcher.matches()) {
Matcher logicalFilePathMatcher = logicalFilePathPattern.matcher(line);
changeLog.setLogicalFilePath(parseString(logicalFilePathMatcher));
Matcher changeLogIdMatcher = changeLogIdPattern.matcher(line);
changeLog.setChangeLogId(parseString(changeLogIdMatcher));
}
Matcher ignoreLinesMatcher = ignoreLinesPattern.matcher(line);
if (ignoreLinesMatcher.matches()) {
if ("start".equals(ignoreLinesMatcher.group(1))) {
while ((line = reader.readLine()) != null) {
ignoreLinesMatcher = ignoreLinesPattern.matcher(line);
if (ignoreLinesMatcher.matches()) {
if ("end".equals(ignoreLinesMatcher.group(1))) {
break;
}
}
}
continue;
} else {
try {
long ignoreCount = Long.parseLong(ignoreLinesMatcher.group(1));
while (ignoreCount > 0 && (line = reader.readLine()) != null) {
ignoreCount--;
}
continue;
} catch (NumberFormatException | NullPointerException nfe) {
throw new ChangeLogParseException("Unknown ignoreLines syntax");
}
}
}
Matcher changeSetPatternMatcher = changeSetPattern.matcher(line);
if (changeSetPatternMatcher.matches()) {
String finalCurrentSql = changeLogParameters.expandExpressions(StringUtil.trimToNull(currentSql.toString()), changeLog);
if (changeSet != null) {
if (finalCurrentSql == null) {
throw new ChangeLogParseException("No SQL for changeset " + changeSet.toString(false));
}
change.setSql(finalCurrentSql);
if (StringUtil.trimToNull(currentRollbackSql.toString()) != null) {
if (currentRollbackSql.toString().trim().toLowerCase().matches("^not required.*")) {
changeSet.addRollbackChange(new EmptyChange());
} else {
RawSQLChange rollbackChange = new RawSQLChange();
rollbackChange.setSql(changeLogParameters.expandExpressions(currentRollbackSql.toString(), changeLog));
if (rollbackSplitStatementsPatternMatcher.matches()) {
rollbackChange.setSplitStatements(rollbackSplitStatements);
}
if (rollbackEndDelimiter != null) {
rollbackChange.setEndDelimiter(rollbackEndDelimiter);
}
changeSet.addRollbackChange(rollbackChange);
}
}
}
Matcher stripCommentsPatternMatcher = stripCommentsPattern.matcher(line);
Matcher splitStatementsPatternMatcher = splitStatementsPattern.matcher(line);
Matcher runWithMatcher = runWithPattern.matcher(line);
rollbackSplitStatementsPatternMatcher = rollbackSplitStatementsPattern.matcher(line);
Matcher endDelimiterPatternMatcher = endDelimiterPattern.matcher(line);
Matcher rollbackEndDelimiterPatternMatcher = rollbackEndDelimiterPattern.matcher(line);
Matcher logicalFilePathMatcher = logicalFilePathPattern.matcher(line);
Matcher runOnChangePatternMatcher = runOnChangePattern.matcher(line);
Matcher runAlwaysPatternMatcher = runAlwaysPattern.matcher(line);
Matcher contextPatternMatcher = contextPattern.matcher(line);
Matcher labelsPatternMatcher = labelsPattern.matcher(line);
Matcher runInTransactionPatternMatcher = runInTransactionPattern.matcher(line);
Matcher dbmsPatternMatcher = dbmsPattern.matcher(line);
Matcher failOnErrorPatternMatcher = failOnErrorPattern.matcher(line);
boolean stripComments = parseBoolean(stripCommentsPatternMatcher, changeSet, true);
boolean splitStatements = parseBoolean(splitStatementsPatternMatcher, changeSet, true);
rollbackSplitStatements = parseBoolean(rollbackSplitStatementsPatternMatcher, changeSet, true);
boolean runOnChange = parseBoolean(runOnChangePatternMatcher, changeSet, false);
boolean runAlways = parseBoolean(runAlwaysPatternMatcher, changeSet, false);
boolean runInTransaction = parseBoolean(runInTransactionPatternMatcher, changeSet, true);
boolean failOnError = parseBoolean(failOnErrorPatternMatcher, changeSet, true);
String runWith = parseString(runWithMatcher);
if (runWith != null) {
runWith = changeLogParameters.expandExpressions(runWith, changeLog);
}
String endDelimiter = parseString(endDelimiterPatternMatcher);
rollbackEndDelimiter = parseString(rollbackEndDelimiterPatternMatcher);
String context = StringUtil.trimToNull(// remove surrounding quotes if they're in there
StringUtil.trimToEmpty(parseString(contextPatternMatcher)).replaceFirst("^\"", "").replaceFirst("\"$", ""));
if (context != null) {
context = changeLogParameters.expandExpressions(context, changeLog);
}
String labels = parseString(labelsPatternMatcher);
if (labels != null) {
labels = changeLogParameters.expandExpressions(labels, changeLog);
}
String logicalFilePath = parseString(logicalFilePathMatcher);
if ((logicalFilePath == null) || "".equals(logicalFilePath)) {
logicalFilePath = changeLog.getLogicalFilePath();
}
if (logicalFilePath != null) {
logicalFilePath = changeLogParameters.expandExpressions(logicalFilePath, changeLog);
}
String dbms = parseString(dbmsPatternMatcher);
if (dbms != null) {
dbms = changeLogParameters.expandExpressions(dbms, changeLog);
}
String changeSetId = changeLogParameters.expandExpressions(StringUtil.stripEnclosingQuotes(changeSetPatternMatcher.group(2)), changeLog);
String changeSetAuthor = changeLogParameters.expandExpressions(StringUtil.stripEnclosingQuotes(changeSetPatternMatcher.group(1)), changeLog);
changeSet = new ChangeSet(changeSetId, changeSetAuthor, runAlways, runOnChange, logicalFilePath, context, dbms, runWith, runInTransaction, changeLog.getObjectQuotingStrategy(), changeLog);
changeSet.setLabels(new Labels(labels));
changeSet.setFailOnError(failOnError);
changeLog.addChangeSet(changeSet);
change = new RawSQLChange();
change.setSql(finalCurrentSql);
if (splitStatementsPatternMatcher.matches()) {
change.setSplitStatements(splitStatements);
}
change.setStripComments(stripComments);
change.setEndDelimiter(endDelimiter);
changeSet.addChange(change);
currentSql.setLength(0);
currentRollbackSql.setLength(0);
} else {
if (changeSet != null) {
Matcher commentMatcher = commentPattern.matcher(line);
Matcher rollbackMatcher = rollbackPattern.matcher(line);
Matcher preconditionsMatcher = preconditionsPattern.matcher(line);
Matcher preconditionMatcher = preconditionPattern.matcher(line);
Matcher validCheckSumMatcher = validCheckSumPattern.matcher(line);
if (commentMatcher.matches()) {
if (commentMatcher.groupCount() == 1) {
changeSet.setComments(commentMatcher.group(1));
}
} else if (validCheckSumMatcher.matches()) {
if (validCheckSumMatcher.groupCount() == 1) {
changeSet.addValidCheckSum(validCheckSumMatcher.group(1));
}
} else if (rollbackMatcher.matches()) {
if (rollbackMatcher.groupCount() == 1) {
currentRollbackSql.append(rollbackMatcher.group(1)).append(System.lineSeparator());
}
} else if (preconditionsMatcher.matches()) {
if (preconditionsMatcher.groupCount() == 1) {
String body = preconditionsMatcher.group(1);
Matcher onFailMatcher = onFailPattern.matcher(body);
Matcher onErrorMatcher = onErrorPattern.matcher(body);
Matcher onUpdateSqlMatcher = onUpdateSqlPattern.matcher(body);
PreconditionContainer pc = new PreconditionContainer();
pc.setOnFail(StringUtil.trimToNull(parseString(onFailMatcher)));
pc.setOnError(StringUtil.trimToNull(parseString(onErrorMatcher)));
pc.setOnSqlOutput(StringUtil.trimToNull(parseString(onUpdateSqlMatcher)));
changeSet.setPreconditions(pc);
}
} else if (preconditionMatcher.matches()) {
if (changeSet.getPreconditions() == null) {
// create the defaults
changeSet.setPreconditions(new PreconditionContainer());
}
if (preconditionMatcher.groupCount() == 2) {
String name = StringUtil.trimToNull(preconditionMatcher.group(1));
if (name != null) {
String body = preconditionMatcher.group(2).trim();
if ("sql-check".equals(name)) {
changeSet.getPreconditions().addNestedPrecondition(parseSqlCheckCondition(changeLogParameters.expandExpressions(StringUtil.trimToNull(body), changeSet.getChangeLog())));
} else {
throw new ChangeLogParseException("The '" + name + "' precondition type is not supported.");
}
}
}
} else {
currentSql.append(line).append(System.lineSeparator());
}
}
}
}
if (changeSet != null) {
change.setSql(changeLogParameters.expandExpressions(StringUtil.trimToNull(currentSql.toString()), changeSet.getChangeLog()));
if ((change.getEndDelimiter() == null) && StringUtil.trimToEmpty(change.getSql()).endsWith("\n/")) {
change.setEndDelimiter("\n/$");
}
if (StringUtil.trimToNull(currentRollbackSql.toString()) != null) {
if (currentRollbackSql.toString().trim().toLowerCase().matches("^not required.*")) {
changeSet.addRollbackChange(new EmptyChange());
} else {
RawSQLChange rollbackChange = new RawSQLChange();
rollbackChange.setSql(changeLogParameters.expandExpressions(currentRollbackSql.toString(), changeSet.getChangeLog()));
if (rollbackSplitStatementsPatternMatcher.matches()) {
rollbackChange.setSplitStatements(rollbackSplitStatements);
}
if (rollbackEndDelimiter != null) {
rollbackChange.setEndDelimiter(rollbackEndDelimiter);
}
changeSet.addRollbackChange(rollbackChange);
}
}
}
} catch (IOException e) {
throw new ChangeLogParseException(e);
}
return changeLog;
}
use of liquibase.changelog.DatabaseChangeLog in project liquibase by liquibase.
the class AbstractIntegrationTest method testInsertLongClob.
@Test
public void testInsertLongClob() {
assumeNotNull(this.getDatabase());
DatabaseChangeLog longClobChangelog = new DatabaseChangeLog();
ChangeSet longClobInsert = new ChangeSet(longClobChangelog);
ColumnConfig clobColumn = new ColumnConfig();
clobColumn.setName("clobColumn");
clobColumn.setType(LoadDataChange.LOAD_DATA_TYPE.CLOB.name());
// Oracle database only allows string values of up to 4000 characters
// so we test that the CLOB insertion is actually done as a CLOB in the JDBC statement
StringBuilder longClobString = new StringBuilder(4001);
for (int i = 0; i < 4001; i++) {
longClobString.append('a');
}
clobColumn.setValue(longClobString.toString());
CreateTableStatement clobTableCreator = new CreateTableStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "tableWithClob");
clobTableCreator.addColumn("clobColumn", new ClobType());
InsertExecutablePreparedStatement insertStatement = new InsertExecutablePreparedStatement(database, database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "tableWithClob", Arrays.asList(clobColumn), longClobInsert, Scope.getCurrentScope().getResourceAccessor());
try {
database.execute(new SqlStatement[] { clobTableCreator, insertStatement }, new ArrayList<>());
} catch (LiquibaseException ex) {
ex.printStackTrace();
fail("Long clob insertion failed!");
}
}
use of liquibase.changelog.DatabaseChangeLog in project liquibase by liquibase.
the class InternalDropAllCommandStep method run.
@Override
public void run(CommandResultsBuilder resultsBuilder) throws Exception {
CommandScope commandScope = resultsBuilder.getCommandScope();
BufferedLogService bufferLog = new BufferedLogService();
validateConnectionAndProjectIdsDependingOnApiKey(commandScope);
Operation dropAllOperation;
LockService lockService = LockServiceFactory.getInstance().getLockService(commandScope.getArgumentValue(DATABASE_ARG));
HubUpdater hubUpdater;
try {
lockService.waitForLock();
DatabaseChangeLog changeLog;
HubRegisterResponse hubRegisterResponse = null;
if (StringUtil.isNotEmpty(commandScope.getArgumentValue(CHANGELOG_FILE_ARG))) {
// Let the user know they can register for Hub
changeLog = parseChangeLogFile(commandScope.getArgumentValue(CHANGELOG_FILE_ARG));
hubUpdater = new HubUpdater(new Date(), changeLog, commandScope.getArgumentValue(DATABASE_ARG));
hubRegisterResponse = hubUpdater.register(commandScope.getArgumentValue(CHANGELOG_FILE_ARG));
// Access the HubChangeLog and check to see if we should run syncHub
HubChangeLog hubChangeLog = getHubChangeLog(changeLog);
checkForRegisteredChangeLog(changeLog, hubChangeLog);
} else {
hubUpdater = new HubUpdater(new Date(), commandScope.getArgumentValue(DATABASE_ARG));
hubRegisterResponse = hubUpdater.register(null);
}
Connection hubConnection = getHubConnection(commandScope);
attachProjectToConnection(commandScope, hubConnection, hubRegisterResponse);
dropAllOperation = hubUpdater.preUpdateHub("DROPALL", "drop-all", hubConnection);
try {
for (CatalogAndSchema schema : commandScope.getArgumentValue(SCHEMAS_ARG)) {
log.info("Dropping Database Objects in schema: " + schema);
checkLiquibaseTables(commandScope.getArgumentValue(DATABASE_ARG));
commandScope.getArgumentValue(DATABASE_ARG).dropDatabaseObjects(schema);
}
} catch (LiquibaseException liquibaseException) {
hubUpdater.postUpdateHubExceptionHandling(dropAllOperation, bufferLog, liquibaseException.getMessage());
return;
}
final HubServiceFactory hubServiceFactory = Scope.getCurrentScope().getSingleton(HubServiceFactory.class);
String apiKey = StringUtil.trimToNull(HubConfiguration.LIQUIBASE_HUB_API_KEY.getCurrentValue());
if (apiKey != null && hubServiceFactory.isOnline()) {
hubUpdater.syncHub(commandScope.getArgumentValue(CHANGELOG_FILE_ARG), hubConnection);
hubUpdater.postUpdateHub(dropAllOperation, bufferLog);
}
} catch (DatabaseException e) {
throw e;
} catch (Exception e) {
throw new DatabaseException(e);
} finally {
lockService.releaseLock();
lockService.destroy();
resetServices();
}
Scope.getCurrentScope().getUI().sendMessage("All objects dropped from " + commandScope.getArgumentValue(DATABASE_ARG).getConnection().getConnectionUserName() + "@" + commandScope.getArgumentValue(DATABASE_ARG).getConnection().getURL());
resultsBuilder.addResult("statusCode", 0);
}
use of liquibase.changelog.DatabaseChangeLog in project liquibase by liquibase.
the class DeactivateChangelogCommandStep method run.
@Override
public void run(CommandResultsBuilder resultsBuilder) throws Exception {
CommandScope commandScope = resultsBuilder.getCommandScope();
try (PrintWriter output = new PrintWriter(resultsBuilder.getOutputStream())) {
//
// Access the HubService
// Stop if we do no have a key
//
final HubServiceFactory hubServiceFactory = Scope.getCurrentScope().getSingleton(HubServiceFactory.class);
if (!hubServiceFactory.isOnline()) {
throw new CommandExecutionException("The command deactivateChangeLog requires communication with Liquibase Hub, \nwhich is prevented by liquibase.hub.mode='off'. \nPlease set to 'all' or 'meta' and try again. \nLearn more at https://hub.liquibase.com");
}
//
// Check for existing changeLog file
//
String changeLogFile = commandScope.getArgumentValue(CHANGELOG_FILE_ARG);
DatabaseChangeLog databaseChangeLog = parseChangeLogFile(changeLogFile);
final String changeLogId = (databaseChangeLog != null ? databaseChangeLog.getChangeLogId() : null);
if (changeLogId == null) {
throw new CommandExecutionException("Changelog '" + changeLogFile + "' does not have a changelog ID and is not registered with Hub.\n" + "For more information visit https://docs.liquibase.com.");
}
final HubService service = Scope.getCurrentScope().getSingleton(HubServiceFactory.class).getService();
HubChangeLog hubChangeLog = service.getHubChangeLog(UUID.fromString(changeLogId));
if (hubChangeLog == null) {
String message = "WARNING: Changelog '" + changeLogFile + "' has a changelog ID but was not found in Hub.\n" + "The changelog ID will be removed from the file, but Hub will not be updated.";
Scope.getCurrentScope().getUI().sendMessage(message);
Scope.getCurrentScope().getLog(DeactivateChangelogCommandStep.class).warning(message);
} else {
//
// Update Hub to deactivate the changelog
//
hubChangeLog.setStatus("INACTIVE");
hubChangeLog = service.deactivateChangeLog(hubChangeLog);
}
//
// Remove the changeLog Id and update the file
//
ChangelogRewriter.ChangeLogRewriterResult rewriterResult = ChangelogRewriter.removeChangeLogId(changeLogFile, changeLogId, databaseChangeLog);
String message = null;
if (rewriterResult.success) {
message = "The changelog '" + changeLogFile + "' was deactivated.\n" + "Note: If this is a shared changelog, please check it into Source Control.\n" + "Operation data sent to the now inactive changelogID will still be accepted at Hub.\n" + "For more information visit https://docs.liquibase.com.\n";
Scope.getCurrentScope().getLog(DeactivateChangelogCommandStep.class).info(message);
output.println(message);
resultsBuilder.addResult("statusCode", 0);
return;
}
throw new CommandExecutionException(rewriterResult.message);
}
}
Aggregations