现在我有一个使用rusqlite
sqlite bindings在我的应用程序打开一个数据库连接,并做了一堆数据库操作的这样的代码:如何存储SQLite准备好的语句供以后使用?
extern crate rusqlite;
use rusqlite::SqliteConnection;
struct MyAppState {
db: SqliteConnection,
// ... pretend there's other fields here ...
}
impl MyAppState {
fn new() -> MyAppState {
let db = SqliteConnection::open(":memory:").unwrap();
MyAppState {
db: db
}
}
fn query_some_info(&mut self, arg: i64) -> i64 {
let mut stmt = self.db.prepare("SELECT ? + 1").unwrap();
let mut result_iter = stmt.query(&[&arg]).unwrap();
let result = result_iter.next().unwrap().unwrap().get(0);
result
}
}
fn main() {
let mut app = MyAppState::new();
for i in range(0, 100) {
let result = app.query_some_info(i);
println!("{}", result);
}
}
由于事先准备好的声明生活在一个局部变量,这似乎错过在某种程度上准备好的陈述的重点,因为每次函数被调用并且局部变量出现时我都必须重新准备它。理想情况下,我会最多准备一次我的语句,并在db连接期间将它们存储在MyAppState
结构中。
然而,由于SqliteStatement
type is parameterized over the lifetime of the db connection,它借用了连接,并推而广之的结构它生活在,我不能做的结构什么了类似的值返回结构或调用它的&mut self
方法(query_some_info
不真的需要在这里采取&mut self
,但我的实际计划中的一些代码确实如此,除非所有事情都继续生活在RefCell
之间,但我认为这并不是最差的)。
通常,当借阅检查员背叛我时,我的追求是放弃堆栈管理,并在其中放置一些Rc<RefCell< >>
,直到全部解决为止,但在这种情况下,这些类型中存在一些生命周期,不知道如何以一种安抚借用检查器的方式来表达它。
理想情况下,我想编写代码,只有在数据库打开时才准备语句,或者在第一次使用时只准备一次,然后在数据库连接期间再次不调用prepare
,同时主要保持rusqlite绑定的安全性,而不是针对sqlite3 C API编写代码或打破抽象或其他任何操作。我如何?
你能提供一个这个想法的例子吗? –