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

liquibase.change.core.SQLFileChange Maven / Gradle / Ivy

There is a newer version: 4.28.0
Show newest version
package liquibase.change.core;

import java.io.IOException;
import java.io.InputStream;

import liquibase.change.*;
import liquibase.database.Database;
import liquibase.exception.SetupException;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.exception.ValidationErrors;
import liquibase.logging.LogFactory;
import liquibase.resource.ResourceAccessor;
import liquibase.util.StreamUtil;
import liquibase.util.StringUtils;

/**
 * Represents a Change for custom SQL stored in a File.
 * 

* To create an instance call the constructor as normal and then call * * @author Paul Keeble * @link{#setFileOpener(FileOpener)} before calling setPath otherwise the * file will likely not be found. */ @DatabaseChange(name="sqlFile", description = "The 'sqlFile' tag allows you to specify any sql statements and have it stored external in a file. It is useful for complex changes that are not supported through LiquiBase's automated refactoring tags such as stored procedures.\n" + "\n" + "The sqlFile refactoring finds the file by searching in the following order:\n" + "\n" + "The file is searched for in the classpath. This can be manually set and by default the liquibase startup script adds the current directory when run.\n" + "The file is searched for using the file attribute as a file name. This allows absolute paths to be used or relative paths to the working directory to be used.\n" + "The 'sqlFile' tag can also support multiline statements in the same file. Statements can either be split using a ; at the end of the last line of the SQL or a go on its own on the line between the statements can be used.Multiline SQL statements are also supported and only a ; or go statement will finish a statement, a new line is not enough. Files containing a single statement do not need to use a ; or go.\n" + "\n" + "The sql file can also contain comments of either of the following formats:\n" + "\n" + "A multiline comment that starts with /* and ends with */.\n" + "A single line comment starting with -- and finishing at the end of the line", priority = ChangeMetaData.PRIORITY_DEFAULT) public class SQLFileChange extends AbstractSQLChange { private String path; private Boolean relativeToChangelogFile; @DatabaseChangeProperty(description = "The file path of the SQL file to load", requiredForDatabase = "all", exampleValue = "my/path/file.sql") public String getPath() { return path; } /** * Sets the file name but setUp must be called for the change to have impact. * * @param fileName The file to use */ public void setPath(String fileName) { path = fileName; } /** * The encoding of the file containing SQL statements * * @return the encoding */ @DatabaseChangeProperty(exampleValue = "utf8") public String getEncoding() { return encoding; } /** * @param encoding the encoding to set */ public void setEncoding(String encoding) { this.encoding = encoding; } public Boolean isRelativeToChangelogFile() { return relativeToChangelogFile; } public void setRelativeToChangelogFile(Boolean relativeToChangelogFile) { this.relativeToChangelogFile = relativeToChangelogFile; } @Override public void finishInitialization() throws SetupException { if (path == null) { throw new SetupException(" - No path specified"); } } public InputStream openSqlStream() throws IOException { if (path == null) { return null; } InputStream innputStream = openFromClasspath(path); if (innputStream == null) { try { innputStream = openFromFileSystem(path); if (innputStream == null) { return null; } } catch (IOException e) { throw new IOException(" -Unable to read file", e); } } return innputStream; } @Override public ValidationErrors validate(Database database) { ValidationErrors validationErrors = new ValidationErrors(); if (StringUtils.trimToNull(getPath()) == null) { validationErrors.addError("'path' is required"); } return validationErrors; } /** * Tries to load the file from the file system. * * @param file The name of the file to search for * @return True if the file was found, false otherwise. */ private InputStream openFromFileSystem(String file) throws IOException { if (relativeToChangelogFile != null && relativeToChangelogFile) { String base; if (getChangeSet().getChangeLog() == null) { base = getChangeSet().getFilePath(); } else { base = getChangeSet().getChangeLog().getPhysicalFilePath().replaceAll("\\\\","/"); } if (!base.contains("/")) { base = "."; } file = base.replaceFirst("/[^/]*$", "") + "/" + file; } return getResourceAccessor().getResourceAsStream(file); } /** * Tries to load a file using the FileOpener. *

* If the fileOpener can not be found then the attempt to load from the * classpath the return is false. * * @param file The file name to try and find. * @return True if the file was found and loaded, false otherwise. */ private InputStream openFromClasspath(String file) throws IOException { if (relativeToChangelogFile != null && relativeToChangelogFile) { String base; if (getChangeSet().getChangeLog() == null) { base = getChangeSet().getFilePath(); } else { base = getChangeSet().getChangeLog().getPhysicalFilePath().replaceAll("\\\\","/"); } if (!base.contains("/")) { base = "."; } file = base.replaceFirst("/[^/]*$", "") + "/" + file; } ResourceAccessor fo = getResourceAccessor(); if (fo == null) { return null; } return fo.getResourceAsStream(file); } @Override public String getConfirmationMessage() { return "SQL in file " + path + " executed"; } @Override @DatabaseChangeProperty(isChangeProperty = false) public String getSql() { String sql = super.getSql(); if (sql == null) { InputStream sqlStream; try { sqlStream = openSqlStream(); if (sqlStream == null) { return null; } return StreamUtil.getStreamContents(sqlStream, encoding); } catch (IOException e) { throw new UnexpectedLiquibaseException(e); } } else { return sql; } } @Override public void setSql(String sql) { if (getChangeSet() != null && getChangeSet().getChangeLogParameters() != null) { sql = getChangeSet().getChangeLogParameters().expandExpressions(sql); } super.setSql(sql); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy