sentinel_driver/connection/portal_impl.rs
1use super::Connection;
2use crate::error::Result;
3use crate::portal::{self, Portal};
4use crate::row::Row;
5use crate::types::ToSql;
6
7impl Connection {
8 /// Create a server-side portal (cursor) for incremental row fetching.
9 ///
10 /// Portals only work inside transactions. The portal borrows the
11 /// connection state, so no concurrent queries while a portal is open.
12 ///
13 /// # Example
14 ///
15 /// ```rust,no_run
16 /// # async fn example(conn: &mut sentinel_driver::Connection) -> sentinel_driver::Result<()> {
17 /// conn.begin().await?;
18 /// let portal = conn.bind_portal("SELECT * FROM big_table", &[]).await?;
19 /// let batch = conn.query_portal(&portal, 100).await?;
20 /// conn.close_portal(portal).await?;
21 /// conn.commit().await?;
22 /// # Ok(())
23 /// # }
24 /// ```
25 pub async fn bind_portal(
26 &mut self,
27 sql: &str,
28 params: &[&(dyn ToSql + Sync)],
29 ) -> Result<Portal> {
30 portal::create_portal(&mut self.conn, sql, params).await
31 }
32
33 /// Fetch up to `max_rows` rows from a portal.
34 ///
35 /// Returns an empty `Vec` when the cursor is exhausted.
36 /// Use `max_rows = 0` to fetch all remaining rows.
37 pub async fn query_portal(&mut self, portal: &Portal, max_rows: i32) -> Result<Vec<Row>> {
38 let mut portal_mut = Portal {
39 name: portal.name.clone(),
40 description: portal.description.clone(),
41 exhausted: portal.exhausted,
42 };
43 let rows = portal::fetch_portal(&mut self.conn, &mut portal_mut, max_rows).await?;
44 Ok(rows)
45 }
46
47 /// Close a portal on the server, freeing resources.
48 pub async fn close_portal(&mut self, portal: Portal) -> Result<()> {
49 portal::close_portal(&mut self.conn, portal).await
50 }
51}