use crate::prelude::*;
use toasty::stmt::Page;
use toasty_core::driver::{Operation, Rows};
#[driver_test(requires(sql))]
pub async fn paginate_composite_key(test: &mut Test) -> Result<()> {
#[derive(Debug, toasty::Model)]
#[key(partition = kind, local = seq)]
struct Event {
kind: String,
seq: i64,
}
let mut db = test.setup_db(models!(Event)).await;
for i in 0..20 {
Event::create().kind("info").seq(i).exec(&mut db).await?;
}
test.log().clear();
let page: Page<_> = Event::filter_by_kind("info")
.order_by(Event::fields().seq().desc())
.paginate(10)
.exec(&mut db)
.await?;
assert_eq!(page.len(), 10);
for (i, expected) in (10..20).rev().enumerate() {
assert_eq!(page[i].seq, expected);
}
let (op, resp) = test.log().pop();
if test.capability().sql {
assert_struct!(op, Operation::QuerySql(_));
} else {
assert_struct!(op, Operation::QueryPk(_));
}
assert_struct!(resp.values, Rows::Stream(_));
let page: Page<_> = page.next(&mut db).await?.unwrap();
assert_eq!(page.len(), 10);
for (i, expected) in (0..10).rev().enumerate() {
assert_eq!(page[i].seq, expected);
}
let page: Page<_> = page.prev(&mut db).await?.unwrap();
assert_eq!(page.len(), 10);
for (i, expected) in (10..20).rev().enumerate() {
assert_eq!(page[i].seq, expected);
}
Ok(())
}
#[driver_test]
pub async fn paginate_composite_key_asc(test: &mut Test) -> Result<()> {
#[derive(Debug, toasty::Model)]
#[key(partition = kind, local = seq)]
struct Event {
kind: String,
seq: i64,
}
let mut db = test.setup_db(models!(Event)).await;
for i in 0..20 {
Event::create().kind("info").seq(i).exec(&mut db).await?;
}
test.log().clear();
let page: Page<_> = Event::filter_by_kind("info")
.order_by(Event::fields().seq().asc())
.paginate(5)
.exec(&mut db)
.await?;
assert_eq!(page.len(), 5);
for (i, expected) in (0..5).enumerate() {
assert_eq!(page[i].seq, expected);
}
let (op, _) = test.log().pop();
if test.capability().sql {
assert_struct!(op, Operation::QuerySql(_));
} else {
assert_struct!(op, Operation::QueryPk(_));
}
let mut all_seqs: Vec<i64> = page.iter().map(|e| e.seq).collect();
let mut current = page;
while let Some(next) = current.next(&mut db).await? {
all_seqs.extend(next.iter().map(|e| e.seq));
current = next;
}
assert_eq!(all_seqs, (0..20).collect::<Vec<_>>());
Ok(())
}
#[driver_test]
pub async fn limit_offset_composite_key(test: &mut Test) -> Result<()> {
#[derive(Debug, toasty::Model)]
#[key(partition = kind, local = seq)]
struct Event {
kind: String,
seq: i64,
}
let mut db = test.setup_db(models!(Event)).await;
for i in 0..20 {
Event::create().kind("info").seq(i).exec(&mut db).await?;
}
let events: Vec<_> = Event::filter_by_kind("info").limit(5).exec(&mut db).await?;
assert_eq!(events.len(), 5);
test.log().clear();
let events: Vec<_> = Event::filter_by_kind("info")
.order_by(Event::fields().seq().asc())
.limit(7)
.offset(5)
.exec(&mut db)
.await?;
assert_eq!(events.len(), 7);
assert_eq!(events[0].seq, 5);
assert_eq!(events[6].seq, 11);
let (op, _) = test.log().pop();
if test.capability().sql {
assert_struct!(op, Operation::QuerySql(_));
} else {
assert_struct!(op, Operation::QueryPk(_));
}
let events: Vec<_> = Event::filter_by_kind("info")
.order_by(Event::fields().seq().asc())
.limit(5)
.offset(0)
.exec(&mut db)
.await?;
assert_eq!(events.len(), 5);
assert_eq!(events[0].seq, 0);
assert_eq!(events[4].seq, 4);
let events: Vec<_> = Event::filter_by_kind("info")
.limit(5)
.offset(100)
.exec(&mut db)
.await?;
assert!(events.is_empty());
let events: Vec<_> = Event::filter_by_kind("info")
.limit(100)
.exec(&mut db)
.await?;
assert_eq!(events.len(), 20);
Ok(())
}
#[driver_test]
pub async fn limit_offset_gsi(test: &mut Test) -> Result<()> {
#[derive(Debug, toasty::Model)]
struct Item {
#[key]
#[auto]
id: uuid::Uuid,
#[index]
category: String,
value: i64,
}
let mut db = test.setup_db(models!(Item)).await;
for i in 0..20 {
Item::create().category("x").value(i).exec(&mut db).await?;
}
let items: Vec<_> = Item::filter_by_category("x").limit(5).exec(&mut db).await?;
assert_eq!(items.len(), 5);
let items: Vec<_> = Item::filter_by_category("x")
.limit(7)
.offset(3)
.exec(&mut db)
.await?;
assert_eq!(items.len(), 7);
let items: Vec<_> = Item::filter_by_category("x")
.limit(100)
.exec(&mut db)
.await?;
assert_eq!(items.len(), 20);
Ok(())
}
#[driver_test]
pub async fn limit_composite_key(test: &mut Test) -> Result<()> {
#[derive(Debug, toasty::Model)]
#[key(partition = kind, local = seq)]
struct Event {
kind: String,
seq: i64,
}
let mut db = test.setup_db(models!(Event)).await;
for i in 0..20 {
Event::create().kind("info").seq(i).exec(&mut db).await?;
}
test.log().clear();
let events: Vec<_> = Event::filter_by_kind("info").limit(7).exec(&mut db).await?;
assert_eq!(events.len(), 7);
let (op, _) = test.log().pop();
if test.capability().sql {
assert_struct!(op, Operation::QuerySql(_));
} else {
assert_struct!(op, Operation::QueryPk(_));
}
test.log().clear();
let events: Vec<_> = Event::filter_by_kind("info")
.order_by(Event::fields().seq().desc())
.limit(5)
.exec(&mut db)
.await?;
assert_eq!(events.len(), 5);
for i in 0..4 {
assert!(events[i].seq > events[i + 1].seq);
}
assert_eq!(events[0].seq, 19);
test.log().clear();
let events: Vec<_> = Event::filter_by_kind("info")
.limit(100)
.exec(&mut db)
.await?;
assert_eq!(events.len(), 20);
Ok(())
}
#[driver_test]
pub async fn sort_composite_key(test: &mut Test) -> Result<()> {
#[derive(Debug, toasty::Model)]
#[key(partition = kind, local = seq)]
struct Event {
kind: String,
seq: i64,
}
let mut db = test.setup_db(models!(Event)).await;
for i in 0..20 {
Event::create().kind("info").seq(i).exec(&mut db).await?;
}
test.log().clear();
let events: Vec<_> = Event::filter_by_kind("info")
.order_by(Event::fields().seq().asc())
.exec(&mut db)
.await?;
assert_eq!(events.len(), 20);
for i in 0..19 {
assert!(events[i].seq < events[i + 1].seq);
}
let (op, resp) = test.log().pop();
if test.capability().sql {
assert_struct!(op, Operation::QuerySql(_));
} else {
assert_struct!(op, Operation::QueryPk(_));
}
assert_struct!(resp.values, Rows::Stream(_));
test.log().clear();
let events: Vec<_> = Event::filter_by_kind("info")
.order_by(Event::fields().seq().desc())
.exec(&mut db)
.await?;
assert_eq!(events.len(), 20);
for i in 0..19 {
assert!(events[i].seq > events[i + 1].seq);
}
let (op, resp) = test.log().pop();
if test.capability().sql {
assert_struct!(op, Operation::QuerySql(_));
} else {
assert_struct!(op, Operation::QueryPk(_));
}
assert_struct!(resp.values, Rows::Stream(_));
Ok(())
}