Search in sources :

Example 1 with Resource

use of org.flywaydb.core.api.resource.Resource in project flyway by flyway.

the class Parser method getNextStatement.

protected SqlStatement getNextStatement(Resource resource, PeekingReader reader, Recorder recorder, PositionTracker tracker, ParserContext context) {
    resetDelimiter(context);
    context.setStatementType(StatementType.UNKNOWN);
    int statementLine = tracker.getLine();
    int statementCol = tracker.getCol();
    try {
        List<Token> tokens = new ArrayList<>();
        List<Token> keywords = new ArrayList<>();
        int statementPos = -1;
        recorder.start();
        int nonCommentPartPos = -1;
        int nonCommentPartLine = -1;
        int nonCommentPartCol = -1;
        StatementType statementType = StatementType.UNKNOWN;
        Boolean canExecuteInTransaction = null;
        String simplifiedStatement = "";
        do {
            Token token = readToken(reader, tracker, context);
            if (token == null) {
                if (tokens.isEmpty()) {
                    recorder.start();
                    statementLine = tracker.getLine();
                    statementCol = tracker.getCol();
                    simplifiedStatement = "";
                } else {
                    recorder.confirm();
                }
                continue;
            }
            TokenType tokenType = token.getType();
            if (tokenType == TokenType.NEW_DELIMITER) {
                if (!tokens.isEmpty() && nonCommentPartPos >= 0) {
                    String sql = recorder.stop();
                    throw new FlywayException("Delimiter changed inside statement at line " + statementLine + " col " + statementCol + ": " + sql);
                }
                context.setDelimiter(new Delimiter(token.getText(), false));
                tokens.clear();
                recorder.start();
                statementLine = tracker.getLine();
                statementCol = tracker.getCol();
                simplifiedStatement = "";
                continue;
            }
            if (shouldDiscard(token, nonCommentPartPos >= 0)) {
                tokens.clear();
                recorder.start();
                statementLine = tracker.getLine();
                statementCol = tracker.getCol();
                simplifiedStatement = "";
                continue;
            }
            if (shouldAdjustBlockDepth(context, tokens, token)) {
                if (tokenType == TokenType.KEYWORD) {
                    keywords.add(token);
                }
                adjustBlockDepth(context, tokens, token, reader);
            }
            int parensDepth = token.getParensDepth();
            int blockDepth = context.getBlockDepth();
            if (TokenType.EOF == tokenType || (TokenType.DELIMITER == tokenType && parensDepth == 0 && blockDepth == 0)) {
                String sql = recorder.stop();
                if (TokenType.EOF == tokenType && (sql.trim().isEmpty() || tokens.isEmpty() || nonCommentPartPos < 0)) {
                    return null;
                }
                if (canExecuteInTransaction == null) {
                    canExecuteInTransaction = determineCanExecuteInTransaction(simplifiedStatement, keywords, true);
                }
                if (TokenType.EOF == tokenType && (parensDepth > 0 || blockDepth > 0)) {
                    throw new FlywayException("Incomplete statement at line " + statementLine + " col " + statementCol + ": " + sql);
                }
                return createStatement(reader, recorder, statementPos, statementLine, statementCol, nonCommentPartPos, nonCommentPartLine, nonCommentPartCol, statementType, canExecuteInTransaction, context.getDelimiter(), sql.trim());
            }
            if (tokens.isEmpty() || tokens.stream().allMatch(t -> t.getType() == TokenType.BLANK_LINES || t.getType() == TokenType.COMMENT)) {
                nonCommentPartPos = -1;
                nonCommentPartLine = -1;
                nonCommentPartCol = -1;
                statementPos = token.getPos();
                statementLine = token.getLine();
                statementCol = token.getCol();
            }
            tokens.add(token);
            recorder.confirm();
            if (nonCommentPartPos < 0 && TokenType.COMMENT != tokenType && TokenType.DELIMITER != tokenType && TokenType.BLANK_LINES != tokenType) {
                nonCommentPartPos = token.getPos();
                nonCommentPartLine = token.getLine();
                nonCommentPartCol = token.getCol();
            }
            if (keywords.size() <= getTransactionalDetectionCutoff() && (tokenType == TokenType.KEYWORD) && parensDepth == 0 && (statementType == StatementType.UNKNOWN || canExecuteInTransaction == null)) {
                if (!simplifiedStatement.isEmpty()) {
                    simplifiedStatement += " ";
                }
                simplifiedStatement += token.getText().toUpperCase(Locale.ENGLISH);
                if (statementType == StatementType.UNKNOWN) {
                    if (keywords.size() > getTransactionalDetectionCutoff()) {
                        statementType = StatementType.GENERIC;
                    } else {
                        statementType = detectStatementType(simplifiedStatement, context, reader);
                        context.setStatementType(statementType);
                    }
                    adjustDelimiter(context, statementType);
                }
                if (canExecuteInTransaction == null) {
                    canExecuteInTransaction = determineCanExecuteInTransaction(simplifiedStatement, keywords, null);
                }
            }
        } while (true);
    } catch (Exception e) {
        IOUtils.close(reader);
        throw new FlywayException("Unable to parse statement in " + resource.getAbsolutePath() + " at line " + statementLine + " col " + statementCol + ". See " + FlywayDbWebsiteLinks.KNOWN_PARSER_LIMITATIONS + " for more information: " + e.getMessage(), e);
    }
}
Also used : BomStrippingReader(org.flywaydb.core.internal.util.BomStrippingReader) java.util(java.util) FlywayException(org.flywaydb.core.api.FlywayException) org.flywaydb.core.internal.sqlscript(org.flywaydb.core.internal.sqlscript) FlywayDbWebsiteLinks(org.flywaydb.core.internal.util.FlywayDbWebsiteLinks) CustomLog(lombok.CustomLog) IOException(java.io.IOException) Reader(java.io.Reader) Configuration(org.flywaydb.core.api.configuration.Configuration) Resource(org.flywaydb.core.api.resource.Resource) IOUtils(org.flywaydb.core.internal.util.IOUtils) LoadableResource(org.flywaydb.core.api.resource.LoadableResource) ResourceName(org.flywaydb.core.internal.resource.ResourceName) BufferedReader(java.io.BufferedReader) Pattern(java.util.regex.Pattern) ResourceNameParser(org.flywaydb.core.internal.resource.ResourceNameParser) FlywayException(org.flywaydb.core.api.FlywayException) FlywayException(org.flywaydb.core.api.FlywayException) IOException(java.io.IOException)

Example 2 with Resource

use of org.flywaydb.core.api.resource.Resource in project flyway by flyway.

the class ResourceNameValidator method validateSQLMigrationNaming.

/**
 * Validates the names of all SQL resources returned by the ResourceProvider
 *
 * @param provider The ResourceProvider to validate
 * @param configuration The configuration to use
 */
public void validateSQLMigrationNaming(ResourceProvider provider, Configuration configuration) {
    List<String> errorsFound = new ArrayList<>();
    ResourceNameParser resourceNameParser = new ResourceNameParser(configuration);
    for (Resource resource : getAllSqlResources(provider, configuration)) {
        String filename = resource.getFilename();
        LOG.debug("Validating " + filename);
        // Filter out special purpose files that the parser will not identify.
        if (isSpecialResourceFile(configuration, filename)) {
            continue;
        }
        ResourceName result = resourceNameParser.parse(filename);
        if (!result.isValid()) {
            errorsFound.add(result.getValidityMessage());
        }
    }
    if (!errorsFound.isEmpty()) {
        if (configuration.isValidateMigrationNaming()) {
            throw new FlywayException("Invalid SQL filenames found:\r\n" + StringUtils.collectionToDelimitedString(errorsFound, "\r\n"));
        } else {
            LOG.info(errorsFound.size() + " SQL migrations were detected but not run because they did not follow the filename convention.");
            LOG.info("If this is in error, enable debug logging or 'validateMigrationNaming' to fail fast and see a list of the invalid file names.");
        }
    }
}
Also used : FlywayException(org.flywaydb.core.api.FlywayException) ArrayList(java.util.ArrayList) Resource(org.flywaydb.core.api.resource.Resource) LoadableResource(org.flywaydb.core.api.resource.LoadableResource)

Aggregations

FlywayException (org.flywaydb.core.api.FlywayException)2 LoadableResource (org.flywaydb.core.api.resource.LoadableResource)2 Resource (org.flywaydb.core.api.resource.Resource)2 BufferedReader (java.io.BufferedReader)1 IOException (java.io.IOException)1 Reader (java.io.Reader)1 java.util (java.util)1 ArrayList (java.util.ArrayList)1 Pattern (java.util.regex.Pattern)1 CustomLog (lombok.CustomLog)1 Configuration (org.flywaydb.core.api.configuration.Configuration)1 ResourceName (org.flywaydb.core.internal.resource.ResourceName)1 ResourceNameParser (org.flywaydb.core.internal.resource.ResourceNameParser)1 org.flywaydb.core.internal.sqlscript (org.flywaydb.core.internal.sqlscript)1 BomStrippingReader (org.flywaydb.core.internal.util.BomStrippingReader)1 FlywayDbWebsiteLinks (org.flywaydb.core.internal.util.FlywayDbWebsiteLinks)1 IOUtils (org.flywaydb.core.internal.util.IOUtils)1