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

com.jn.sqlhelper.common.sql.sqlscript.PlainSqlScriptParser Maven / Gradle / Ivy

There is a newer version: 5.0.7
Show newest version
package com.jn.sqlhelper.common.sql.sqlscript;

import com.jn.langx.Named;
import com.jn.langx.Parser;
import com.jn.langx.io.resource.Resource;
import com.jn.langx.io.resource.Resources;
import com.jn.langx.util.Strings;
import com.jn.langx.util.collection.Collects;
import com.jn.langx.util.function.Consumer;
import com.jn.langx.util.io.Charsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 *  一行只能一个简单的SQL,但不能一行多个SQL语句。
 *  支持一个SQL语句要跨行。
 *  不支持字符串跨行。
 *  对于自定义换行符的语句,要单独成行
 */
public abstract class PlainSqlScriptParser implements Parser>, Named {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    public List parse(PlainSqlScript sqlScript) {
        Resource sqlScriptResource = sqlScript.getResource();
        final List lines = Collects.emptyArrayList();
        Resources.readUsingDelimiter(sqlScriptResource, "\n", Charsets.getCharset(sqlScript.getEncoding()), new Consumer() {
            @Override
            public void accept(String line) {
                lines.add(line);
            }
        });
        List sqls = linesToStatements(lines);
        return sqls;
    }

    protected PlainSqlStatementBuilder newSqlStatementBuilder(){
        return new PlainSqlStatementBuilder();
    }

    /**
     * Turns these lines in a series of statements.
     *
     * @param lines The lines to analyse.
     * @return The statements contained in these lines (in order).
     */
    /* private -> for testing */
    protected List linesToStatements(List lines) {
        List statements = new ArrayList();

        PlainSqlDelimiter nonStandardDelimiter = null;
        PlainSqlStatementBuilder sqlStatementExtractor = newSqlStatementBuilder();

        for (int lineNumber = 1; lineNumber <= lines.size(); lineNumber++) {
            String line = lines.get(lineNumber - 1);

            if (sqlStatementExtractor.isEmpty()) {
                if (Strings.isBlank(line)) {
                    // Skip empty line between statements.
                    continue;
                }

                PlainSqlDelimiter newDelimiter = sqlStatementExtractor.extractNewDelimiterFromLine(line);
                if (newDelimiter != null) {
                    nonStandardDelimiter = newDelimiter;
                    // Skip this line as it was an explicit delimiter change directive outside of any statements.
                    continue;
                }

                sqlStatementExtractor.setLineNumber(lineNumber);

                // Start a new statement, marking it with this line number.
                if (nonStandardDelimiter != null) {
                    sqlStatementExtractor.setDelimiter(nonStandardDelimiter);
                }
            }

            sqlStatementExtractor.addLine(line);

            if (sqlStatementExtractor.isTerminated()) {
                PlainSqlStatement sqlStatement = sqlStatementExtractor.getSqlStatement();
                statements.add(sqlStatement);
                logger.debug("Found statement at line " + sqlStatement.getLineNumber() + ": " + sqlStatement.getSql());

                sqlStatementExtractor = newSqlStatementBuilder();
            } else if (sqlStatementExtractor.canDiscard()) {
                sqlStatementExtractor = newSqlStatementBuilder();
            }
        }

        // Catch any statements not followed by delimiter.
        if (!sqlStatementExtractor.isEmpty()) {
            statements.add(sqlStatementExtractor.getSqlStatement());
        }

        return statements;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy