use crate::FfiConnection;
use async_trait::async_trait;
use refinery_core::{
AsyncMigrate, Migration,
traits::r#async::{AsyncQuery, AsyncTransaction}
};
use sea_orm::{ConnectionTrait, DbErr, Statement};
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
#[async_trait]
impl AsyncTransaction for FfiConnection {
type Error = DbErr;
async fn execute<'a, T>(&mut self, queries: T) -> Result<usize, DbErr>
where
T: Iterator<Item = &'a str> + Send
{
let transaction = self.begin().await?;
let mut count = 0;
for query in queries {
transaction.execute_unprepared(query).await?;
count += 1;
}
transaction.commit().await?;
Ok(count)
}
}
#[async_trait]
impl AsyncQuery<Vec<Migration>> for FfiConnection {
async fn query(&mut self, query: &str) -> Result<Vec<Migration>, DbErr> {
let result = self
.query_all(Statement::from_string(self.get_database_backend(), query))
.await?;
result
.into_iter()
.map(|row| {
let version = row.try_get_by("version")?;
let name = row.try_get_by("name")?;
let applied_on = row.try_get_by("applied_on").or_else(|_| {
let applied_on: String = row.try_get_by("applied_on")?;
OffsetDateTime::parse(&applied_on, &Rfc3339).map_err(|err| {
DbErr::TryIntoErr {
from: "String",
into: "OffsetDateTime",
source: Box::new(err)
}
})
})?;
let checksum = row.try_get_by("checksum").or_else(|_| {
let checksum: String = row.try_get_by("checksum")?;
checksum.parse().map_err(|err| DbErr::TryIntoErr {
from: "String",
into: "u64",
source: Box::new(err)
})
})?;
Ok(Migration::applied(version, name, applied_on, checksum))
})
.collect()
}
}
impl AsyncMigrate for FfiConnection {}