toasty_driver_integration_suite/tests/
batch_update_delete.rs

1use crate::prelude::*;
2
3/// Batch two updates of the same model.
4#[driver_test(id(ID), requires(sql))]
5pub async fn batch_two_updates_same_model(t: &mut Test) -> Result<()> {
6    #[derive(Debug, toasty::Model)]
7    struct User {
8        #[key]
9        #[auto]
10        id: ID,
11        #[index]
12        name: String,
13    }
14
15    let mut db = t.setup_db(models!(User)).await;
16    User::create().name("Alice").exec(&mut db).await?;
17    User::create().name("Bob").exec(&mut db).await?;
18
19    t.log().clear();
20    let ((), ()): ((), ()) = toasty::batch((
21        User::filter_by_name("Alice").update().name("Alice2"),
22        User::filter_by_name("Bob").update().name("Bob2"),
23    ))
24    .exec(&mut db)
25    .await?;
26
27    // Verify updates applied
28    let alice: Vec<User> = User::filter_by_name("Alice2").exec(&mut db).await?;
29    assert_eq!(alice.len(), 1);
30    let bob: Vec<User> = User::filter_by_name("Bob2").exec(&mut db).await?;
31    assert_eq!(bob.len(), 1);
32
33    Ok(())
34}
35
36/// Batch two deletes of the same model.
37#[driver_test(id(ID), requires(sql))]
38pub async fn batch_two_deletes_same_model(t: &mut Test) -> Result<()> {
39    #[derive(Debug, toasty::Model)]
40    struct User {
41        #[key]
42        #[auto]
43        id: ID,
44        #[index]
45        name: String,
46    }
47
48    let mut db = t.setup_db(models!(User)).await;
49    User::create().name("Alice").exec(&mut db).await?;
50    User::create().name("Bob").exec(&mut db).await?;
51    User::create().name("Carol").exec(&mut db).await?;
52
53    t.log().clear();
54    let ((), ()): ((), ()) = toasty::batch((
55        User::filter_by_name("Alice").delete(),
56        User::filter_by_name("Bob").delete(),
57    ))
58    .exec(&mut db)
59    .await?;
60
61    // Verify deletes applied, Carol remains
62    let all: Vec<User> = User::all().exec(&mut db).await?;
63    assert_eq!(all.len(), 1);
64    assert_eq!(all[0].name, "Carol");
65
66    Ok(())
67}
68
69/// Batch mixing update and delete of different models.
70#[driver_test(id(ID), requires(sql))]
71pub async fn batch_update_and_delete(t: &mut Test) -> Result<()> {
72    #[derive(Debug, toasty::Model)]
73    struct User {
74        #[key]
75        #[auto]
76        id: ID,
77        #[index]
78        name: String,
79    }
80
81    #[derive(Debug, toasty::Model)]
82    struct Post {
83        #[key]
84        #[auto]
85        id: ID,
86        #[index]
87        title: String,
88    }
89
90    let mut db = t.setup_db(models!(User, Post)).await;
91    User::create().name("Alice").exec(&mut db).await?;
92    Post::create().title("Hello").exec(&mut db).await?;
93
94    t.log().clear();
95    let ((), ()): ((), ()) = toasty::batch((
96        User::filter_by_name("Alice").update().name("Alice2"),
97        Post::filter_by_title("Hello").delete(),
98    ))
99    .exec(&mut db)
100    .await?;
101
102    // User updated
103    let users: Vec<User> = User::filter_by_name("Alice2").exec(&mut db).await?;
104    assert_eq!(users.len(), 1);
105
106    // Post deleted
107    let posts: Vec<Post> = Post::all().exec(&mut db).await?;
108    assert_eq!(posts.len(), 0);
109
110    Ok(())
111}
112
113/// Batch all four statement types: query, create, update, delete.
114#[driver_test(id(ID), requires(sql))]
115pub async fn batch_all_four_statement_types(t: &mut Test) -> Result<()> {
116    #[derive(Debug, toasty::Model)]
117    struct User {
118        #[key]
119        #[auto]
120        id: ID,
121        #[index]
122        name: String,
123    }
124
125    let mut db = t.setup_db(models!(User)).await;
126    User::create().name("Alice").exec(&mut db).await?;
127    User::create().name("Bob").exec(&mut db).await?;
128
129    t.log().clear();
130    let (queried, created, (), ()): (Vec<User>, User, (), ()) = toasty::batch((
131        User::filter_by_name("Alice"),
132        User::create().name("Carol"),
133        User::filter_by_name("Alice").update().name("Alice2"),
134        User::filter_by_name("Bob").delete(),
135    ))
136    .exec(&mut db)
137    .await?;
138
139    assert_struct!(queried, [_ { name: "Alice" }]);
140    assert_eq!(created.name, "Carol");
141
142    // Verify update applied
143    let alice: Vec<User> = User::filter_by_name("Alice2").exec(&mut db).await?;
144    assert_eq!(alice.len(), 1);
145
146    // Verify delete applied
147    let bob: Vec<User> = User::filter_by_name("Bob").exec(&mut db).await?;
148    assert_eq!(bob.len(), 0);
149
150    // Carol was created
151    let carol: Vec<User> = User::filter_by_name("Carol").exec(&mut db).await?;
152    assert_eq!(carol.len(), 1);
153
154    Ok(())
155}
156
157/// Batch a delete using the model instance builder.
158#[driver_test(id(ID), requires(sql))]
159pub async fn batch_instance_delete(t: &mut Test) -> Result<()> {
160    #[derive(Debug, toasty::Model)]
161    struct User {
162        #[key]
163        #[auto]
164        id: ID,
165        name: String,
166    }
167
168    let mut db = t.setup_db(models!(User)).await;
169    let alice = User::create().name("Alice").exec(&mut db).await?;
170    let bob = User::create().name("Bob").exec(&mut db).await?;
171
172    t.log().clear();
173    let ((), ()): ((), ()) = toasty::batch((alice.delete(), bob.delete()))
174        .exec(&mut db)
175        .await?;
176
177    let all: Vec<User> = User::all().exec(&mut db).await?;
178    assert_eq!(all.len(), 0);
179
180    Ok(())
181}