@@ -321,6 +321,70 @@ impl Client {
321
321
Ok ( first)
322
322
}
323
323
324
+ /// Like `query_one`, but requires the types of query parameters to be explicitly specified.
325
+ ///
326
+ /// Compared to `query_one`, this method allows performing queries without three round trips (for
327
+ /// prepare, execute, and close) by requiring the caller to specify parameter values along with
328
+ /// their Postgres type. Thus, this is suitable in environments where prepared statements aren't
329
+ /// supported (such as Cloudflare Workers with Hyperdrive).
330
+ ///
331
+ /// Executes a statement which returns a single row, returning it.
332
+ ///
333
+ /// Returns an error if the query does not return exactly one row.
334
+ ///
335
+ /// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
336
+ /// provided, 1-indexed.
337
+ ///
338
+ pub async fn query_typed_one (
339
+ & self ,
340
+ statement : & str ,
341
+ params : & [ ( & ( dyn ToSql +Sync ) , Type ) ] ,
342
+ ) ->Result < Row , Error > {
343
+ self . query_typed_opt ( statement, params)
344
+ . await
345
+ . and_then ( |res| res. ok_or_else ( Error :: row_count) )
346
+ }
347
+
348
+ /// Like `query_one`, but requires the types of query parameters to be explicitly specified.
349
+ ///
350
+ /// Compared to `query_one`, this method allows performing queries without three round trips (for
351
+ /// prepare, execute, and close) by requiring the caller to specify parameter values along with
352
+ /// their Postgres type. Thus, this is suitable in environments where prepared statements aren't
353
+ /// supported (such as Cloudflare Workers with Hyperdrive).
354
+ ///
355
+ /// A statement may contain parameters, specified by `$n`, where `n` is the index of the
356
+ /// parameter of the list provided, 1-indexed.
357
+ /// Executes a statements which returns zero or one rows, returning it.
358
+ ///
359
+ /// Returns an error if the query returns more than one row.
360
+ pub async fn query_typed_opt (
361
+ & self ,
362
+ statement : & str ,
363
+ params : & [ ( & ( dyn ToSql +Sync ) , Type ) ] ,
364
+ ) ->Result < Option < Row > , Error > {
365
+ let stream =self
366
+ . query_typed_raw ( statement, params. iter ( ) . map ( |( v, t) |( * v, t. clone ( ) ) ) )
367
+ . await ?;
368
+ pin_mut ! ( stream) ;
369
+
370
+ let mut first =None ;
371
+
372
+ // Originally this was two calls to `try_next().await?`,
373
+ // once for the first element, and second to error if more than one.
374
+ //
375
+ // However, this new form with only one .await in a loop generates
376
+ // slightly smaller codegen/stack usage for the resulting future.
377
+ while let Some ( row) = stream. try_next ( ) . await ?{
378
+ if first. is_some ( ) {
379
+ return Err ( Error :: row_count ( ) ) ;
380
+ }
381
+
382
+ first =Some ( row) ;
383
+ }
384
+
385
+ Ok ( first)
386
+ }
387
+
324
388
/// The maximally flexible version of [`query`].
325
389
///
326
390
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list