15 个版本
使用旧的 Rust 2015
0.4.5 | 2019 年 3 月 21 日 |
---|---|
0.4.4 | 2019 年 3 月 21 日 |
0.4.2 | 2018 年 12 月 24 日 |
0.4.1 | 2018 年 7 月 14 日 |
0.1.2 | 2017 年 5 月 15 日 |
#1375 在 数据库接口
24 每月下载量
110KB
2.5K SLoC
一个全异步的 Postgres 客户端。Postgres 有“语句”的概念,即命名或未命名的 SQL 命令,以及“门径”,其中门径是结果的一个实例。所有对数据库的查询都遵循相同的顺序:解析、绑定、执行、关闭(门径和/或语句)。
语句和门径可以是命名的或未命名的,尽管使用 Connection 类型的
query
方法编写原型代码可能更容易,该方法使用未命名的语句和未命名的门径来执行正确的顺序。
与同步客户端相反,此客户端需要在异步 I/O 时在事件循环中存储请求。此存储的确切类型需要由此 crate 的用户提供,并且需要实现 Request
和 HandleRow
特性。
此 crate 提供了两个 API 级别
-
一个基于
spawn_connection
的高级 API,它使用现有的事件循环。此 API 需要现有的Request+HandleRow
实例。 -
一个基于
Connection
类型的低级 API,可能用于构建更复杂或更直接的流水线,例如通过另一个协议隧道,或等待服务器执行查询。
extern crate tokio;
extern crate pleingres;
extern crate futures;
extern crate env_logger;
extern crate uuid;
use uuid::Uuid;
use std::rc::Rc;
use std::net::ToSocketAddrs;
use futures::Future;
// A `Request` is the type used for communication with the
// client event loop. It is used both for sending input and
// receiving output.
struct Request {
login: String,
id: Option<Uuid>
}
// Requests must implement the `pleingres::Request` trait,
// meaning they can be converted to commands to be sent to
// the server.
impl pleingres::Request for Request {
fn request(&mut self, mut buf: pleingres::Buffer) {
buf.bind("SELECT id FROM users WHERE login=$1", &[&self.login]).execute(0);
}
}
impl pleingres::HandleRow for Request {
fn row(&mut self, mut row: pleingres::Row) -> bool {
if let Some(id) = row.next() {
self.id = Some(pleingres::FromSql::from_sql(id).unwrap())
}
true
}
}
fn main() {
env_logger::try_init().unwrap_or(());
let p = Rc::new(pleingres::Parameters {
addr: "::1:5432".to_socket_addrs().unwrap().next().unwrap(),
user: "pe".to_string(),
password: "password".to_string(),
database: Some("pijul".to_string()),
idle_timeout: Some(std::time::Duration::from_millis(20_000)),
tcp_keepalive: Some(std::time::Duration::from_millis(10000)),
ssl: None,
});
let mut l = tokio::reactor::Core::new().unwrap();
let db:pleingres::Handle<Request> =
pleingres::spawn_connection(p.clone(), l.handle()).unwrap();
l.run(db
.send_request(
Request { login: "me".to_string(), id: None }
)
.and_then(|dbreq| {
if let Some(ref id) = dbreq.id {
println!("id: {:?}", id)
}
futures::finished(())
})).unwrap()
}
或者,可以使用 sql 插件实现 pleingres::Request
。在上面的例子中,我们会用以下替换
struct Request {
login: String,
id: Option<Uuid>
}
impl pleingres::Request for Request {
fn request(&mut self, mut buf: pleingres::Buffer) {
buf.bind("SELECT id FROM users WHERE login=$1", &[&self.login]).execute(0);
}
}
只需
#[sql("SELECT id FROM users WHERE login = $login")]
struct Request {
login: String,
id: Option<Uuid>
}
依赖项
~12MB
~211K SLoC