use super::ProductStoreOperations;
use crate::product::{
store::{diesel::schema::product_property_value, error::ProductStoreError},
MAX_COMMIT_NUM,
};
use diesel::{dsl::update, prelude::*};
pub(in crate::product) trait UpdateProductOperation {
fn update_product(
&self,
product_id: &str,
service_id: Option<&str>,
current_commit_num: i64,
) -> Result<(), ProductStoreError>;
}
#[cfg(feature = "postgres")]
impl<'a> UpdateProductOperation for ProductStoreOperations<'a, diesel::pg::PgConnection> {
fn update_product(
&self,
product_id: &str,
service_id: Option<&str>,
current_commit_num: i64,
) -> Result<(), ProductStoreError> {
self.conn.transaction::<_, ProductStoreError, _>(|| {
pg::update_product_property_values(
&*self.conn,
product_id,
service_id,
current_commit_num,
)?;
Ok(())
})
}
}
#[cfg(feature = "sqlite")]
impl<'a> UpdateProductOperation for ProductStoreOperations<'a, diesel::sqlite::SqliteConnection> {
fn update_product(
&self,
product_id: &str,
service_id: Option<&str>,
current_commit_num: i64,
) -> Result<(), ProductStoreError> {
self.conn.transaction::<_, ProductStoreError, _>(|| {
sqlite::update_product_property_values(
&*self.conn,
product_id,
service_id,
current_commit_num,
)?;
Ok(())
})
}
}
#[cfg(feature = "postgres")]
mod pg {
use super::*;
pub fn update_product_property_values(
conn: &PgConnection,
product_id: &str,
service_id: Option<&str>,
current_commit_num: i64,
) -> QueryResult<()> {
let update = update(product_property_value::table);
if let Some(service_id) = service_id {
update
.filter(
product_property_value::product_id
.eq(product_id)
.and(product_property_value::end_commit_num.eq(MAX_COMMIT_NUM))
.and(product_property_value::service_id.eq(service_id)),
)
.set(product_property_value::end_commit_num.eq(current_commit_num))
.execute(conn)
.map(|_| ())
} else {
update
.filter(
product_property_value::product_id
.eq(product_id)
.and(product_property_value::end_commit_num.eq(MAX_COMMIT_NUM)),
)
.set(product_property_value::end_commit_num.eq(current_commit_num))
.execute(conn)
.map(|_| ())
}
}
}
#[cfg(feature = "sqlite")]
mod sqlite {
use super::*;
pub fn update_product_property_values(
conn: &SqliteConnection,
product_id: &str,
service_id: Option<&str>,
current_commit_num: i64,
) -> QueryResult<()> {
let update = update(product_property_value::table);
if let Some(service_id) = service_id {
update
.filter(
product_property_value::product_id
.eq(product_id)
.and(product_property_value::end_commit_num.eq(MAX_COMMIT_NUM))
.and(product_property_value::service_id.eq(service_id)),
)
.set(product_property_value::end_commit_num.eq(current_commit_num))
.execute(conn)
.map(|_| ())
} else {
update
.filter(
product_property_value::product_id
.eq(product_id)
.and(product_property_value::end_commit_num.eq(MAX_COMMIT_NUM)),
)
.set(product_property_value::end_commit_num.eq(current_commit_num))
.execute(conn)
.map(|_| ())
}
}
}