提示词:请用rust调用duckdb-rs实现一个duckdb CLI,支持语法突出显示和计时,还支持命令行管道输入输出
Cargo.toml

[package]
name = "duckdb-cli"
version = "0.1.0"
edition = "2024"[dependencies]
duckdb = "1.3.1"
syntect = "5.0"
atty = "0.2"
rustyline = "12.0"

main.rs

use std::{error::Error,io::{self, BufRead, Write},time::Instant,
};use duckdb::{params, Connection};
use rustyline::{completion::Completer,highlight::Highlighter,hint::Hinter,validate::Validator,Helper, history::History,
};
use syntect::{easy::HighlightLines,highlighting::{Style, ThemeSet},parsing::SyntaxSet,util::{as_24_bit_terminal_escaped, LinesWithEndings},
};fn main() -> Result<(), Box<dyn Error>> {// 初始化DuckDB连接let conn = Connection::open_in_memory()?;// 检查是否是管道输入if atty::isnt(atty::Stream::Stdin) {// 管道模式:从stdin读取SQL并执行let stdin = io::stdin();let mut stdout = io::stdout();for line in stdin.lock().lines() {let sql = line?;if sql.trim().is_empty() {continue;}let start_time = Instant::now();let mut stmt = conn.prepare(&sql)?;let rows = stmt.query_map(params![], |row| Ok(row.get::<_, String>(0)?))?;for row in rows {writeln!(stdout, "{}", row?)?;}eprintln!("Query executed in {:?}", start_time.elapsed());}} else {// 交互模式:println!("DuckDB CLI (v{})", env!("CARGO_PKG_VERSION"));println!("Enter SQL commands or .exit to quit");let mut rl = rustyline::Editor::<SQLHelper, rustyline::history::DefaultHistory>::new()?;loop {match rl.readline("duckdb> ") {Ok(line) => {let line = line.trim();if line.eq_ignore_ascii_case(".exit") {break;}if line.is_empty() {continue;}// 执行并计时let start_time = Instant::now();let mut stmt = conn.prepare(line)?;let rows = stmt.query_map(params![], |row| Ok(row.get::<_, String>(0)?))?;// 输出结果let mut count = 0;for row in rows {println!("{}", row?);count += 1;}println!("\n{} row{} in {:?}",count,if count == 1 { "" } else { "s" },start_time.elapsed());rl.add_history_entry(line);}Err(_) => break,}}}Ok(())
}struct SQLHelper {ps: SyntaxSet,ts: ThemeSet,
}impl SQLHelper {fn new() -> Self {Self {ps: SyntaxSet::load_defaults_newlines(),ts: ThemeSet::load_defaults(),}}
}impl Highlighter for SQLHelper {fn highlight<'l>(&self, line: &'l str, _pos: usize) -> std::borrow::Cow<'l, str> {let syntax = self.ps.find_syntax_by_extension("sql").unwrap();let mut h = HighlightLines::new(syntax, &self.ts.themes["base16-ocean.dark"]);let mut highlighted = String::new();for line in LinesWithEndings::from(line) {let ranges = h.highlight_line(line, &self.ps).unwrap();highlighted.push_str(&as_24_bit_terminal_escaped(&ranges[..], false));}std::borrow::Cow::Owned(highlighted)}fn highlight_prompt<'b, 's: 'b, 'p: 'b>(&'s self,prompt: &'p str,_default: bool,) -> std::borrow::Cow<'b, str> {std::borrow::Cow::Borrowed(prompt)}fn highlight_hint<'h>(&self, hint: &'h str) -> std::borrow::Cow<'h, str> {std::borrow::Cow::Borrowed(hint)}fn highlight_candidate<'c>(&self,candidate: &'c str,_completion: rustyline::CompletionType,) -> std::borrow::Cow<'c, str> {std::borrow::Cow::Borrowed(candidate)}fn highlight_char(&self, _line: &str, _pos: usize) -> bool {false}
}impl Completer for SQLHelper {type Candidate = String;fn complete(&self,_line: &str,_pos: usize,_ctx: &rustyline::Context<'_>,) -> rustyline::Result<(usize, Vec<Self::Candidate>)> {Ok((0, Vec::new()))}
}impl Hinter for SQLHelper {type Hint = String;
}impl Validator for SQLHelper {}impl Helper for SQLHelper {}

目前的功能很简单,就是输入查询语句,输出结果和计时信息,以及退出。让他实现带语法高亮的REPL,但实际上没有实现。(你看到了是因为csdn的代码渲染结果)
程序还有限制,只能输出字符类型,其他类型要用::转换,否则报错。
交互模式

 ./duckdb-cli
DuckDB CLI (v0.1.0)
Enter SQL commands or .exit to quit
duckdb> select 1 a;
Error: InvalidColumnType(0, "a", Int)./duckdb-cli
DuckDB CLI (v0.1.0)
Enter SQL commands or .exit to quit
duckdb> select 'xyz' a;
xyz1 row in 1.01681ms
duckdb> create table t(i int);0 rows in 3.20001ms
duckdb> insert into t select 1;
Error: InvalidColumnType(0, "Count", BigInt)

命令行管道模式

echo "select 'a'" |./duckdb-cli
a
Query executed in 1.03702msecho "select sum(i)::varchar from range(10000000)t(i)" |./duckdb-cli
49999995000000
Query executed in 127.35006ms

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88639.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88639.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/88639.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++,从汇编角度看《虚拟继承的邪恶》

刷到一篇文章&#xff1a; 作者&#xff1a; 原文&#xff1a;虛擬繼承的邪惡 讨论到这样的一个程序&#xff0c;最终输出什么&#xff1f;&#xff1f;&#xff1f; 代码有简化命名 using namespace std;class A { public:A(int a 0) : v(a) {};int v; };template <type…

多 Agent 强化学习实践指南(一):CTDE PPO 在合作捕食者-猎物游戏中的应用详解

我们来详细讲解如何在合作捕食者-猎物游戏中结合 PPO (Proximal Policy Optimization) 算法。我们将聚焦于 CTDE&#xff08;Centralized Training, Decentralized Execution&#xff0c;集中训练、分散执行&#xff09; 模式&#xff0c;因为这是处理合作多 Agent 任务的常用且…

Web应用文件上传安全设计指南

引言 在当今的Web应用中&#xff0c;文件上传功能已成为基础且必要的服务能力&#xff0c;但不当的设计可能带来目录遍历、代码注入、服务端资源耗尽等安全风险。本文从威胁模型、安全设计原则、技术实现三个维度&#xff0c;系统阐述安全文件上传架构的设计要点。 一、威胁模型…

用 React Three Fiber 实现 3D 城市模型的扩散光圈特效

本文介绍了如何使用 React Three Fiber&#xff08;R3F&#xff09;和 Three.js 实现一个从中心向外扩散的光圈特效&#xff08;DiffuseAperture 组件&#xff09;&#xff0c;并将其集成到城市 3D 模型&#xff08;CityModel 组件&#xff09;中。该特效通过动态调整圆柱几何体…

【牛客刷题】COUNT数字计数

文章目录 一、题目介绍二、题解思路三、算法实现四、复杂度分析五 、关键步骤解析5.1 数字分解5.2 三种情况处理5.2.1 情况1: d < c u r d < cur d<cur(完整周期)5.2.2 情况2: d = c u r d = cur d=cur(混合周期)5.2.3 情况3: d > c u r d > cur d>cu…

AGV穿梭不“迷路”CCLinkIE转Modbus TCP的衔接技巧

在AGV控制系统集成中&#xff0c;工程师常面临一个现实难题&#xff1a;如何让CCLinkIE总线与Modbus TCP设备实现高效通信&#xff1f;这种跨协议的连接需求&#xff0c;往往需要耗费大量时间调试。本文将通过实际案例解析&#xff0c;为制造行业工程师提供可复用的解决方案。【…

【代码随想录】刷题笔记——哈希表篇

目录 242. 有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和 454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和 242. 有效的字母异位词 思路 代码 class Solution {public boolean isAnagram(String s, String t) {if (s.length() ! t.length()…

Python爬虫实战:研究messytables库相关技术

1. 引言 在当今数字化时代,互联网上存在着大量有价值的数据。然而,这些数据通常以不规则的格式存在,尤其是表格数据,可能包含复杂的表头、合并单元格、不规则布局等问题。传统的数据处理工具往往难以应对这些挑战。 网络爬虫技术可以帮助我们从网页上自动提取数据,而 mes…

Vue3的组件通信方式

通信方式适用层级数据流向复杂度Props/Emits父子组件单向/双向★☆☆v-model父子组件双向★☆☆Provide/Inject跨层级组件自上而下★★☆事件总线任意组件任意方向★★★Pinia/Vuex全局状态任意方向★★☆Refs模板引用父子组件父→子★☆☆作用域插槽父子组件子→父★★☆Web W…

创客匠人:大健康创始人IP如何用“社会责任”构建品牌护城河

一、商业与责任的失衡困局部分大健康IP将利润置于首位&#xff0c;甚至牺牲用户利益&#xff0c;导致品牌形象脆弱。某保健品公司因夸大宣传被曝光后&#xff0c;尽管销量曾达千万&#xff0c;却因缺乏社会认同&#xff0c;一夜之间崩塌&#xff0c;证明没有社会责任支撑的商业…

AI:机器人未来的形态是什么?

机器人未来的形态将受到技术进步、应用场景需求和社会接受度的综合影响&#xff0c;以下是对未来机器人形态的预测&#xff0c;涵盖技术趋势、设计方向和应用场景&#xff1a; 1. 形态多样化与通用化 人形机器人&#xff08;Humanoid Robots&#xff09;&#xff1a; 趋势&…

创建 UIKit 项目教程

一、打开 XCode&#xff0c;选择 iOS 下的 App&#xff0c;然后点 Next二、Interface 选择 Storyboard&#xff0c;然后点 Next三、删掉 Main.storyboard四、删掉 SceneDelegate.swift五、AppDelegate.swift 只保留第一个函数六、在 AppDelegate.swift 文件里的 application 函…

防爬虫君子协定 Robots.txt 文件

1.什么是robots.txt ? robots.txt是一个位于网站根目录的文本文件,用于指导搜索引擎爬虫如何访问和抓取网站内容。它遵循特定的语法规则,是网站与爬虫通信的重要工具。当搜索引擎访问一个网站时,它首先会检查该网站的根域下是否有一个叫做robots.txt的纯文本文件。Robots.…

浅谈 Python 中的 yield——生成器对象与函数调用的区别

我们来看这么一个例子&#xff1a; def greeter():name yield "你是谁&#xff1f;"yield f"你好&#xff0c;{name}"g greeter() print(next(g)) # → "你是谁&#xff1f;" print(g.send("张三")) # → "你好&#xf…

云端docker小知识

1、docker的三个关键概念image、container、dockerfile2、docker的container3、dockerfile4、docker制作image5、linux&#xff08;ubuntu&#xff09;安装docker&#xff08;步骤1和4&#xff09;6、docker基本命令docker images 查看全部镜像docker rmi -f 1e5f3c5b981a 删除…

【Elasticsearch】昂贵算法与廉价算法

在 Elasticsearch 里&#xff0c;“昂贵”并不单指“CPU 时间”&#xff0c;而是综合了 **CPU、内存、磁盘 I/O、网络传输** 以及 **实现复杂度** 的代价。下面把常见“昂贵算法”拆开说&#xff1a;1. **高计算密度的文本算法** • **match_phrase slop**&#xff08;带跨距…

深度学习-多分类

​开头摘要​​&#xff1a; 本文将深入探讨如何使用PyTorch实现基于Softmax回归的MNIST手写数字识别系统。从多分类问题的核心概念出发&#xff0c;详细解析​​One-Hot编码​​技术如何将类别标签向量化&#xff0c;剖析​​交叉熵损失函数​​的数学原理及其在训练中的优化机…

JVM 类加载过程

一、加载&#xff08;Loading&#xff09;目标&#xff1a;把字节码文件&#xff08;.class&#xff09;“读入 JVM”&#xff0c;生成类的 “半成品”&#xff08;Class 对象&#xff09;。Bootstrap ClassLoader&#xff08;启动类加载器&#xff09;&#xff1a;负责加载 JV…

通俗范畴论13 鸡与蛋的故事番外篇

通俗范畴论13 鸡与蛋的故事番外篇 在上一篇中,我们得到了鸡与蛋的Set局部小范畴如下: 鸡与蛋 SetSetSet 局部小范畴 如上图所示,每个鸡来自于一个蛋,每个蛋来自于一只鸡,如此循环,以至于无穷… 是的,假设鸡与蛋两个对象代表的集合,都是无穷集合,这个系统就没有问题…

记录跟随recyclerview滑动的指示器

老早之前做的一个功能&#xff0c;横向recyclerview滑动时&#xff0c;底部做跟随滑动指示器。今天代码不用了&#xff0c;记录下代码。<LinearLayoutandroid:layout_width"match_parent"android:layout_height"wrap_content"android:layout_marginTop&…