Sea Ext
This commit is contained in:
parent
b9c017b1fa
commit
da2c1b9b19
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -2763,6 +2763,8 @@ dependencies = [
|
||||
"console",
|
||||
"lazy_static",
|
||||
"linked-hash-map",
|
||||
"ron",
|
||||
"serde",
|
||||
"similar",
|
||||
"yaml-rust",
|
||||
]
|
||||
@ -3282,7 +3284,9 @@ dependencies = [
|
||||
"async-trait",
|
||||
"clap 3.2.25",
|
||||
"dotenv",
|
||||
"insta",
|
||||
"sea-orm-migration",
|
||||
"sqlx",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
@ -4592,6 +4596,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"bitflags",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rumqttc"
|
||||
version = "0.21.0"
|
||||
|
@ -19,5 +19,10 @@ async-trait = { version = "0.1.68" }
|
||||
[dependencies.sea-orm-migration]
|
||||
version = "0.11.0"
|
||||
features = [
|
||||
"sqlx-postgres"
|
||||
"sqlx-postgres",
|
||||
'runtime-tokio-rustls'
|
||||
]
|
||||
|
||||
[dev-dependencies]
|
||||
insta = { version = "1.29.0", features = ['ron'] }
|
||||
sqlx = { version = "0.6.3", features = ['runtime-tokio-rustls'] }
|
||||
|
@ -1,31 +1,49 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
use sea_query::expr::SimpleExpr;
|
||||
|
||||
/// ```sql
|
||||
/// id character varying NOT NULL,
|
||||
/// email character varying,
|
||||
/// billing_address_id character varying,
|
||||
/// shipping_address_id character varying,
|
||||
/// region_id character varying NOT NULL,
|
||||
/// customer_id character varying,
|
||||
/// payment_id character varying,
|
||||
/// type public.cart_types DEFAULT 'default'::public.cart_types NOT NULL,
|
||||
/// completed_at timestamp with time zone,
|
||||
/// created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// deleted_at timestamp with time zone,
|
||||
/// metadata jsonb,
|
||||
/// idempotency_key character varying,
|
||||
/// context jsonb,
|
||||
/// payment_authorized_at timestamp with time zone,
|
||||
/// sales_channel_id character varying
|
||||
/// ```
|
||||
use crate::sea_orm::Iterable;
|
||||
use crate::{ts_def_now_not_null, DropTable, IntoColumnDef};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
async fn up(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
Self::create_carts(m).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
self.drop_table(m, Cart::Carts).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Migration {
|
||||
/// ```sql
|
||||
/// CREATE TABLE carts
|
||||
/// (
|
||||
/// id uuid NOT NULL,
|
||||
/// email character varying,
|
||||
/// billing_address_id uuid,
|
||||
/// shipping_address_id uuid,
|
||||
/// region_id uuid NOT NULL,
|
||||
/// customer_id uuid,
|
||||
/// payment_id uuid,
|
||||
/// type cart_types DEFAULT 'default'::cart_types NOT NULL,
|
||||
/// completed_at timestamp with time zone,
|
||||
/// created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// deleted_at timestamp with time zone,
|
||||
/// metadata jsonb,
|
||||
/// idempotency_key character varying,
|
||||
/// context jsonb,
|
||||
/// payment_authorized_at timestamp with time zone,
|
||||
/// sales_channel_id uuid
|
||||
/// );
|
||||
/// ```
|
||||
async fn create_carts(manager: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
@ -37,48 +55,35 @@ impl MigrationTrait for Migration {
|
||||
.default(SimpleExpr::Custom("public.uuid_generate_v4()".into()))
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Cart::Email).string())
|
||||
.col(ColumnDef::new(Cart::BillingAddressId).uuid())
|
||||
.col(ColumnDef::new(Cart::ShippingAddressId).uuid())
|
||||
.col(ColumnDef::new(Cart::RegionId).uuid().not_null())
|
||||
.col(ColumnDef::new(Cart::CustomerId).uuid())
|
||||
.col(ColumnDef::new(Cart::PaymentId).uuid())
|
||||
.col(Cart::Email.col().string())
|
||||
.col(Cart::BillingAddressId.col().uuid())
|
||||
.col(Cart::ShippingAddressId.col().uuid())
|
||||
.col(Cart::RegionId.col().uuid().not_null())
|
||||
.col(Cart::CustomerId.col().uuid())
|
||||
.col(Cart::PaymentId.col().uuid())
|
||||
.col(
|
||||
ColumnDef::new(Cart::CartType)
|
||||
.string()
|
||||
.default(SimpleExpr::Custom("'default'::public.cart_types".into()))
|
||||
Cart::CartType
|
||||
.col()
|
||||
.enumeration(
|
||||
crate::types::CartType::CartTypes,
|
||||
crate::types::CartType::iter().skip(1),
|
||||
)
|
||||
.default(crate::types::CartType::Default.to_string())
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Cart::CompletedAt).timestamp())
|
||||
.col(
|
||||
ColumnDef::new(Cart::CreatedAt)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Cart::UpdatedAt)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Cart::DeletedAt).timestamp())
|
||||
.col(ColumnDef::new(Cart::Metadata).json_binary())
|
||||
.col(ColumnDef::new(Cart::IdempotencyKey).uuid())
|
||||
.col(ColumnDef::new(Cart::Context).json_binary())
|
||||
.col(ColumnDef::new(Cart::PaymentAuthorizedAt).timestamp())
|
||||
.col(ColumnDef::new(Cart::SalesChannelId).uuid())
|
||||
.col(Cart::CompletedAt.col().timestamp())
|
||||
.col(ts_def_now_not_null!(Cart::CreatedAt))
|
||||
.col(ts_def_now_not_null!(Cart::UpdatedAt))
|
||||
.col(Cart::DeletedAt.col().timestamp())
|
||||
.col(Cart::Metadata.col().json_binary())
|
||||
.col(Cart::IdempotencyKey.col().uuid())
|
||||
.col(Cart::Context.col().json_binary())
|
||||
.col(Cart::PaymentAuthorizedAt.col().timestamp())
|
||||
.col(Cart::SalesChannelId.col().uuid())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Cart::Carts).to_owned())
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
|
@ -1,5 +1,7 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
use crate::{to_pk2_name, CreateIndexExt, DropTable, IntoColumnDef};
|
||||
|
||||
/// ```sql
|
||||
/// CREATE TABLE cart_discounts
|
||||
/// (
|
||||
@ -17,47 +19,94 @@ pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(CartDiscount::CartDiscounts)
|
||||
.col(ColumnDef::new(CartDiscount::CartId).uuid().not_null())
|
||||
.col(ColumnDef::new(CartDiscount::DiscountId).uuid().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(CartGiftCard::CartGiftCards)
|
||||
.col(ColumnDef::new(CartGiftCard::CartId).uuid().not_null())
|
||||
.col(ColumnDef::new(CartGiftCard::GiftCardId).uuid().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
async fn up(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
Self::create_cart_discounts(m).await?;
|
||||
Self::create_cart_gift_cards(m).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(CartDiscount::CartDiscounts).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(CartGiftCard::CartGiftCards).to_owned())
|
||||
.await?;
|
||||
async fn down(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
self.drop_table(m, CartDiscount::CartDiscounts).await?;
|
||||
self.drop_table(m, CartGiftCard::CartGiftCards).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
impl Migration {
|
||||
/// ```sql
|
||||
/// CREATE TABLE cart_discounts
|
||||
/// (
|
||||
/// cart_id uuid NOT NULL,
|
||||
/// discount_id uuid NOT NULL
|
||||
/// );
|
||||
/// ```
|
||||
async fn create_cart_discounts(m: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
.if_not_exists()
|
||||
.table(CartDiscount::CartDiscounts)
|
||||
.col(CartDiscount::CartId.col().uuid().not_null())
|
||||
.col(CartDiscount::DiscountId.col().uuid().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_2col_idx(
|
||||
CartDiscount::CartDiscounts,
|
||||
CartDiscount::CartId,
|
||||
CartDiscount::DiscountId,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// ```sql
|
||||
/// CREATE TABLE cart_gift_cards
|
||||
/// (
|
||||
/// cart_id uuid NOT NULL,
|
||||
/// gift_card_id uuid NOT NULL
|
||||
/// );
|
||||
/// ```
|
||||
async fn create_cart_gift_cards(m: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
.table(CartGiftCard::CartGiftCards)
|
||||
.if_not_exists()
|
||||
.col(CartGiftCard::CartId.col().uuid().not_null())
|
||||
.col(CartGiftCard::GiftCardId.col().uuid().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_index(
|
||||
IndexCreateStatement::new()
|
||||
.table(CartGiftCard::CartGiftCards)
|
||||
.col(CartGiftCard::CartId)
|
||||
.col(CartGiftCard::GiftCardId)
|
||||
.name(&to_pk2_name(
|
||||
CartGiftCard::CartGiftCards,
|
||||
CartGiftCard::CartId,
|
||||
CartGiftCard::GiftCardId,
|
||||
))
|
||||
.primary()
|
||||
.if_not_exists()
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Iden, Clone, Copy)]
|
||||
enum CartDiscount {
|
||||
CartDiscounts,
|
||||
CartId,
|
||||
DiscountId,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
enum CartGiftCard {
|
||||
CartGiftCards,
|
||||
CartId,
|
||||
|
@ -3,7 +3,7 @@ use sea_orm_migration::prelude::*;
|
||||
use crate::sea_orm::Iterable;
|
||||
use crate::{
|
||||
auto_uuid_not_null, create_type, drop_type, to_fk_name, to_pk2_name, ts_def_now_not_null,
|
||||
DropTable, IntoColumnDef,
|
||||
CreateIndexExt, DropTable, IntoColumnDef,
|
||||
};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
@ -122,9 +122,11 @@ impl Migration {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
.table(Order::Orders)
|
||||
.if_not_exists()
|
||||
.col(auto_uuid_not_null!(Order::Id))
|
||||
.col(
|
||||
ColumnDef::new(Order::Status)
|
||||
Order::Status
|
||||
.col()
|
||||
.enumeration(
|
||||
crate::types::OrderStatus::OrderStatuses,
|
||||
crate::types::OrderStatus::iter().skip(1),
|
||||
@ -133,7 +135,8 @@ impl Migration {
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Order::FulfillmentStatus)
|
||||
Order::FulfillmentStatus
|
||||
.col()
|
||||
.enumeration(
|
||||
crate::types::OrderFulfillmentStatus::OrderFulfillmentStatuses,
|
||||
crate::types::OrderFulfillmentStatus::iter().take(1),
|
||||
@ -141,31 +144,32 @@ impl Migration {
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Order::PaymentStatus)
|
||||
Order::PaymentStatus
|
||||
.col()
|
||||
.enumeration(
|
||||
crate::types::OrderPaymentStatus::OrderPaymentStatuses,
|
||||
crate::types::OrderPaymentStatus::iter().take(1),
|
||||
)
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Order::DisplayId).uuid())
|
||||
.col(ColumnDef::new(Order::CartId).uuid())
|
||||
.col(ColumnDef::new(Order::CustomerId).uuid())
|
||||
.col(ColumnDef::new(Order::Email).uuid())
|
||||
.col(ColumnDef::new(Order::BillingAddressId).uuid())
|
||||
.col(ColumnDef::new(Order::ShippingAddressId).uuid())
|
||||
.col(ColumnDef::new(Order::RegionId).uuid())
|
||||
.col(ColumnDef::new(Order::CurrencyCode).uuid())
|
||||
.col(ColumnDef::new(Order::TaxRate).uuid())
|
||||
.col(ColumnDef::new(Order::CanceledAt).uuid())
|
||||
.col(ColumnDef::new(Order::CreatedAt).uuid())
|
||||
.col(ColumnDef::new(Order::UpdatedAt).uuid())
|
||||
.col(ColumnDef::new(Order::Metadata).uuid())
|
||||
.col(ColumnDef::new(Order::IdempotencyKey).uuid())
|
||||
.col(ColumnDef::new(Order::DraftOrderId).uuid())
|
||||
.col(ColumnDef::new(Order::NoNotification).uuid())
|
||||
.col(ColumnDef::new(Order::ExternalId).uuid())
|
||||
.col(ColumnDef::new(Order::SalesChannelId).uuid())
|
||||
.col(Order::DisplayId.col().uuid())
|
||||
.col(Order::CartId.col().uuid())
|
||||
.col(Order::CustomerId.col().uuid())
|
||||
.col(Order::Email.col().uuid())
|
||||
.col(Order::BillingAddressId.col().uuid())
|
||||
.col(Order::ShippingAddressId.col().uuid())
|
||||
.col(Order::RegionId.col().uuid())
|
||||
.col(Order::CurrencyCode.col().uuid())
|
||||
.col(Order::TaxRate.col().uuid())
|
||||
.col(Order::CanceledAt.col().uuid())
|
||||
.col(Order::CreatedAt.col().uuid())
|
||||
.col(Order::UpdatedAt.col().uuid())
|
||||
.col(Order::Metadata.col().uuid())
|
||||
.col(Order::IdempotencyKey.col().uuid())
|
||||
.col(Order::DraftOrderId.col().uuid())
|
||||
.col(Order::NoNotification.col().uuid())
|
||||
.col(Order::ExternalId.col().uuid())
|
||||
.col(Order::SalesChannelId.col().uuid())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
@ -183,11 +187,20 @@ impl Migration {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
.table(OrderDiscount::OrderDiscounts)
|
||||
.col(ColumnDef::new(OrderDiscount::OrderId).uuid().not_null())
|
||||
.col(ColumnDef::new(OrderDiscount::DiscountId).uuid().not_null())
|
||||
.if_not_exists()
|
||||
.col(OrderDiscount::OrderId.col().uuid().not_null())
|
||||
.col(OrderDiscount::DiscountId.col().uuid().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_2col_idx(
|
||||
OrderDiscount::OrderDiscounts,
|
||||
OrderDiscount::OrderId,
|
||||
OrderDiscount::DiscountId,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -216,22 +229,23 @@ impl Migration {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
.table(OrderEdit::OrderEdits)
|
||||
.if_not_exists()
|
||||
.col(auto_uuid_not_null!(OrderEdit::Id))
|
||||
.col(ts_def_now_not_null!(OrderEdit::CreatedAt))
|
||||
.col(ts_def_now_not_null!(OrderEdit::UpdatedAt))
|
||||
.col(ColumnDef::new(OrderEdit::OrderId).uuid().not_null())
|
||||
.col(ColumnDef::new(OrderEdit::InternalNote).string())
|
||||
.col(ColumnDef::new(OrderEdit::CreatedBy).uuid().not_null())
|
||||
.col(ColumnDef::new(OrderEdit::RequestedBy).uuid())
|
||||
.col(ColumnDef::new(OrderEdit::RequestedAt).timestamp())
|
||||
.col(ColumnDef::new(OrderEdit::ConfirmedBy).uuid())
|
||||
.col(ColumnDef::new(OrderEdit::ConfirmedAt).timestamp())
|
||||
.col(ColumnDef::new(OrderEdit::DeclinedBy).uuid())
|
||||
.col(ColumnDef::new(OrderEdit::DeclinedReason).string())
|
||||
.col(ColumnDef::new(OrderEdit::DeclinedAt).timestamp())
|
||||
.col(ColumnDef::new(OrderEdit::CanceledBy).uuid())
|
||||
.col(ColumnDef::new(OrderEdit::CanceledAt).timestamp())
|
||||
.col(ColumnDef::new(OrderEdit::PaymentCollectionId).uuid())
|
||||
.col(OrderEdit::OrderId.col().uuid().not_null())
|
||||
.col(OrderEdit::InternalNote.col().string())
|
||||
.col(OrderEdit::CreatedBy.col().uuid().not_null())
|
||||
.col(OrderEdit::RequestedBy.col().uuid())
|
||||
.col(OrderEdit::RequestedAt.col().timestamp())
|
||||
.col(OrderEdit::ConfirmedBy.col().uuid())
|
||||
.col(OrderEdit::ConfirmedAt.col().timestamp())
|
||||
.col(OrderEdit::DeclinedBy.col().uuid())
|
||||
.col(OrderEdit::DeclinedReason.col().string())
|
||||
.col(OrderEdit::DeclinedAt.col().timestamp())
|
||||
.col(OrderEdit::CanceledBy.col().uuid())
|
||||
.col(OrderEdit::CanceledAt.col().timestamp())
|
||||
.col(OrderEdit::PaymentCollectionId.col().uuid())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
@ -249,11 +263,20 @@ impl Migration {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
.table(OrderGiftCard::OrderGiftCards)
|
||||
.col(ColumnDef::new(OrderGiftCard::OrderId).uuid().not_null())
|
||||
.col(ColumnDef::new(OrderGiftCard::GiftCardId).uuid().not_null())
|
||||
.if_not_exists()
|
||||
.col(OrderGiftCard::OrderId.col().uuid().not_null())
|
||||
.col(OrderGiftCard::GiftCardId.col().uuid().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_2col_idx(
|
||||
OrderGiftCard::OrderGiftCards,
|
||||
OrderGiftCard::OrderId,
|
||||
OrderGiftCard::GiftCardId,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -421,31 +444,20 @@ impl Migration {
|
||||
Table::create()
|
||||
.table(PaymentCollectionPayment::PaymentCollectionPayments)
|
||||
.col(
|
||||
ColumnDef::new(PaymentCollectionPayment::PaymentCollectionId)
|
||||
.uuid()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(PaymentCollectionPayment::PaymentId)
|
||||
PaymentCollectionPayment::PaymentCollectionId
|
||||
.col()
|
||||
.uuid()
|
||||
.not_null(),
|
||||
)
|
||||
.col(PaymentCollectionPayment::PaymentId.col().uuid().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_index(
|
||||
IndexCreateStatement::new()
|
||||
.table(PaymentCollectionPayment::PaymentCollectionPayments)
|
||||
.col(PaymentCollectionPayment::PaymentCollectionId)
|
||||
.col(PaymentCollectionPayment::PaymentId)
|
||||
.primary()
|
||||
.name(&to_pk2_name(
|
||||
m.create_2col_idx(
|
||||
PaymentCollectionPayment::PaymentCollectionPayments,
|
||||
PaymentCollectionPayment::PaymentCollectionId,
|
||||
PaymentCollectionPayment::PaymentId,
|
||||
))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -494,18 +506,10 @@ impl Migration {
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_index(
|
||||
IndexCreateStatement::new()
|
||||
.table(PaymentCollectionSession::PaymentCollectionSessions)
|
||||
.col(PaymentCollectionSession::PaymentCollectionId)
|
||||
.col(PaymentCollectionSession::PaymentSessionId)
|
||||
.primary()
|
||||
.name(&to_pk2_name(
|
||||
m.create_2col_idx(
|
||||
PaymentCollectionSession::PaymentCollectionSessions,
|
||||
PaymentCollectionSession::PaymentCollectionId,
|
||||
PaymentCollectionSession::PaymentSessionId,
|
||||
))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
@ -589,7 +593,7 @@ impl Migration {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum Order {
|
||||
Orders,
|
||||
Id,
|
||||
@ -616,14 +620,14 @@ pub enum Order {
|
||||
SalesChannelId,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum OrderDiscount {
|
||||
OrderDiscounts,
|
||||
OrderId,
|
||||
DiscountId,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum OrderEdit {
|
||||
OrderEdits,
|
||||
Id,
|
||||
@ -644,14 +648,14 @@ pub enum OrderEdit {
|
||||
PaymentCollectionId,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum OrderGiftCard {
|
||||
OrderGiftCards,
|
||||
OrderId,
|
||||
GiftCardId,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum OrderItemChange {
|
||||
OrderItemChanges,
|
||||
Id,
|
||||
@ -664,7 +668,7 @@ pub enum OrderItemChange {
|
||||
LineItemId,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum Payment {
|
||||
Payments,
|
||||
Id,
|
||||
@ -702,21 +706,21 @@ pub enum PaymentCollection {
|
||||
CreatedBy,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum PaymentCollectionPayment {
|
||||
PaymentCollectionPayments,
|
||||
PaymentCollectionId,
|
||||
PaymentId,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum PaymentCollectionSession {
|
||||
PaymentCollectionSessions,
|
||||
PaymentCollectionId,
|
||||
PaymentSessionId,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
#[derive(Iden, Copy, Clone)]
|
||||
pub enum PaymentProvider {
|
||||
PaymentProviders,
|
||||
Id,
|
||||
|
@ -2,8 +2,8 @@ use sea_orm_migration::prelude::*;
|
||||
|
||||
use crate::constraint::Check;
|
||||
use crate::{
|
||||
auto_uuid_not_null, create_constraint, create_type, drop_type, to_fk_name, to_pk2_name,
|
||||
ts_def_now_not_null, AsIden,
|
||||
auto_uuid_not_null, create_type, drop_type, to_fk_name, to_pk2_name, ts_def_now_not_null,
|
||||
AsIden, CreateConstraint,
|
||||
};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
@ -55,20 +55,30 @@ impl Migration {
|
||||
/// );
|
||||
/// ```
|
||||
async fn create_line_items(&self, m: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
create_constraint(
|
||||
m,
|
||||
m.create_constraint(
|
||||
LineItem::LineItems,
|
||||
Check::lower_eq(LineItem::ShippedQuantity, LineItem::FulfilledQuantity),
|
||||
Check::less_eq(LineItem::ShippedQuantity, LineItem::FulfilledQuantity),
|
||||
)
|
||||
.await?;
|
||||
|
||||
create_constraint(
|
||||
m,
|
||||
m.create_constraint(
|
||||
LineItem::LineItems,
|
||||
Check::greater(LineItem::Quantity, 0.iden()),
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_constraint(
|
||||
LineItem::LineItems,
|
||||
Check::less_eq(LineItem::ReturnedQuantity, LineItem::Quantity),
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_constraint(
|
||||
LineItem::LineItems,
|
||||
Check::less_eq(LineItem::FulfilledQuantity, LineItem::Quantity),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
use crate::{auto_uuid_not_null, ts_def_now_not_null, IntoColumnDef};
|
||||
use crate::{auto_uuid_not_null, ts_def_now_not_null, DropTable, IntoColumnDef};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
@ -14,13 +14,8 @@ impl MigrationTrait for Migration {
|
||||
}
|
||||
|
||||
async fn down(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
m.drop_table(Table::drop().table(GiftCard::GiftCards).to_owned())
|
||||
.await?;
|
||||
m.drop_table(
|
||||
Table::drop()
|
||||
.table(GiftCardTransaction::GiftCardTransactions)
|
||||
.to_owned(),
|
||||
)
|
||||
self.drop_table(m, GiftCard::GiftCards).await?;
|
||||
self.drop_table(m, GiftCardTransaction::GiftCardTransactions)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
|
@ -1,78 +1,68 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
use sea_query::expr::SimpleExpr;
|
||||
|
||||
use crate::{auto_uuid_not_null, ts_def_now_not_null, DropTable, IntoColumnDef};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
Self::create_batch_jobs(manager).await
|
||||
}
|
||||
|
||||
async fn down(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
self.drop_table(m, BatchJob::BatchJobs).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Migration {
|
||||
/// ```sql
|
||||
/// CREATE TABLE batch_jobs
|
||||
/// (
|
||||
/// id uuid NOT NULL,
|
||||
/// type text NOT NULL,
|
||||
/// created_by character varying,
|
||||
/// context jsonb,
|
||||
/// result jsonb,
|
||||
/// dry_run boolean DEFAULT false NOT NULL,
|
||||
/// created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// pre_processed_at timestamp with time zone,
|
||||
/// confirmed_at timestamp with time zone,
|
||||
/// processing_at timestamp with time zone,
|
||||
/// completed_at timestamp with time zone,
|
||||
/// failed_at timestamp with time zone,
|
||||
/// canceled_at timestamp with time zone,
|
||||
/// updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// deleted_at timestamp with time zone
|
||||
/// );
|
||||
/// ```
|
||||
async fn create_batch_jobs(manager: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
// id character varying NOT NULL,
|
||||
// type text NOT NULL,
|
||||
// created_by character varying,
|
||||
// context jsonb,
|
||||
// result jsonb,
|
||||
// dry_run boolean DEFAULT false NOT NULL,
|
||||
// created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
// pre_processed_at timestamp with time zone,
|
||||
// confirmed_at timestamp with time zone,
|
||||
// processing_at timestamp with time zone,
|
||||
// completed_at timestamp with time zone,
|
||||
// failed_at timestamp with time zone,
|
||||
// canceled_at timestamp with time zone,
|
||||
// updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
// deleted_at timestamp with time zone
|
||||
.table(BatchJob::BatchJobs)
|
||||
.col(
|
||||
ColumnDef::new(BatchJob::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.default(SimpleExpr::Custom("public.uuid_generate_v4()".into()))
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(BatchJob::BatchType).string().not_null())
|
||||
.col(ColumnDef::new(BatchJob::CreatedBy).uuid())
|
||||
.col(ColumnDef::new(BatchJob::Context).json_binary())
|
||||
.col(ColumnDef::new(BatchJob::Result).json_binary())
|
||||
.col(
|
||||
ColumnDef::new(BatchJob::DryRun)
|
||||
.boolean()
|
||||
.default(false)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(BatchJob::CreatedAt)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(BatchJob::PreProcessedAt).timestamp())
|
||||
.col(ColumnDef::new(BatchJob::ConfirmedAt).timestamp())
|
||||
.col(ColumnDef::new(BatchJob::ProcessingAt).timestamp())
|
||||
.col(ColumnDef::new(BatchJob::CompletedAt).timestamp())
|
||||
.col(ColumnDef::new(BatchJob::FailedAt).timestamp())
|
||||
.col(ColumnDef::new(BatchJob::CanceledAt).timestamp())
|
||||
.col(
|
||||
ColumnDef::new(BatchJob::UpdatedAt)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(BatchJob::DeletedAt).timestamp())
|
||||
.col(auto_uuid_not_null!(BatchJob::Id))
|
||||
.col(BatchJob::BatchType.col().string().not_null())
|
||||
.col(BatchJob::CreatedBy.col().uuid())
|
||||
.col(BatchJob::Context.col().json_binary())
|
||||
.col(BatchJob::Result.col().json_binary())
|
||||
.col(BatchJob::DryRun.col().boolean().default(false).not_null())
|
||||
.col(ts_def_now_not_null!(BatchJob::CreatedAt))
|
||||
.col(BatchJob::PreProcessedAt.col().timestamp())
|
||||
.col(BatchJob::ConfirmedAt.col().timestamp())
|
||||
.col(BatchJob::ProcessingAt.col().timestamp())
|
||||
.col(BatchJob::CompletedAt.col().timestamp())
|
||||
.col(BatchJob::FailedAt.col().timestamp())
|
||||
.col(BatchJob::CanceledAt.col().timestamp())
|
||||
.col(ts_def_now_not_null!(BatchJob::UpdatedAt))
|
||||
.col(BatchJob::DeletedAt.col().timestamp())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(BatchJob::BatchJobs).to_owned())
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
pub use sea_orm_migration::prelude::*;
|
||||
|
||||
pub mod carts;
|
||||
@ -16,238 +14,8 @@ pub mod checkouts;
|
||||
pub use checkouts::*;
|
||||
pub mod shipping;
|
||||
pub use shipping::*;
|
||||
mod sea_ext;
|
||||
pub use sea_ext::*;
|
||||
pub mod types;
|
||||
|
||||
pub use types::*;
|
||||
|
||||
use crate::constraint::Check;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! ts_def_now_not_null {
|
||||
($identifier: expr) => {
|
||||
ColumnDef::new($identifier)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null()
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! auto_uuid_not_null {
|
||||
($identifier: expr) => {
|
||||
ColumnDef::new($identifier)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.default(SimpleExpr::Custom("public.uuid_generate_v4()".into()))
|
||||
.primary_key()
|
||||
};
|
||||
}
|
||||
|
||||
// #[macro_export]
|
||||
// macro_rules! col {
|
||||
// ($name: expr $ty: expr) => {
|
||||
// ColumnDef::new($name).$ty()
|
||||
// };
|
||||
// ($name: expr auto uuid) => {
|
||||
// $crate::auto_uuid_not_null!($name)
|
||||
// };
|
||||
// ($name: expr $ty: expr default $value: expr) => {
|
||||
// $crate::col!($name $ty).default($value)
|
||||
// };
|
||||
// }
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait DropTable {
|
||||
async fn drop_table<I: Iden + 'static>(
|
||||
&self,
|
||||
manager: &SchemaManager<'_>,
|
||||
identifier: I,
|
||||
) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(identifier).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MigrationTrait> DropTable for T {}
|
||||
|
||||
pub trait IntoColumnDef: IntoIden {
|
||||
fn col(self) -> ColumnDef
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
ColumnDef::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoIden> IntoColumnDef for T {}
|
||||
|
||||
pub fn to_pk2_name<T1: IntoIden, C1: IntoIden, C2: IntoIden>(t1: T1, c1: C1, c2: C2) -> String {
|
||||
let t1 = to_snake(t1.into_iden().to_string());
|
||||
let c1 = to_snake(c1.into_iden().to_string());
|
||||
let c2 = to_snake(c2.into_iden().to_string());
|
||||
|
||||
format!("pk_{}_{}_{}", t1, c1, c2)
|
||||
}
|
||||
|
||||
pub fn to_fk_name<T1: IntoIden, C1: IntoIden, T2: IntoIden, C2: IntoIden>(
|
||||
t1: T1,
|
||||
c1: C1,
|
||||
t2: T2,
|
||||
c2: C2,
|
||||
) -> String {
|
||||
let t1 = to_snake(t1.into_iden().to_string());
|
||||
let c1 = to_snake(c1.into_iden().to_string());
|
||||
let t2 = to_snake(t2.into_iden().to_string());
|
||||
let c2 = to_snake(c2.into_iden().to_string());
|
||||
|
||||
format!("fk_{}_{}_{}_{}", t1, c1, t2, c2)
|
||||
}
|
||||
|
||||
fn to_snake(s: String) -> String {
|
||||
s.chars().fold(String::new(), |mut m, c| {
|
||||
if c.is_ascii_uppercase() {
|
||||
m.push('_');
|
||||
}
|
||||
m.push(c.to_ascii_lowercase());
|
||||
m
|
||||
})
|
||||
}
|
||||
|
||||
pub mod constraint {
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use crate::{Constraint, Iden};
|
||||
|
||||
pub enum Check {
|
||||
Lower(Box<dyn Iden>, Box<dyn Iden>),
|
||||
LowerEq(Box<dyn Iden>, Box<dyn Iden>),
|
||||
Eq(Box<dyn Iden>, Box<dyn Iden>),
|
||||
GreaterEq(Box<dyn Iden>, Box<dyn Iden>),
|
||||
Greater(Box<dyn Iden>, Box<dyn Iden>),
|
||||
Or(Box<Check>, Box<Check>),
|
||||
}
|
||||
|
||||
impl Check {
|
||||
pub fn or(self, r: Check) -> Check {
|
||||
Check::Or(Box::new(self), Box::new(r))
|
||||
}
|
||||
|
||||
pub fn constraint(self) -> Constraint {
|
||||
Constraint::Check(self)
|
||||
}
|
||||
|
||||
pub fn to_name(&self) -> String {
|
||||
match self {
|
||||
Check::Lower(l, r) => format!("{}_lw_{}", l.to_string(), r.to_string()),
|
||||
Check::LowerEq(l, r) => format!("{}_le_{}", l.to_string(), r.to_string()),
|
||||
Check::Eq(l, r) => format!("{}_eq_{}", l.to_string(), r.to_string()),
|
||||
Check::GreaterEq(l, r) => format!("{}_ge_{}", l.to_string(), r.to_string()),
|
||||
Check::Greater(l, r) => format!("{}_g_{}", l.to_string(), r.to_string()),
|
||||
Check::Or(l, r) => format!("{}_or_{}", l.to_name(), r.to_name()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Check {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Check::Lower(l, r) => {
|
||||
f.write_fmt(format_args!("{} < {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::LowerEq(l, r) => {
|
||||
f.write_fmt(format_args!("{} <= {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::Eq(l, r) => {
|
||||
f.write_fmt(format_args!("{} = {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::GreaterEq(l, r) => {
|
||||
f.write_fmt(format_args!("{} >= {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::Greater(l, r) => {
|
||||
f.write_fmt(format_args!("{} > {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::Or(l, r) => f.write_fmt(format_args!("({l}) OR ({r})")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Check {
|
||||
pub fn lower<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::Lower(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn lower_eq<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::LowerEq(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn eq<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::Eq(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn greater_eq<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::GreaterEq(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn greater<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::Greater(Box::new(l), Box::new(r))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CheckUSize(usize);
|
||||
|
||||
impl Iden for CheckUSize {
|
||||
fn unquoted(&self, s: &mut dyn Write) {
|
||||
s.write_str(&format!("{}", self.0)).ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AsIden<I: Iden> {
|
||||
fn iden(self) -> I;
|
||||
}
|
||||
|
||||
impl AsIden<CheckUSize> for usize {
|
||||
fn iden(self) -> CheckUSize {
|
||||
CheckUSize(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Constraint {
|
||||
Check(Check),
|
||||
}
|
||||
|
||||
impl Constraint {
|
||||
fn to_name(&self) -> String {
|
||||
match self {
|
||||
Constraint::Check(check) => format!("ck_{}", check.to_name()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Check> for Constraint {
|
||||
fn from(value: Check) -> Self {
|
||||
Self::Check(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Constraint {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Constraint::Check(check) => f.write_fmt(format_args!("CHECK {check}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_constraint<T: Iden, C: Into<Constraint>>(
|
||||
m: &SchemaManager<'_>,
|
||||
table: T,
|
||||
c: C,
|
||||
) -> Result<(), DbErr> {
|
||||
let c = c.into();
|
||||
m.get_connection()
|
||||
.execute_unprepared(&format!(
|
||||
"ALTER TABLE {} ADD CONSTRAINT {} {}",
|
||||
table.to_string(),
|
||||
c.to_name(),
|
||||
c
|
||||
))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -3,146 +3,120 @@ use sea_orm_migration::sea_orm::Statement;
|
||||
use sea_query::expr::SimpleExpr;
|
||||
|
||||
use crate::sea_orm::DatabaseBackend;
|
||||
use crate::{auto_uuid_not_null, ts_def_now_not_null, DropTable, IntoColumnDef};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.get_connection()
|
||||
async fn up(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
m.get_connection()
|
||||
.execute(Statement::from_string(
|
||||
DatabaseBackend::Postgres,
|
||||
"CREATE EXTENSION \"uuid-ossp\"".to_string(),
|
||||
))
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_table(
|
||||
Self::create_analytics_configs(m).await?;
|
||||
Self::create_addresses(m).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
self.drop_table(m, Address::Addresses).await?;
|
||||
self.drop_table(m, AnalyticsConfig::AnalyticsConfigs)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Migration {
|
||||
/// ```sql
|
||||
/// CREATE TABLE analytics_configs
|
||||
/// (
|
||||
/// id uuid NOT NULL,
|
||||
/// created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// deleted_at timestamp with time zone,
|
||||
/// user_id uuid NOT NULL,
|
||||
/// opt_out boolean DEFAULT false NOT NULL,
|
||||
/// anonymize boolean DEFAULT false NOT NULL
|
||||
/// );
|
||||
/// ```
|
||||
async fn create_analytics_configs(m: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
// id character varying NOT NULL,
|
||||
// created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
// updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
// deleted_at timestamp with time zone,
|
||||
// user_id character varying NOT NULL,
|
||||
// opt_out boolean DEFAULT false NOT NULL,
|
||||
// anonymize boolean DEFAULT false NOT NULL
|
||||
.table(AnalyticsConfig::AnalyticsConfigs)
|
||||
.col(
|
||||
ColumnDef::new(AnalyticsConfig::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.default(SimpleExpr::Custom("uuid_generate_v4()".into()))
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(AnalyticsConfig::CreatedAt)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(AnalyticsConfig::UpdatedAt)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(AnalyticsConfig::DeletedAt).timestamp())
|
||||
.col(auto_uuid_not_null!(AnalyticsConfig::Id))
|
||||
.col(ts_def_now_not_null!(AnalyticsConfig::CreatedAt))
|
||||
.col(ts_def_now_not_null!(AnalyticsConfig::UpdatedAt))
|
||||
.col(AnalyticsConfig::DeletedAt.col().timestamp())
|
||||
.col(ColumnDef::new(AnalyticsConfig::UserId).uuid().not_null())
|
||||
.col(
|
||||
ColumnDef::new(AnalyticsConfig::OptOut)
|
||||
AnalyticsConfig::OptOut
|
||||
.col()
|
||||
.boolean()
|
||||
.default(false)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(AnalyticsConfig::Anonymize)
|
||||
AnalyticsConfig::Anonymize
|
||||
.col()
|
||||
.boolean()
|
||||
.default(false)
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
// id character varying NOT NULL,
|
||||
// customer_id character varying,
|
||||
// company character varying,
|
||||
// first_name character varying,
|
||||
// last_name character varying,
|
||||
// address_1 character varying,
|
||||
// address_2 character varying,
|
||||
// city character varying,
|
||||
// country_code character varying,
|
||||
// province character varying,
|
||||
// postal_code character varying,
|
||||
// phone character varying,
|
||||
// created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
// updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
// deleted_at timestamp with time zone,
|
||||
// metadata jsonb
|
||||
.table(Address::Addresses)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Address::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.default(SimpleExpr::Custom("uuid_generate_v4()".into()))
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Address::CustomerId).uuid())
|
||||
.col(ColumnDef::new(Address::Company).string())
|
||||
.col(ColumnDef::new(Address::FirstName).string())
|
||||
.col(ColumnDef::new(Address::LastName).string())
|
||||
.col(ColumnDef::new(Address::Address1).string())
|
||||
.col(ColumnDef::new(Address::Address2).string())
|
||||
.col(ColumnDef::new(Address::City).string())
|
||||
.col(ColumnDef::new(Address::CountryCode).string())
|
||||
.col(ColumnDef::new(Address::Province).string())
|
||||
.col(ColumnDef::new(Address::PostalCode).string())
|
||||
.col(ColumnDef::new(Address::Phone).string())
|
||||
.col(
|
||||
ColumnDef::new(Address::CreatedAt)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Address::UpdatedAt)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Address::DeletedAt).timestamp())
|
||||
.col(ColumnDef::new(Address::Metadata).json_binary())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Address::Addresses).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(
|
||||
Table::drop()
|
||||
.table(AnalyticsConfig::AnalyticsConfigs)
|
||||
/// ```sql
|
||||
/// CREATE TABLE addresses
|
||||
/// (
|
||||
/// id uuid NOT NULL,
|
||||
/// customer_id uuid,
|
||||
/// company character varying,
|
||||
/// first_name character varying,
|
||||
/// last_name character varying,
|
||||
/// address_1 character varying,
|
||||
/// address_2 character varying,
|
||||
/// city character varying,
|
||||
/// country_code character varying,
|
||||
/// province character varying,
|
||||
/// postal_code character varying,
|
||||
/// phone character varying,
|
||||
/// created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
/// deleted_at timestamp with time zone,
|
||||
/// metadata jsonb
|
||||
/// );
|
||||
/// ```
|
||||
async fn create_addresses(m: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
.table(Address::Addresses)
|
||||
.if_not_exists()
|
||||
.col(auto_uuid_not_null!(Address::Id))
|
||||
.col(Address::CustomerId.col().uuid())
|
||||
.col(Address::Company.col().string())
|
||||
.col(Address::FirstName.col().string())
|
||||
.col(Address::LastName.col().string())
|
||||
.col(Address::Address1.col().string())
|
||||
.col(Address::Address2.col().string())
|
||||
.col(Address::City.col().string())
|
||||
.col(Address::CountryCode.col().string())
|
||||
.col(Address::Province.col().string())
|
||||
.col(Address::PostalCode.col().string())
|
||||
.col(Address::Phone.col().string())
|
||||
.col(ts_def_now_not_null!(Address::CreatedAt))
|
||||
.col(ts_def_now_not_null!(Address::UpdatedAt))
|
||||
.col(Address::DeletedAt.col().timestamp())
|
||||
.col(Address::Metadata.col().json_binary())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.get_connection()
|
||||
.execute(Statement::from_string(
|
||||
DatabaseBackend::Postgres,
|
||||
"DROP SCHEMA jobs".to_string(),
|
||||
))
|
||||
.await?;
|
||||
Ok(())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ use sea_query::expr::SimpleExpr;
|
||||
use crate::types::{
|
||||
ClaimItemReason, ClaimOrderFulfillmentStatus, ClaimOrderPaymentStatus, ClaimOrderType,
|
||||
};
|
||||
use crate::{auto_uuid_not_null, ts_def_now_not_null};
|
||||
use crate::{auto_uuid_not_null, ts_def_now_not_null, DropTable, IntoColumnDef};
|
||||
|
||||
/// ```sql
|
||||
/// CREATE TABLE claim_images
|
||||
@ -83,22 +83,12 @@ impl MigrationTrait for Migration {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(ClaimImage::ClaimImages).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(ClaimItem::ClaimItems).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(ClaimItemTag::ClaimItemTags).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(ClaimOrder::ClaimOrders).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(ClaimTag::ClaimTags).to_owned())
|
||||
.await?;
|
||||
async fn down(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
self.drop_table(m, ClaimImage::ClaimImages).await?;
|
||||
self.drop_table(m, ClaimItem::ClaimItems).await?;
|
||||
self.drop_table(m, ClaimItemTag::ClaimItemTags).await?;
|
||||
self.drop_table(m, ClaimOrder::ClaimOrders).await?;
|
||||
self.drop_table(m, ClaimTag::ClaimTags).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -116,11 +106,19 @@ impl Migration {
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(ClaimItemTag::ClaimItemTags)
|
||||
.col(ColumnDef::new(ClaimItemTag::ItemId).uuid().not_null())
|
||||
.col(ColumnDef::new(ClaimItemTag::TagId).uuid().not_null())
|
||||
.col(ClaimItemTag::ItemId.col().uuid().not_null())
|
||||
.col(ClaimItemTag::TagId.col().uuid().not_null())
|
||||
.primary_key(
|
||||
IndexCreateStatement::new()
|
||||
.table(ClaimItemTag::ClaimItemTags)
|
||||
.col(ClaimItemTag::ItemId)
|
||||
.col(ClaimItemTag::TagId)
|
||||
.primary(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// ```sql
|
||||
@ -145,23 +143,24 @@ impl Migration {
|
||||
Table::create()
|
||||
.table(ClaimItem::ClaimItems)
|
||||
.col(auto_uuid_not_null!(ClaimItem::Id))
|
||||
.col(ColumnDef::new(ClaimItem::ClaimOrderId).uuid().not_null())
|
||||
.col(ColumnDef::new(ClaimItem::ItemId).uuid().not_null())
|
||||
.col(ColumnDef::new(ClaimItem::VariantId).uuid().not_null())
|
||||
.col(ClaimItem::ClaimOrderId.col().uuid().not_null())
|
||||
.col(ClaimItem::ItemId.col().uuid().not_null())
|
||||
.col(ClaimItem::VariantId.col().uuid().not_null())
|
||||
.col(
|
||||
ColumnDef::new(ClaimItem::Reason)
|
||||
ClaimItem::Reason
|
||||
.col()
|
||||
.enumeration(
|
||||
ClaimItemReason::ClaimItemReasons,
|
||||
ClaimItemReason::iter().skip(1),
|
||||
)
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(ClaimItem::Note).string())
|
||||
.col(ColumnDef::new(ClaimItem::Quantity).integer().not_null())
|
||||
.col(ClaimItem::Note.col().string())
|
||||
.col(ClaimItem::Quantity.col().integer().not_null())
|
||||
.col(ts_def_now_not_null!(ClaimItem::CreatedAt))
|
||||
.col(ts_def_now_not_null!(ClaimItem::UpdatedAt))
|
||||
.col(ColumnDef::new(ClaimItem::DeletedAt).timestamp())
|
||||
.col(ColumnDef::new(ClaimItem::Metadata).json_binary())
|
||||
.col(ClaimItem::DeletedAt.col().timestamp())
|
||||
.col(ClaimItem::Metadata.col().json_binary())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
@ -185,12 +184,12 @@ impl Migration {
|
||||
Table::create()
|
||||
.table(ClaimImage::ClaimImages)
|
||||
.col(auto_uuid_not_null!(ClaimImage::Id))
|
||||
.col(ColumnDef::new(ClaimImage::ClaimItemId).uuid().not_null())
|
||||
.col(ColumnDef::new(ClaimImage::Url).string().not_null())
|
||||
.col(ClaimImage::ClaimItemId.col().uuid().not_null())
|
||||
.col(ClaimImage::Url.col().string().not_null())
|
||||
.col(ts_def_now_not_null!(ClaimImage::CreatedAt))
|
||||
.col(ts_def_now_not_null!(ClaimImage::UpdatedAt))
|
||||
.col(ColumnDef::new(ClaimImage::DeletedAt).string())
|
||||
.col(ColumnDef::new(ClaimImage::Metadata).json_binary())
|
||||
.col(ClaimImage::DeletedAt.col().string())
|
||||
.col(ClaimImage::Metadata.col().json_binary())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
@ -222,7 +221,8 @@ impl Migration {
|
||||
.table(ClaimOrder::ClaimOrders)
|
||||
.col(auto_uuid_not_null!(ClaimOrder::Id))
|
||||
.col(
|
||||
ColumnDef::new(ClaimOrder::PaymentStatus)
|
||||
ClaimOrder::PaymentStatus
|
||||
.col()
|
||||
.enumeration(
|
||||
ClaimOrderPaymentStatus::ClaimOrderPaymentStatuses,
|
||||
ClaimOrderPaymentStatus::iter().skip(1),
|
||||
@ -231,7 +231,8 @@ impl Migration {
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(ClaimOrder::FulfillmentStatus)
|
||||
ClaimOrder::FulfillmentStatus
|
||||
.col()
|
||||
.enumeration(
|
||||
ClaimOrderFulfillmentStatus::ClaimOrderFulfillmentStatuses,
|
||||
ClaimOrderFulfillmentStatus::iter().skip(1),
|
||||
@ -240,23 +241,24 @@ impl Migration {
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(ClaimOrder::ClaimOrderType)
|
||||
ClaimOrder::ClaimOrderType
|
||||
.col()
|
||||
.enumeration(
|
||||
ClaimOrderType::ClaimOrderTypes,
|
||||
ClaimOrderType::iter().skip(1),
|
||||
)
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(ClaimOrder::OrderId).uuid().not_null())
|
||||
.col(ColumnDef::new(ClaimOrder::ShippingAddressId).uuid())
|
||||
.col(ColumnDef::new(ClaimOrder::RefundAmount).integer())
|
||||
.col(ColumnDef::new(ClaimOrder::CanceledAt).timestamp())
|
||||
.col(ClaimOrder::OrderId.col().uuid().not_null())
|
||||
.col(ClaimOrder::ShippingAddressId.col().uuid())
|
||||
.col(ClaimOrder::RefundAmount.col().integer())
|
||||
.col(ClaimOrder::CanceledAt.col().timestamp())
|
||||
.col(ts_def_now_not_null!(ClaimOrder::CreatedAt))
|
||||
.col(ts_def_now_not_null!(ClaimOrder::UpdatedAt))
|
||||
.col(ColumnDef::new(ClaimOrder::DeletedAt).timestamp())
|
||||
.col(ColumnDef::new(ClaimOrder::Metadata).json_binary())
|
||||
.col(ColumnDef::new(ClaimOrder::IdempotencyKey).uuid())
|
||||
.col(ColumnDef::new(ClaimOrder::NoNotification).boolean())
|
||||
.col(ClaimOrder::DeletedAt.col().timestamp())
|
||||
.col(ClaimOrder::Metadata.col().json_binary())
|
||||
.col(ClaimOrder::IdempotencyKey.col().uuid())
|
||||
.col(ClaimOrder::NoNotification.col().boolean())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
@ -279,11 +281,11 @@ impl Migration {
|
||||
Table::create()
|
||||
.table(ClaimTag::ClaimTags)
|
||||
.col(auto_uuid_not_null!(ClaimTag::Id))
|
||||
.col(ColumnDef::new(ClaimTag::Value).string())
|
||||
.col(ClaimTag::Value.col().string())
|
||||
.col(ts_def_now_not_null!(ClaimTag::CreatedAt))
|
||||
.col(ts_def_now_not_null!(ClaimTag::UpdatedAt))
|
||||
.col(ColumnDef::new(ClaimTag::DeletedAt).timestamp())
|
||||
.col(ColumnDef::new(ClaimTag::Metadata).json_binary())
|
||||
.col(ClaimTag::DeletedAt.col().timestamp())
|
||||
.col(ClaimTag::Metadata.col().json_binary())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
|
@ -1,7 +1,7 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
use sea_query::expr::SimpleExpr;
|
||||
|
||||
use crate::{auto_uuid_not_null, ts_def_now_not_null};
|
||||
use crate::{auto_uuid_not_null, ts_def_now_not_null, DropTable, IntoColumnDef};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
@ -16,12 +16,9 @@ impl MigrationTrait for Migration {
|
||||
}
|
||||
|
||||
async fn down(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||
m.drop_table(Table::drop().table(Country::Countries).to_owned())
|
||||
.await?;
|
||||
m.drop_table(Table::drop().table(Currency::Currencies).to_owned())
|
||||
.await?;
|
||||
m.drop_table(Table::drop().table(Currency::Currencies).to_owned())
|
||||
.await?;
|
||||
self.drop_table(m, Country::Countries).await?;
|
||||
self.drop_table(m, Currency::Currencies).await?;
|
||||
self.drop_table(m, Currency::Currencies).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -44,12 +41,12 @@ impl Migration {
|
||||
Table::create()
|
||||
.table(Country::Countries)
|
||||
.col(auto_uuid_not_null!(Country::Id))
|
||||
.col(ColumnDef::new(Country::Iso2).char_len(2).not_null())
|
||||
.col(ColumnDef::new(Country::Iso3).char_len(3).not_null())
|
||||
.col(ColumnDef::new(Country::NumCode).integer().not_null())
|
||||
.col(ColumnDef::new(Country::Name).string().not_null())
|
||||
.col(ColumnDef::new(Country::DisplayName).string().not_null())
|
||||
.col(ColumnDef::new(Country::RegionId).uuid())
|
||||
.col(Country::Iso2.col().char_len(2).not_null())
|
||||
.col(Country::Iso3.col().char_len(3).not_null())
|
||||
.col(Country::NumCode.col().integer().not_null())
|
||||
.col(Country::Name.col().string().not_null())
|
||||
.col(Country::DisplayName.col().string().not_null())
|
||||
.col(Country::RegionId.col().uuid())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
@ -83,10 +80,10 @@ impl Migration {
|
||||
m.create_table(
|
||||
Table::create()
|
||||
.table(Currency::Currencies)
|
||||
.col(ColumnDef::new(Currency::Code).string().not_null())
|
||||
.col(ColumnDef::new(Currency::Symbol).string().not_null())
|
||||
.col(ColumnDef::new(Currency::SymbolNative).string().not_null())
|
||||
.col(ColumnDef::new(Currency::Name).string().not_null())
|
||||
.col(Currency::Code.col().string().not_null())
|
||||
.col(Currency::Symbol.col().string().not_null())
|
||||
.col(Currency::SymbolNative.col().string().not_null())
|
||||
.col(Currency::Name.col().string().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
@ -94,6 +91,7 @@ impl Migration {
|
||||
IndexCreateStatement::new()
|
||||
.table(Currency::Currencies)
|
||||
.col(Currency::Code)
|
||||
.primary()
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
@ -120,27 +118,29 @@ impl Migration {
|
||||
Table::create()
|
||||
.table(Region::Regions)
|
||||
.col(auto_uuid_not_null!(Region::Id))
|
||||
.col(ColumnDef::new(Region::Name).string().not_null())
|
||||
.col(ColumnDef::new(Region::CurrencyCode).string().not_null())
|
||||
.col(ColumnDef::new(Region::TaxRate).double().not_null())
|
||||
.col(ColumnDef::new(Region::TaxCode).string().not_null())
|
||||
.col(Region::Name.col().string().not_null())
|
||||
.col(Region::CurrencyCode.col().string().not_null())
|
||||
.col(Region::TaxRate.col().double().not_null())
|
||||
.col(Region::TaxCode.col().string().not_null())
|
||||
.col(ts_def_now_not_null!(Region::CreatedAt))
|
||||
.col(ts_def_now_not_null!(Region::UpdatedAt))
|
||||
.col(ColumnDef::new(Region::DeletedAt).timestamp())
|
||||
.col(ColumnDef::new(Region::Metadata).json_binary())
|
||||
.col(Region::DeletedAt.col().timestamp())
|
||||
.col(Region::Metadata.col().json_binary())
|
||||
.col(
|
||||
ColumnDef::new(Region::GiftCardsTaxable)
|
||||
Region::GiftCardsTaxable
|
||||
.col()
|
||||
.boolean()
|
||||
.default(true)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Region::AutomaticTaxes)
|
||||
Region::AutomaticTaxes
|
||||
.col()
|
||||
.boolean()
|
||||
.default(true)
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Region::TaxProviderId).uuid().not_null())
|
||||
.col(Region::TaxProviderId.col().uuid().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
338
migration/src/sea_ext/mod.rs
Normal file
338
migration/src/sea_ext/mod.rs
Normal file
@ -0,0 +1,338 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
use crate::constraint::Check;
|
||||
use crate::DbErr;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! ts_def_now_not_null {
|
||||
($identifier: expr) => {
|
||||
ColumnDef::new($identifier)
|
||||
.timestamp()
|
||||
.default(SimpleExpr::Custom("now()".into()))
|
||||
.not_null()
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! auto_uuid_not_null {
|
||||
($identifier: expr) => {
|
||||
ColumnDef::new($identifier)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.default(SimpleExpr::Custom("public.uuid_generate_v4()".into()))
|
||||
.primary_key()
|
||||
};
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait DropTable {
|
||||
async fn drop_table<I: Iden + 'static>(
|
||||
&self,
|
||||
manager: &SchemaManager<'_>,
|
||||
identifier: I,
|
||||
) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(identifier).if_exists().to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MigrationTrait> DropTable for T {}
|
||||
|
||||
pub trait IntoColumnDef: IntoIden {
|
||||
fn col(self) -> ColumnDef
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
ColumnDef::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoIden> IntoColumnDef for T {}
|
||||
|
||||
#[async_trait]
|
||||
pub trait CreateIndexExt {
|
||||
async fn create_2col_idx<T, C1, C2>(&self, table: T, col1: C1, col2: C2) -> Result<(), DbErr>
|
||||
where
|
||||
T: IntoIden + Copy + 'static + Sync + Send,
|
||||
C1: IntoIden + Copy + 'static + Sync + Send,
|
||||
C2: IntoIden + Copy + 'static + Sync + Send;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl CreateIndexExt for SchemaManager<'_> {
|
||||
async fn create_2col_idx<T, C1, C2>(&self, table: T, col1: C1, col2: C2) -> Result<(), DbErr>
|
||||
where
|
||||
T: IntoIden + Copy + 'static + Sync + Send,
|
||||
C1: IntoIden + Copy + 'static + Sync + Send,
|
||||
C2: IntoIden + Copy + 'static + Sync + Send,
|
||||
{
|
||||
self.create_index(
|
||||
IndexCreateStatement::new()
|
||||
.table(table)
|
||||
.col(col1)
|
||||
.col(col2)
|
||||
.name(&to_pk2_name(table, col1, col2))
|
||||
.primary()
|
||||
.if_not_exists()
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_pk2_name<T1: IntoIden, C1: IntoIden, C2: IntoIden>(t1: T1, c1: C1, c2: C2) -> String {
|
||||
let t1 = to_snake(t1.into_iden().to_string());
|
||||
let c1 = to_snake(c1.into_iden().to_string());
|
||||
let c2 = to_snake(c2.into_iden().to_string());
|
||||
|
||||
format!("pk_{}_{}_{}", t1, c1, c2)
|
||||
}
|
||||
|
||||
pub fn to_fk_name<T1: IntoIden, C1: IntoIden, T2: IntoIden, C2: IntoIden>(
|
||||
t1: T1,
|
||||
c1: C1,
|
||||
t2: T2,
|
||||
c2: C2,
|
||||
) -> String {
|
||||
let t1 = to_snake(t1.into_iden().to_string());
|
||||
let c1 = to_snake(c1.into_iden().to_string());
|
||||
let t2 = to_snake(t2.into_iden().to_string());
|
||||
let c2 = to_snake(c2.into_iden().to_string());
|
||||
|
||||
format!("fk_{}_{}_{}_{}", t1, c1, t2, c2)
|
||||
}
|
||||
|
||||
fn to_snake(s: String) -> String {
|
||||
s.chars().fold(String::new(), |mut m, c| {
|
||||
if c.is_ascii_uppercase() {
|
||||
m.push('_');
|
||||
}
|
||||
m.push(c.to_ascii_lowercase());
|
||||
m
|
||||
})
|
||||
}
|
||||
|
||||
pub mod constraint {
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use crate::{Constraint, Iden};
|
||||
|
||||
pub enum Check {
|
||||
Lower(Box<dyn Iden>, Box<dyn Iden>),
|
||||
LowerEq(Box<dyn Iden>, Box<dyn Iden>),
|
||||
Eq(Box<dyn Iden>, Box<dyn Iden>),
|
||||
GreaterEq(Box<dyn Iden>, Box<dyn Iden>),
|
||||
Greater(Box<dyn Iden>, Box<dyn Iden>),
|
||||
NotNull(Box<dyn Iden>),
|
||||
Or(Box<Check>, Box<Check>),
|
||||
}
|
||||
|
||||
impl std::ops::BitOr for Check {
|
||||
type Output = Check;
|
||||
|
||||
fn bitor(self, rhs: Self) -> Self::Output {
|
||||
self.or(rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Check {
|
||||
pub fn or(self, r: Check) -> Check {
|
||||
Check::Or(Box::new(self), Box::new(r))
|
||||
}
|
||||
|
||||
pub fn constraint(self) -> Constraint {
|
||||
Constraint::Check(self)
|
||||
}
|
||||
|
||||
pub fn to_name(&self) -> String {
|
||||
match self {
|
||||
Check::Lower(l, r) => format!("{}_lw_{}", l.to_string(), r.to_string()),
|
||||
Check::LowerEq(l, r) => format!("{}_le_{}", l.to_string(), r.to_string()),
|
||||
Check::Eq(l, r) => format!("{}_eq_{}", l.to_string(), r.to_string()),
|
||||
Check::GreaterEq(l, r) => format!("{}_ge_{}", l.to_string(), r.to_string()),
|
||||
Check::Greater(l, r) => format!("{}_g_{}", l.to_string(), r.to_string()),
|
||||
Check::Or(l, r) => format!("{}_or_{}", l.to_name(), r.to_name()),
|
||||
Check::NotNull(l) => format!("{}_inn", l.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Check {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Check::Lower(l, r) => {
|
||||
f.write_fmt(format_args!("{} < {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::LowerEq(l, r) => {
|
||||
f.write_fmt(format_args!("{} <= {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::Eq(l, r) => {
|
||||
f.write_fmt(format_args!("{} = {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::GreaterEq(l, r) => {
|
||||
f.write_fmt(format_args!("{} >= {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::Greater(l, r) => {
|
||||
f.write_fmt(format_args!("{} > {}", l.to_string(), r.to_string()))
|
||||
}
|
||||
Check::Or(l, r) => f.write_fmt(format_args!("({l}) OR ({r})")),
|
||||
Check::NotNull(l) => f.write_fmt(format_args!("{} IS NOT NULL", l.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Check {
|
||||
pub fn less<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::Lower(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn less_eq<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::LowerEq(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn eq<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::Eq(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn greater_eq<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::GreaterEq(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn greater<L: Iden + 'static, R: Iden + 'static>(l: L, r: R) -> Check {
|
||||
Check::Greater(Box::new(l), Box::new(r))
|
||||
}
|
||||
pub fn not_null<L: Iden + 'static>(l: L) -> Check {
|
||||
Check::NotNull(Box::new(l))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CheckUSize(usize);
|
||||
|
||||
impl Iden for CheckUSize {
|
||||
fn unquoted(&self, s: &mut dyn Write) {
|
||||
s.write_str(&format!("{}", self.0)).ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AsIden<I: Iden> {
|
||||
fn iden(self) -> I;
|
||||
}
|
||||
|
||||
impl AsIden<CheckUSize> for usize {
|
||||
fn iden(self) -> CheckUSize {
|
||||
CheckUSize(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Constraint {
|
||||
Check(Check),
|
||||
}
|
||||
|
||||
impl Constraint {
|
||||
fn to_name(&self) -> String {
|
||||
match self {
|
||||
Constraint::Check(check) => format!("ck_{}", check.to_name()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Check> for Constraint {
|
||||
fn from(value: Check) -> Self {
|
||||
Self::Check(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Constraint {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Constraint::Check(check) => f.write_fmt(format_args!("CHECK {check}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
pub trait CreateConstraint {
|
||||
async fn create_constraint<T: Iden, C: Into<Constraint>>(
|
||||
&self,
|
||||
table: T,
|
||||
c: C,
|
||||
) -> Result<(), DbErr>;
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl CreateConstraint for SchemaManager<'_> {
|
||||
async fn create_constraint<T: Iden, C>(&self, table: T, c: C) -> Result<(), DbErr>
|
||||
where
|
||||
C: Into<Constraint>,
|
||||
{
|
||||
let c = c.into();
|
||||
self.get_connection()
|
||||
.execute_unprepared(&format!(
|
||||
"ALTER TABLE {} ADD CONSTRAINT {} {}",
|
||||
table.to_string(),
|
||||
c.to_name(),
|
||||
c
|
||||
))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use insta::assert_ron_snapshot;
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
use crate::constraint::Check;
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum ShippingMethod {
|
||||
ShippingMethods,
|
||||
Id,
|
||||
ShippingOptionId,
|
||||
OrderId,
|
||||
CartId,
|
||||
SwapId,
|
||||
ReturnId,
|
||||
Price,
|
||||
Data,
|
||||
ClaimOrderId,
|
||||
}
|
||||
|
||||
fn complex_or_check() -> Check {
|
||||
Check::not_null(ShippingMethod::ClaimOrderId)
|
||||
| Check::not_null(ShippingMethod::OrderId)
|
||||
| Check::not_null(ShippingMethod::CartId)
|
||||
| Check::not_null(ShippingMethod::SwapId)
|
||||
| Check::not_null(ShippingMethod::ReturnId)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn combine_not_null_or_sql() {
|
||||
let s = complex_or_check();
|
||||
|
||||
assert_ron_snapshot!(s.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn combine_not_null_or_name() {
|
||||
let s = complex_or_check();
|
||||
|
||||
assert_ron_snapshot!(s.to_name());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constraint_combine_not_null_or_sql() {
|
||||
let c = complex_or_check().constraint();
|
||||
|
||||
assert_ron_snapshot!(c.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constraint_combine_not_null_or_name() {
|
||||
let c = complex_or_check().constraint();
|
||||
|
||||
assert_ron_snapshot!(c.to_name());
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: migration/src/sea_ext/mod.rs
|
||||
expression: s.to_name()
|
||||
---
|
||||
"claim_order_id_inn_or_order_id_inn_or_cart_id_inn_or_swap_id_inn_or_return_id_inn"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: migration/src/sea_ext/mod.rs
|
||||
expression: s.to_string()
|
||||
---
|
||||
"((((claim_order_id IS NOT NULL) OR (order_id IS NOT NULL)) OR (cart_id IS NOT NULL)) OR (swap_id IS NOT NULL)) OR (return_id IS NOT NULL)"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: migration/src/sea_ext/mod.rs
|
||||
expression: c.to_name()
|
||||
---
|
||||
"ck_claim_order_id_inn_or_order_id_inn_or_cart_id_inn_or_swap_id_inn_or_return_id_inn"
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: migration/src/sea_ext/mod.rs
|
||||
expression: c.to_string()
|
||||
---
|
||||
"CHECK ((((claim_order_id IS NOT NULL) OR (order_id IS NOT NULL)) OR (cart_id IS NOT NULL)) OR (swap_id IS NOT NULL)) OR (return_id IS NOT NULL)"
|
@ -1,8 +1,10 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
use crate::constraint::Check;
|
||||
use crate::sea_orm::Iterable;
|
||||
use crate::{
|
||||
auto_uuid_not_null, create_type, drop_type, ts_def_now_not_null, DropTable, IntoColumnDef,
|
||||
auto_uuid_not_null, create_type, drop_type, ts_def_now_not_null, AsIden, CreateConstraint,
|
||||
DropTable, IntoColumnDef,
|
||||
};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
@ -114,12 +116,33 @@ impl Migration {
|
||||
/// data jsonb NOT NULL,
|
||||
/// claim_order_id uuid,
|
||||
/// CONSTRAINT "CHK_64c6812fe7815be30d688df513" CHECK ((price >= 0)),
|
||||
/// CONSTRAINT "CHK_a7020b08665bbd64d84a6641cf" CHECK (((claim_order_id
|
||||
/// IS NOT NULL) OR (order_id IS NOT NULL) OR
|
||||
/// (cart_id IS NOT NULL) OR (swap_id IS NOT NULL) OR
|
||||
/// (return_id IS NOT NULL))) );
|
||||
/// CONSTRAINT "CHK_a7020b08665bbd64d84a6641cf" CHECK (
|
||||
/// (
|
||||
/// (claim_order_id IS NOT NULL)
|
||||
/// OR (order_id IS NOT NULL)
|
||||
/// OR (cart_id IS NOT NULL)
|
||||
/// OR (swap_id IS NOT NULL)
|
||||
/// OR (return_id IS NOT NULL)
|
||||
/// )
|
||||
/// )
|
||||
/// );
|
||||
/// ```
|
||||
async fn create_shipping_methods(m: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
m.create_constraint(
|
||||
ShippingMethod::ShippingMethods,
|
||||
Check::greater_eq(ShippingMethod::Price, 0.iden()),
|
||||
)
|
||||
.await?;
|
||||
|
||||
m.create_constraint(
|
||||
ShippingMethod::ShippingMethods,
|
||||
Check::not_null(ShippingMethod::ClaimOrderId)
|
||||
| Check::not_null(ShippingMethod::OrderId)
|
||||
| Check::not_null(ShippingMethod::CartId)
|
||||
| Check::not_null(ShippingMethod::SwapId)
|
||||
| Check::not_null(ShippingMethod::ReturnId),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -161,6 +184,11 @@ impl Migration {
|
||||
/// );
|
||||
/// ````
|
||||
async fn create_shipping_options(m: &SchemaManager<'_>) -> Result<(), DbErr> {
|
||||
m.create_constraint(
|
||||
ShippingOption::ShippingOptions,
|
||||
Check::greater_eq(ShippingOption::Amount, 0.iden()),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user