Skip to content

Commit c573f61

Browse files
chore: reorder v2 migrations folders (#8671)
1 parent d164954 commit c573f61

File tree

36 files changed

+196
-126
lines changed

36 files changed

+196
-126
lines changed

crates/common_enums/src/enums.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8073,6 +8073,7 @@ pub enum UIWidgetFormLayout {
80738073
Clone,
80748074
Copy,
80758075
Debug,
8076+
Default,
80768077
Eq,
80778078
PartialEq,
80788079
serde::Deserialize,
@@ -8085,6 +8086,7 @@ pub enum UIWidgetFormLayout {
80858086
#[strum(serialize_all = "snake_case")]
80868087
#[serde(rename_all = "snake_case")]
80878088
pub enum DeleteStatus {
8089+
#[default]
80888090
Active,
80898091
Redacted,
80908092
}

crates/diesel_models/src/business_profile.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,10 @@ pub struct Profile {
402402
pub three_ds_decision_manager_config: Option<common_types::payments::DecisionManagerRecord>,
403403
pub should_collect_cvv_during_payment:
404404
Option<primitive_wrappers::ShouldCollectCvvDuringPayment>,
405-
pub is_external_vault_enabled: Option<bool>,
406-
pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
407405
pub revenue_recovery_retry_algorithm_type: Option<common_enums::RevenueRecoveryAlgorithmType>,
408406
pub revenue_recovery_retry_algorithm_data: Option<RevenueRecoveryAlgorithmData>,
407+
pub is_external_vault_enabled: Option<bool>,
408+
pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
409409
}
410410

411411
impl Profile {

crates/diesel_models/src/customers.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use time::PrimitiveDateTime;
66
#[cfg(feature = "v1")]
77
use crate::schema::customers;
88
#[cfg(feature = "v2")]
9-
use crate::{enums::DeleteStatus, schema_v2::customers};
9+
use crate::{
10+
diesel_impl::RequiredFromNullableWithDefault, enums::DeleteStatus, schema_v2::customers,
11+
};
1012

1113
#[cfg(feature = "v1")]
1214
#[derive(
@@ -164,6 +166,7 @@ pub struct Customer {
164166
pub merchant_reference_id: Option<common_utils::id_type::CustomerId>,
165167
pub default_billing_address: Option<Encryption>,
166168
pub default_shipping_address: Option<Encryption>,
169+
#[diesel(deserialize_as = RequiredFromNullableWithDefault<DeleteStatus>)]
167170
pub status: DeleteStatus,
168171
pub id: common_utils::id_type::GlobalCustomerId,
169172
}

crates/diesel_models/src/lib.rs

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ pub mod user_key_store;
6161
pub mod user_role;
6262

6363
use diesel_impl::{DieselArray, OptionalDieselArray};
64+
#[cfg(feature = "v2")]
65+
use diesel_impl::{RequiredFromNullable, RequiredFromNullableWithDefault};
6466

6567
pub type StorageResult<T> = error_stack::Result<T, errors::DatabaseError>;
6668
pub type PgPooledConn = async_bb8_diesel::Connection<diesel::PgConnection>;
@@ -71,7 +73,6 @@ pub use self::{
7173
payment_intent::*, payment_method::*, payout_attempt::*, payouts::*, process_tracker::*,
7274
refund::*, reverse_lookup::*, user_authentication_method::*,
7375
};
74-
7576
/// The types and implementations provided by this module are required for the schema generated by
7677
/// `diesel_cli` 2.0 to work with the types defined in Rust code. This is because
7778
/// [`diesel`][diesel] 2.0 [changed the nullability of array elements][diesel-2.0-array-nullability],
@@ -83,13 +84,18 @@ pub use self::{
8384
/// [diesel-2.0-array-nullability]: https://diesel.rs/guides/migration_guide.html#2-0-0-nullability-of-array-elements
8485
#[doc(hidden)]
8586
pub(crate) mod diesel_impl {
87+
#[cfg(feature = "v2")]
88+
use common_utils::{id_type, types};
8689
use diesel::{
8790
deserialize::FromSql,
8891
pg::Pg,
8992
sql_types::{Array, Nullable},
9093
Queryable,
9194
};
9295

96+
#[cfg(feature = "v2")]
97+
use crate::enums;
98+
9399
pub struct DieselArray<T>(Vec<Option<T>>);
94100

95101
impl<T> From<DieselArray<T>> for Vec<T> {
@@ -130,6 +136,119 @@ pub(crate) mod diesel_impl {
130136
Ok(Self(row))
131137
}
132138
}
139+
#[cfg(feature = "v2")]
140+
/// If the DB value is null, this wrapper will return an error when deserializing.
141+
///
142+
/// This is useful when you want to ensure that a field is always present, even if the database
143+
/// value is NULL. If the database column contains a NULL value, an error will be returned.
144+
pub struct RequiredFromNullable<T>(T);
145+
146+
#[cfg(feature = "v2")]
147+
impl<T> RequiredFromNullable<T> {
148+
/// Extracts the inner value from the wrapper
149+
pub fn into_inner(self) -> T {
150+
self.0
151+
}
152+
}
153+
154+
#[cfg(feature = "v2")]
155+
impl<T, ST, DB> Queryable<Nullable<ST>, DB> for RequiredFromNullable<T>
156+
where
157+
DB: diesel::backend::Backend,
158+
T: Queryable<ST, DB>,
159+
Option<T::Row>: FromSql<Nullable<ST>, DB>,
160+
ST: diesel::sql_types::SingleValue,
161+
{
162+
type Row = Option<T::Row>;
163+
164+
fn build(row: Self::Row) -> diesel::deserialize::Result<Self> {
165+
match row {
166+
Some(inner_row) => {
167+
let value = T::build(inner_row)?;
168+
Ok(Self(value))
169+
}
170+
None => Err("Cannot deserialize NULL value for required field. Check if the database column that should not be NULL contains a NULL value.".into()),
171+
}
172+
}
173+
}
174+
175+
#[cfg(feature = "v2")]
176+
/// If the DB value is null, this wrapper will provide a default value for the type `T`.
177+
///
178+
/// This is useful when you want to ensure that a field is always present, even if the database
179+
/// value is NULL. The default value is provided by the `Default` trait implementation of `T`.
180+
pub struct RequiredFromNullableWithDefault<T>(T);
181+
#[cfg(feature = "v2")]
182+
impl<T> RequiredFromNullableWithDefault<T> {
183+
/// Extracts the inner value from the wrapper
184+
pub fn into_inner(self) -> T {
185+
self.0
186+
}
187+
}
188+
#[cfg(feature = "v2")]
189+
impl<T, ST, DB> Queryable<Nullable<ST>, DB> for RequiredFromNullableWithDefault<T>
190+
where
191+
DB: diesel::backend::Backend,
192+
T: Queryable<ST, DB>,
193+
T: Default,
194+
Option<T::Row>: FromSql<Nullable<ST>, DB>,
195+
ST: diesel::sql_types::SingleValue,
196+
{
197+
type Row = Option<T::Row>;
198+
199+
fn build(row: Self::Row) -> diesel::deserialize::Result<Self> {
200+
match row {
201+
Some(inner_row) => {
202+
let value = T::build(inner_row)?;
203+
Ok(Self(value))
204+
}
205+
None => Ok(Self(T::default())),
206+
}
207+
}
208+
}
209+
210+
#[cfg(feature = "v2")]
211+
/// Macro to implement From trait for types wrapped in RequiredFromNullable
212+
#[macro_export]
213+
macro_rules! impl_from_required_from_nullable {
214+
($($type:ty),* $(,)?) => {
215+
$(
216+
impl From<$crate::RequiredFromNullable<$type>> for $type {
217+
fn from(wrapper: $crate::RequiredFromNullable<$type>) -> Self {
218+
wrapper.into_inner()
219+
}
220+
}
221+
)*
222+
};
223+
}
224+
225+
#[cfg(feature = "v2")]
226+
/// Macro to implement From trait for types wrapped in RequiredFromNullableWithDefault
227+
#[macro_export]
228+
macro_rules! impl_from_required_from_nullable_with_default {
229+
($($type:ty),* $(,)?) => {
230+
$(
231+
impl From<$crate::RequiredFromNullableWithDefault<$type>> for $type {
232+
fn from(wrapper: $crate::RequiredFromNullableWithDefault<$type>) -> Self {
233+
wrapper.into_inner()
234+
}
235+
}
236+
)*
237+
};
238+
}
239+
#[cfg(feature = "v2")]
240+
crate::impl_from_required_from_nullable_with_default!(enums::DeleteStatus);
241+
242+
#[cfg(feature = "v2")]
243+
crate::impl_from_required_from_nullable!(
244+
enums::AuthenticationType,
245+
types::MinorUnit,
246+
enums::PaymentMethod,
247+
enums::Currency,
248+
id_type::ProfileId,
249+
time::PrimitiveDateTime,
250+
id_type::RefundReferenceId,
251+
);
133252
}
134253

135254
pub(crate) mod metrics {

crates/diesel_models/src/merchant_connector_account.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ impl MerchantConnectorAccount {
6464
}
6565
}
6666

67+
#[cfg(feature = "v2")]
68+
use crate::RequiredFromNullable;
69+
6770
#[cfg(feature = "v2")]
6871
#[derive(
6972
Clone,
@@ -91,6 +94,7 @@ pub struct MerchantConnectorAccount {
9194
pub connector_webhook_details: Option<pii::SecretSerdeValue>,
9295
#[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)]
9396
pub frm_config: Option<Vec<pii::SecretSerdeValue>>,
97+
#[diesel(deserialize_as = RequiredFromNullable<id_type::ProfileId>)]
9498
pub profile_id: id_type::ProfileId,
9599
#[diesel(deserialize_as = super::OptionalDieselArray<String>)]
96100
pub applepay_verified_domains: Option<Vec<String>>,

crates/diesel_models/src/payment_attempt.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::enums as storage_enums;
1515
#[cfg(feature = "v1")]
1616
use crate::schema::payment_attempt;
1717
#[cfg(feature = "v2")]
18-
use crate::schema_v2::payment_attempt;
18+
use crate::{schema_v2::payment_attempt, RequiredFromNullable};
1919

2020
common_utils::impl_to_sql_from_sql_json!(ConnectorMandateReferenceId);
2121
#[derive(
@@ -48,6 +48,7 @@ pub struct PaymentAttempt {
4848
pub error_message: Option<String>,
4949
pub surcharge_amount: Option<MinorUnit>,
5050
pub payment_method_id: Option<id_type::GlobalPaymentMethodId>,
51+
#[diesel(deserialize_as = RequiredFromNullable<storage_enums::AuthenticationType>)]
5152
pub authentication_type: storage_enums::AuthenticationType,
5253
#[serde(with = "common_utils::custom_serde::iso8601")]
5354
pub created_at: PrimitiveDateTime,
@@ -73,6 +74,7 @@ pub struct PaymentAttempt {
7374
pub encoded_data: Option<masking::Secret<String>>,
7475
pub unified_code: Option<String>,
7576
pub unified_message: Option<String>,
77+
#[diesel(deserialize_as = RequiredFromNullable<MinorUnit>)]
7678
pub net_amount: MinorUnit,
7779
pub external_three_ds_authentication_attempted: Option<bool>,
7880
pub authentication_connector: Option<String>,
@@ -93,6 +95,8 @@ pub struct PaymentAttempt {
9395
pub charges: Option<common_types::payments::ConnectorChargeResponseData>,
9496
pub processor_merchant_id: Option<id_type::MerchantId>,
9597
pub created_by: Option<String>,
98+
pub connector_request_reference_id: Option<String>,
99+
#[diesel(deserialize_as = RequiredFromNullable<storage_enums::PaymentMethod>)]
96100
pub payment_method_type_v2: storage_enums::PaymentMethod,
97101
pub connector_payment_id: Option<ConnectorTransactionId>,
98102
pub payment_method_subtype: storage_enums::PaymentMethodType,
@@ -114,7 +118,6 @@ pub struct PaymentAttempt {
114118
pub network_decline_code: Option<String>,
115119
/// A string indicating how to proceed with an network error if payment gateway provide one. This is used to understand the network error code better.
116120
pub network_error_message: Option<String>,
117-
pub connector_request_reference_id: Option<String>,
118121
}
119122

120123
#[cfg(feature = "v1")]

crates/diesel_models/src/payment_intent.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use crate::schema::payment_intent;
1111
use crate::schema_v2::payment_intent;
1212
#[cfg(feature = "v2")]
1313
use crate::types::{FeatureMetadata, OrderDetailsWithAmount};
14+
#[cfg(feature = "v2")]
15+
use crate::RequiredFromNullable;
1416
use crate::{business_profile::PaymentLinkBackgroundImageConfig, enums as storage_enums};
1517

1618
#[cfg(feature = "v2")]
@@ -20,6 +22,7 @@ pub struct PaymentIntent {
2022
pub merchant_id: common_utils::id_type::MerchantId,
2123
pub status: storage_enums::IntentStatus,
2224
pub amount: MinorUnit,
25+
#[diesel(deserialize_as = RequiredFromNullable<storage_enums::Currency>)]
2326
pub currency: storage_enums::Currency,
2427
pub amount_captured: Option<MinorUnit>,
2528
pub customer_id: Option<common_utils::id_type::GlobalCustomerId>,
@@ -40,12 +43,14 @@ pub struct PaymentIntent {
4043
pub connector_metadata: Option<pii::SecretSerdeValue>,
4144
pub feature_metadata: Option<FeatureMetadata>,
4245
pub attempt_count: i16,
46+
#[diesel(deserialize_as = RequiredFromNullable<common_utils::id_type::ProfileId>)]
4347
pub profile_id: common_utils::id_type::ProfileId,
4448
pub payment_link_id: Option<String>,
4549
pub updated_by: String,
4650
pub surcharge_applicable: Option<bool>,
4751
pub request_incremental_authorization: Option<RequestIncrementalAuthorization>,
4852
pub authorization_count: Option<i32>,
53+
#[diesel(deserialize_as = RequiredFromNullable<PrimitiveDateTime>)]
4954
pub session_expiry: PrimitiveDateTime,
5055
pub request_external_three_ds_authentication: Option<bool>,
5156
pub frm_metadata: Option<pii::SecretSerdeValue>,

0 commit comments

Comments
 (0)