Skip to main content

modelite/query/
bulk.rs

1use sqlx::{QueryBuilder, Sqlite};
2use sqlx::sqlite::SqliteQueryResult;
3
4use crate::Model;
5
6pub struct BulkQueryIterator<'s, M: Model + ?Sized + 's, I: Iterator<Item = &'s M>> {
7    pub(crate) iter: I,
8    pub(crate) chunk_size: usize,
9}
10
11impl<'s, M: Model + 's, I: Iterator<Item = &'s M>> Iterator for BulkQueryIterator<'s, M, I> {
12    type Item = QueryBuilder<'s, Sqlite>;
13
14    fn next(&mut self) -> Option<Self::Item> {
15        let mut chunk = self.iter.by_ref().take(self.chunk_size).peekable();
16        if chunk.peek().is_none() { return None; }
17        Some(M::insert_all_unchecked(chunk))
18    }
19}
20
21impl<'s, M: Model + 's, I: Iterator<Item = &'s M>> BulkQueryIterator<'s, M, I> {
22    pub async fn execute_all(self, e: &sqlx::Pool<Sqlite>) -> Result<Vec<SqliteQueryResult>, sqlx::Error> {
23        let mut vec = Vec::new();
24        for mut query in self {
25            vec.push(query.build().execute(e).await?);
26        }
27        return Ok(vec);
28    }
29}
30
31/// Execute all queries in a bulk query (see `Model::insert_bulk`).
32///
33/// # Example
34/// ```ignore
35/// # use modelite::{Model, execute_all};
36/// # let conn = sqlx::SqlitePool::connect(":memory:").await.unwrap();
37///
38/// #[derive(Model)]
39/// struct Person {
40///     name: String,
41///     age: u32
42/// }
43///
44/// let query = Person::insert_bulk(&conn, vec![Person { name: "John Johnson".to_string(), age: 43 }, /* more entries*/].iter()).await.unwrap();
45/// execute_all!(&conn, query).await.unwrap();
46/// ```
47#[cfg(feature = "sqlx")]
48#[macro_export]
49macro_rules! execute_all {
50    ($bulk_query_iterator: expr, $executor: expr) => {
51        async {
52            for mut query in $bulk_query_iterator {
53                query.build().execute($executor).await?;
54            }
55
56            Ok::<(), sqlx::Error>(())
57        }
58        // ::futures::future::try_join_all($bulk_query_iterator.map(async |q: ::modelite::ModeliteQuery<'_>| q.execute($executor).await))
59    }
60}