54
54
//! The client supports *pipelined* requests. Pipelining can improve performance in use cases in which multiple,
55
55
//! independent queries need to be executed. In a traditional workflow, each query is sent to the server after the
56
56
//! previous query completes. In contrast, pipelining allows the client to send all of the queries to the server up
57
- //! front, eliminating time spent on both sides waiting for the other to finish sending data:
57
+ //! front, minimizing time spent by one side waiting for the other to finish sending data:
58
58
//!
59
59
//! ```not_rust
60
60
//! Sequential Pipelined
75
75
//! the connection to work concurrently when possible.
76
76
//!
77
77
//! Pipelining happens automatically when futures are polled concurrently (for example, by using the futures `join`
78
- //! combinator). Say we want to prepare 2 statements:
79
- //!
80
- //! ```no_run
81
- //! use futures::Future;
82
- //! use tokio_postgres::{Client, Error, Statement};
83
- //!
84
- //! fn prepare_sequential(
85
- //! client: &mut Client,
86
- //! ) -> impl Future<Item = (Statement, Statement), Error = Error>
87
- //! {
88
- //! client.prepare("SELECT * FROM foo")
89
- //! .and_then({
90
- //! let f = client.prepare("INSERT INTO bar (id, name) VALUES ($1, $2)");
91
- //! |s1| f.map(|s2| (s1, s2))
92
- //! })
93
- //! }
94
- //!
95
- //! fn prepare_pipelined(
96
- //! client: &mut Client,
97
- //! ) -> impl Future<Item = (Statement, Statement), Error = Error>
98
- //! {
99
- //! client.prepare("SELECT * FROM foo")
100
- //! .join(client.prepare("INSERT INTO bar (id, name) VALUES ($1, $2)"))
101
- //! }
102
- //! ```
78
+ //! combinator). Say we want to prepare 2 statements.
103
79
//!
104
80
//! # Runtime
105
81
//!
@@ -143,6 +119,13 @@ fn next_portal() -> String {
143
119
format ! ( "p{}" , ID . fetch_add( 1 , Ordering :: SeqCst ) )
144
120
}
145
121
122
+ /// A convenience function which parses a connection string and connects to the database.
123
+ ///
124
+ /// See the documentation for [`Config`] for details on the connection string format.
125
+ ///
126
+ /// Requires the `runtime` Cargo feature (enabled by default).
127
+ ///
128
+ /// [`Config`]: ./Config.t.html
146
129
#[ cfg( feature = "runtime" ) ]
147
130
pub fn connect < T > ( config : & str , tls_mode : T ) -> Connect < T >
148
131
where
@@ -151,33 +134,73 @@ where
151
134
Connect ( proto:: ConnectFuture :: new ( tls_mode, config. parse ( ) ) )
152
135
}
153
136
137
+ /// An asynchronous PostgreSQL client.
138
+ ///
139
+ /// The client is one half of what is returned when a connection is established. Users interact with the database
140
+ /// through this client object.
154
141
pub struct Client ( proto:: Client ) ;
155
142
156
143
impl Client {
144
+ /// Creates a new prepared statement.
145
+ ///
146
+ /// Prepared statements can be executed repeatedly, and may contain query parameters (indicated by `$1`, `$2`, etc),
147
+ /// which are set when executed. Prepared statements can only be used with the connection that created them.
157
148
pub fn prepare ( & mut self , query : & str ) -> Prepare {
158
149
self . prepare_typed ( query, & [ ] )
159
150
}
160
151
152
+ /// Like `prepare`, but allows the types of query parameters to be explicitly specified.
153
+ ///
154
+ /// The list of types may be smaller than the number of parameters - the types of the remaining parameters will be
155
+ /// inferred. For example, `client.prepare_typed(query, &[])` is equivalent to `client.prepare(query)`.
161
156
pub fn prepare_typed ( & mut self , query : & str , param_types : & [ Type ] ) -> Prepare {
162
157
Prepare ( self . 0 . prepare ( next_statement ( ) , query, param_types) )
163
158
}
164
159
160
+ /// Executes a statement, returning the number of rows modified.
161
+ ///
162
+ /// If the statement does not modify any rows (e.g. `SELECT`), 0 is returned.
163
+ ///
164
+ /// # Panics
165
+ ///
166
+ /// Panics if the number of parameters provided does not match the number expected.
165
167
pub fn execute ( & mut self , statement : & Statement , params : & [ & dyn ToSql ] ) -> Execute {
166
168
Execute ( self . 0 . execute ( & statement. 0 , params) )
167
169
}
168
170
171
+ /// Executes a statement, returning a stream of the resulting rows.
172
+ ///
173
+ /// # Panics
174
+ ///
175
+ /// Panics if the number of parameters provided does not match the number expected.
169
176
pub fn query ( & mut self , statement : & Statement , params : & [ & dyn ToSql ] ) -> Query {
170
177
Query ( self . 0 . query ( & statement. 0 , params) )
171
178
}
172
179
180
+ /// Binds a statement to a set of parameters, creating a `Portal` which can be incrementally queried.
181
+ ///
182
+ /// Portals only last for the duration of the transaction in which they are created - in particular, a portal
183
+ /// created outside of a transaction is immediately destroyed. Portals can only be used on the connection that
184
+ /// created them.
185
+ /// # Panics
186
+ ///
187
+ /// Panics if the number of parameters provided does not match the number expected.
173
188
pub fn bind ( & mut self , statement : & Statement , params : & [ & dyn ToSql ] ) -> Bind {
174
189
Bind ( self . 0 . bind ( & statement. 0 , next_portal ( ) , params) )
175
190
}
176
191
192
+ /// Continues execution of a portal, returning a stream of the resulting rows.
193
+ ///
194
+ /// Unlike `query`, portals can be incrementally evaluated by limiting the number of rows returned in each call to
195
+ /// query_portal. If the requested number is negative or 0, all rows will be returned.
177
196
pub fn query_portal ( & mut self , portal : & Portal , max_rows : i32 ) -> QueryPortal {
178
197
QueryPortal ( self . 0 . query_portal ( & portal. 0 , max_rows) )
179
198
}
180
199
200
+ /// Executes a `COPY FROM STDIN` statement, returning the number of rows created.
201
+ ///
202
+ /// The data in the provided stream is passed along to the server verbatim; it is the caller's responsibility to
203
+ /// ensure it uses the proper format.
181
204
pub fn copy_in < S > (
182
205
& mut self ,
183
206
statement : & Statement ,
@@ -194,18 +217,36 @@ impl Client {
194
217
CopyIn ( self . 0 . copy_in ( & statement. 0 , params, stream) )
195
218
}
196
219
220
+ /// Executes a `COPY TO STDOUT` statement, returning a stream of the resulting data.
197
221
pub fn copy_out ( & mut self , statement : & Statement , params : & [ & dyn ToSql ] ) -> CopyOut {
198
222
CopyOut ( self . 0 . copy_out ( & statement. 0 , params) )
199
223
}
200
224
201
- pub fn transaction ( & mut self ) -> TransactionBuilder {
202
- TransactionBuilder ( self . 0 . clone ( ) )
203
- }
204
-
225
+ /// Executes a sequence of SQL statements.
226
+ ///
227
+ /// Statements should be separated by semicolons. If an error occurs, execution of the sequence will stop at that
228
+ /// point. This is intended for the execution of batches of non-dynamic statements, for example, the creation of
229
+ /// a schema for a fresh database.
230
+ ///
231
+ /// # Warning
232
+ ///
233
+ /// Prepared statements should be use for any query which contains user-specified data, as they provided the
234
+ /// functionality to safely imbed that data in the request. Do not form statements via string concatenation and pass
235
+ /// them to this method!
205
236
pub fn batch_execute ( & mut self , query : & str ) -> BatchExecute {
206
237
BatchExecute ( self . 0 . batch_execute ( query) )
207
238
}
208
239
240
+ pub fn transaction ( & mut self ) -> TransactionBuilder {
241
+ TransactionBuilder ( self . 0 . clone ( ) )
242
+ }
243
+
244
+ /// Attempts to cancel an in-progress query.
245
+ ///
246
+ /// The server provides no information about whether a cancellation attempt was successful or not. An error will
247
+ /// only be returned if the client was unable to connect to the database.
248
+ ///
249
+ /// Requires the `runtime` Cargo feature (enabled by default).
209
250
#[ cfg( feature = "runtime" ) ]
210
251
pub fn cancel_query < T > ( & mut self , make_tls_mode : T ) -> CancelQuery < T >
211
252
where
@@ -214,6 +255,8 @@ impl Client {
214
255
CancelQuery ( self . 0 . cancel_query ( make_tls_mode) )
215
256
}
216
257
258
+ /// Like `cancel_query`, but uses a stream which is already connected to the server rather than opening a new
259
+ /// connection itself.
217
260
pub fn cancel_query_raw < S , T > ( & mut self , stream : S , tls_mode : T ) -> CancelQueryRaw < S , T >
218
261
where
219
262
S : AsyncRead + AsyncWrite ,
@@ -222,26 +265,47 @@ impl Client {
222
265
CancelQueryRaw ( self . 0 . cancel_query_raw ( stream, tls_mode) )
223
266
}
224
267
268
+ /// Determines if the connection to the server has already closed.
269
+ ///
270
+ /// In that case, all future queries will fail.
225
271
pub fn is_closed ( & self ) -> bool {
226
272
self . 0 . is_closed ( )
227
273
}
228
274
275
+ /// Polls the client to check if it is idle.
276
+ ///
277
+ /// A connection is idle if there are no outstanding requests, whether they have begun being polled or not. For
278
+ /// example, this can be used by a connection pool to ensure that all work done by one checkout is done before
279
+ /// making the client available for a new request. Otherwise, any non-completed work from the first request could
280
+ /// interleave with the second.
229
281
pub fn poll_idle ( & mut self ) -> Poll < ( ) , Error > {
230
282
self . 0 . poll_idle ( )
231
283
}
232
284
}
233
285
286
+ /// A connection to a PostgreSQL database.
287
+ ///
288
+ /// This is one half of what is returned when a new connection is established. It performs the actual IO with the
289
+ /// server, and should generally be spawned off onto an executor to run in the background.
290
+ ///
291
+ /// `Connection` implements `Future`, and only resolves when the connection is closed, either because a fatal error has
292
+ /// occurred, or because its associated `Client` has dropped and all outstanding work has completed.
234
293
#[ must_use = "futures do nothing unless polled" ]
235
294
pub struct Connection < S > ( proto:: Connection < S > ) ;
236
295
237
296
impl < S > Connection < S >
238
297
where
239
298
S : AsyncRead + AsyncWrite ,
240
299
{
300
+ /// Returns the value of a runtime parameter for this connection.
241
301
pub fn parameter ( & self , name : & str ) -> Option < & str > {
242
302
self . 0 . parameter ( name)
243
303
}
244
304
305
+ /// Polls for asynchronous messages from the server.
306
+ ///
307
+ /// The server can send notices as well as notifications asynchronously to the client. Applications which wish to
308
+ /// examine those messages should use this method to drive the connection rather than its `Future` implementation.
245
309
pub fn poll_message ( & mut self ) -> Poll < Option < AsyncMessage > , Error > {
246
310
self . 0 . poll_message ( )
247
311
}
@@ -259,9 +323,16 @@ where
259
323
}
260
324
}
261
325
326
+ /// An asynchronous message from the server.
262
327
#[ allow( clippy:: large_enum_variant) ]
263
328
pub enum AsyncMessage {
329
+ /// A notice.
330
+ ///
331
+ /// Notices use the same format as errors, but aren't "errors" per-se.
264
332
Notice ( DbError ) ,
333
+ /// A notification.
334
+ ///
335
+ /// Connections can subscribe to notifications with the `LISTEN` command.
265
336
Notification ( Notification ) ,
266
337
#[ doc( hidden) ]
267
338
__NonExhaustive,
@@ -361,14 +432,19 @@ impl Future for Prepare {
361
432
}
362
433
}
363
434
435
+ /// A prepared statement.
436
+ ///
437
+ /// Prepared statements can only be used with the connection that created them.
364
438
#[ derive( Clone ) ]
365
439
pub struct Statement ( proto:: Statement ) ;
366
440
367
441
impl Statement {
442
+ /// Returns the expected types of the statement's parameters.
368
443
pub fn params ( & self ) -> & [ Type ] {
369
444
self . 0 . params ( )
370
445
}
371
446
447
+ /// Returns information about the columns returned when the statement is queried.
372
448
pub fn columns ( & self ) -> & [ Column ] {
373
449
self . 0 . columns ( )
374
450
}
@@ -426,6 +502,10 @@ impl Stream for QueryPortal {
426
502
}
427
503
}
428
504
505
+ /// A portal.
506
+ ///
507
+ /// Portals can only be used with the connection that created them, and only exist for the duration of the transaction
508
+ /// in which they were created.
429
509
pub struct Portal ( proto:: Portal ) ;
430
510
431
511
#[ must_use = "futures do nothing unless polled" ]
@@ -512,10 +592,24 @@ impl Future for BatchExecute {
512
592
/// An asynchronous notification.
513
593
#[ derive( Clone , Debug ) ]
514
594
pub struct Notification {
595
+ process_id : i32 ,
596
+ channel : String ,
597
+ payload : String ,
598
+ }
599
+
600
+ impl Notification {
515
601
/// The process ID of the notifying backend process.
516
- pub process_id : i32 ,
602
+ pub fn process_id ( & self ) -> i32 {
603
+ self . process_id
604
+ }
605
+
517
606
/// The name of the channel that the notify has been raised on.
518
- pub channel : String ,
607
+ pub fn channel ( & self ) -> & str {
608
+ & self . channel
609
+ }
610
+
519
611
/// The "payload" string passed from the notifying process.
520
- pub payload : String ,
612
+ pub fn payload ( & self ) -> & str {
613
+ & self . payload
614
+ }
521
615
}
0 commit comments