Package adipe.translate

Source Code of adipe.translate.Queries

package adipe.translate;

import static com.google.common.base.Preconditions.checkState;

import java.util.List;

import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.antlr.v4.runtime.tree.ErrorNode;

import ra.Term;
import ra.Utils;
import adipe.translate.impl.TranslationVisitor;
import adipe.translate.ra.Schema;
import adipe.translate.sql.parser.SqlParser;
import adipe.translate.sql.parser.SqlParser.SelectStatementContext;
import adipe.translate.sql.parser.SqlParser.SelectStatementEofContext;
import adipe.translate.sql.parser.SqlParser.SelectStatementsEofContext;
import adipe.translate.sql.parser.SqlParserUtils;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;

/**
* Utils
*
*/
public final class Queries {
    private Queries() { }

    /**
     * Get relational algebra of sql query
     * @param schema        the database schema under which to translate
     * @param sqlQuery      the sql query in a text form
     * @return              the query translated into a relational algebra term
     * @side                calls {@code Utils.reset()}
     * @side                calls {@code schema.reset()}
     * @throws TranslationException
     * @throws ParseCancellationException
     * @throws TranslationException when a derived table is parsed, but has a derived column list of the wrong size
     * @throws RuntimeException
     */
    public static Term getRaOf(Schema schema, String sqlQuery)
            throws RuntimeException, TranslationException, ParseCancellationException
    {
      // TODO do we actually throw RuntimeException?
        Utils.reset();
        schema.reset();
        SelectStatementEofContext tree = Queries.getQueryTree(sqlQuery);
        //TODO this catch code is duplicated in {@link getMultipleRas}
        try {
            return TranslationVisitor.create(schema).visit(tree);
        } catch (WrappedException e) {
            //TODO change exceptions thrown
            throw new TranslationException(e.getCause().getMessage(), e.getCause());
        } catch (NullPointerException e) {
            throw new TranslationException(String.format("%s", e), e);
        } catch (RuntimeException e) {
            // TODO the translation should not explicitly throw RuntimeException instances
            // this should only happen on programming errors, like array[-1], etc.
            String message = e.getMessage();
            if (message == null) {
                message = e.toString();
            }
            throw new TranslationException(message, e);
        }
    }

    /**
     * Get relational algebras of multiple semicolon separated sql queries
     * @param schema        the database schema under which to translate
     * @param sqlSource     the semicolon separated sql queries in a text form
     * @param queries       must be non-null
     * @param formulas      must be non-null
     * @side                calls {@code Utils.reset()}
     * @side                calls {@code schema.reset()}
     * @side                clears and populates the lists {@code queries} and {@code formulas} respectively with
     *                      the sql queries and their translated counterparts, in order of presence in {@code sqlSource}
     * @throws TranslationException
     * @throws TranslationException when a derived table is parsed, but has a derived column list of the wrong size
     * @throws ParseCancellationException
     * @throws RuntimeException
     */
    public static void getMultipleRasOf(Schema schema, String sqlSource,
            List<String> queries, List<Term> formulas) throws RuntimeException, TranslationException, ParseCancellationException {
      // TODO do we actually throw RuntimeException?
        Utils.reset();
        schema.reset();
        queries.clear();
        formulas.clear();
        List<SelectStatementContext> trees = Lists.newArrayList();
        Queries.getMultipleQueryTrees(sqlSource, queries, trees);
        try {
            for (int i = 0; i < trees.size(); ++i) {
                formulas.add(TranslationVisitor.create(schema).visit(trees.get(i)));
            }
        } catch (WrappedException e) {
            throw new TranslationException(e.getCause().getMessage(), e.getCause());
        } catch (NullPointerException e) {
            throw new TranslationException(String.format("%s", e), e);
        } catch (RuntimeException e) {
            // TODO the translation should not explicitly throw RuntimeException instances
            // this should only happen on programming errors, like array[-1], etc.
            String message = e.getMessage();
            if (message == null) {
                message = e.toString();
            }
            throw new TranslationException(message, e);

            // TODO extract common code from {@link #getMultipleRasOf} and {@link #getRaOf}
        }
    }

    /**
     * Parse an SQL query to a tree
     * Do not use, public because @VisibleForTesting
     *
     * @param source
     * @return The parse tree of the query
     * @throws ParseCancellationException
     */
    @VisibleForTesting
    public static SelectStatementEofContext getQueryTree(String source)
            throws ParseCancellationException
    {
        SelectStatementEofContext tree;
        tree = getParser(source, null).selectStatementEof();

        checkState(tree != null);
        checkState(!(tree instanceof ErrorNode));
        return tree;
    }

    /**
     * Parse multiple semicolon separated SQL queries to a trees
     *
     * @param source    semicolon separated SQL queries
     * @side  populate {@code queries} and {@code trees} with the sql queries and their trees, in order of presence in {@code source}
     * @throws ParseCancellationException
     */
    private static void getMultipleQueryTrees(String source,
            List<String> queries, List<SelectStatementContext> trees)
                    throws ParseCancellationException
    {
        SelectStatementsEofContext tree;
        queries.clear();
        trees.clear();
        List<CharStream> charStreamL = Lists.newArrayList();
        SqlParser parser = getParser(source, charStreamL);

        tree = parser.selectStatementsEof();

        checkState(tree != null);
        checkState(!(tree instanceof ErrorNode));

        for (SelectStatementContext ssctx : tree.selectStatementsEtc().selectStatement())
        {
            trees.add(ssctx);
            queries.add(charStreamL.get(0).getText(new Interval(ssctx.start.getStartIndex(), ssctx.stop.getStopIndex())));
        }
    }

    /**
     * Get a {@link Parser} instance of parsing {@code source}
     * @side   if {@code charStreamL} is not null, add the {@code CharStream} instance representing
     *         the query source into {@code charStreamL}
     * @throws none
     */
    @VisibleForTesting
    public static SqlParser getParser(String source, List<CharStream> charStreamL) {
//        System.err.println(source);

        return new SqlParserUtils().getParser(source, charStreamL);
    }
}
TOP

Related Classes of adipe.translate.Queries

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.