sea-orm-ffi 0.1.3

Compatibility layer for Sea-ORM when crossing a Rust-to-Rust FFI boundary
Documentation
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")?;

				// applied_on is stored as a string, so fall back to parsing here if the
				// database cannot return it as a timestamp
				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)
						}
					})
				})?;

				// checksum is stored as a string, so fall back to parsing here if the
				// database cannot return it as an u64
				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 {}