mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat(drainer): added drainer which reads from redis stream and executes queries on DB (#142)
This commit is contained in:
@ -5,6 +5,10 @@ edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[features]
|
||||
default = ["kv_store"]
|
||||
kv_store = []
|
||||
|
||||
[dependencies]
|
||||
async-bb8-diesel = { git = "https://github.com/juspay/async-bb8-diesel", rev = "412663e16802dbc58a1b98bfcbe78fa0090311eb" }
|
||||
async-trait = "0.1.57"
|
||||
@ -23,4 +27,4 @@ time = { version = "0.3.14", features = ["serde", "serde-well-known", "std"] }
|
||||
common_utils = { version = "0.1.0", path = "../common_utils" }
|
||||
masking = { version = "0.1.0", path = "../masking" }
|
||||
router_derive = { version = "0.1.0", path = "../router_derive" }
|
||||
router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] }
|
||||
router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] }
|
||||
@ -8,7 +8,7 @@ pub enum DatabaseError {
|
||||
UniqueViolation,
|
||||
#[error("No fields were provided to be updated")]
|
||||
NoFieldsToUpdate,
|
||||
#[error("An error occurred when generating raw SQL query")]
|
||||
#[error("An error occurred when generating typed SQL query")]
|
||||
QueryGenerationFailed,
|
||||
// InsertFailed,
|
||||
#[error("An unknown error occurred")]
|
||||
|
||||
61
crates/storage_models/src/kv.rs
Normal file
61
crates/storage_models/src/kv.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use error_stack::{IntoReport, ResultExt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
errors,
|
||||
payment_attempt::{PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate},
|
||||
payment_intent::{PaymentIntent, PaymentIntentNew, PaymentIntentUpdate},
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case", tag = "db_op", content = "data")]
|
||||
pub enum DBOperation {
|
||||
Insert { insertable: Insertable },
|
||||
Update { updatable: Updateable },
|
||||
Delete,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct TypedSql {
|
||||
#[serde(flatten)]
|
||||
pub op: DBOperation,
|
||||
}
|
||||
|
||||
impl TypedSql {
|
||||
pub fn to_field_value_pairs(
|
||||
&self,
|
||||
) -> crate::CustomResult<Vec<(&str, String)>, errors::DatabaseError> {
|
||||
Ok(vec![(
|
||||
"typed_sql",
|
||||
serde_json::to_string(self)
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::QueryGenerationFailed)?,
|
||||
)])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case", tag = "table", content = "data")]
|
||||
pub enum Insertable {
|
||||
PaymentIntent(PaymentIntentNew),
|
||||
PaymentAttempt(PaymentAttemptNew),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case", tag = "table", content = "data")]
|
||||
pub enum Updateable {
|
||||
PaymentIntentUpdate(PaymentIntentUpdateMems),
|
||||
PaymentAttemptUpdate(PaymentAttemptUpdateMems),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PaymentIntentUpdateMems {
|
||||
pub orig: PaymentIntent,
|
||||
pub update_data: PaymentIntentUpdate,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PaymentAttemptUpdateMems {
|
||||
pub orig: PaymentAttempt,
|
||||
pub update_data: PaymentAttemptUpdate,
|
||||
}
|
||||
@ -7,6 +7,8 @@ pub mod enums;
|
||||
pub mod ephemeral_key;
|
||||
pub mod errors;
|
||||
pub mod events;
|
||||
#[cfg(feature = "kv_store")]
|
||||
pub mod kv;
|
||||
pub mod locker_mock_up;
|
||||
pub mod mandate;
|
||||
pub mod merchant_account;
|
||||
|
||||
@ -40,7 +40,9 @@ pub struct PaymentAttempt {
|
||||
pub error_code: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay, Serialize, Deserialize,
|
||||
)]
|
||||
#[diesel(table_name = payment_attempt)]
|
||||
pub struct PaymentAttemptNew {
|
||||
pub payment_id: String,
|
||||
@ -76,7 +78,7 @@ pub struct PaymentAttemptNew {
|
||||
pub error_code: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum PaymentAttemptUpdate {
|
||||
Update {
|
||||
amount: i64,
|
||||
|
||||
@ -31,7 +31,17 @@ pub struct PaymentIntent {
|
||||
pub client_secret: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Insertable, router_derive::DebugAsDisplay)]
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
Default,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Insertable,
|
||||
router_derive::DebugAsDisplay,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
#[diesel(table_name = payment_intent)]
|
||||
pub struct PaymentIntentNew {
|
||||
pub payment_id: String,
|
||||
@ -57,7 +67,7 @@ pub struct PaymentIntentNew {
|
||||
pub off_session: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum PaymentIntentUpdate {
|
||||
ResponseUpdate {
|
||||
status: storage_enums::IntentStatus,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use router_env::{tracing, tracing::instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
address::{Address, AddressNew, AddressUpdate, AddressUpdateInternal},
|
||||
errors,
|
||||
@ -12,7 +12,7 @@ use crate::{
|
||||
impl AddressNew {
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert(self, conn: &PgPooledConn) -> CustomResult<Address, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, Address, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,11 +23,10 @@ impl Address {
|
||||
address_id: String,
|
||||
address: AddressUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
address_id.clone(),
|
||||
AddressUpdateInternal::from(address),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -53,10 +52,9 @@ impl Address {
|
||||
conn: &PgPooledConn,
|
||||
address_id: &str,
|
||||
) -> CustomResult<bool, errors::DatabaseError> {
|
||||
generics::generic_delete::<<Self as HasTable>::Table, _, _>(
|
||||
generics::generic_delete::<<Self as HasTable>::Table, _>(
|
||||
conn,
|
||||
dsl::address_id.eq(address_id.to_owned()),
|
||||
ExecuteQuery::<Self>::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
@ -67,13 +65,12 @@ impl Address {
|
||||
merchant_id: &str,
|
||||
address: AddressUpdate,
|
||||
) -> CustomResult<Vec<Self>, errors::DatabaseError> {
|
||||
generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
dsl::merchant_id
|
||||
.eq(merchant_id.to_owned())
|
||||
.and(dsl::customer_id.eq(customer_id.to_owned())),
|
||||
AddressUpdateInternal::from(address),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::associations::HasTable;
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
configs::{Config, ConfigNew, ConfigUpdate, ConfigUpdateInternal},
|
||||
errors, CustomResult, PgPooledConn,
|
||||
@ -10,7 +10,7 @@ use crate::{
|
||||
impl ConfigNew {
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert(self, conn: &PgPooledConn) -> CustomResult<Config, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, Config, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,11 +29,10 @@ impl Config {
|
||||
key: &str,
|
||||
config_update: ConfigUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
key.to_owned(),
|
||||
ConfigUpdateInternal::from(config_update),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use router_env::{tracing, tracing::instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
connector_response::{
|
||||
ConnectorResponse, ConnectorResponseNew, ConnectorResponseUpdate,
|
||||
@ -18,8 +18,7 @@ impl ConnectorResponseNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<ConnectorResponse, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, ConnectorResponse, _>(conn, self, ExecuteQuery::new())
|
||||
.await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,11 +29,10 @@ impl ConnectorResponse {
|
||||
conn: &PgPooledConn,
|
||||
connector_response: ConnectorResponseUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id,
|
||||
ConnectorResponseUpdateInternal::from(connector_response),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use router_env::{tracing, tracing::instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
customers::{Customer, CustomerNew, CustomerUpdate, CustomerUpdateInternal},
|
||||
errors,
|
||||
@ -15,7 +15,7 @@ impl CustomerNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<Customer, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, Customer, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,11 +27,10 @@ impl Customer {
|
||||
merchant_id: String,
|
||||
customer: CustomerUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
(customer_id.clone(), merchant_id.clone()),
|
||||
CustomerUpdateInternal::from(customer),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -55,12 +54,11 @@ impl Customer {
|
||||
customer_id: &str,
|
||||
merchant_id: &str,
|
||||
) -> CustomResult<bool, errors::DatabaseError> {
|
||||
generics::generic_delete::<<Self as HasTable>::Table, _, _>(
|
||||
generics::generic_delete::<<Self as HasTable>::Table, _>(
|
||||
conn,
|
||||
dsl::customer_id
|
||||
.eq(customer_id.to_owned())
|
||||
.and(dsl::merchant_id.eq(merchant_id.to_owned())),
|
||||
ExecuteQuery::<Self>::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
events::{Event, EventNew},
|
||||
@ -10,6 +10,6 @@ use crate::{
|
||||
impl EventNew {
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert(self, conn: &PgPooledConn) -> CustomResult<Event, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, Event, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
use std::{fmt::Debug, marker::PhantomData};
|
||||
use std::fmt::Debug;
|
||||
|
||||
use async_bb8_diesel::{AsyncRunQueryDsl, ConnectionError};
|
||||
use async_trait::async_trait;
|
||||
use diesel::{
|
||||
associations::HasTable,
|
||||
debug_query,
|
||||
@ -24,402 +23,44 @@ use router_env::{logger, tracing, tracing::instrument};
|
||||
|
||||
use crate::{errors, CustomResult, PgPooledConn};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RawSqlQuery {
|
||||
pub sql: String,
|
||||
// The inner `Vec<u8>` can be considered to be byte array
|
||||
pub binds: Vec<Option<Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl RawSqlQuery {
|
||||
pub fn to_field_value_pairs(&self) -> Vec<(&str, String)> {
|
||||
vec![
|
||||
("sql", self.sql.clone()),
|
||||
(
|
||||
"binds",
|
||||
serde_json::to_string(
|
||||
&self
|
||||
.binds
|
||||
.iter()
|
||||
.map(|bytes| bytes.as_ref().map(hex::encode))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExecuteQuery<R>(PhantomData<R>);
|
||||
|
||||
impl<R> ExecuteQuery<R> {
|
||||
pub fn new() -> Self {
|
||||
Self(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Default for ExecuteQuery<R> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RawQuery;
|
||||
|
||||
#[async_trait]
|
||||
pub trait QueryExecutionMode<Q>
|
||||
where
|
||||
Q: QueryFragment<Pg> + Send + 'static,
|
||||
{
|
||||
type InsertOutput;
|
||||
type UpdateOutput;
|
||||
type UpdateWithResultsOutput;
|
||||
type UpdateByIdOutput;
|
||||
type DeleteOutput;
|
||||
type DeleteWithResultsOutput;
|
||||
type DeleteOneWithResultOutput;
|
||||
|
||||
async fn insert(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
debug_values: String,
|
||||
) -> CustomResult<Self::InsertOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: AsQuery + QueryFragment<Pg> + RunQueryDsl<PgConnection>;
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
debug_values: String,
|
||||
) -> CustomResult<Self::UpdateOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: QueryId;
|
||||
|
||||
async fn update_with_results(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
debug_values: String,
|
||||
) -> CustomResult<Self::UpdateWithResultsOutput, errors::DatabaseError>;
|
||||
|
||||
async fn update_by_id(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
debug_values: String,
|
||||
) -> CustomResult<Self::UpdateByIdOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: Clone;
|
||||
|
||||
async fn delete(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: QueryId;
|
||||
|
||||
async fn delete_with_results(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteWithResultsOutput, errors::DatabaseError>;
|
||||
|
||||
async fn delete_one_with_result(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteOneWithResultOutput, errors::DatabaseError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<Q, R> QueryExecutionMode<Q> for ExecuteQuery<R>
|
||||
where
|
||||
Q: LoadQuery<'static, PgConnection, R> + QueryFragment<Pg> + Send + Sync + 'static,
|
||||
R: Send + Sync + 'static,
|
||||
{
|
||||
type InsertOutput = R;
|
||||
type UpdateOutput = usize;
|
||||
type UpdateWithResultsOutput = Vec<R>;
|
||||
type UpdateByIdOutput = R;
|
||||
type DeleteOutput = bool;
|
||||
type DeleteWithResultsOutput = Vec<R>;
|
||||
type DeleteOneWithResultOutput = R;
|
||||
|
||||
async fn insert(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
debug_values: String,
|
||||
) -> CustomResult<Self::InsertOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: AsQuery + QueryFragment<Pg> + RunQueryDsl<PgConnection>,
|
||||
{
|
||||
match query.get_result_async(conn).await {
|
||||
Ok(value) => Ok(value),
|
||||
Err(error) => match error {
|
||||
ConnectionError::Query(DieselError::DatabaseError(
|
||||
diesel::result::DatabaseErrorKind::UniqueViolation,
|
||||
_,
|
||||
)) => Err(report!(error)).change_context(errors::DatabaseError::UniqueViolation),
|
||||
_ => Err(report!(error)).change_context(errors::DatabaseError::Others),
|
||||
}
|
||||
.attach_printable_lazy(|| format!("Error while inserting {}", debug_values)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
debug_values: String,
|
||||
) -> CustomResult<Self::UpdateOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: QueryId,
|
||||
{
|
||||
query
|
||||
.execute_async(conn)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::Others)
|
||||
.attach_printable_lazy(|| format!("Error while updating {}", debug_values))
|
||||
}
|
||||
|
||||
async fn update_with_results(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
debug_values: String,
|
||||
) -> CustomResult<Self::UpdateWithResultsOutput, errors::DatabaseError> {
|
||||
query
|
||||
.get_results_async(conn)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::Others)
|
||||
.attach_printable_lazy(|| format!("Error while updating {}", debug_values))
|
||||
}
|
||||
|
||||
async fn update_by_id(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
debug_values: String,
|
||||
) -> CustomResult<Self::UpdateByIdOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: Clone,
|
||||
{
|
||||
// Cloning query for calling `debug_query` later
|
||||
match query.to_owned().get_result_async(conn).await {
|
||||
Ok(result) => {
|
||||
logger::debug!(query = %debug_query::<Pg, _>(&query).to_string());
|
||||
Ok(result)
|
||||
}
|
||||
Err(error) => match error {
|
||||
// Failed to generate query, no fields were provided to be updated
|
||||
ConnectionError::Query(DieselError::QueryBuilderError(_)) => {
|
||||
Err(report!(error)).change_context(errors::DatabaseError::NoFieldsToUpdate)
|
||||
}
|
||||
ConnectionError::Query(DieselError::NotFound) => {
|
||||
Err(report!(error)).change_context(errors::DatabaseError::NotFound)
|
||||
}
|
||||
_ => Err(report!(error)).change_context(errors::DatabaseError::Others),
|
||||
}
|
||||
.attach_printable_lazy(|| format!("Error while updating by ID {}", debug_values)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: QueryId,
|
||||
{
|
||||
query
|
||||
.execute_async(conn)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::Others)
|
||||
.attach_printable("Error while deleting")
|
||||
.and_then(|result| match result {
|
||||
n if n > 0 => {
|
||||
logger::debug!("{n} records deleted");
|
||||
Ok(true)
|
||||
}
|
||||
0 => {
|
||||
Err(report!(errors::DatabaseError::NotFound)
|
||||
.attach_printable("No records deleted"))
|
||||
}
|
||||
_ => Ok(true), // n is usize, rustc requires this for exhaustive check
|
||||
})
|
||||
}
|
||||
|
||||
async fn delete_with_results(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteWithResultsOutput, errors::DatabaseError> {
|
||||
query
|
||||
.get_results_async(conn)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::Others)
|
||||
.attach_printable("Error while deleting")
|
||||
}
|
||||
|
||||
async fn delete_one_with_result(
|
||||
&self,
|
||||
conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteOneWithResultOutput, errors::DatabaseError> {
|
||||
match query.get_result_async(conn).await {
|
||||
Ok(value) => Ok(value),
|
||||
Err(error) => match error {
|
||||
ConnectionError::Query(DieselError::NotFound) => {
|
||||
Err(report!(error)).change_context(errors::DatabaseError::NotFound)
|
||||
}
|
||||
_ => Err(report!(error)).change_context(errors::DatabaseError::Others),
|
||||
}
|
||||
.attach_printable("Error while deleting"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<Q> QueryExecutionMode<Q> for RawQuery
|
||||
where
|
||||
Q: QueryFragment<Pg> + Send + 'static,
|
||||
{
|
||||
type InsertOutput = RawSqlQuery;
|
||||
type UpdateOutput = RawSqlQuery;
|
||||
type UpdateWithResultsOutput = RawSqlQuery;
|
||||
type UpdateByIdOutput = RawSqlQuery;
|
||||
type DeleteOutput = RawSqlQuery;
|
||||
type DeleteWithResultsOutput = RawSqlQuery;
|
||||
type DeleteOneWithResultOutput = RawSqlQuery;
|
||||
|
||||
async fn insert(
|
||||
&self,
|
||||
_conn: &PgPooledConn,
|
||||
query: Q,
|
||||
_debug_values: String,
|
||||
) -> CustomResult<Self::InsertOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: AsQuery + QueryFragment<Pg> + RunQueryDsl<PgConnection>,
|
||||
{
|
||||
generate_raw_query(query)
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&self,
|
||||
_conn: &PgPooledConn,
|
||||
query: Q,
|
||||
_debug_values: String,
|
||||
) -> CustomResult<Self::UpdateOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: QueryId,
|
||||
{
|
||||
generate_raw_query(query)
|
||||
}
|
||||
|
||||
async fn update_with_results(
|
||||
&self,
|
||||
_conn: &PgPooledConn,
|
||||
query: Q,
|
||||
_debug_values: String,
|
||||
) -> CustomResult<Self::UpdateWithResultsOutput, errors::DatabaseError> {
|
||||
generate_raw_query(query)
|
||||
}
|
||||
|
||||
async fn update_by_id(
|
||||
&self,
|
||||
_conn: &PgPooledConn,
|
||||
query: Q,
|
||||
_debug_values: String,
|
||||
) -> CustomResult<Self::UpdateByIdOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: Clone,
|
||||
{
|
||||
generate_raw_query(query)
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
&self,
|
||||
_conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteOutput, errors::DatabaseError>
|
||||
where
|
||||
Q: QueryId,
|
||||
{
|
||||
generate_raw_query(query)
|
||||
}
|
||||
|
||||
async fn delete_with_results(
|
||||
&self,
|
||||
_conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteWithResultsOutput, errors::DatabaseError> {
|
||||
generate_raw_query(query)
|
||||
}
|
||||
|
||||
async fn delete_one_with_result(
|
||||
&self,
|
||||
_conn: &PgPooledConn,
|
||||
query: Q,
|
||||
) -> CustomResult<Self::DeleteOneWithResultOutput, errors::DatabaseError> {
|
||||
generate_raw_query(query)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_raw_query<Q>(query: Q) -> CustomResult<RawSqlQuery, errors::DatabaseError>
|
||||
where
|
||||
Q: QueryFragment<Pg>,
|
||||
{
|
||||
let raw_query = diesel::query_builder::raw_query(&query)
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::QueryGenerationFailed)?;
|
||||
|
||||
Ok(RawSqlQuery {
|
||||
sql: raw_query.raw_sql,
|
||||
binds: raw_query.raw_binds,
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_insert<T, V, R, Q>(
|
||||
pub(super) async fn generic_insert<T, V, R>(
|
||||
conn: &PgPooledConn,
|
||||
values: V,
|
||||
execution_mode: Q,
|
||||
) -> CustomResult<Q::InsertOutput, errors::DatabaseError>
|
||||
) -> CustomResult<R, errors::DatabaseError>
|
||||
where
|
||||
T: HasTable<Table = T> + Table + 'static,
|
||||
V: Debug + Insertable<T>,
|
||||
<T as QuerySource>::FromClause: QueryFragment<Pg> + Send,
|
||||
<T as QuerySource>::FromClause: QueryFragment<Pg>,
|
||||
<V as Insertable<T>>::Values: CanInsertInSingleQuery<Pg> + QueryFragment<Pg> + 'static,
|
||||
InsertStatement<T, <V as Insertable<T>>::Values>:
|
||||
AsQuery + LoadQuery<'static, PgConnection, R> + Clone + Send,
|
||||
AsQuery + LoadQuery<'static, PgConnection, R> + Send,
|
||||
R: Send + 'static,
|
||||
|
||||
Q: QueryExecutionMode<InsertStatement<T, <V as Insertable<T>>::Values>>,
|
||||
{
|
||||
let debug_values = format!("{:?}", values);
|
||||
|
||||
let query = diesel::insert_into(<T as HasTable>::table()).values(values);
|
||||
logger::debug!(query = %debug_query::<Pg, _>(&query).to_string());
|
||||
|
||||
execution_mode.insert(conn, query, debug_values).await
|
||||
match query.get_result_async(conn).await.into_report() {
|
||||
Ok(value) => Ok(value),
|
||||
Err(err) => match err.current_context() {
|
||||
ConnectionError::Query(DieselError::DatabaseError(
|
||||
diesel::result::DatabaseErrorKind::UniqueViolation,
|
||||
_,
|
||||
)) => Err(err).change_context(errors::DatabaseError::UniqueViolation),
|
||||
_ => Err(err).change_context(errors::DatabaseError::Others),
|
||||
},
|
||||
}
|
||||
.attach_printable_lazy(|| format!("Error while inserting {}", debug_values))
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_update<T, V, P, Q>(
|
||||
pub(super) async fn generic_update<T, V, P>(
|
||||
conn: &PgPooledConn,
|
||||
predicate: P,
|
||||
values: V,
|
||||
execution_mode: Q,
|
||||
) -> CustomResult<Q::UpdateOutput, errors::DatabaseError>
|
||||
) -> CustomResult<usize, errors::DatabaseError>
|
||||
where
|
||||
T: FilterDsl<P> + HasTable<Table = T> + Table + 'static,
|
||||
V: AsChangeset<Target = <<T as FilterDsl<P>>::Output as HasTable>::Table> + Debug,
|
||||
@ -429,30 +70,26 @@ where
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
<V as AsChangeset>::Changeset,
|
||||
>: AsQuery + QueryFragment<Pg> + QueryId + Send + 'static,
|
||||
|
||||
Q: QueryExecutionMode<
|
||||
UpdateStatement<
|
||||
<<T as FilterDsl<P>>::Output as HasTable>::Table,
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
<V as AsChangeset>::Changeset,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
let debug_values = format!("{:?}", values);
|
||||
|
||||
let query = diesel::update(<T as HasTable>::table().filter(predicate)).set(values);
|
||||
logger::debug!(query = %debug_query::<Pg, _>(&query).to_string());
|
||||
|
||||
execution_mode.update(conn, query, debug_values).await
|
||||
query
|
||||
.execute_async(conn)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::Others)
|
||||
.attach_printable_lazy(|| format!("Error while updating {}", debug_values))
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_update_with_results<T, V, P, R, Q>(
|
||||
pub(super) async fn generic_update_with_results<T, V, P, R>(
|
||||
conn: &PgPooledConn,
|
||||
predicate: P,
|
||||
values: V,
|
||||
execution_mode: Q,
|
||||
) -> CustomResult<Q::UpdateWithResultsOutput, errors::DatabaseError>
|
||||
) -> CustomResult<Vec<R>, errors::DatabaseError>
|
||||
where
|
||||
T: FilterDsl<P> + HasTable<Table = T> + Table + 'static,
|
||||
V: AsChangeset<Target = <<T as FilterDsl<P>>::Output as HasTable>::Table> + Debug + 'static,
|
||||
@ -463,32 +100,26 @@ where
|
||||
<V as AsChangeset>::Changeset,
|
||||
>: AsQuery + LoadQuery<'static, PgConnection, R> + QueryFragment<Pg> + Send,
|
||||
R: Send + 'static,
|
||||
|
||||
Q: QueryExecutionMode<
|
||||
UpdateStatement<
|
||||
<<T as FilterDsl<P>>::Output as HasTable>::Table,
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
<V as AsChangeset>::Changeset,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
let debug_values = format!("{:?}", values);
|
||||
|
||||
let query = diesel::update(<T as HasTable>::table().filter(predicate)).set(values);
|
||||
logger::debug!(query = %debug_query::<Pg, _>(&query).to_string());
|
||||
|
||||
execution_mode
|
||||
.update_with_results(conn, query, debug_values)
|
||||
query
|
||||
.get_results_async(conn)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::Others)
|
||||
.attach_printable_lazy(|| format!("Error while updating {}", debug_values))
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_update_by_id<T, V, Pk, R, Q>(
|
||||
pub(super) async fn generic_update_by_id<T, V, Pk, R>(
|
||||
conn: &PgPooledConn,
|
||||
id: Pk,
|
||||
values: V,
|
||||
execution_mode: Q,
|
||||
) -> CustomResult<Q::UpdateByIdOutput, errors::DatabaseError>
|
||||
) -> CustomResult<R, errors::DatabaseError>
|
||||
where
|
||||
T: FindDsl<Pk> + HasTable<Table = T> + LimitDsl + Table + 'static,
|
||||
V: AsChangeset<Target = <<T as FindDsl<Pk>>::Output as HasTable>::Table> + Debug,
|
||||
@ -509,28 +140,33 @@ where
|
||||
<<T as FindDsl<Pk>>::Output as IntoUpdateTarget>::WhereClause: Clone,
|
||||
<V as AsChangeset>::Changeset: Clone,
|
||||
<<<T as FindDsl<Pk>>::Output as HasTable>::Table as QuerySource>::FromClause: Clone,
|
||||
|
||||
Q: QueryExecutionMode<
|
||||
UpdateStatement<
|
||||
<<T as FindDsl<Pk>>::Output as HasTable>::Table,
|
||||
<<T as FindDsl<Pk>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
<V as AsChangeset>::Changeset,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
let debug_values = format!("{:?}", values);
|
||||
|
||||
let query = diesel::update(<T as HasTable>::table().find(id.to_owned())).set(values);
|
||||
|
||||
execution_mode.update_by_id(conn, query, debug_values).await
|
||||
match query.to_owned().get_result_async(conn).await {
|
||||
Ok(result) => {
|
||||
logger::debug!(query = %debug_query::<Pg, _>(&query).to_string());
|
||||
Ok(result)
|
||||
}
|
||||
Err(ConnectionError::Query(DieselError::QueryBuilderError(_))) => {
|
||||
generic_find_by_id_core::<T, _, _>(conn, id).await
|
||||
}
|
||||
Err(ConnectionError::Query(DieselError::NotFound)) => {
|
||||
Err(report!(errors::DatabaseError::NotFound))
|
||||
.attach_printable_lazy(|| format!("Error while updating by ID {}", debug_values))
|
||||
}
|
||||
_ => Err(report!(errors::DatabaseError::Others))
|
||||
.attach_printable_lazy(|| format!("Error while updating by ID {}", debug_values)),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_delete<T, P, Q>(
|
||||
pub(super) async fn generic_delete<T, P>(
|
||||
conn: &PgPooledConn,
|
||||
predicate: P,
|
||||
execution_mode: Q,
|
||||
) -> CustomResult<Q::DeleteOutput, errors::DatabaseError>
|
||||
) -> CustomResult<bool, errors::DatabaseError>
|
||||
where
|
||||
T: FilterDsl<P> + HasTable<Table = T> + Table + 'static,
|
||||
<T as FilterDsl<P>>::Output: IntoUpdateTarget,
|
||||
@ -538,55 +174,33 @@ where
|
||||
<<T as FilterDsl<P>>::Output as HasTable>::Table,
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
>: AsQuery + QueryFragment<Pg> + QueryId + Send + 'static,
|
||||
|
||||
Q: QueryExecutionMode<
|
||||
DeleteStatement<
|
||||
<<T as FilterDsl<P>>::Output as HasTable>::Table,
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
let query = diesel::delete(<T as HasTable>::table().filter(predicate));
|
||||
logger::debug!(query = %debug_query::<Pg, _>(&query).to_string());
|
||||
|
||||
execution_mode.delete(conn, query).await
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_delete_with_results<T, P, R, Q>(
|
||||
conn: &PgPooledConn,
|
||||
predicate: P,
|
||||
execution_mode: Q,
|
||||
) -> CustomResult<Q::DeleteWithResultsOutput, errors::DatabaseError>
|
||||
where
|
||||
T: FilterDsl<P> + HasTable<Table = T> + Table + 'static,
|
||||
<T as FilterDsl<P>>::Output: IntoUpdateTarget,
|
||||
DeleteStatement<
|
||||
<<T as FilterDsl<P>>::Output as HasTable>::Table,
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
>: AsQuery + LoadQuery<'static, PgConnection, R> + QueryFragment<Pg> + Send + 'static,
|
||||
R: Send + 'static,
|
||||
|
||||
Q: QueryExecutionMode<
|
||||
DeleteStatement<
|
||||
<<T as FilterDsl<P>>::Output as HasTable>::Table,
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
let query = diesel::delete(<T as HasTable>::table().filter(predicate));
|
||||
logger::debug!(query = %debug_query::<Pg, _>(&query).to_string());
|
||||
|
||||
execution_mode.delete_with_results(conn, query).await
|
||||
query
|
||||
.execute_async(conn)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::Others)
|
||||
.attach_printable_lazy(|| "Error while deleting")
|
||||
.and_then(|result| match result {
|
||||
n if n > 0 => {
|
||||
logger::debug!("{n} records deleted");
|
||||
Ok(true)
|
||||
}
|
||||
0 => {
|
||||
Err(report!(errors::DatabaseError::NotFound).attach_printable("No records deleted"))
|
||||
}
|
||||
_ => Ok(true), // n is usize, rustc requires this for exhaustive check
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_delete_one_with_result<T, P, R, Q>(
|
||||
pub(super) async fn generic_delete_one_with_result<T, P, R>(
|
||||
conn: &PgPooledConn,
|
||||
predicate: P,
|
||||
execution_mode: Q,
|
||||
) -> CustomResult<Q::DeleteOneWithResultOutput, errors::DatabaseError>
|
||||
) -> CustomResult<R, errors::DatabaseError>
|
||||
where
|
||||
T: FilterDsl<P> + HasTable<Table = T> + Table + 'static,
|
||||
<T as FilterDsl<P>>::Output: IntoUpdateTarget,
|
||||
@ -595,18 +209,22 @@ where
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
>: AsQuery + LoadQuery<'static, PgConnection, R> + QueryFragment<Pg> + Send + 'static,
|
||||
R: Send + Clone + 'static,
|
||||
|
||||
Q: QueryExecutionMode<
|
||||
DeleteStatement<
|
||||
<<T as FilterDsl<P>>::Output as HasTable>::Table,
|
||||
<<T as FilterDsl<P>>::Output as IntoUpdateTarget>::WhereClause,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
let query = diesel::delete(<T as HasTable>::table().filter(predicate));
|
||||
logger::debug!(query = %debug_query::<Pg, _>(&query).to_string());
|
||||
|
||||
execution_mode.delete_one_with_result(conn, query).await
|
||||
query
|
||||
.get_results_async(conn)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::DatabaseError::Others)
|
||||
.attach_printable_lazy(|| "Error while deleting")
|
||||
.and_then(|result| {
|
||||
result.first().cloned().ok_or_else(|| {
|
||||
report!(errors::DatabaseError::NotFound)
|
||||
.attach_printable("Object to be deleted does not exist")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
@ -638,7 +256,7 @@ where
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_find_by_id<T, Pk, R>(
|
||||
pub(super) async fn generic_find_by_id<T, Pk, R>(
|
||||
conn: &PgPooledConn,
|
||||
id: Pk,
|
||||
) -> CustomResult<R, errors::DatabaseError>
|
||||
@ -654,7 +272,7 @@ where
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_find_by_id_optional<T, Pk, R>(
|
||||
pub(super) async fn generic_find_by_id_optional<T, Pk, R>(
|
||||
conn: &PgPooledConn,
|
||||
id: Pk,
|
||||
) -> CustomResult<Option<R>, errors::DatabaseError>
|
||||
@ -699,7 +317,7 @@ where
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_find_one<T, P, R>(
|
||||
pub(super) async fn generic_find_one<T, P, R>(
|
||||
conn: &PgPooledConn,
|
||||
predicate: P,
|
||||
) -> CustomResult<R, errors::DatabaseError>
|
||||
@ -713,7 +331,7 @@ where
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_find_one_optional<T, P, R>(
|
||||
pub(super) async fn generic_find_one_optional<T, P, R>(
|
||||
conn: &PgPooledConn,
|
||||
predicate: P,
|
||||
) -> CustomResult<Option<R>, errors::DatabaseError>
|
||||
@ -727,7 +345,7 @@ where
|
||||
}
|
||||
|
||||
#[instrument(level = "DEBUG", skip_all)]
|
||||
pub async fn generic_filter<T, P, R>(
|
||||
pub(super) async fn generic_filter<T, P, R>(
|
||||
conn: &PgPooledConn,
|
||||
predicate: P,
|
||||
limit: Option<i64>,
|
||||
@ -759,7 +377,7 @@ where
|
||||
.attach_printable_lazy(|| "Error filtering records by predicate")
|
||||
}
|
||||
|
||||
pub fn to_optional<T>(
|
||||
fn to_optional<T>(
|
||||
arg: CustomResult<T, errors::DatabaseError>,
|
||||
) -> CustomResult<Option<T>, errors::DatabaseError> {
|
||||
match arg {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, ExpressionMethods};
|
||||
use router_env::{tracing, tracing::instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
locker_mock_up::{LockerMockUp, LockerMockUpNew},
|
||||
@ -15,7 +15,7 @@ impl LockerMockUpNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<LockerMockUp, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, LockerMockUp, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,10 +37,9 @@ impl LockerMockUp {
|
||||
conn: &PgPooledConn,
|
||||
card_id: &str,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
generics::generic_delete_one_with_result::<<Self as HasTable>::Table, _, Self, _>(
|
||||
generics::generic_delete_one_with_result::<<Self as HasTable>::Table, _, _>(
|
||||
conn,
|
||||
dsl::card_id.eq(card_id.to_owned()),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -2,13 +2,13 @@ use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use error_stack::report;
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{errors, mandate::*, schema::mandate::dsl, CustomResult, PgPooledConn};
|
||||
|
||||
impl MandateNew {
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert(self, conn: &PgPooledConn) -> CustomResult<Mandate, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, Mandate, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,13 +48,12 @@ impl Mandate {
|
||||
mandate_id: &str,
|
||||
mandate: MandateUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
dsl::merchant_id
|
||||
.eq(merchant_id.to_owned())
|
||||
.and(dsl::mandate_id.eq(mandate_id.to_owned())),
|
||||
MandateUpdateInternal::from(mandate),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await?
|
||||
.first()
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, ExpressionMethods};
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
merchant_account::{
|
||||
@ -17,7 +17,7 @@ impl MerchantAccountNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<MerchantAccount, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, MerchantAccount, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,11 +28,10 @@ impl MerchantAccount {
|
||||
conn: &PgPooledConn,
|
||||
merchant_account: MerchantAccountUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id,
|
||||
MerchantAccountUpdateInternal::from(merchant_account),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -48,10 +47,9 @@ impl MerchantAccount {
|
||||
conn: &PgPooledConn,
|
||||
merchant_id: &str,
|
||||
) -> CustomResult<bool, errors::DatabaseError> {
|
||||
generics::generic_delete::<<Self as HasTable>::Table, _, _>(
|
||||
generics::generic_delete::<<Self as HasTable>::Table, _>(
|
||||
conn,
|
||||
dsl::merchant_id.eq(merchant_id.to_owned()),
|
||||
ExecuteQuery::<Self>::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
merchant_connector_account::{
|
||||
@ -18,12 +18,7 @@ impl MerchantConnectorAccountNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<MerchantConnectorAccount, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, MerchantConnectorAccount, _>(
|
||||
conn,
|
||||
self,
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,11 +29,10 @@ impl MerchantConnectorAccount {
|
||||
conn: &PgPooledConn,
|
||||
merchant_connector_account: MerchantConnectorAccountUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id,
|
||||
MerchantConnectorAccountUpdateInternal::from(merchant_connector_account),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -55,12 +49,11 @@ impl MerchantConnectorAccount {
|
||||
merchant_id: &str,
|
||||
merchant_connector_id: &i32,
|
||||
) -> CustomResult<bool, errors::DatabaseError> {
|
||||
generics::generic_delete::<<Self as HasTable>::Table, _, _>(
|
||||
generics::generic_delete::<<Self as HasTable>::Table, _>(
|
||||
conn,
|
||||
dsl::merchant_id
|
||||
.eq(merchant_id.to_owned())
|
||||
.and(dsl::merchant_connector_id.eq(merchant_connector_id.to_owned())),
|
||||
ExecuteQuery::<Self>::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use error_stack::IntoReport;
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery, RawQuery, RawSqlQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
enums, errors,
|
||||
payment_attempt::{
|
||||
@ -18,15 +18,7 @@ impl PaymentAttemptNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<PaymentAttempt, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, PaymentAttempt, _>(conn, self, ExecuteQuery::new()).await
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert_query(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<RawSqlQuery, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, PaymentAttempt, _>(conn, self, RawQuery).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,11 +29,12 @@ impl PaymentAttempt {
|
||||
conn: &PgPooledConn,
|
||||
payment_attempt: PaymentAttemptUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id,
|
||||
dsl::payment_id
|
||||
.eq(self.payment_id.to_owned())
|
||||
.and(dsl::merchant_id.eq(self.merchant_id.to_owned())),
|
||||
PaymentAttemptUpdateInternal::from(payment_attempt),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -49,25 +42,12 @@ impl PaymentAttempt {
|
||||
errors::DatabaseError::NoFieldsToUpdate => Ok(self),
|
||||
_ => Err(error),
|
||||
},
|
||||
result => result,
|
||||
Ok(mut payment_attempts) => payment_attempts
|
||||
.pop()
|
||||
.ok_or(error_stack::report!(errors::DatabaseError::NotFound)),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn update_query(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
payment_attempt: PaymentAttemptUpdate,
|
||||
) -> CustomResult<RawSqlQuery, errors::DatabaseError> {
|
||||
generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
conn,
|
||||
self.id,
|
||||
PaymentAttemptUpdateInternal::from(payment_attempt),
|
||||
RawQuery,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn find_by_payment_id_merchant_id(
|
||||
conn: &PgPooledConn,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery, RawQuery, RawSqlQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
payment_intent::{
|
||||
@ -17,15 +17,7 @@ impl PaymentIntentNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<PaymentIntent, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, PaymentIntent, _>(conn, self, ExecuteQuery::new()).await
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert_query(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<RawSqlQuery, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, PaymentIntent, _>(conn, self, RawQuery).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,11 +28,12 @@ impl PaymentIntent {
|
||||
conn: &PgPooledConn,
|
||||
payment_intent: PaymentIntentUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id,
|
||||
dsl::payment_id
|
||||
.eq(self.payment_id.to_owned())
|
||||
.and(dsl::merchant_id.eq(self.merchant_id.to_owned())),
|
||||
PaymentIntentUpdateInternal::from(payment_intent),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -48,25 +41,12 @@ impl PaymentIntent {
|
||||
errors::DatabaseError::NoFieldsToUpdate => Ok(self),
|
||||
_ => Err(error),
|
||||
},
|
||||
result => result,
|
||||
Ok(mut payment_intents) => payment_intents
|
||||
.pop()
|
||||
.ok_or(error_stack::report!(errors::DatabaseError::NotFound)),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn update_query(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
payment_intent: PaymentIntentUpdate,
|
||||
) -> CustomResult<RawSqlQuery, errors::DatabaseError> {
|
||||
generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
conn,
|
||||
self.id,
|
||||
PaymentIntentUpdateInternal::from(payment_intent),
|
||||
RawQuery,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn find_by_payment_id_merchant_id(
|
||||
conn: &PgPooledConn,
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use error_stack::ResultExt;
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
payment_method::{PaymentMethod, PaymentMethodNew},
|
||||
@ -16,7 +15,7 @@ impl PaymentMethodNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<PaymentMethod, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, PaymentMethod, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,15 +25,11 @@ impl PaymentMethod {
|
||||
conn: &PgPooledConn,
|
||||
payment_method_id: String,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
let result =
|
||||
generics::generic_delete_one_with_result::<<Self as HasTable>::Table, _, Self, _>(
|
||||
conn,
|
||||
dsl::payment_method_id.eq(payment_method_id),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
.attach_printable("Error while deleting by payment method ID")?;
|
||||
Ok(result)
|
||||
generics::generic_delete_one_with_result::<<Self as HasTable>::Table, _, Self>(
|
||||
conn,
|
||||
dsl::payment_method_id.eq(payment_method_id),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
@ -43,17 +38,13 @@ impl PaymentMethod {
|
||||
merchant_id: &str,
|
||||
payment_method_id: &str,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
let result =
|
||||
generics::generic_delete_one_with_result::<<Self as HasTable>::Table, _, Self, _>(
|
||||
conn,
|
||||
dsl::merchant_id
|
||||
.eq(merchant_id.to_owned())
|
||||
.and(dsl::payment_method_id.eq(payment_method_id.to_owned())),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(result)
|
||||
generics::generic_delete_one_with_result::<<Self as HasTable>::Table, _, Self>(
|
||||
conn,
|
||||
dsl::merchant_id
|
||||
.eq(merchant_id.to_owned())
|
||||
.and(dsl::payment_method_id.eq(payment_method_id.to_owned())),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
|
||||
@ -2,7 +2,7 @@ use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use router_env::tracing::{self, instrument};
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
enums, errors,
|
||||
process_tracker::{
|
||||
@ -18,7 +18,7 @@ impl ProcessTrackerNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<ProcessTracker, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, ProcessTracker, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,11 +29,10 @@ impl ProcessTracker {
|
||||
conn: &PgPooledConn,
|
||||
process: ProcessTrackerUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id.clone(),
|
||||
ProcessTrackerUpdateInternal::from(process),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -51,11 +50,10 @@ impl ProcessTracker {
|
||||
task_ids: Vec<String>,
|
||||
task_update: ProcessTrackerUpdate,
|
||||
) -> CustomResult<usize, errors::DatabaseError> {
|
||||
generics::generic_update::<<Self as HasTable>::Table, _, _, _>(
|
||||
generics::generic_update::<<Self as HasTable>::Table, _, _>(
|
||||
conn,
|
||||
dsl::id.eq_any(task_ids),
|
||||
ProcessTrackerUpdateInternal::from(task_update),
|
||||
ExecuteQuery::<Self>::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
@ -118,7 +116,7 @@ impl ProcessTracker {
|
||||
ids: Vec<String>,
|
||||
schedule_time: PrimitiveDateTime,
|
||||
) -> CustomResult<usize, errors::DatabaseError> {
|
||||
generics::generic_update::<<Self as HasTable>::Table, _, _, _>(
|
||||
generics::generic_update::<<Self as HasTable>::Table, _, _>(
|
||||
conn,
|
||||
dsl::status
|
||||
.eq(enums::ProcessTrackerStatus::ProcessStarted)
|
||||
@ -127,7 +125,6 @@ impl ProcessTracker {
|
||||
dsl::status.eq(enums::ProcessTrackerStatus::Processing),
|
||||
dsl::schedule_time.eq(schedule_time),
|
||||
),
|
||||
ExecuteQuery::<Self>::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
|
||||
use router_env::{tracing, tracing::instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
refund::{Refund, RefundNew, RefundUpdate, RefundUpdateInternal},
|
||||
@ -14,7 +14,7 @@ use crate::{
|
||||
impl RefundNew {
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert(self, conn: &PgPooledConn) -> CustomResult<Refund, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, Refund, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,11 +25,10 @@ impl Refund {
|
||||
conn: &PgPooledConn,
|
||||
refund: RefundUpdate,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, Self, _>(
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id,
|
||||
RefundUpdateInternal::from(refund),
|
||||
ExecuteQuery::new(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use diesel::{associations::HasTable, ExpressionMethods};
|
||||
use router_env::tracing::{self, instrument};
|
||||
|
||||
use super::generics::{self, ExecuteQuery};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
schema::temp_card::dsl,
|
||||
@ -15,7 +15,7 @@ impl TempCardNew {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<TempCard, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, TempCard, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ impl TempCard {
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
) -> CustomResult<Self, errors::DatabaseError> {
|
||||
generics::generic_insert::<_, _, TempCard, _>(conn, self, ExecuteQuery::new()).await
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
|
||||
Reference in New Issue
Block a user