mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
remove the DB type parameter from HasCursor and push to an associated type; remove Cursor::first
This commit is contained in:
parent
d981262e7e
commit
72b60e8a7d
@ -16,32 +16,28 @@ use crate::{Connect, Pool, Row};
|
||||
/// Initially the `Cursor` is positioned before the first row. The `next` method moves the cursor
|
||||
/// to the next row, and because it returns `None` when there are no more rows, it can be used
|
||||
/// in a `while` loop to iterate through all returned rows.
|
||||
pub trait Cursor<'c, 'q, DB>
|
||||
pub trait Cursor<'c, 'q>
|
||||
where
|
||||
Self: Send,
|
||||
DB: Database,
|
||||
// `.await`-ing a cursor will return the affected rows from the query
|
||||
Self: Future<Output = crate::Result<u64>>,
|
||||
{
|
||||
type Database: Database;
|
||||
|
||||
#[doc(hidden)]
|
||||
fn from_pool<E>(pool: &Pool<DB::Connection>, query: E) -> Self
|
||||
fn from_pool<E>(pool: &Pool<<Self::Database as Database>::Connection>, query: E) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
E: Execute<'q, DB>;
|
||||
E: Execute<'q, Self::Database>;
|
||||
|
||||
#[doc(hidden)]
|
||||
fn from_connection<E, C>(conn: C, query: E) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
DB::Connection: Connect,
|
||||
C: Into<MaybeOwnedConnection<'c, DB::Connection>>,
|
||||
E: Execute<'q, DB>;
|
||||
|
||||
#[doc(hidden)]
|
||||
fn first(self) -> BoxFuture<'c, crate::Result<Option<<DB as HasRow<'c>>::Row>>>
|
||||
where
|
||||
'q: 'c;
|
||||
<Self::Database as Database>::Connection: Connect,
|
||||
C: Into<MaybeOwnedConnection<'c, <Self::Database as Database>::Connection>>,
|
||||
E: Execute<'q, Self::Database>;
|
||||
|
||||
/// Fetch the next row in the result. Returns `None` if there are no more rows.
|
||||
fn next(&mut self) -> BoxFuture<crate::Result<Option<<DB as HasRow>::Row>>>;
|
||||
fn next(&mut self) -> BoxFuture<crate::Result<Option<<Self::Database as HasRow>::Row>>>;
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ where
|
||||
Self: Sized + 'static,
|
||||
Self: for<'a> HasRow<'a, Database = Self>,
|
||||
Self: for<'a> HasRawValue<'a>,
|
||||
Self: for<'c, 'q> HasCursor<'c, 'q, Self>,
|
||||
Self: for<'c, 'q> HasCursor<'c, 'q, Database = Self>,
|
||||
{
|
||||
/// The concrete `Connection` implementation for this database.
|
||||
type Connection: Connection<Database = Self>;
|
||||
@ -34,11 +34,10 @@ pub trait HasRawValue<'a> {
|
||||
type RawValue;
|
||||
}
|
||||
|
||||
pub trait HasCursor<'c, 'q, DB>
|
||||
where
|
||||
DB: Database,
|
||||
{
|
||||
type Cursor: Cursor<'c, 'q, DB>;
|
||||
pub trait HasCursor<'c, 'q> {
|
||||
type Database: Database;
|
||||
|
||||
type Cursor: Cursor<'c, 'q, Database = Self::Database>;
|
||||
}
|
||||
|
||||
pub trait HasRow<'a> {
|
||||
|
||||
@ -22,18 +22,12 @@ where
|
||||
type Database: Database;
|
||||
|
||||
/// Executes a query that may or may not return a result set.
|
||||
fn execute<'q, E>(
|
||||
self,
|
||||
query: E,
|
||||
) -> <Self::Database as HasCursor<'c, 'q, Self::Database>>::Cursor
|
||||
fn execute<'q, E>(self, query: E) -> <Self::Database as HasCursor<'c, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, Self::Database>;
|
||||
|
||||
#[doc(hidden)]
|
||||
fn execute_by_ref<'b, E>(
|
||||
&mut self,
|
||||
query: E,
|
||||
) -> <Self::Database as HasCursor<'_, 'b, Self::Database>>::Cursor
|
||||
fn execute_by_ref<'b, E>(&mut self, query: E) -> <Self::Database as HasCursor<'_, 'b>>::Cursor
|
||||
where
|
||||
E: Execute<'b, Self::Database>;
|
||||
}
|
||||
|
||||
@ -19,12 +19,12 @@ impl<'p, C, DB> Executor<'p> for &'p Pool<C>
|
||||
where
|
||||
C: Connect<Database = DB>,
|
||||
DB: Database<Connection = C>,
|
||||
DB: for<'c, 'q> HasCursor<'c, 'q, DB>,
|
||||
DB: for<'c, 'q> HasCursor<'c, 'q, Database = DB>,
|
||||
for<'con> &'con mut C: Executor<'con>,
|
||||
{
|
||||
type Database = DB;
|
||||
|
||||
fn execute<'q, E>(self, query: E) -> <Self::Database as HasCursor<'p, 'q, DB>>::Cursor
|
||||
fn execute<'q, E>(self, query: E) -> <Self::Database as HasCursor<'p, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, DB>,
|
||||
{
|
||||
@ -36,7 +36,7 @@ where
|
||||
fn execute_by_ref<'q, 'e, E>(
|
||||
&'e mut self,
|
||||
query: E,
|
||||
) -> <Self::Database as HasCursor<'_, 'q, DB>>::Cursor
|
||||
) -> <Self::Database as HasCursor<'_, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, DB>,
|
||||
{
|
||||
@ -48,12 +48,12 @@ impl<'c, C, DB> Executor<'c> for &'c mut PoolConnection<C>
|
||||
where
|
||||
C: Connect<Database = DB>,
|
||||
DB: Database<Connection = C>,
|
||||
DB: for<'c2, 'q> HasCursor<'c2, 'q, DB>,
|
||||
DB: for<'c2, 'q> HasCursor<'c2, 'q, Database = DB>,
|
||||
for<'con> &'con mut C: Executor<'con>,
|
||||
{
|
||||
type Database = C::Database;
|
||||
|
||||
fn execute<'q, E>(self, query: E) -> <Self::Database as HasCursor<'c, 'q, DB>>::Cursor
|
||||
fn execute<'q, E>(self, query: E) -> <Self::Database as HasCursor<'c, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
@ -65,7 +65,7 @@ where
|
||||
fn execute_by_ref<'q, 'e, E>(
|
||||
&'e mut self,
|
||||
query: E,
|
||||
) -> <Self::Database as HasCursor<'_, 'q, DB>>::Cursor
|
||||
) -> <Self::Database as HasCursor<'_, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
@ -77,11 +77,11 @@ impl<C, DB> Executor<'static> for PoolConnection<C>
|
||||
where
|
||||
C: Connect<Database = DB>,
|
||||
DB: Database<Connection = C>,
|
||||
DB: for<'c, 'q> HasCursor<'c, 'q, DB>,
|
||||
DB: for<'c, 'q> HasCursor<'c, 'q, Database = DB>,
|
||||
{
|
||||
type Database = DB;
|
||||
|
||||
fn execute<'q, E>(self, query: E) -> <DB as HasCursor<'static, 'q, DB>>::Cursor
|
||||
fn execute<'q, E>(self, query: E) -> <DB as HasCursor<'static, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
@ -90,7 +90,7 @@ where
|
||||
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
fn execute_by_ref<'q, 'e, E>(&'e mut self, query: E) -> <DB as HasCursor<'_, 'q, DB>>::Cursor
|
||||
fn execute_by_ref<'q, 'e, E>(&'e mut self, query: E) -> <DB as HasCursor<'_, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
|
||||
@ -87,8 +87,9 @@ pub struct PgConnection {
|
||||
pub(super) next_statement_id: u32,
|
||||
pub(super) is_ready: bool,
|
||||
|
||||
// TODO: Think of a better way to do this, better name perhaps?
|
||||
pub(super) data_row_values_buf: Vec<Option<Range<u32>>>,
|
||||
// Work buffer for the value ranges of the current row
|
||||
// This is used as the backing memory for each Row's value indexes
|
||||
pub(super) current_row_values: Vec<Option<Range<u32>>>,
|
||||
}
|
||||
|
||||
// https://www.postgresql.org/docs/12/protocol-flow.html#id-1.10.5.7.3
|
||||
@ -234,7 +235,7 @@ impl PgConnection {
|
||||
|
||||
Ok(Self {
|
||||
stream,
|
||||
data_row_values_buf: Vec::new(),
|
||||
current_row_values: Vec::with_capacity(10),
|
||||
next_statement_id: 1,
|
||||
is_ready: true,
|
||||
})
|
||||
|
||||
@ -32,7 +32,9 @@ pub struct PgCursor<'c, 'q> {
|
||||
state: State<'c, 'q>,
|
||||
}
|
||||
|
||||
impl<'c, 'q> Cursor<'c, 'q, Postgres> for PgCursor<'c, 'q> {
|
||||
impl<'c, 'q> Cursor<'c, 'q> for PgCursor<'c, 'q> {
|
||||
type Database = Postgres;
|
||||
|
||||
#[doc(hidden)]
|
||||
fn from_pool<E>(pool: &Pool<PgConnection>, query: E) -> Self
|
||||
where
|
||||
@ -64,14 +66,6 @@ impl<'c, 'q> Cursor<'c, 'q, Postgres> for PgCursor<'c, 'q> {
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn first(self) -> BoxFuture<'c, crate::Result<Option<PgRow<'c>>>>
|
||||
where
|
||||
'q: 'c,
|
||||
{
|
||||
Box::pin(first(self))
|
||||
}
|
||||
|
||||
fn next(&mut self) -> BoxFuture<crate::Result<Option<PgRow<'_>>>> {
|
||||
Box::pin(next(self))
|
||||
}
|
||||
@ -266,51 +260,3 @@ async fn next<'a, 'c: 'a, 'q: 'a>(
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn first<'c, 'q>(mut cursor: PgCursor<'c, 'q>) -> crate::Result<Option<PgRow<'c>>> {
|
||||
let mut conn = cursor.source.resolve().await?;
|
||||
|
||||
match cursor.state {
|
||||
State::Query(q, ref mut arguments) => {
|
||||
// write out the query to the connection
|
||||
write(&mut conn, q, arguments.take()).await?;
|
||||
}
|
||||
|
||||
State::NextRow => {
|
||||
// just grab the next row as the first
|
||||
}
|
||||
|
||||
State::Resolve(_) | State::AffectedRows(_) => {
|
||||
panic!("`PgCursor` must not be used after being polled");
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match conn.stream.read().await? {
|
||||
Message::ParseComplete | Message::BindComplete => {
|
||||
// ignore x_complete messages
|
||||
}
|
||||
|
||||
Message::CommandComplete => {
|
||||
// no more rows
|
||||
break;
|
||||
}
|
||||
|
||||
Message::DataRow => {
|
||||
let data = DataRow::read(&mut conn)?;
|
||||
|
||||
return Ok(Some(PgRow {
|
||||
connection: conn,
|
||||
columns: Arc::default(),
|
||||
data,
|
||||
}));
|
||||
}
|
||||
|
||||
message => {
|
||||
return Err(protocol_err!("first: unexpected message: {:?}", message).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@ -20,7 +20,9 @@ impl<'a> HasRow<'a> for Postgres {
|
||||
type Row = super::PgRow<'a>;
|
||||
}
|
||||
|
||||
impl<'s, 'q> HasCursor<'s, 'q, Postgres> for Postgres {
|
||||
impl<'s, 'q> HasCursor<'s, 'q> for Postgres {
|
||||
type Database = Postgres;
|
||||
|
||||
type Cursor = super::PgCursor<'s, 'q>;
|
||||
}
|
||||
|
||||
|
||||
@ -121,36 +121,12 @@ where
|
||||
executor.execute(self).await
|
||||
}
|
||||
|
||||
pub fn fetch<'e, E>(self, executor: E) -> <DB as HasCursor<'e, 'q, DB>>::Cursor
|
||||
pub fn fetch<'e, E>(self, executor: E) -> <DB as HasCursor<'e, 'q>>::Cursor
|
||||
where
|
||||
E: Executor<'e, Database = DB>,
|
||||
{
|
||||
executor.execute(self)
|
||||
}
|
||||
|
||||
pub async fn fetch_optional<'e, E>(
|
||||
self,
|
||||
executor: E,
|
||||
) -> crate::Result<Option<<DB as HasRow<'e>>::Row>>
|
||||
where
|
||||
E: Executor<'e, Database = DB>,
|
||||
'q: 'e,
|
||||
{
|
||||
executor.execute(self).first().await
|
||||
}
|
||||
|
||||
pub async fn fetch_one<'e, E>(self, executor: E) -> crate::Result<<DB as HasRow<'e>>::Row>
|
||||
where
|
||||
E: Executor<'e, Database = DB>,
|
||||
'q: 'e,
|
||||
{
|
||||
self.fetch_optional(executor)
|
||||
.and_then(|row| match row {
|
||||
Some(row) => ready(Ok(row)),
|
||||
None => ready(Err(crate::Error::NotFound)),
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q, DB, F> Map<'q, DB, F>
|
||||
|
||||
@ -136,10 +136,7 @@ where
|
||||
{
|
||||
type Database = <T as Connection>::Database;
|
||||
|
||||
fn execute<'q, E>(
|
||||
self,
|
||||
query: E,
|
||||
) -> <<T as Connection>::Database as HasCursor<'c, 'q, DB>>::Cursor
|
||||
fn execute<'q, E>(self, query: E) -> <<T as Connection>::Database as HasCursor<'c, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
@ -150,7 +147,7 @@ where
|
||||
fn execute_by_ref<'q, 'e, E>(
|
||||
&'e mut self,
|
||||
query: E,
|
||||
) -> <Self::Database as HasCursor<'e, 'q, DB>>::Cursor
|
||||
) -> <Self::Database as HasCursor<'e, 'q>>::Cursor
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user