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(&mut self, queries: &[&str]) -> Result<usize, Self::Error> {
36        let transaction = self.transaction()?;
37        let mut count = 0;
38        for query in queries.iter() {
39            transaction.execute_batch(query)?;
40            count += 1;
41        }
42        transaction.commit()?;
43        Ok(count)
44    }
45}
46
47impl Query<Vec<Migration>> for RqlConnection {
48    fn query(&mut self, query: &str) -> Result<Vec<Migration>, Self::Error> {
49        let transaction = self.transaction()?;
50        let applied = query_applied_migrations(&transaction, query)?;
51        transaction.commit()?;
52        Ok(applied)
53    }
54}
55
56impl Migrate for RqlConnection {}