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);
}
}
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.");
}
}
}
Aggregations