我正在尝试通过创建 REST API 并将帖子提交到数据库来对评论示例进行简单的扩展。我正在处理程序本身的范围之外创建连接,我假设这就是我的问题所在。我只是不知道如何解决它。
这是帖子处理程序的代码:
server.get("/comments", middleware! {
let mut stmt = conn.prepare("SELECT * FROM comment").unwrap();
let mut iter = stmt.query_map(&[], |row| {
Comment { id: row.get(0), author: row.get(1), text: row.get(2) }
}).unwrap();
let mut out: Vec<Comment> = Vec::new();
for comment in iter {
out.push(comment.unwrap());
}
json::encode(&out).unwrap()
});
这是我得到的错误:
<nickel macros>:22:50: 22:66 error: the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<rusqlite::InnerConnection>` [E0277]
我认为错误是因为我创建了实例,然后尝试在闭包中使用它,并且一旦我的主函数完成,该变量可能会被销毁。
最佳答案
这是一个 MCVE重现问题(您应该在提问时提供这些):
extern crate rusqlite;
#[macro_use]
extern crate nickel;
use nickel::{Nickel, HttpRouter};
use rusqlite::Connection;
fn main() {
let mut server = Nickel::new();
let conn = Connection::open_in_memory().unwrap();
server.get("/comments", middleware! {
let _stmt = conn.prepare("SELECT * FROM comment").unwrap();
""
});
server.listen("127.0.0.1:6767");
}
Types that are not
Sync
are those that have "interior mutability" in a non-thread-safe way, such asCell
andRefCell
这与您收到的错误消息相符。 Connection
内部的某些内容具有内部可变性,这意味着编译器无法自动保证跨线程共享它是安全的。我有一个recent question 可能对Connection
的实现者有用,如果他们能够保证共享的安全性(也许SQLite本身会做出保证)。
您可以做的最简单的事情是确保一次只有一个线程可以访问数据库对象:
use std::sync::Mutex;
fn main() {
let mut server = Nickel::new();
let conn = Mutex::new(Connection::open_in_memory().unwrap());
server.get("/comments", middleware! {
let conn = conn.lock().unwrap();
let _stmt = conn.prepare("SELECT * FROM comment").unwrap();
""
});
server.listen("127.0.0.1:6767");
}
关于rust - 如何创建使用数据库连接的 Nickel 处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36694984/