Search in sources :

Example 1 with SQLControlToken

use of org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken in project dbeaver by dbeaver.

the class ExasolSQLDialect method extendRules.

@Override
public void extendRules(@NotNull List<IRule> rules, @NotNull SQLRuleProvider.RulePosition position) {
    if (position == SQLRuleProvider.RulePosition.CONTROL) {
        final SQLControlToken defineToken = new SQLControlToken(new TextAttribute(UIUtils.getGlobalColor(SQLConstants.CONFIG_COLOR_COMMAND), null, SWT.BOLD), "exasol.define");
        // $NON-NLS-1$
        SQLFullLineRule defineRule = new SQLFullLineRule("define", defineToken);
        rules.add(defineRule);
        // $NON-NLS-1$
        SQLFullLineRule defineRule2 = new SQLFullLineRule("DEFINE", defineToken);
        rules.add(defineRule2);
    }
}
Also used : SQLFullLineRule(org.jkiss.dbeaver.ui.editors.sql.syntax.rules.SQLFullLineRule) TextAttribute(org.eclipse.jface.text.TextAttribute) SQLControlToken(org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken)

Example 2 with SQLControlToken

use of org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken in project dbeaver by dbeaver.

the class MySQLDialect method extendRules.

@Override
public void extendRules(@NotNull List<IRule> rules, @NotNull RulePosition position) {
    if (position == RulePosition.CONTROL) {
        final SQLControlToken sourceToken = new SQLControlToken(new TextAttribute(UIUtils.getGlobalColor(SQLConstants.CONFIG_COLOR_COMMAND), null, SWT.BOLD), "mysql.source");
        // $NON-NLS-1$
        SQLFullLineRule sourceRule2 = new SQLFullLineRule("SOURCE", sourceToken);
        rules.add(sourceRule2);
    }
}
Also used : SQLFullLineRule(org.jkiss.dbeaver.ui.editors.sql.syntax.rules.SQLFullLineRule) TextAttribute(org.eclipse.jface.text.TextAttribute) SQLControlToken(org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken)

Example 3 with SQLControlToken

use of org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken in project dbeaver by dbeaver.

the class SQLEditorBase method parseQuery.

protected SQLScriptElement parseQuery(final IDocument document, final int startPos, final int endPos, final int currentPos, final boolean scriptMode, final boolean keepDelimiters) {
    if (endPos - startPos <= 0) {
        return null;
    }
    SQLDialect dialect = getSQLDialect();
    // Parse range
    boolean useBlankLines = !scriptMode && syntaxManager.isBlankLineDelimiter();
    ruleManager.setRange(document, startPos, endPos - startPos);
    int statementStart = startPos;
    int bracketDepth = 0;
    boolean hasBlocks = false;
    boolean hasValuableTokens = false;
    boolean hasBlockHeader = false;
    String blockTogglePattern = null;
    int lastTokenLineFeeds = 0;
    int prevNotEmptyTokenType = SQLToken.T_UNKNOWN;
    for (; ; ) {
        IToken token = ruleManager.nextToken();
        int tokenOffset = ruleManager.getTokenOffset();
        int tokenLength = ruleManager.getTokenLength();
        int tokenType = token instanceof SQLToken ? ((SQLToken) token).getType() : SQLToken.T_UNKNOWN;
        if (tokenOffset < startPos) {
            // This may happen with EOF tokens (bug in jface?)
            return null;
        }
        boolean isDelimiter = tokenType == SQLToken.T_DELIMITER;
        boolean isControl = false;
        String delimiterText = null;
        try {
            if (isDelimiter) {
                // Save delimiter text
                try {
                    delimiterText = document.get(tokenOffset, tokenLength);
                } catch (BadLocationException e) {
                    log.debug(e);
                }
            } else if (useBlankLines && token.isWhitespace() && tokenLength >= 1) {
                // Check for blank line delimiter
                if (lastTokenLineFeeds + countLineFeeds(document, tokenOffset, tokenLength) >= 2) {
                    isDelimiter = true;
                }
            }
            lastTokenLineFeeds = 0;
            if (tokenLength == 1) {
                // Check for bracket block begin/end
                try {
                    char aChar = document.getChar(tokenOffset);
                    if (aChar == '(' || aChar == '{' || aChar == '[') {
                        bracketDepth++;
                    } else if (aChar == ')' || aChar == '}' || aChar == ']') {
                        bracketDepth--;
                    }
                } catch (BadLocationException e) {
                    log.warn(e);
                }
            }
            if (tokenType == SQLToken.T_BLOCK_BEGIN && prevNotEmptyTokenType == SQLToken.T_BLOCK_END) {
                // This is a tricky thing.
                // In some dialects block end looks like END CASE, END LOOP. It is parsed as
                // Block end followed by block begin (as CASE and LOOP are block begin tokens)
                // So let's ignore block begin if previos token was block end and there were no delimtiers.
                tokenType = SQLToken.T_UNKNOWN;
            }
            if (tokenType == SQLToken.T_BLOCK_HEADER) {
                bracketDepth++;
                hasBlocks = true;
                hasBlockHeader = true;
            } else if (tokenType == SQLToken.T_BLOCK_TOGGLE) {
                String togglePattern;
                try {
                    togglePattern = document.get(tokenOffset, tokenLength);
                } catch (BadLocationException e) {
                    log.warn(e);
                    togglePattern = "";
                }
                // Toggles can be nested (PostgreSQL) and we need to count only outer
                if (bracketDepth == 1 && togglePattern.equals(blockTogglePattern)) {
                    bracketDepth--;
                    blockTogglePattern = null;
                } else if (bracketDepth == 0 && blockTogglePattern == null) {
                    bracketDepth++;
                    blockTogglePattern = togglePattern;
                } else {
                    log.debug("Block toggle token inside another block. Can't process it");
                }
                hasBlocks = true;
            } else if (tokenType == SQLToken.T_BLOCK_BEGIN) {
                if (!hasBlockHeader) {
                    bracketDepth++;
                }
                hasBlocks = true;
                hasBlockHeader = false;
            } else if (bracketDepth > 0 && tokenType == SQLToken.T_BLOCK_END) {
                // This END doesn't mean block
                if (hasBlocks) {
                    bracketDepth--;
                }
                hasBlockHeader = false;
            } else if (isDelimiter && bracketDepth > 0) {
                // Delimiter in some brackets - ignore it
                continue;
            } else if (tokenType == SQLToken.T_SET_DELIMITER || tokenType == SQLToken.T_CONTROL) {
                isDelimiter = true;
                isControl = true;
            } else if (tokenType == SQLToken.T_COMMENT) {
                lastTokenLineFeeds = tokenLength < 2 ? 0 : countLineFeeds(document, tokenOffset + tokenLength - 2, 2);
            }
            boolean cursorInsideToken = currentPos >= tokenOffset && currentPos < tokenOffset + tokenLength;
            if (isControl && (scriptMode || cursorInsideToken) && !hasValuableTokens) {
                // Control query
                try {
                    String controlText = document.get(tokenOffset, tokenLength);
                    String commandId = null;
                    if (token instanceof SQLControlToken) {
                        commandId = ((SQLControlToken) token).getCommandId();
                    }
                    return new SQLControlCommand(getDataSource(), syntaxManager, controlText.trim(), commandId, tokenOffset, tokenLength, tokenType == SQLToken.T_SET_DELIMITER);
                } catch (BadLocationException e) {
                    // $NON-NLS-1$
                    log.warn("Can't extract control statement", e);
                    return null;
                }
            }
            if (hasValuableTokens && (token.isEOF() || (isDelimiter && tokenOffset >= currentPos) || tokenOffset > endPos)) {
                if (tokenOffset > endPos) {
                    tokenOffset = endPos;
                }
                if (tokenOffset >= document.getLength()) {
                    // Sometimes (e.g. when comment finishing script text)
                    // last token offset is beyond document range
                    tokenOffset = document.getLength();
                }
                assert (tokenOffset >= currentPos);
                try {
                    // remove leading spaces
                    while (statementStart < tokenOffset && Character.isWhitespace(document.getChar(statementStart))) {
                        statementStart++;
                    }
                    /*
                        while (statementStart < tokenOffset && Character.isWhitespace(document.getChar(tokenOffset - 1))) {
                            tokenOffset--;
                            tokenLength++;
                        }
*/
                    if (tokenOffset == statementStart) {
                        // Empty statement
                        if (token.isEOF()) {
                            return null;
                        }
                        statementStart = tokenOffset + tokenLength;
                        continue;
                    }
                    String queryText = document.get(statementStart, tokenOffset - statementStart);
                    queryText = SQLUtils.fixLineFeeds(queryText);
                    if (isDelimiter && (keepDelimiters || (hasBlocks ? dialect.isDelimiterAfterBlock() : dialect.isDelimiterAfterQuery()))) {
                        if (delimiterText != null && delimiterText.equals(SQLConstants.DEFAULT_STATEMENT_DELIMITER)) {
                            // Add delimiter in the end of query. Do this only for semicolon delimiters
                            // Quite dirty workaround needed for SQL server
                            queryText += delimiterText;
                        }
                    }
                    int queryEndPos = tokenOffset;
                    if (tokenType == SQLToken.T_DELIMITER) {
                        queryEndPos += tokenLength;
                    }
                    // make script line
                    return new SQLQuery(getDataSource(), queryText, statementStart, queryEndPos - statementStart);
                } catch (BadLocationException ex) {
                    // $NON-NLS-1$
                    log.warn("Can't extract query", ex);
                    return null;
                }
            }
            if (isDelimiter) {
                statementStart = tokenOffset + tokenLength;
            }
            if (token.isEOF()) {
                return null;
            }
            if (!hasValuableTokens && !token.isWhitespace() && !isControl) {
                if (tokenType == SQLToken.T_COMMENT) {
                    hasValuableTokens = dialect.supportsCommentQuery();
                } else {
                    hasValuableTokens = true;
                }
            }
        } finally {
            if (!token.isWhitespace() && !token.isEOF()) {
                prevNotEmptyTokenType = tokenType;
            }
        }
    }
}
Also used : IToken(org.eclipse.jface.text.rules.IToken) SQLToken(org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLToken) BasicSQLDialect(org.jkiss.dbeaver.model.impl.sql.BasicSQLDialect) SQLControlToken(org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken)

Aggregations

SQLControlToken (org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken)3 TextAttribute (org.eclipse.jface.text.TextAttribute)2 SQLFullLineRule (org.jkiss.dbeaver.ui.editors.sql.syntax.rules.SQLFullLineRule)2 IToken (org.eclipse.jface.text.rules.IToken)1 BasicSQLDialect (org.jkiss.dbeaver.model.impl.sql.BasicSQLDialect)1 SQLToken (org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLToken)1