Struct mysql_async::QueryResult
source · pub struct QueryResult<'a, 't: 'a, P> { /* private fields */ }
Expand description
Result of a query or statement execution.
Represents an asynchronous query result, that may not be fully consumed.
§Note
Unconsumed query results are dropped implicitly when corresponding connection is dropped or queried. Also note, that in this case all remaining errors will be emitted to the caller:
use mysql_async::*;
use mysql_async::prelude::*;
let mut conn = Conn::new(get_opts()).await?;
// second result set will contain an error,
// but the first result set is ok, so this line will pass
conn.query_iter("DO 1; BLABLA;").await?;
// `QueryResult` was dropped withot being consumed
// driver must cleanup any unconsumed result to perform another query on `conn`,
// so this operation will be performed implicitly, but the unconsumed result
// contains an error claiming about 'BLABLA', so this error will be emitted here:
assert!(conn.query_iter("DO 1").await.unwrap_err().to_string().contains("BLABLA"));
Implementations§
source§impl<'a, 't: 'a, P> QueryResult<'a, 't, P>
impl<'a, 't: 'a, P> QueryResult<'a, 't, P>
sourcepub fn stream<'r, T: Unpin + FromRow + Send + 'static>(
&'r mut self,
) -> BoxFuture<'r, Result<Option<ResultSetStream<'r, 'a, 't, T, P>>>>
pub fn stream<'r, T: Unpin + FromRow + Send + 'static>( &'r mut self, ) -> BoxFuture<'r, Result<Option<ResultSetStream<'r, 'a, 't, T, P>>>>
Returns a Stream
for the current result set.
The returned stream satisfies futures_util::TryStream
,
so you can use futures_util::TryStreamExt
functions on it.
§Behavior
§Conversion
This stream will convert each row into T
using FromRow
implementation.
If the row type is unknown please use the Row
type for T
to make this conversion infallible.
§Consumption
The call to QueryResult::stream
entails the consumption of the current result set,
practically this means that the second call to QueryResult::stream
will return
the next result set stream even if the stream returned from the first call wasn’t
explicitly consumed:
let mut conn = Conn::new(get_opts()).await?;
// This query result will contain two result sets.
let mut result = conn.query_iter("SELECT 1; SELECT 2;").await?;
// The first result set stream is dropped here without being consumed,
let _ = result.stream::<u8>().await?;
// so it will be implicitly consumed here.
let mut stream = result.stream::<u8>().await?.expect("the second result set must be here");
assert_eq!(2_u8, stream.next().await.unwrap()?);
§Errors
Note, that QueryResult::stream
may error if:
- current result set contains an error,
- previously unconsumed result set stream contained an error.
let mut conn = Conn::new(get_opts()).await?;
// The second result set of this query will contain an error.
let mut result = conn.query_iter("SELECT 1; SELECT FOO(); SELECT 2;").await?;
// First result set stream is dropped here without being consumed,
let _ = result.stream::<Row>().await?;
// so it will be implicitly consumed on the second call to `QueryResult::stream`
// that will error complaining about unknown FOO
assert!(result.stream::<Row>().await.unwrap_err().to_string().contains("FOO"));
sourcepub fn stream_and_drop<T: Unpin + FromRow + Send + 'static>(
self,
) -> BoxFuture<'a, Result<Option<ResultSetStream<'a, 'a, 't, T, P>>>>
pub fn stream_and_drop<T: Unpin + FromRow + Send + 'static>( self, ) -> BoxFuture<'a, Result<Option<ResultSetStream<'a, 'a, 't, T, P>>>>
Owned version of the QueryResult::stream
.
Returned stream will stop iteration on the first result set boundary.
See also Query::stream
, Queryable::query_stream
,
Queryable::exec_stream
.
The following example uses the Query::stream
function
that is based on the QueryResult::stream_and_drop
:
let pool = Pool::new(get_opts());
let mut conn = pool.get_conn().await?;
// This example uses the `Query::stream` function that is based on `QueryResult::stream_and_drop`:
let mut stream = "SELECT 1 UNION ALL SELECT 2".stream::<u8, _>(&mut conn).await?;
let rows = stream.try_collect::<Vec<_>>().await.unwrap();
assert_eq!(vec![1, 2], rows);
// Only the first result set will go into the stream:
let mut stream = r"
SELECT 'foo' UNION ALL SELECT 'bar';
SELECT 'baz' UNION ALL SELECT 'quux';".stream::<String, _>(&mut conn).await?;
let rows = stream.try_collect::<Vec<_>>().await.unwrap();
assert_eq!(vec!["foo".to_owned(), "bar".to_owned()], rows);
// We can also build a `'static` stream by giving away the connection:
let stream = "SELECT 2 UNION ALL SELECT 3".stream::<u8, _>(conn).await?;
// `tokio::spawn` requires `'static`
let handle = tokio::spawn(async move {
stream.try_collect::<Vec<_>>().await.unwrap()
});
assert_eq!(vec![2, 3], handle.await?);
source§impl<'a, 't: 'a, P> QueryResult<'a, 't, P>where
P: Protocol,
impl<'a, 't: 'a, P> QueryResult<'a, 't, P>where
P: Protocol,
pub fn new<T: Into<Connection<'a, 't>>>(conn: T) -> Self
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
true
if there are no more rows nor result sets in this query.
This function will return false
if the last result set was taken
by the QueryResult::stream
that was dropped before being fully consumed
(i.e. caller will get false
even if QueryResult data is reachable only for library internals).
sourcepub fn last_insert_id(&self) -> Option<u64>
pub fn last_insert_id(&self) -> Option<u64>
Last insert id, if any.
sourcepub fn affected_rows(&self) -> u64
pub fn affected_rows(&self) -> u64
Number of affected rows as reported by the server, or 0
.
sourcepub fn info(&self) -> Cow<'_, str>
pub fn info(&self) -> Cow<'_, str>
Text information as reported by the server, or an empty string.
sourcepub async fn collect<R>(&mut self) -> Result<Vec<R>>
pub async fn collect<R>(&mut self) -> Result<Vec<R>>
Collects the current result set of this query result.
It is parametrized by R
and internally calls R::from_row(Row)
on each row.
It will collect rows up to a neares result set boundary. This means that you should call
collect
as many times as result sets in your query result. For example query
SELECT 'foo'; SELECT 'foo', 'bar';
will produce QueryResult
with two result sets in it.
One can use QueryResult::is_empty
to make sure that there is no more result sets.
§Panic
It’ll panic if any row isn’t convertible to R
(i.e. programmer error or unknown schema).
- In case of programmer error see
FromRow
docs; - In case of unknown schema use
QueryResult::try_collect
.
sourcepub async fn try_collect<R>(
&mut self,
) -> Result<Vec<StdResult<R, FromRowError>>>
pub async fn try_collect<R>( &mut self, ) -> Result<Vec<StdResult<R, FromRowError>>>
Collects the current result set of this query result.
It works the same way as QueryResult::collect
but won’t panic if row isn’t convertible
to R
.
sourcepub async fn collect_and_drop<R>(self) -> Result<Vec<R>>
pub async fn collect_and_drop<R>(self) -> Result<Vec<R>>
Collects the current result set of this query result and drops everything else.
§Panic
It’ll panic if any row isn’t convertible to R
(i.e. programmer error or unknown schema).
- In case of programmer error see
FromRow
docs; - In case of unknown schema use
QueryResult::try_collect
.
sourcepub async fn try_collect_and_drop<R>(
self,
) -> Result<Vec<StdResult<R, FromRowError>>>
pub async fn try_collect_and_drop<R>( self, ) -> Result<Vec<StdResult<R, FromRowError>>>
Collects the current result set of this query result and drops everything else.
It works the same way as QueryResult::collect_and_drop
but won’t panic if row isn’t
convertible to R
.
sourcepub async fn for_each<F>(&mut self, fun: F) -> Result<()>
pub async fn for_each<F>(&mut self, fun: F) -> Result<()>
Executes fun
on every row of the current result set.
It will stop on the nearest result set boundary (see QueryResult::collect
docs).
sourcepub async fn for_each_and_drop<F>(self, fun: F) -> Result<()>
pub async fn for_each_and_drop<F>(self, fun: F) -> Result<()>
Executes fun
on every row of the current result set and drops everything else.
sourcepub async fn map<F, U>(&mut self, fun: F) -> Result<Vec<U>>
pub async fn map<F, U>(&mut self, fun: F) -> Result<Vec<U>>
Maps every row of the current result set to U
using fun
.
It will stop on the nearest result set boundary (see QueryResult::collect
docs).
sourcepub async fn map_and_drop<F, U>(self, fun: F) -> Result<Vec<U>>
pub async fn map_and_drop<F, U>(self, fun: F) -> Result<Vec<U>>
Map every row of the current result set to U
using fun
and drops everything else.
sourcepub async fn reduce<T, F, U>(&mut self, init: U, fun: F) -> Result<U>
pub async fn reduce<T, F, U>(&mut self, init: U, fun: F) -> Result<U>
Reduces rows of the current result set to U
using fun
.
It will stop on the nearest result set boundary (see QueryResult::collect
docs).
sourcepub async fn reduce_and_drop<T, F, U>(self, init: U, fun: F) -> Result<U>
pub async fn reduce_and_drop<T, F, U>(self, init: U, fun: F) -> Result<U>
Reduces rows of the current result set to U
using fun
and drops everything else.
sourcepub async fn drop_result(self) -> Result<()>
pub async fn drop_result(self) -> Result<()>
Drops this query result.
sourcepub fn columns_ref(&self) -> &[Column]
pub fn columns_ref(&self) -> &[Column]
Returns a reference to a columns list of this query result.
Empty list means that this result set was never meant to contain rows.
Trait Implementations§
Auto Trait Implementations§
impl<'a, 't, P> Freeze for QueryResult<'a, 't, P>
impl<'a, 't, P> !RefUnwindSafe for QueryResult<'a, 't, P>
impl<'a, 't, P> Send for QueryResult<'a, 't, P>where
P: Send,
impl<'a, 't, P> Sync for QueryResult<'a, 't, P>where
P: Sync,
impl<'a, 't, P> Unpin for QueryResult<'a, 't, P>where
P: Unpin,
impl<'a, 't, P> !UnwindSafe for QueryResult<'a, 't, P>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> FmtForward for T
impl<T> FmtForward for T
source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moresource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moresource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.source§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<T> Tap for T
impl<T> Tap for T
source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moresource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moresource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moresource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moresource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moresource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moresource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.