migration/
m20240404_000013_tickets_recreate_ticket.rs

1use sea_orm_migration::prelude::*;
2
3use crate::BackendType;
4
5#[derive(DeriveMigrationName)]
6pub struct Migration(pub crate::BackendType);
7
8#[async_trait::async_trait]
9impl MigrationTrait for Migration {
10    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
11        // TODO: we have to drop here, if the previous non-release migration is retained.
12        // Remove, if the previous ticket_stats migration is compacted before the release
13        // and compact this change as well.
14        manager
15            .drop_index(Index::drop().name("idx_ticket_channel_id_epoch_index").to_owned())
16            .await?;
17
18        manager
19            .drop_index(Index::drop().name("idx_fk_ticket_channel").to_owned())
20            .await?;
21
22        manager
23            .drop_table(Table::drop().table(Ticket::Table).to_owned())
24            .await?;
25
26        let mut table = Table::create()
27            .table(Ticket::Table)
28            .if_not_exists()
29            .col(
30                ColumnDef::new(Ticket::Id)
31                    .integer()
32                    .not_null()
33                    .auto_increment()
34                    .primary_key(),
35            )
36            .col(ColumnDef::new(Ticket::ChannelId).string_len(64).not_null())
37            .col(ColumnDef::new(Ticket::Amount).binary_len(12).not_null())
38            .col(ColumnDef::new(Ticket::Index).binary_len(8).not_null())
39            .col(ColumnDef::new(Ticket::IndexOffset).unsigned().not_null())
40            .col(ColumnDef::new(Ticket::WinningProbability).binary_len(7).not_null())
41            .col(ColumnDef::new(Ticket::ChannelEpoch).binary_len(8).not_null())
42            .col(ColumnDef::new(Ticket::Signature).binary_len(64).not_null())
43            .col(ColumnDef::new(Ticket::Response).binary_len(32).not_null())
44            .col(ColumnDef::new(Ticket::State).tiny_unsigned().not_null().default(0))
45            .col(ColumnDef::new(Ticket::Hash).binary_len(32).not_null())
46            .clone();
47
48        manager
49            .create_table(if self.0 == BackendType::SQLite {
50                table.to_owned()
51            } else {
52                table
53                    .foreign_key(
54                        ForeignKey::create()
55                            .name("fk_ticket_channel")
56                            .from_tbl(Ticket::Table)
57                            .from_col(Ticket::ChannelId)
58                            .from_col(Ticket::ChannelEpoch)
59                            .to_tbl(Channel::Table)
60                            .to_col(Channel::ChannelId)
61                            .to_col(Channel::Epoch)
62                            .on_delete(ForeignKeyAction::Cascade)
63                            .on_update(ForeignKeyAction::Restrict),
64                    )
65                    // TODO: is it possible to have to foreign keys between same tables ?
66                    /*.foreign_key(
67                        ForeignKey::create()
68                            .name("fk_ticket_issuer_channel_source")
69                            .from_tbl(Ticket::Table)
70                            .from_col(Ticket::ChannelId)
71                            .from_col(Ticket::Issuer)
72                            .to_tbl(Channel::Table)
73                            .to_col(Channel::ChannelId)
74                            .to_col(Channel::Source)
75                            .on_delete(ForeignKeyAction::Cascade)
76                            .on_update(ForeignKeyAction::Restrict),
77                    )*/
78                    .to_owned()
79            })
80            .await?;
81
82        manager
83            .create_index(
84                Index::create()
85                    .name("idx_fk_ticket_channel")
86                    .if_not_exists()
87                    .table(Ticket::Table)
88                    .col(Ticket::ChannelId)
89                    .col(Ticket::ChannelEpoch)
90                    .to_owned(),
91            )
92            .await?;
93
94        manager
95            .create_index(
96                Index::create()
97                    .name("idx_ticket_channel_id_epoch_index")
98                    .if_not_exists()
99                    .table(Ticket::Table)
100                    .col(Ticket::ChannelId)
101                    .col(Ticket::ChannelEpoch)
102                    .col(Ticket::Index)
103                    .unique()
104                    .to_owned(),
105            )
106            .await
107    }
108
109    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
110        manager
111            .drop_index(Index::drop().name("idx_ticket_channel_id_epoch_index").to_owned())
112            .await?;
113
114        manager
115            .drop_index(Index::drop().name("idx_fk_ticket_channel").to_owned())
116            .await?;
117
118        manager.drop_table(Table::drop().table(Ticket::Table).to_owned()).await
119    }
120}
121
122#[derive(DeriveIden)]
123enum Ticket {
124    Table,
125    Id,
126    ChannelId,
127    Amount,
128    Index,
129    IndexOffset,
130    WinningProbability,
131    ChannelEpoch,
132    Signature,
133    Response,
134    State,
135    Hash,
136}
137
138#[allow(clippy::enum_variant_names)]
139#[derive(DeriveIden)]
140enum Channel {
141    Table,
142    ChannelId,
143    Epoch,
144}