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

Commit384043e

Browse files
committed
execute_typed tests
1 parent9200080 commit384043e

File tree

7 files changed

+200
-13
lines changed

7 files changed

+200
-13
lines changed

‎postgres/src/client.rs‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,48 @@ impl Client {
8383
self.connection.block_on(self.client.execute(query, params))
8484
}
8585

86+
/// Executes a statement, returning the number of rows modified.
87+
///
88+
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list
89+
/// provided, 1-indexed.
90+
///
91+
///
92+
/// Compared to `execute`, this method allows performing queries without three round trips (for
93+
/// prepare, execute, and close) by requiring the caller to specify parameter values along with
94+
/// their Postgres type. Thus, this is suitable in environments where prepared statements aren't
95+
/// supported (such as Cloudflare Workers with Hyperdrive).
96+
///
97+
/// If the statement does not modify any rows (e.g. `SELECT`), 0 is returned.
98+
///
99+
///
100+
/// # Example
101+
///
102+
/// ```no_run
103+
/// use postgres::{Client, NoTls};
104+
///
105+
/// # fn main() -> Result<(), postgres::Error> {
106+
/// let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
107+
///
108+
/// let bar = 1i32;
109+
/// let baz = true;
110+
/// let rows_updated = client.execute_typed(
111+
/// "UPDATE foo SET bar = $1 WHERE baz = $2",
112+
/// &[(&bar, Type::INT4), (&baz, Type::BOOL)],
113+
/// )?;
114+
///
115+
/// println!("{} rows updated", rows_updated);
116+
/// # Ok(())
117+
/// # }
118+
/// ```
119+
pubfnexecute_typed(
120+
&mutself,
121+
query:&str,
122+
params:&[(&(dynToSql +Sync),Type)],
123+
) ->Result<u64,Error>{
124+
self.connection
125+
.block_on(self.client.execute_typed(query, params))
126+
}
127+
86128
/// Executes a statement, returning the resulting rows.
87129
///
88130
/// A statement may contain parameters, specified by `$n`, where `n` is the index of the parameter of the list

‎postgres/src/generic_client.rs‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ pub trait GenericClient: private::Sealed {
1717
where
1818
T: ?Sized +ToStatement;
1919

20+
/// Like `Client::execute_typed`.
21+
fnexecute_typed(
22+
&mutself,
23+
query:&str,
24+
params:&[(&(dynToSql +Sync),Type)],
25+
) ->Result<u64,Error>;
26+
2027
/// Like `Client::query`.
2128
fnquery<T>(&mutself,query:&T,params:&[&(dynToSql +Sync)]) ->Result<Vec<Row>,Error>
2229
where
@@ -207,6 +214,14 @@ impl GenericClient for Client {
207214
fntransaction(&mutself) ->Result<Transaction<'_>,Error>{
208215
self.transaction()
209216
}
217+
218+
fnexecute_typed(
219+
&mutself,
220+
query:&str,
221+
params:&[(&(dynToSql +Sync),Type)],
222+
) ->Result<u64,Error>{
223+
self.execute_typed(query, params)
224+
}
210225
}
211226

212227
impl private::SealedforTransaction<'_>{}
@@ -319,4 +334,12 @@ impl GenericClient for Transaction<'_> {
319334
) ->Result<Option<Row>,Error>{
320335
self.query_typed_opt(query, params)
321336
}
337+
338+
fnexecute_typed(
339+
&mutself,
340+
query:&str,
341+
params:&[(&(dynToSql +Sync),Type)],
342+
) ->Result<u64,Error>{
343+
self.execute_typed(query, params)
344+
}
322345
}

‎postgres/src/transaction.rs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ impl<'a> Transaction<'a> {
7070
.block_on(self.transaction.as_ref().unwrap().execute(query, params))
7171
}
7272

73+
/// Like `Client::execute_typed`.
74+
pubfnexecute_typed(
75+
&mutself,
76+
query:&str,
77+
params:&[(&(dynToSql +Sync),Type)],
78+
) ->Result<u64,Error>{
79+
self.connection.block_on(
80+
self.transaction
81+
.as_ref()
82+
.unwrap()
83+
.execute_typed(query, params),
84+
)
85+
}
86+
7387
/// Like `Client::query`.
7488
pubfnquery<T>(&mutself,query:&T,params:&[&(dynToSql +Sync)]) ->Result<Vec<Row>,Error>
7589
where

‎tokio-postgres/src/generic_client.rs‎

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ pub trait GenericClient: private::Sealed {
2525
I:IntoIterator<Item =P> +Sync +Send,
2626
I::IntoIter:ExactSizeIterator;
2727

28+
/// Like [`Client::execute_typed`].
29+
asyncfnexecute_typed(
30+
&self,
31+
statement:&str,
32+
params:&[(&(dynToSql +Sync),Type)],
33+
) ->Result<u64,Error>;
34+
2835
/// Like [`Client::query`].
2936
asyncfnquery<T>(&self,query:&T,params:&[&(dynToSql +Sync)]) ->Result<Vec<Row>,Error>
3037
where
@@ -117,6 +124,14 @@ impl GenericClient for Client {
117124
self.execute(query, params).await
118125
}
119126

127+
asyncfnexecute_typed(
128+
&self,
129+
statement:&str,
130+
params:&[(&(dynToSql +Sync),Type)],
131+
) ->Result<u64,Error>{
132+
self.execute_typed(statement, params).await
133+
}
134+
120135
asyncfnexecute_raw<P,I,T>(&self,statement:&T,params:I) ->Result<u64,Error>
121136
where
122137
T: ?Sized +ToStatement +Sync +Send,
@@ -297,6 +312,23 @@ impl GenericClient for Transaction<'_> {
297312
self.query_typed(statement, params).await
298313
}
299314

315+
asyncfnquery_typed_one(
316+
&self,
317+
statement:&str,
318+
params:&[(&(dynToSql +Sync),Type)],
319+
) ->Result<Row,Error>{
320+
self.query_typed_one(statement, params).await
321+
}
322+
323+
/// Like [`Client::query_opt_typed`].
324+
asyncfnquery_typed_opt(
325+
&self,
326+
statement:&str,
327+
params:&[(&(dynToSql +Sync),Type)],
328+
) ->Result<Option<Row>,Error>{
329+
self.query_typed_opt(statement, params).await
330+
}
331+
300332
asyncfnquery_typed_raw<P,I>(&self,statement:&str,params:I) ->Result<RowStream,Error>
301333
where
302334
P:BorrowToSql,
@@ -334,20 +366,11 @@ impl GenericClient for Transaction<'_> {
334366
self.client()
335367
}
336368

337-
asyncfnquery_typed_one(
369+
asyncfnexecute_typed(
338370
&self,
339371
statement:&str,
340372
params:&[(&(dynToSql +Sync),Type)],
341-
) ->Result<Row,Error>{
342-
self.query_typed_one(statement, params).await
343-
}
344-
345-
/// Like [`Client::query_opt_typed`].
346-
asyncfnquery_typed_opt(
347-
&self,
348-
statement:&str,
349-
params:&[(&(dynToSql +Sync),Type)],
350-
) ->Result<Option<Row>,Error>{
351-
self.query_typed_opt(statement, params).await
373+
) ->Result<u64,Error>{
374+
self.client().execute_typed(statement, params).await
352375
}
353376
}

‎tokio-postgres/src/query.rs‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,24 @@ where
149149

150150
loop{
151151
match responses.next().await?{
152+
Message::ParseComplete
153+
|Message::BindComplete
154+
|Message::ParameterDescription(_)
155+
|Message::RowDescription(_) =>{}
156+
Message::NoData =>{
157+
rows =0;
158+
}
159+
152160
Message::DataRow(_) =>{}
153161
Message::CommandComplete(body) =>{
154162
rows =extract_row_affected(&body)?;
155163
}
164+
156165
Message::EmptyQueryResponse => rows =0,
157166
Message::ReadyForQuery(_) =>returnOk(rows),
158-
_ =>returnErr(Error::unexpected_message()),
167+
_ =>{
168+
returnErr(Error::unexpected_message());
169+
}
159170
}
160171
}
161172
}

‎tokio-postgres/src/transaction.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,15 @@ impl<'a> Transaction<'a> {
183183
self.client.execute(statement, params).await
184184
}
185185

186+
/// Like `Client::execute_typed`.
187+
pubasyncfnexecute_typed(
188+
&self,
189+
statement:&str,
190+
params:&[(&(dynToSql +Sync),Type)],
191+
) ->Result<u64,Error>{
192+
self.client.execute_typed(statement, params).await
193+
}
194+
186195
/// Like `Client::execute_iter`.
187196
pubasyncfnexecute_raw<P,I,T>(&self,statement:&T,params:I) ->Result<u64,Error>
188197
where

‎tokio-postgres/tests/test/main.rs‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,71 @@ async fn transaction_commit() {
403403
assert_eq!(rows[0].get::<_,&str>(0),"steven");
404404
}
405405

406+
#[tokio::test]
407+
asyncfnexecute_typed(){
408+
let client =connect("user=postgres").await;
409+
410+
client
411+
.batch_execute(
412+
"
413+
CREATE TEMPORARY TABLE foo (
414+
name TEXT,
415+
age INT
416+
);
417+
INSERT INTO foo (name, age) VALUES ('alice', 20), ('bob', 30), ('carol', 40);
418+
",
419+
)
420+
.await
421+
.unwrap();
422+
423+
// one row is modified, hence expect 1
424+
let n = client
425+
.execute_typed(
426+
"INSERT INTO foo (name, age) VALUES ($1, $2)",
427+
&[(&"dave",Type::TEXT),(&39i32,Type::INT4)],
428+
)
429+
.await
430+
.unwrap();
431+
432+
assert_eq!(n,1);
433+
434+
// confirming execution succeeded
435+
let row = client
436+
.query_typed_one(
437+
"SELECT age FROM foo WHERE name = $1",
438+
&[(&"dave",Type::TEXT)],
439+
)
440+
.await
441+
.unwrap();
442+
443+
assert_eq!(row.get::<_,i32>(0),39);
444+
445+
// there are 4 rows in the table, that will be updated
446+
let n = client
447+
.execute_typed("UPDATE foo SET age = $1",&[(&100i32,Type::INT4)])
448+
.await
449+
.unwrap();
450+
451+
assert_eq!(n,4);
452+
// no rows are modified, hence expect 0
453+
let n = client
454+
.execute_typed("SELECT * FROM foo WHERE age < $1",&[(&50i32,Type::INT4)])
455+
.await
456+
.unwrap();
457+
assert_eq!(n,0);
458+
459+
// there are 4 rows in the table, that will be updated
460+
let n = client
461+
.execute_typed(
462+
"UPDATE foo SET age = $1 RETURNING name",
463+
&[(&200i32,Type::INT4)],
464+
)
465+
.await
466+
.unwrap();
467+
468+
assert_eq!(n,4);
469+
}
470+
406471
#[tokio::test]
407472
asyncfntransaction_rollback(){
408473
letmut client =connect("user=postgres").await;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp