Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add methodsquery_typed_opt,query_typed_one andexecute_typed#1265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
ash-hashtag wants to merge1 commit intorust-postgres:master
base:master
Choose a base branch
Loading
fromash-hashtag:query_typed_helpers
Open
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletionspostgres/src/client.rs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,6 +83,48 @@ impl Client {
self.connection.block_on(self.client.execute(query, params))
}

/// Executes a statement, returning the number of rows modified.
///
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
/// provided, 1-indexed.
///
///
/// Compared to `execute`, this method allows performing queries without three round trips (for
/// prepare, execute, and close) by requiring the caller to specify parameter values along with
/// their Postgres type. Thus, this is suitable in environments where prepared statements aren't
/// supported (such as Cloudflare Workers with Hyperdrive).
///
/// If the statement does not modify any rows (e.g. `SELECT`), 0 is returned.
///
///
/// # Example
///
/// ```no_run
/// use postgres::{Client, NoTls, types::Type};
///
/// # fn main() -> Result<(), postgres::Error> {
/// let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
///
/// let bar = 1i32;
/// let baz = true;
/// let rows_updated = client.execute_typed(
/// "UPDATE foo SET bar = $1 WHERE baz = $2",
/// &[(&bar, Type::INT4), (&baz, Type::BOOL)],
/// )?;
///
/// println!("{} rows updated", rows_updated);
/// # Ok(())
/// # }
/// ```
pub fn execute_typed(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<u64, Error> {
self.connection
.block_on(self.client.execute_typed(query, params))
}

/// Executes a statement, returning the resulting rows.
///
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
Expand DownExpand Up@@ -275,6 +317,49 @@ impl Client {
.block_on(self.client.query_typed(query, params))
}

/// Like `query_one`, but requires the types of query parameters to be explicitly specified.
///
/// Compared to `query_one`, this method allows performing queries without three round trips (for
/// prepare, execute, and close) by requiring the caller to specify parameter values along with
/// their Postgres type. Thus, this is suitable in environments where prepared statements aren't
/// supported (such as Cloudflare Workers with Hyperdrive).
///
/// Executes a statement which returns a single row, returning it.
///
/// Returns an error if the query does not return exactly one row.
///
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
/// provided, 1-indexed.
pub fn query_typed_one(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Row, Error> {
self.connection
.block_on(self.client.query_typed_one(query, params))
}

/// Like `query_opt`, but requires the types of query parameters to be explicitly specified.
///
/// Compared to `query_opt`, this method allows performing queries without three round trips (for
/// prepare, execute, and close) by requiring the caller to specify parameter values along with
/// their Postgres type. Thus, this is suitable in environments where prepared statements aren't
/// supported (such as Cloudflare Workers with Hyperdrive).
/// Executes a statement which returns zero or one rows, returning it.
///
/// Returns an error if the query returns more than one row.
///
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
/// provided, 1-indexed.
pub fn query_typed_opt(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Option<Row>, Error> {
self.connection
.block_on(self.client.query_typed_opt(query, params))
}

/// The maximally flexible version of [`query_typed`].
///
/// Compared to `query`, this method allows performing queries without three round trips (for
Expand Down
69 changes: 69 additions & 0 deletionspostgres/src/generic_client.rs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,13 @@ pub trait GenericClient: private::Sealed {
where
T: ?Sized + ToStatement;

/// Like `Client::execute_typed`.
fn execute_typed(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<u64, Error>;

/// Like `Client::query`.
fn query<T>(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>, Error>
where
Expand DownExpand Up@@ -51,6 +58,20 @@ pub trait GenericClient: private::Sealed {
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Vec<Row>, Error>;

/// Like `Client::query_typed_one`.
fn query_typed_one(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Row, Error>;

/// Like `Client::query_typed_opt`.
fn query_typed_opt(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Option<Row>, Error>;

/// Like [`Client::query_typed_raw`]
fn query_typed_raw<P, I>(&mut self, statement: &str, params: I) -> Result<RowIter<'_>, Error>
where
Expand DownExpand Up@@ -136,6 +157,22 @@ impl GenericClient for Client {
self.query_typed(statement, params)
}

fn query_typed_one(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Row, Error> {
self.query_typed_one(query, params)
}

fn query_typed_opt(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Option<Row>, Error> {
self.query_typed_opt(query, params)
}

fn query_typed_raw<P, I>(&mut self, statement: &str, params: I) -> Result<RowIter<'_>, Error>
where
P: BorrowToSql,
Expand DownExpand Up@@ -177,6 +214,14 @@ impl GenericClient for Client {
fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
self.transaction()
}

fn execute_typed(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<u64, Error> {
self.execute_typed(query, params)
}
}

impl private::Sealed for Transaction<'_> {}
Expand DownExpand Up@@ -273,4 +318,28 @@ impl GenericClient for Transaction<'_> {
fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
self.transaction()
}

fn query_typed_one(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Row, Error> {
self.query_typed_one(query, params)
}

fn query_typed_opt(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Option<Row>, Error> {
self.query_typed_opt(query, params)
}
Comment on lines +322 to +336

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

NIT: this should be moved up, just afterquery_typed


fn execute_typed(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<u64, Error> {
self.execute_typed(query, params)
}
}
42 changes: 42 additions & 0 deletionspostgres/src/transaction.rs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,6 +70,20 @@ impl<'a> Transaction<'a> {
.block_on(self.transaction.as_ref().unwrap().execute(query, params))
}

/// Like `Client::execute_typed`.
pub fn execute_typed(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<u64, Error> {
self.connection.block_on(
self.transaction
.as_ref()
.unwrap()
.execute_typed(query, params),
)
}

/// Like `Client::query`.
pub fn query<T>(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>, Error>
where
Expand DownExpand Up@@ -129,6 +143,34 @@ impl<'a> Transaction<'a> {
)
}

/// Like `Client::query_typed_one`.
pub fn query_typed_one(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Row, Error> {
self.connection.block_on(
self.transaction
.as_ref()
.unwrap()
.query_typed_one(query, params),
)
}

/// Like `Client::query_typed_opt`.
pub fn query_typed_opt(
&mut self,
query: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Option<Row>, Error> {
self.connection.block_on(
self.transaction
.as_ref()
.unwrap()
.query_typed_opt(query, params),
)
}

/// Like `Client::query_typed_raw`.
pub fn query_typed_raw<P, I>(&mut self, query: &str, params: I) -> Result<RowIter<'_>, Error>
where
Expand Down
87 changes: 87 additions & 0 deletionstokio-postgres/src/client.rs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -388,6 +388,70 @@ impl Client {
.await
}

/// Like `query_one`, but requires the types of query parameters to be explicitly specified.
///
/// Compared to `query_one`, this method allows performing queries without three round trips (for
/// prepare, execute, and close) by requiring the caller to specify parameter values along with
/// their Postgres type. Thus, this is suitable in environments where prepared statements aren't
/// supported (such as Cloudflare Workers with Hyperdrive).
///
/// Executes a statement which returns a single row, returning it.
///
/// Returns an error if the query does not return exactly one row.
///
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
/// provided, 1-indexed.
///
pub async fn query_typed_one(
&self,
statement: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Row, Error> {
self.query_typed_opt(statement, params)
.await
.and_then(|res| res.ok_or_else(Error::row_count))
}

/// Like `query_one`, but requires the types of query parameters to be explicitly specified.
///
/// Compared to `query_one`, this method allows performing queries without three round trips (for
/// prepare, execute, and close) by requiring the caller to specify parameter values along with
/// their Postgres type. Thus, this is suitable in environments where prepared statements aren't
/// supported (such as Cloudflare Workers with Hyperdrive).
///
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the
/// parameter of the list provided, 1-indexed.
/// Executes a statements which returns zero or one rows, returning it.
///
/// Returns an error if the query returns more than one row.
pub async fn query_typed_opt(
&self,
statement: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<Option<Row>, Error> {
let mut stream = pin!(
self.query_typed_raw(statement, params.iter().map(|(v, t)| (*v, t.clone())))
.await?
);

let mut first = None;

// Originally this was two calls to `try_next().await?`,
// once for the first element, and second to error if more than one.
//
// However, this new form with only one .await in a loop generates
// slightly smaller codegen/stack usage for the resulting future.
while let Some(row) = stream.try_next().await? {
if first.is_some() {
return Err(Error::row_count());
}

first = Some(row);
}

Ok(first)
}

/// The maximally flexible version of [`query_typed`].
///
/// Compared to `query`, this method allows performing queries without three round trips (for
Expand DownExpand Up@@ -453,6 +517,29 @@ impl Client {
self.execute_raw(statement, slice_iter(params)).await
}

/// Executes a statement, returning the number of rows modified.
///
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
/// provided, 1-indexed.
///
/// The `statement` argument can either be a `Statement`, or a raw query string. If the same statement will be
/// repeatedly executed (perhaps with different query parameters), consider preparing the statement up front
/// with the `prepare` method.
///
/// If the statement does not modify any rows (e.g. `SELECT`), 0 is returned.
pub async fn execute_typed(
&self,
statement: &str,
params: &[(&(dyn ToSql + Sync), Type)],
) -> Result<u64, Error> {
query::execute_typed(
&self.inner,
statement,
params.iter().map(|(v, t)| (*v, t.clone())),
)
.await
}

/// The maximally flexible version of [`execute`].
///
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp