use super::CommitStoreOperations;
use crate::commits::store::diesel::models::{CommitModel, NewCommitModel};
use crate::commits::store::diesel::{schema::commits, CommitStoreError};
use crate::error::{ConstraintViolationError, ConstraintViolationType, InternalError};
use diesel::{dsl::insert_into, prelude::*};
pub(in crate::commits) trait CommitStoreAddCommitOperation {
fn add_commit(&self, commit: NewCommitModel) -> Result<(), CommitStoreError>;
}
#[cfg(feature = "postgres")]
impl<'a> CommitStoreAddCommitOperation for CommitStoreOperations<'a, diesel::pg::PgConnection> {
fn add_commit(&self, commit: NewCommitModel) -> Result<(), CommitStoreError> {
self.conn.transaction::<_, CommitStoreError, _>(|| {
let duplicate_commit = commits::table
.filter(commits::commit_id.eq(&commit.commit_id))
.first::<CommitModel>(self.conn)
.map(Some)
.optional()
.map_err(|err| {
CommitStoreError::InternalError(InternalError::from_source(Box::new(err)))
})?;
if duplicate_commit.is_some() {
return Err(CommitStoreError::ConstraintViolationError(
ConstraintViolationError::with_violation_type(ConstraintViolationType::Unique),
));
}
insert_into(commits::table)
.values(commit)
.execute(self.conn)
.map(|_| ())?;
Ok(())
})
}
}
#[cfg(feature = "sqlite")]
impl<'a> CommitStoreAddCommitOperation
for CommitStoreOperations<'a, diesel::sqlite::SqliteConnection>
{
fn add_commit(&self, commit: NewCommitModel) -> Result<(), CommitStoreError> {
self.conn.transaction::<_, CommitStoreError, _>(|| {
let duplicate_commit = commits::table
.filter(commits::commit_id.eq(&commit.commit_id))
.first::<CommitModel>(self.conn)
.map(Some)
.optional()
.map_err(|err| {
CommitStoreError::InternalError(InternalError::from_source(Box::new(err)))
})?;
if duplicate_commit.is_some() {
return Err(CommitStoreError::ConstraintViolationError(
ConstraintViolationError::with_violation_type(ConstraintViolationType::Unique),
));
}
insert_into(commits::table)
.values(commit)
.execute(self.conn)
.map(|_| ())?;
Ok(())
})
}
}