現在我有一個使用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編寫代碼或打破抽象或其他任何操作。我如何?
你能提供一個這個想法的例子嗎? –