Skip to content

Commit 4e0b67d

Browse files
committed
chore: add support for deserializing from nullable db column
1 parent 9eb342e commit 4e0b67d

File tree

2 files changed

+71
-33
lines changed

2 files changed

+71
-33
lines changed

crates/diesel_models/src/lib.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub mod user_authentication_method;
6060
pub mod user_key_store;
6161
pub mod user_role;
6262

63-
use diesel_impl::{DieselArray, OptionalDieselArray};
63+
use diesel_impl::{DieselArray, OptionalDieselArray, RequiredFromNullable};
6464

6565
pub type StorageResult<T> = error_stack::Result<T, errors::DatabaseError>;
6666
pub type PgPooledConn = async_bb8_diesel::Connection<diesel::PgConnection>;
@@ -130,6 +130,35 @@ pub(crate) mod diesel_impl {
130130
Ok(Self(row))
131131
}
132132
}
133+
134+
pub struct RequiredFromNullable<T>(T);
135+
136+
impl<T> RequiredFromNullable<T> {
137+
/// Extracts the inner value from the wrapper
138+
pub fn into_inner(self) -> T {
139+
self.0
140+
}
141+
}
142+
143+
impl<T, ST, DB> Queryable<Nullable<ST>, DB> for RequiredFromNullable<T>
144+
where
145+
DB: diesel::backend::Backend,
146+
T: Queryable<ST, DB>,
147+
Option<T::Row>: FromSql<Nullable<ST>, DB>,
148+
ST: diesel::sql_types::SingleValue,
149+
{
150+
type Row = Option<T::Row>;
151+
152+
fn build(row: Self::Row) -> diesel::deserialize::Result<Self> {
153+
match row {
154+
Some(inner_row) => {
155+
let value = T::build(inner_row)?;
156+
Ok(RequiredFromNullable(value))
157+
}
158+
None => Err("Cannot deserialize NULL value for required field".into()),
159+
}
160+
}
161+
}
133162
}
134163

135164
pub(crate) mod metrics {

crates/diesel_models/src/refund.rs

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use common_utils::{
2-
pii,
2+
id_type, pii,
33
types::{ChargeRefunds, ConnectorTransactionId, ConnectorTransactionIdTrait, MinorUnit},
44
};
55
use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
@@ -11,6 +11,14 @@ use crate::enums as storage_enums;
1111
use crate::schema::refund;
1212
#[cfg(feature = "v2")]
1313
use crate::schema_v2::refund;
14+
#[cfg(feature = "v2")]
15+
use crate::RequiredFromNullable;
16+
#[cfg(feature = "v2")]
17+
impl From<RequiredFromNullable<id_type::RefundReferenceId>> for id_type::RefundReferenceId {
18+
fn from(wrapper: RequiredFromNullable<id_type::RefundReferenceId>) -> Self {
19+
wrapper.into_inner()
20+
}
21+
}
1422
#[cfg(feature = "v1")]
1523
#[derive(
1624
Clone,
@@ -27,8 +35,8 @@ use crate::schema_v2::refund;
2735
pub struct Refund {
2836
pub internal_reference_id: String,
2937
pub refund_id: String, //merchant_reference id
30-
pub payment_id: common_utils::id_type::PaymentId,
31-
pub merchant_id: common_utils::id_type::MerchantId,
38+
pub payment_id: id_type::PaymentId,
39+
pub merchant_id: id_type::MerchantId,
3240
pub connector_transaction_id: ConnectorTransactionId,
3341
pub connector: String,
3442
pub connector_refund_id: Option<ConnectorTransactionId>,
@@ -50,11 +58,11 @@ pub struct Refund {
5058
pub attempt_id: String,
5159
pub refund_reason: Option<String>,
5260
pub refund_error_code: Option<String>,
53-
pub profile_id: Option<common_utils::id_type::ProfileId>,
61+
pub profile_id: Option<id_type::ProfileId>,
5462
pub updated_by: String,
55-
pub merchant_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
63+
pub merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
5664
pub charges: Option<ChargeRefunds>,
57-
pub organization_id: common_utils::id_type::OrganizationId,
65+
pub organization_id: id_type::OrganizationId,
5866
/// INFO: This field is deprecated and replaced by processor_refund_data
5967
pub connector_refund_data: Option<String>,
6068
/// INFO: This field is deprecated and replaced by processor_transaction_data
@@ -82,8 +90,8 @@ pub struct Refund {
8290
)]
8391
#[diesel(table_name = refund, primary_key(id), check_for_backend(diesel::pg::Pg))]
8492
pub struct Refund {
85-
pub payment_id: common_utils::id_type::GlobalPaymentId,
86-
pub merchant_id: common_utils::id_type::MerchantId,
93+
pub payment_id: id_type::GlobalPaymentId,
94+
pub merchant_id: id_type::MerchantId,
8795
pub connector_transaction_id: ConnectorTransactionId,
8896
pub connector: String,
8997
pub connector_refund_id: Option<ConnectorTransactionId>,
@@ -102,21 +110,22 @@ pub struct Refund {
102110
#[serde(with = "common_utils::custom_serde::iso8601")]
103111
pub modified_at: PrimitiveDateTime,
104112
pub description: Option<String>,
105-
pub attempt_id: common_utils::id_type::GlobalAttemptId,
113+
pub attempt_id: id_type::GlobalAttemptId,
106114
pub refund_reason: Option<String>,
107115
pub refund_error_code: Option<String>,
108-
pub profile_id: Option<common_utils::id_type::ProfileId>,
116+
pub profile_id: Option<id_type::ProfileId>,
109117
pub updated_by: String,
110118
pub charges: Option<ChargeRefunds>,
111-
pub organization_id: common_utils::id_type::OrganizationId,
119+
pub organization_id: id_type::OrganizationId,
112120
pub split_refunds: Option<common_types::refunds::SplitRefund>,
113121
pub unified_code: Option<String>,
114122
pub unified_message: Option<String>,
115123
pub processor_refund_data: Option<String>,
116124
pub processor_transaction_data: Option<String>,
117-
pub id: common_utils::id_type::GlobalRefundId,
118-
pub merchant_reference_id: Option<common_utils::id_type::RefundReferenceId>,
119-
pub connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
125+
pub id: id_type::GlobalRefundId,
126+
#[diesel(deserialize_as = RequiredFromNullable<id_type::RefundReferenceId>)]
127+
pub merchant_reference_id: id_type::RefundReferenceId,
128+
pub connector_id: Option<id_type::MerchantConnectorAccountId>,
120129
}
121130

122131
#[cfg(feature = "v1")]
@@ -134,8 +143,8 @@ pub struct Refund {
134143
#[diesel(table_name = refund)]
135144
pub struct RefundNew {
136145
pub refund_id: String,
137-
pub payment_id: common_utils::id_type::PaymentId,
138-
pub merchant_id: common_utils::id_type::MerchantId,
146+
pub payment_id: id_type::PaymentId,
147+
pub merchant_id: id_type::MerchantId,
139148
pub internal_reference_id: String,
140149
pub external_reference_id: Option<String>,
141150
pub connector_transaction_id: ConnectorTransactionId,
@@ -156,11 +165,11 @@ pub struct RefundNew {
156165
pub description: Option<String>,
157166
pub attempt_id: String,
158167
pub refund_reason: Option<String>,
159-
pub profile_id: Option<common_utils::id_type::ProfileId>,
168+
pub profile_id: Option<id_type::ProfileId>,
160169
pub updated_by: String,
161-
pub merchant_connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
170+
pub merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
162171
pub charges: Option<ChargeRefunds>,
163-
pub organization_id: common_utils::id_type::OrganizationId,
172+
pub organization_id: id_type::OrganizationId,
164173
pub split_refunds: Option<common_types::refunds::SplitRefund>,
165174
pub processor_refund_data: Option<String>,
166175
pub processor_transaction_data: Option<String>,
@@ -180,10 +189,10 @@ pub struct RefundNew {
180189
)]
181190
#[diesel(table_name = refund)]
182191
pub struct RefundNew {
183-
pub merchant_reference_id: common_utils::id_type::RefundReferenceId,
184-
pub payment_id: common_utils::id_type::GlobalPaymentId,
185-
pub merchant_id: common_utils::id_type::MerchantId,
186-
pub id: common_utils::id_type::GlobalRefundId,
192+
pub merchant_reference_id: id_type::RefundReferenceId,
193+
pub payment_id: id_type::GlobalPaymentId,
194+
pub merchant_id: id_type::MerchantId,
195+
pub id: id_type::GlobalRefundId,
187196
pub external_reference_id: Option<String>,
188197
pub connector_transaction_id: ConnectorTransactionId,
189198
pub connector: String,
@@ -201,13 +210,13 @@ pub struct RefundNew {
201210
#[serde(with = "common_utils::custom_serde::iso8601")]
202211
pub modified_at: PrimitiveDateTime,
203212
pub description: Option<String>,
204-
pub attempt_id: common_utils::id_type::GlobalAttemptId,
213+
pub attempt_id: id_type::GlobalAttemptId,
205214
pub refund_reason: Option<String>,
206-
pub profile_id: Option<common_utils::id_type::ProfileId>,
215+
pub profile_id: Option<id_type::ProfileId>,
207216
pub updated_by: String,
208-
pub connector_id: Option<common_utils::id_type::MerchantConnectorAccountId>,
217+
pub connector_id: Option<id_type::MerchantConnectorAccountId>,
209218
pub charges: Option<ChargeRefunds>,
210-
pub organization_id: common_utils::id_type::OrganizationId,
219+
pub organization_id: id_type::OrganizationId,
211220
pub split_refunds: Option<common_types::refunds::SplitRefund>,
212221
pub processor_refund_data: Option<String>,
213222
pub processor_transaction_data: Option<String>,
@@ -781,18 +790,18 @@ impl RefundUpdate {
781790
pub struct RefundCoreWorkflow {
782791
pub refund_internal_reference_id: String,
783792
pub connector_transaction_id: ConnectorTransactionId,
784-
pub merchant_id: common_utils::id_type::MerchantId,
785-
pub payment_id: common_utils::id_type::PaymentId,
793+
pub merchant_id: id_type::MerchantId,
794+
pub payment_id: id_type::PaymentId,
786795
pub processor_transaction_data: Option<String>,
787796
}
788797

789798
#[cfg(feature = "v2")]
790799
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
791800
pub struct RefundCoreWorkflow {
792-
pub refund_id: common_utils::id_type::GlobalRefundId,
801+
pub refund_id: id_type::GlobalRefundId,
793802
pub connector_transaction_id: ConnectorTransactionId,
794-
pub merchant_id: common_utils::id_type::MerchantId,
795-
pub payment_id: common_utils::id_type::GlobalPaymentId,
803+
pub merchant_id: id_type::MerchantId,
804+
pub payment_id: id_type::GlobalPaymentId,
796805
pub processor_transaction_data: Option<String>,
797806
}
798807

0 commit comments

Comments
 (0)