(四)PrestoDB源码解析(一)

本文介绍了PrestoDB的presto-cli模块,主要负责SQL查询的客户端功能。它通过RESTful请求将SQL发送给Coordinator执行。查询流程包括用户输入SQL,组装成RESTful请求,发送给Coordinator,接收并分批查询结果。源码分析涉及Presto、Console、StatementClientFactory和Query等类,详细阐述了SQL执行和结果获取的过程。
摘要由CSDN通过智能技术生成

presto-cli模块

概要

  1. 该模块主要负责查询SQL的客户端功能,利用RESTful请求发送给Coordinator实现SQL语句的查询。
  2. PrestoDB可以通过presto-cli客户端和JDBC连接这两种方法实现SQL的查询。
  3. presto-cli模块查询流程:通过用户输入SQL将语句组装成一个RESTful请求,发送给Coordinator执行该SQL,并启动查询方法,分批查询结果和用于下一个RESTful请求的nextUrl地址,如果地址为空则停止查询,否则再次发送HTTP请求进行结果查询,不断返回给客户端并在前端显示。

源码

  1. 进入客户端主方法:Presto类(该方法主要是客户端的启动方法)
//这是进入客户端的主方法
public final class Presto
{
    private Presto() {}

    public static void main(String[] args)
    {
        //根据传递的参数初始化一个Console对象,该对象保存了启动cli时的所有参数
        Console console = singleCommand(Console.class).parse(args);
        //如果启动的时候有--help等,返回帮助信息然后退出
        if (console.helpOption.showHelpIfRequested() ||
                console.versionOption.showVersionIfRequested()) {
            return;
        }

        System.exit(console.run() ? 0 : 1);
    }
}
  1. 进入实际运行的线程run:Console类(该方法主要包装,获取参数并提交查询)
   public boolean run()
    {
        //获取所有客户端传入的参数,参数已经被组装到ClientSession
        ClientSession session = clientOptions.toClientSession();
        //如果Cli启动的时候指定了--execute,则hasQuery为true,说明需要直接执行shell传入的参数
        boolean hasQuery = !isNullOrEmpty(clientOptions.execute);
        //如果Cli启动的时候指定了-f或者--file,则isFromFile为true,说明需要直接执行文件中的SQL
        boolean isFromFile = !isNullOrEmpty(clientOptions.file);

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

        //初始化日志
        initializeLogging(clientOptions.logLevelsFile);

        //获取--execute对应的sql,这里指:如果通过--execute在运行客户端jar包时就指定了sql的话直接从这里拿sql
        String query = clientOptions.execute;
        if (hasQuery) {
            query += ";";
        }

        if (isFromFile) {
            if (hasQuery) {
                //在启动时不能同时指定execute和file
                throw new RuntimeException("both --execute and --file specified");
            }
            try {
                //读取文件中的sql
                query = Files.asCharSource(new File(clientOptions.file), UTF_8).read();
                hasQuery = true;
            }
            catch (IOException e) {
                throw new RuntimeException(format("Error reading from file %s: %s", clientOptions.file, e.getMessage()));
            }
        }

        // abort any running query if the CLI is terminated
        AtomicBoolean exiting = new AtomicBoolean();
        ThreadInterruptor interruptor = new ThreadInterruptor();
        CountDownLatch exited = new CountDownLatch(1);
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            exiting.set(true);
            interruptor.interrupt();
            awaitUninterruptibly(exited, EXIT_DELAY.toMillis(), MILLISECONDS);
        }));

        //生成一个查询的包装类,后面的查询会通过该类启动和执行
        try (QueryRunner queryRunner = new QueryRunner(
                session,
                clientOptions.debug,
                Optional.ofNullable(clientOptions.socksProxy),
                Optional.ofNullable(clientOptions.httpProxy),
                Optional.ofNullable(clientOptions.keystorePath),
                Optional.ofNullable(clientOptions.keystorePassword),
                Optional.ofNullable(clientOptions.truststorePath),
                Optional.ofNullable(clientOptions.truststorePassword),
                Optional.ofNullable(clientOptions.accessToken),
                Optional.ofNullable(clientOptions.user),
                clientOptions.password ? Optional.of(getPassword()) : Optional.empty(),
                Optional.ofNullable(clientOptions.krb5Principal),
                Optional.ofNullable(clientOptions.krb5RemoteServiceName),
                Optional.ofNullable(clientOptions.krb5ConfigPath),
                Optional.ofNullable(clientOptions.krb5KeytabPath),
                Optional.ofNullable(clientOptions.krb5CredentialCachePath),
                !clientOptions.krb5DisableRemoteServiceHostnameCanonicalization)) {
            if (hasQuery) {
                //启动Cli的时候指定--execute或--file参数,则执行该方法,否则就直接启动Cli,接受终端用户在Cli的输入,并提交查询
                return executeCommand(queryRunner, query, clientOptions.outputFormat, clientOptions.ignoreErrors);
            }
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值