I am having trouble figuring out how to return an Iterator (impl or Box) when using prepare and query.
Here is what I have tried:
fn foo<'a>(
conn: &'a mut rusqlite::Connection
) -> Box<impl 'a + fallible_streaming_iterator::FallibleStreamingIterator<Item=rusqlite::Row<'a>>> {
Box::new(
conn
.prepare("SELECT a, b FROM t")
.unwrap()
.query(rusqlite::NO_PARAMS)
.unwrap()
)
}
The problem is the prepared statement is a temporary variable owned by the function scope. (error[E0515]: cannot return value referencing temporary value).
Not possible to return
FallibleStreamingIterator<Item=rusqlite::Row<'a>>instance fromfoofunction.
Rust borrow checker will not allow to do that.
To understand why, we need to understand how rusqlite::Rows<'a> is structured.
/// An handle for the resulting rows of a query.
#[must_use = "Rows is lazy and will do nothing unless consumed"]
pub struct Rows<'stmt> {
pub(crate) stmt: Option<&'stmt Statement<'stmt>>,
row: Option<Row<'stmt>>,
}
Github source: Rows
and it's FallibleStreamingIterator implementation looks like
impl<'stmt> FallibleStreamingIterator for Rows<'stmt> {
type Error = Error;
type Item = Row<'stmt>;
#[inline]
fn advance(&mut self) -> Result<()> {
...
Github source: FallibleStreamingIterator
Rows holds a reference to Statement. Let's try to infer lifetime 'stmt here.
Statement (scope limited to `foo` func)
|
Rows (refers Statement so valid scope `foo`)
|
FallibleStreamingIterator (refers Rows so valid scope `foo`)
Possible solution could be
rusqlite::Statement<'a> and query on desired locationIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With