Search in sources :

Example 1 with UtfBomAwareReader

use of liquibase.resource.UtfBomAwareReader in project liquibase by liquibase.

the class LoadDataChange method getCSVReader.

public CSVReader getCSVReader() throws IOException {
    ResourceAccessor resourceAccessor = getResourceAccessor();
    if (resourceAccessor == null) {
        throw new UnexpectedLiquibaseException("No file resourceAccessor specified for " + getFile());
    }
    InputStream stream = StreamUtil.openStream(file, isRelativeToChangelogFile(), getChangeSet(), resourceAccessor);
    if (stream == null) {
        return null;
    }
    Reader streamReader;
    if (getEncoding() == null) {
        streamReader = new UtfBomAwareReader(stream);
    } else {
        streamReader = new UtfBomAwareReader(stream, getEncoding());
    }
    char quotchar;
    if (StringUtils.trimToEmpty(this.quotchar).length() == 0) {
        // hope this is impossible to have a field surrounded with non ascii char 0x01
        quotchar = '\1';
    } else {
        quotchar = this.quotchar.charAt(0);
    }
    if (separator == null) {
        separator = liquibase.util.csv.CSVReader.DEFAULT_SEPARATOR + "";
    }
    return new CSVReader(streamReader, separator.charAt(0), quotchar);
}
Also used : ResourceAccessor(liquibase.resource.ResourceAccessor) CSVReader(liquibase.util.csv.CSVReader) EmptyLineAndCommentSkippingInputStream(liquibase.io.EmptyLineAndCommentSkippingInputStream) InputStream(java.io.InputStream) CSVReader(liquibase.util.csv.CSVReader) UtfBomAwareReader(liquibase.resource.UtfBomAwareReader) Reader(java.io.Reader) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) UtfBomAwareReader(liquibase.resource.UtfBomAwareReader)

Example 2 with UtfBomAwareReader

use of liquibase.resource.UtfBomAwareReader 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);
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new UtfBomAwareReader(openChangeLogFile(physicalChangeLogLocation, resourceAccessor)));
        StringBuffer currentSql = new StringBuffer();
        StringBuffer currentRollbackSql = new StringBuffer();
        ChangeSet changeSet = null;
        RawSQLChange change = null;
        Pattern changeLogPattern = Pattern.compile("\\-\\-\\s*liquibase formatted.*", Pattern.CASE_INSENSITIVE);
        Pattern changeSetPattern = Pattern.compile("\\-\\-[\\s]*changeset\\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 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 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);
        boolean rollbackSplitStatements = true;
        String rollbackEndDelimiter = null;
        String line;
        while ((line = reader.readLine()) != null) {
            Matcher changeLogPatterMatcher = changeLogPattern.matcher(line);
            if (changeLogPatterMatcher.matches()) {
                Matcher logicalFilePathMatcher = logicalFilePathPattern.matcher(line);
                changeLog.setLogicalFilePath(parseString(logicalFilePathMatcher));
            }
            Matcher changeSetPatternMatcher = changeSetPattern.matcher(line);
            if (changeSetPatternMatcher.matches()) {
                String finalCurrentSql = changeLogParameters.expandExpressions(StringUtils.trimToNull(currentSql.toString()), changeLog);
                if (changeSet != null) {
                    if (finalCurrentSql == null) {
                        throw new ChangeLogParseException("No SQL for changeset " + changeSet.toString(false));
                    }
                    change.setSql(finalCurrentSql);
                    if (StringUtils.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));
                            changeSet.addRollbackChange(rollbackChange);
                        }
                    }
                }
                Matcher stripCommentsPatternMatcher = stripCommentsPattern.matcher(line);
                Matcher splitStatementsPatternMatcher = splitStatementsPattern.matcher(line);
                Matcher 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 endDelimiter = parseString(endDelimiterPatternMatcher);
                rollbackEndDelimiter = parseString(rollbackEndDelimiterPatternMatcher);
                String context = StringUtils.trimToNull(//remove surrounding quotes if they're in there
                StringUtils.trimToEmpty(parseString(contextPatternMatcher)).replaceFirst("^\"", "").replaceFirst("\"$", ""));
                String labels = parseString(labelsPatternMatcher);
                String logicalFilePath = parseString(logicalFilePathMatcher);
                if (logicalFilePath == null || "".equals(logicalFilePath)) {
                    logicalFilePath = changeLog.getLogicalFilePath();
                }
                String dbms = parseString(dbmsPatternMatcher);
                changeSet = new ChangeSet(changeSetPatternMatcher.group(2), changeSetPatternMatcher.group(1), runAlways, runOnChange, logicalFilePath, context, dbms, runInTransaction, changeLog.getObjectQuotingStrategy(), changeLog);
                changeSet.setLabels(new Labels(labels));
                changeSet.setFailOnError(failOnError);
                changeLog.addChangeSet(changeSet);
                change = new RawSQLChange();
                change.setSql(finalCurrentSql);
                change.setResourceAccessor(resourceAccessor);
                change.setSplitStatements(splitStatements);
                change.setStripComments(stripComments);
                change.setEndDelimiter(endDelimiter);
                changeSet.addChange(change);
                currentSql = new StringBuffer();
                currentRollbackSql = new StringBuffer();
            } 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(SystemUtils.LINE_SEPARATOR);
                        }
                    } 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(StringUtils.trimToNull(parseString(onFailMatcher)));
                            pc.setOnError(StringUtils.trimToNull(parseString(onErrorMatcher)));
                            pc.setOnSqlOutput(StringUtils.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 = StringUtils.trimToNull(preconditionMatcher.group(1));
                            if (name != null) {
                                String body = preconditionMatcher.group(2).trim();
                                if ("sql-check".equals(name)) {
                                    changeSet.getPreconditions().addNestedPrecondition(parseSqlCheckCondition(changeLogParameters.expandExpressions(StringUtils.trimToNull(body), changeSet.getChangeLog())));
                                } else {
                                    throw new ChangeLogParseException("The '" + name + "' precondition type is not supported.");
                                }
                            }
                        }
                    } else {
                        currentSql.append(line).append(SystemUtils.LINE_SEPARATOR);
                    }
                }
            }
        }
        if (changeSet != null) {
            change.setSql(changeLogParameters.expandExpressions(StringUtils.trimToNull(currentSql.toString()), changeSet.getChangeLog()));
            if (change.getEndDelimiter() == null && StringUtils.trimToEmpty(change.getSql()).endsWith("\n/")) {
                change.setEndDelimiter("\n/$");
            }
            if (StringUtils.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()));
                    rollbackChange.setSplitStatements(rollbackSplitStatements);
                    if (rollbackEndDelimiter != null) {
                        rollbackChange.setEndDelimiter(rollbackEndDelimiter);
                    }
                    changeSet.addRollbackChange(rollbackChange);
                }
            }
        }
    } catch (IOException e) {
        throw new ChangeLogParseException(e);
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ignore) {
            }
        }
    }
    return changeLog;
}
Also used : RawSQLChange(liquibase.change.core.RawSQLChange) Pattern(java.util.regex.Pattern) PreconditionContainer(liquibase.precondition.core.PreconditionContainer) Matcher(java.util.regex.Matcher) Labels(liquibase.Labels) IOException(java.io.IOException) EmptyChange(liquibase.change.core.EmptyChange) DatabaseChangeLog(liquibase.changelog.DatabaseChangeLog) ChangeLogParseException(liquibase.exception.ChangeLogParseException) BufferedReader(java.io.BufferedReader) UtfBomAwareReader(liquibase.resource.UtfBomAwareReader) ChangeSet(liquibase.changelog.ChangeSet)

Example 3 with UtfBomAwareReader

use of liquibase.resource.UtfBomAwareReader in project liquibase by liquibase.

the class StreamUtil method getStreamContents.

/**
     * Reads a stream until the end of file into a String and uses the machines
     * default encoding to convert to characters the bytes from the Stream.
     *
     * @param ins The InputStream to read.
     * @param  charsetName The name of a supported {@link java.nio.charset.Charset </code>charset<code>}
     * @return The contents of the input stream as a String
     * @throws IOException If there is an error reading the stream.
     */
public static String getStreamContents(InputStream ins, String charsetName) throws IOException {
    UtfBomAwareReader reader;
    if (ins == null) {
        throw new IOException("No stream to open");
    }
    try {
        if (charsetName == null) {
            reader = new UtfBomAwareReader(ins);
        } else {
            String charsetCanonicalName = Charset.forName(charsetName).name();
            String encoding;
            reader = new UtfBomAwareReader(ins, charsetName);
            encoding = Charset.forName(reader.getEncoding()).name();
            if (charsetCanonicalName.startsWith("UTF") && !charsetCanonicalName.equals(encoding)) {
                reader.close();
                throw new IllegalArgumentException("Expected encoding was '" + charsetCanonicalName + "' but a BOM was detected for '" + encoding + "'");
            }
        }
        return getReaderContents(reader);
    } finally {
        ins.close();
    }
}
Also used : UtfBomAwareReader(liquibase.resource.UtfBomAwareReader)

Example 4 with UtfBomAwareReader

use of liquibase.resource.UtfBomAwareReader in project liquibase by liquibase.

the class FormattedSqlChangeLogParser method supports.

@Override
public boolean supports(String changeLogFile, ResourceAccessor resourceAccessor) {
    BufferedReader reader = null;
    try {
        if (changeLogFile.endsWith(".sql")) {
            InputStream fileStream = openChangeLogFile(changeLogFile, resourceAccessor);
            if (fileStream == null) {
                return false;
            }
            reader = new BufferedReader(new UtfBomAwareReader(fileStream));
            String line = reader.readLine();
            return line != null && line.matches("\\-\\-\\s*liquibase formatted.*");
        } else {
            return false;
        }
    } catch (IOException e) {
        LogFactory.getLogger().debug("Exception reading " + changeLogFile, e);
        return false;
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                LogFactory.getLogger().debug("Exception closing " + changeLogFile, e);
            }
        }
    }
}
Also used : InputStream(java.io.InputStream) BufferedReader(java.io.BufferedReader) IOException(java.io.IOException) UtfBomAwareReader(liquibase.resource.UtfBomAwareReader)

Aggregations

UtfBomAwareReader (liquibase.resource.UtfBomAwareReader)4 BufferedReader (java.io.BufferedReader)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 Reader (java.io.Reader)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 Labels (liquibase.Labels)1 EmptyChange (liquibase.change.core.EmptyChange)1 RawSQLChange (liquibase.change.core.RawSQLChange)1 ChangeSet (liquibase.changelog.ChangeSet)1 DatabaseChangeLog (liquibase.changelog.DatabaseChangeLog)1 ChangeLogParseException (liquibase.exception.ChangeLogParseException)1 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)1 EmptyLineAndCommentSkippingInputStream (liquibase.io.EmptyLineAndCommentSkippingInputStream)1 PreconditionContainer (liquibase.precondition.core.PreconditionContainer)1 ResourceAccessor (liquibase.resource.ResourceAccessor)1 CSVReader (liquibase.util.csv.CSVReader)1