Skip to content

Commit

Permalink
docs: update for new paging API
Browse files Browse the repository at this point in the history
  • Loading branch information
wprzytula committed Aug 26, 2024
1 parent 2610b3e commit a139ca5
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 23 deletions.
77 changes: 61 additions & 16 deletions docs/source/queries/paged.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Paged query
Sometimes query results might not fit in a single page. Paged queries
allow to receive the whole result page by page.
Sometimes query results might be so big that one prefers not to fetch them all at once,
e.g. to reduce latency and/or memory footprint.
Paged queries allow to receive the whole result page by page, with a configurable page size.

`Session::query_iter` and `Session::execute_iter` take a [simple query](simple.md) or a [prepared query](prepared.md)
and return an `async` iterator over result `Rows`.
`Session::query_iter` and `Session::execute_iter` take a [simple query](simple.md)
or a [prepared query](prepared.md) and return an `async` iterator over result `Rows`.

> ***Warning***\
> In case of unprepared variant (`Session::query_iter`) if the values are not empty
Expand Down Expand Up @@ -79,7 +80,7 @@ On a `Query`:
use scylla::query::Query;

let mut query: Query = Query::new("SELECT a, b FROM ks.t");
query.set_page_size(16);
query.set_page_size(16.try_into().unwrap());

let _ = session.query_iter(query, &[]).await?; // ...
# Ok(())
Expand All @@ -98,7 +99,7 @@ let mut prepared: PreparedStatement = session
.prepare("SELECT a, b FROM ks.t")
.await?;

prepared.set_page_size(16);
prepared.set_page_size(16.try_into().unwrap());

let _ = session.execute_iter(prepared, &[]).await?; // ...
# Ok(())
Expand All @@ -117,12 +118,33 @@ On a `Query`:
# use std::error::Error;
# async fn check_only_compiles(session: &Session) -> Result<(), Box<dyn Error>> {
use scylla::query::Query;
use scylla::statement::{PagingState, PagingStateResponse};
use std::ops::ControlFlow;

let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6.try_into().unwrap());

let mut paging_state = PagingState::start();
loop {
let (res, paging_state_response) = session
.query_single_page(paged_query.clone(), &[], paging_state)
.await?;

// Do something with `res`.
// ...

match paging_state_response.into_paging_control_flow() {
ControlFlow::Break(()) => {
// No more pages to be fetched.
break;
}
ControlFlow::Continue(new_paging_state) => {
// Update paging state from the response, so that query
// will be resumed from where it ended the last time.
paging_state = new_paging_state
}
}
}

let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6);
let res1 = session.query(paged_query.clone(), &[]).await?;
let res2 = session
.query_single_page(paged_query.clone(), &[], res1.paging_state)
.await?;
# Ok(())
# }
```
Expand All @@ -139,14 +161,37 @@ On a `PreparedStatement`:
# use std::error::Error;
# async fn check_only_compiles(session: &Session) -> Result<(), Box<dyn Error>> {
use scylla::query::Query;
use scylla::statement::{PagingState, PagingStateResponse};
use std::ops::ControlFlow;

let paged_prepared = session
.prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7))
.await?;
let res1 = session.execute(&paged_prepared, &[]).await?;
let res2 = session
.execute_single_page(&paged_prepared, &[], res1.paging_state)
.prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7.try_into().unwrap()))
.await?;

let mut paging_state = PagingState::start();
loop {
let (res, paging_state_response) = session
.execute_single_page(&paged_prepared, &[], paging_state)
.await?;

println!(
"Paging state response from the prepared statement execution: {:#?} ({} rows)",
paging_state_response,
res.rows_num()?,
);

match paging_state_response.into_paging_control_flow() {
ControlFlow::Break(()) => {
// No more pages to be fetched.
break;
}
ControlFlow::Continue(new_paging_state) => {
// Update paging state from the response, so that query
// will be resumed from where it ended the last time.
paging_state = new_paging_state
}
}
}
# Ok(())
# }
```
Expand Down
3 changes: 2 additions & 1 deletion docs/source/queries/result.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Query result

`Session::query` and `Session::execute` return a `QueryResult` with rows represented as `Option<Vec<Row>>`.
`Session::query_unpaged`, `Session::query_single_page`, `Session::execute_unpaged` and `Session::execute_single_page`
return a `QueryResult` with rows represented as `Option<Vec<Row>>`.

### Basic representation
`Row` is a basic representation of a received row. It can be used by itself, but it's a bit awkward to use:
Expand Down
9 changes: 4 additions & 5 deletions docs/source/queries/simple.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ session
> By default the query is unpaged and might cause heavy load on the cluster.\
> In such cases set a page size and use [paged query](paged.md) instead.\
>
> When page size is set, `query` will return only the first page of results.
> `query_unpaged` will return all results in one, possibly giant, piece
> (unless a timeout occurs due to high load incurred by the cluster).
> ***Warning***\
> If the values are not empty, driver first needs to send a `PREPARE` request
> in order to fetch information required to serialize values. This will affect
> performance because 2 round trips will be required instead of 1.
### First argument - the query
As the first argument `Session::query` takes anything implementing `Into<Query>`.\
As the first argument `Session::query_unpaged` takes anything implementing `Into<Query>`.\
You can create a query manually to set custom options. For example to change query consistency:
```rust
# extern crate scylla;
Expand Down Expand Up @@ -74,7 +75,7 @@ Here the first `?` will be filled with `2` and the second with `"Some text"`.
See [Query values](values.md) for more information about sending values in queries

### Query result
`Session::query` returns `QueryResult` with rows represented as `Option<Vec<Row>>`.\
`Session::query_unpaged` returns `QueryResult` with rows represented as `Option<Vec<Row>>`.\
Each row can be parsed as a tuple of rust types using `rows_typed`:
```rust
# extern crate scylla;
Expand All @@ -92,8 +93,6 @@ while let Some(read_row) = iter.next().transpose()? {
# Ok(())
# }
```
> In cases where page size is set, simple query returns only a single page of results.\
> To receive all pages use a [paged query](paged.md) instead.\

See [Query result](result.md) for more information about handling query results

Expand Down
4 changes: 3 additions & 1 deletion docs/source/queries/usekeyspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ session
The first argument is the keyspace name.\
The second argument states whether this name is case sensitive.

It is also possible to send raw use keyspace query using `Session::query` instead of `Session::use_keyspace` such as:
It is also possible to send raw use keyspace query using `Session::query_*` instead of `Session::use_keyspace` such as:

```rust
# extern crate scylla;
# use scylla::Session;
Expand All @@ -59,6 +60,7 @@ session.query_unpaged("USE my_keyspace", &[]).await?;
# Ok(())
# }
```

This method has a slightly worse latency than `Session::use_keyspace` - there are two roundtrips needed instead of one.
Therefore, `Session::use_keyspace` is the preferred method for setting keyspaces.

Expand Down

0 comments on commit a139ca5

Please sign in to comment.