com.facebook.presto.cli.ConsoleOld.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.presto.cli.ConsoleOld.java

Source

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.facebook.presto.cli;

import com.facebook.presto.cli.ClientOptions.OutputFormat;
import com.facebook.presto.client.ClientSession;
import com.facebook.presto.sql.parser.StatementSplitter;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.Files;
import io.airlift.command.Command;
import io.airlift.command.HelpOption;
import io.airlift.log.Logging;
import io.airlift.log.LoggingConfiguration;
import jline.console.history.FileHistory;
import jline.console.history.MemoryHistory;
import org.fusesource.jansi.AnsiConsole;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;

import static com.facebook.presto.cli.Help.getHelpText;
import static com.facebook.presto.sql.parser.StatementSplitter.Statement;
import static com.facebook.presto.sql.parser.StatementSplitter.squeezeStatement;
import static com.google.common.io.ByteStreams.nullOutputStream;
import static io.airlift.log.Logging.Level;
import static java.lang.String.format;
import static jline.internal.Configuration.getUserHome;

@Command(name = "presto", description = "Presto interactive console")
public class ConsoleOld implements Runnable {
    private static final String PROMPT_NAME = "presto";

    @Inject
    public HelpOption helpOption;

    @Inject
    public ClientOptions clientOptions = new ClientOptions();

    @Override
    public void run() {
        ClientSession session = clientOptions.toClientSession();
        boolean hasQuery = !Strings.isNullOrEmpty(clientOptions.execute);
        boolean isFromFile = !Strings.isNullOrEmpty(clientOptions.file);

        if (!hasQuery || !isFromFile) {
            AnsiConsole.systemInstall();
        }

        initializeLogging(session.isDebug());

        String query = clientOptions.execute;
        if (isFromFile) {
            if (hasQuery) {
                throw new RuntimeException("both --execute and --file specified");
            }
            try {
                query = Files.toString(new File(clientOptions.file), Charsets.UTF_8);
                hasQuery = true;
            } catch (IOException e) {
                throw new RuntimeException(
                        format("Error reading from file %s: %s", clientOptions.file, e.getMessage()));
            }
        }

        try (QueryRunner queryRunner = QueryRunner.create(session)) {
            if (hasQuery) {
                executeCommand(queryRunner, query, clientOptions.outputFormat);
            } else {
                runConsole(queryRunner, session);
            }
        }
    }

    @SuppressWarnings("fallthrough")
    private void runConsole(QueryRunner queryRunner, ClientSession session) {
        try (TableNameCompleter tableNameCompleter = new TableNameCompleter(clientOptions.toClientSession(),
                queryRunner); LineReader reader = new LineReader(getHistory(), tableNameCompleter)) {
            tableNameCompleter.populateCache(session.getSchema());
            StringBuilder buffer = new StringBuilder();
            while (true) {
                // read a line of input from user
                String prompt = PROMPT_NAME + ":" + session.getSchema();
                if (buffer.length() > 0) {
                    prompt = Strings.repeat(" ", prompt.length() - 1) + "-";
                }
                String line = reader.readLine(prompt + "> ");

                // add buffer to history and clear on user interrupt
                if (reader.interrupted()) {
                    String partial = squeezeStatement(buffer.toString());
                    if (!partial.isEmpty()) {
                        reader.getHistory().add(partial);
                    }
                    buffer = new StringBuilder();
                    continue;
                }

                // exit on EOF
                if (line == null) {
                    return;
                }

                // check for special commands if this is the first line
                if (buffer.length() == 0) {
                    String command = line.trim();
                    if (command.endsWith(";")) {
                        command = command.substring(0, command.length() - 1).trim();
                    }
                    switch (command.toLowerCase()) {
                    case "exit":
                    case "quit":
                        return;
                    case "help":
                        System.out.println();
                        System.out.println(getHelpText());
                        continue;
                    }
                }

                // not a command, add line to buffer
                buffer.append(line).append("\n");

                // execute any complete statements
                String sql = buffer.toString();
                StatementSplitter splitter = new StatementSplitter(sql, ImmutableSet.of(";", "\\G"));
                for (Statement split : splitter.getCompleteStatements()) {
                    OutputFormat outputFormat = OutputFormat.ALIGNED;
                    if (split.terminator().equals("\\G")) {
                        outputFormat = OutputFormat.VERTICAL;
                    }

                    process(queryRunner, split.statement(), outputFormat, true);
                    reader.getHistory().add(squeezeStatement(split.statement()) + split.terminator());
                }

                // replace buffer with trailing partial statement
                buffer = new StringBuilder();
                String partial = splitter.getPartialStatement();
                if (!partial.isEmpty()) {
                    buffer.append(partial).append('\n');
                }
            }
        } catch (IOException e) {
            System.err.println("Readline error: " + e.getMessage());
        }
    }

    private static void executeCommand(QueryRunner queryRunner, String query, OutputFormat outputFormat) {
        StatementSplitter splitter = new StatementSplitter(query + ";");
        for (Statement split : splitter.getCompleteStatements()) {
            process(queryRunner, split.statement(), outputFormat, false);
        }
    }

    private static void process(QueryRunner queryRunner, String sql, OutputFormat outputFormat,
            boolean interactive) {
        try (Query query = queryRunner.startQuery(sql)) {
            query.renderOutput(System.out, outputFormat, interactive);
        } catch (RuntimeException e) {
            System.out.println("Error running command: " + e.getMessage());
            if (queryRunner.getSession().isDebug()) {
                e.printStackTrace();
            }
        }
    }

    private static MemoryHistory getHistory() {
        MemoryHistory history;
        File historyFile = new File(getUserHome(), ".presto_history");
        try {
            history = new FileHistory(historyFile);
        } catch (IOException e) {
            System.err.printf("WARNING: Failed to load history file (%s): %s. "
                    + "History will not be available during this session.%n", historyFile, e.getMessage());
            history = new MemoryHistory();
        }
        history.setAutoTrim(true);
        return history;
    }

    private static void initializeLogging(boolean debug) {
        // unhook out and err while initializing logging or logger will print to them
        PrintStream out = System.out;
        PrintStream err = System.err;
        try {
            if (debug) {
                Logging logging = Logging.initialize();
                logging.configure(new LoggingConfiguration());
                logging.setLevel("com.facebook.presto", Level.DEBUG);
            } else {
                System.setOut(nullPrintStream());
                System.setErr(nullPrintStream());

                Logging logging = Logging.initialize();
                logging.configure(new LoggingConfiguration());
                logging.disableConsole();
            }
        } catch (IOException e) {
            throw Throwables.propagate(e);
        } finally {
            System.setOut(out);
            System.setErr(err);
        }
    }

    private static PrintStream nullPrintStream() {
        return new PrintStream(nullOutputStream());
    }
}