mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-03 01:32:17 +00:00
bind/rust: Fix lifetime issue with pragma_query
Shallow cloning in Row ended up invalidating the pointer to value
This commit is contained in:
parent
ed0e3b1ba2
commit
4766c9c286
4 changed files with 52 additions and 16 deletions
|
@ -13,7 +13,7 @@ async fn main() {
|
|||
.unwrap();
|
||||
|
||||
conn.pragma_query("journal_mode", |row| {
|
||||
println!("{}", row.get_value(0));
|
||||
println!("{:?}", row.get_value(0));
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
|
|
@ -124,17 +124,28 @@ impl Connection {
|
|||
Ok(statement)
|
||||
}
|
||||
|
||||
pub fn pragma_query<F>(&self, pragma_name: &str, f: F) -> Result<()>
|
||||
pub fn pragma_query<F>(&self, pragma_name: &str, mut f: F) -> Result<()>
|
||||
where
|
||||
F: FnMut(&limbo_core::Row) -> limbo_core::Result<()>,
|
||||
F: FnMut(&Row) -> limbo_core::Result<()>,
|
||||
{
|
||||
let conn = self
|
||||
.inner
|
||||
.lock()
|
||||
.map_err(|e| Error::MutexError(e.to_string()))?;
|
||||
|
||||
conn.pragma_query(pragma_name, f)
|
||||
.map_err(|e| Error::SqlExecutionFailure(e.to_string()))
|
||||
let rows: Vec<Row> = conn
|
||||
.pragma_query(pragma_name)
|
||||
.map_err(|e| Error::SqlExecutionFailure(e.to_string()))?
|
||||
.iter()
|
||||
.map(|row| row.iter().collect::<Row>())
|
||||
.collect();
|
||||
|
||||
rows.iter().try_for_each(|row| {
|
||||
f(row).map_err(|e| {
|
||||
Error::SqlExecutionFailure(format!("Error executing user defined function: {}", e))
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,3 +331,20 @@ impl Row {
|
|||
self.values.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromIterator<&'a limbo_core::Value> for Row {
|
||||
fn from_iter<T: IntoIterator<Item = &'a limbo_core::Value>>(iter: T) -> Self {
|
||||
let values = iter
|
||||
.into_iter()
|
||||
.map(|v| match v {
|
||||
limbo_core::Value::Integer(i) => limbo_core::Value::Integer(*i),
|
||||
limbo_core::Value::Null => limbo_core::Value::Null,
|
||||
limbo_core::Value::Float(f) => limbo_core::Value::Float(*f),
|
||||
limbo_core::Value::Text(s) => limbo_core::Value::Text(s.clone()),
|
||||
limbo_core::Value::Blob(b) => limbo_core::Value::Blob(b.clone()),
|
||||
})
|
||||
.collect();
|
||||
|
||||
Row { values }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ pub enum LimboError {
|
|||
SchemaLocked,
|
||||
#[error("Database Connection is read-only")]
|
||||
ReadOnly,
|
||||
#[error("Database is busy")]
|
||||
Busy,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
|
28
core/lib.rs
28
core/lib.rs
|
@ -89,10 +89,6 @@ pub(crate) type MvStore = mvcc::MvStore<mvcc::LocalClock>;
|
|||
|
||||
pub(crate) type MvCursor = mvcc::cursor::ScanCursor<mvcc::LocalClock>;
|
||||
|
||||
// Not so sure if we should expose this row to the user
|
||||
// or make a wrapper around it to sharp some corners
|
||||
pub type Row = vdbe::Row;
|
||||
|
||||
pub struct Database {
|
||||
mv_store: Option<Rc<MvStore>>,
|
||||
schema: Arc<RwLock<Schema>>,
|
||||
|
@ -586,22 +582,30 @@ impl Connection {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn pragma_query<F>(self: &Rc<Connection>, pragma_name: &str, mut f: F) -> Result<()>
|
||||
where
|
||||
F: FnMut(&Row) -> Result<()>,
|
||||
{
|
||||
// Clearly there is something to improve here, Vec<Vec<Value>> isn't a couple of tea
|
||||
pub fn pragma_query(self: &Rc<Connection>, pragma_name: &str) -> Result<Vec<Vec<Value>>> {
|
||||
let pragma = format!("PRAGMA {}", pragma_name);
|
||||
let mut stmt = self.prepare(pragma)?;
|
||||
let mut results = Vec::new();
|
||||
loop {
|
||||
match stmt.step()? {
|
||||
vdbe::StepResult::Row => {
|
||||
let row = stmt.row().unwrap();
|
||||
f(row)?;
|
||||
let row: Vec<Value> = stmt
|
||||
.row()
|
||||
.unwrap()
|
||||
.get_values()
|
||||
.map(|v| v.clone())
|
||||
.collect();
|
||||
results.push(row);
|
||||
}
|
||||
vdbe::StepResult::Interrupt | vdbe::StepResult::Busy => {
|
||||
return Err(LimboError::Busy);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,6 +685,8 @@ impl Statement {
|
|||
}
|
||||
}
|
||||
|
||||
pub type Row = vdbe::Row;
|
||||
|
||||
pub type StepResult = vdbe::StepResult;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue