refinery_core/drivers/
rusqlite.rs

1use crate::traits::sync::{Migrate, Query, Transaction};
2use crate::Migration;
3use rusqlite::{Connection as RqlConnection, Error as RqlError};
4use time::format_description::well_known::Rfc3339;
5use time::OffsetDateTime;
6
7fn query_applied_migrations(
8    transaction: &RqlConnection,
9    query: &str,
10) -> Result<Vec<Migration>, RqlError> {
11    let mut stmt = transaction.prepare(query)?;
12    let mut rows = stmt.query([])?;
13    let mut applied = Vec::new();
14    while let Some(row) = rows.next()? {
15        let version = row.get(0)?;
16        let applied_on: String = row.get(2)?;
17        // Safe to call unwrap, as we stored it in RFC3339 format on the database
18        let applied_on = OffsetDateTime::parse(&applied_on, &Rfc3339).unwrap();
19
20        let checksum: String = row.get(3)?;
21        applied.push(Migration::applied(
22            version,
23            row.get(1)?,
24            applied_on,
25            checksum
26                .parse::<u64>()
27                .expect("checksum must be a valid u64"),
28        ));
29    }
30    Ok(applied)
31}
32
33impl Transaction for RqlConnection {
34    type Error = RqlError;
35    fn execute<'a, T: Iterator<Item = &'a str>>(
36        &mut self,
37        queries: T,
38    ) -> Result<usize, Self::Error> {
39        let transaction = self.transaction()?;
40        let mut count = 0;
41        for query in queries {
42            transaction.execute_batch(query)?;
43            count += 1;
44        }
45        transaction.commit()?;
46        Ok(count)
47    }
48}
49
50impl Query<Vec<Migration>> for RqlConnection {
51    fn query(&mut self, query: &str) -> Result<Vec<Migration>, Self::Error> {
52        let transaction = self.transaction()?;
53        let applied = query_applied_migrations(&transaction, query)?;
54        transaction.commit()?;
55        Ok(applied)
56    }
57}
58
59impl Migrate for RqlConnection {}