DeepSeek改写glaredb的示例实现自定义CLI界面程序

GlareDB最近将它的软件包发布到了 crates.io,并给出了示例

我新建了一个rust项目,

cargo new gldbe --vcs none
    Creating binary (application) `gldbe` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
export PATH=/par/mold240/bin:$PATH
export CARGO_INCREMENTAL=1
cargo build --release
error: could not find `Cargo.toml` in `/par` or any parent directory
cd gldbe
cargo build --release

让DeepSeek把示例注释翻译成中文,并加入处理查询的CLI界面函数。然后把代码复制粘贴到项目的main.rs中。

编译出错了。

error: failed to run custom build command for `glaredb_proto v25.6.3`

Caused by:
  process didn't exit successfully: `/par/gldbe/target/release/build/glaredb_proto-ee8a4e4c2c6ac941/build-script-build` (exit status: 1)
  --- stdout
  Could not find `protoc`. If `protoc` is installed, try setting the `PROTOC` environment variable to the path of the `protoc` binary. To install it on Debian, run `apt-get install protobuf-compiler`. It is also available at https://github.com/protocolbuffers/protobuf/releases  For more information: https://docs.rs/prost-build/#sourcing-protoc
warning: build failed, waiting for other jobs to finish...

从https://github.1git.de/protocolbuffers/protobuf/releases/download/v31.1/protoc-31.1-linux-x86_64.zip下载protoc的二进制包,并把protoc文件解压到/par, 再将/par加入搜索路径PATH环境变量。

export PATH=/par:/par/mold240/bin:$PATH

注意不要下载错误的版本,我一开始误下载了aarch-64版本,结果报错:

Caused by:
  process didn't exit successfully: `/par/gldbe/target/release/build/glaredb_proto-ee8a4e4c2c6ac941/build-script-build` (exit status: 1)
  --- stdout
  failed to invoke protoc (hint: https://docs.rs/prost-build/#sourcing-protoc): (path: protoc): Exec format error (os error 8)

再次编译,又有一个错误,问题出在新增的cli_interface函数中。

error[E0433]: failed to resolve: use of unresolved module or unlinked crate `tokio`
  --> src/main.rs:33:54
   |
33 | fn cli_interface(engine: SingleUserEngine, tokio_rt: tokio::runtime::Runtime) -> Result<(), Box<dyn Error>> {
   |                                                      ^^^^^ use of unresolved module or unlinked crate `tokio`
   |
   = help: if you wanted to use a crate named `tokio`, use `cargo add tokio` to add it to your `Cargo.toml`

error[E0107]: missing generics for struct `SingleUserEngine`
  --> src/main.rs:33:26
   |
33 | fn cli_interface(engine: SingleUserEngine, tokio_rt: tokio::runtime::Runtime) -> Result<(), Box<dyn Error>> {
   |                          ^^^^^^^^^^^^^^^^ expected 2 generic arguments
   |
note: struct defined here, with 2 generic parameters: `P`, `R`
  --> /usr/local/cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-4dc01642fd091eda/glaredb_core-25.6.3/src/engine/single_user.rs:19:12
   |
19 | pub struct SingleUserEngine<P: PipelineRuntime, R: SystemRuntime> {
   |            ^^^^^^^^^^^^^^^^ -                   -
help: add missing generic arguments
   |
33 | fn cli_interface(engine: SingleUserEngine<P, R>, tokio_rt: tokio::runtime::Runtime) -> Result<(), Box<dyn Error>> {
   |                                          ++++++

Some errors have detailed explanations: E0107, E0433.

把cli_interface函数体代码从函数中摘出来,直接放在main函数中,编译就通过了。(从注释可以看到)

use std::error::Error;

use glaredb_core::{
    arrays::format::pretty::{components::PRETTY_COMPONENTS, table::PrettyTable},
    engine::single_user::SingleUserEngine,
};
use glaredb_rt_native::runtime::{
    NativeSystemRuntime, ThreadedNativeExecutor, new_tokio_runtime_for_io,
};

fn main() -> Result<(), Box<dyn Error>> {
    // 创建一个用于远程IO(对象存储)的tokio运行时。如果已经存在tokio运行时,可以跳过此步骤。
    // 应该将现有tokio运行时的句柄传递给NativeSystemRuntime。
    let tokio_rt = new_tokio_runtime_for_io()?;
    // 创建一个用于执行查询的'执行器'。`try_new`会创建一个使用所有线程的线程池。
    // 也可以使用`try_new_with_num_threads`作为替代方案。
    let executor = ThreadedNativeExecutor::try_new()?;
    // 创建一个用于访问外部数据(如文件系统、HTTP客户端等)的'运行时'。
    let runtime = NativeSystemRuntime::new(tokio_rt.handle().clone());

    // 数据库引擎的简单包装器,包含一个连接到该数据库引擎的会话。
    let engine = SingleUserEngine::try_new(executor, runtime.clone())?;
    // 注册所有默认扩展(parquet, csv等)。或者可以使用单独的`ext_` crate有选择地注册扩展。
    glaredb_ext_default::register_all(&engine.engine)?;

    // 启动CLI界面
    //cli_interface(engine, tokio_rt)?;

    //Ok(())
//}

/// 实现一个简单的CLI界面,允许用户输入SQL查询并查看结果
//fn cli_interface(engine: SingleUserEngine, tokio_rt: tokio::runtime::Runtime) -> Result<(), Box<dyn Error>> {
    use std::io::{self, Write};
    
    println!("GlareDB CLI (输入.exit退出)");
    
    loop {
        print!("gldbe> ");
        io::stdout().flush()?;
        
        let mut input = String::new();
        io::stdin().read_line(&mut input)?;
        
        // 去除前后空白字符
        let input = input.trim();
        
        // 检查退出命令
        if input.eq_ignore_ascii_case(".exit") {
            break;
        }
        
        // 跳过空输入
        if input.is_empty() {
            continue;
        }
        
        // 执行查询并显示结果
        let (batches, schema) = tokio_rt.block_on(async {
            let mut q_res = engine
                .session()
                .query(input)
                .await?;

            let batches = q_res.output.collect().await?;
            Ok::<_, Box<dyn Error>>((batches, q_res.output_schema))
        })?;

        let table = PrettyTable::try_new(&schema, &batches, 100, None, PRETTY_COMPONENTS)?;
        println!("{table}");
    }
    
    Ok(())
}

以下是执行效果, 很简陋,也很实用,没有什么多余的功能,各人可以在此基础上发挥。

target/release/gldbe
GlareDB CLI (输入.exit退出)
gldbe> .timer on
Error: Expected a SQL statement, got Period

target/release/gldbe
GlareDB CLI (输入.exit退出)
gldbe> select 1 a,'abc' b;
┌───────┬──────┐
│ a     │ b    │
│ Int32 │ Utf8 │
├───────┼──────┤
│     1 │ abc  │
└───────┴──────┘
gldbe> select * from '/par/foods.csv' limit 4;
┌────────────┬──────────┬─────────┬──────────┐
│ category   │ calories │ fats_g  │ sugars_g │
│ Utf8       │ Int64    │ Float64 │ Int64    │
├────────────┼──────────┼─────────┼──────────┤
│ vegetables │       450.52 │
│ seafood    │      15050 │
│ meat       │      10050 │
│ fruit      │       60011 │
└────────────┴──────────┴─────────┴──────────┘
gldbe> .exit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值