1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! Utilities to assist in migrating your database.
//!
//! # Example - Single migration
//! If you don't need to run any other migrations the [`Migrator`] struct can be used directly
//!
//! ```rust
//! use async_sea_orm_session::migration::Migrator;
//! use async_sea_orm_session::DatabaseSessionStore;
//! use sea_orm::{Database, DatabaseConnection};
//! use sea_orm_migration::MigratorTrait;
//!
//! # async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
//!
//! let db: DatabaseConnection =
//!     Database::connect("protocol://username:password@host/database").await?;
//!
//! // Run the async-sea-orm-session migration, if it hasn't already been run.
//! Migrator::up(&db, None).await?;
//! let store = DatabaseSessionStore::new(db);
//! # Ok(())
//! # }
//! ```
//!
//! # Example - Multiple migrations
//! The previous example isn't super useful because it doesn't allow you to run other migrations.
//! To resolve this you should include [`SessionTableMigration`] directly in your own
//! [`MigratorTrait`] implementation, as in the example below:
//!
//! ```rust,ignore
//! // In migrations/src/lib.rs
//! pub use sea_orm_migration::prelude::*;
//! use async_sea_orm_session::migration::SessionTableMigration;
//!
//! mod m20220101_000001_sample_migration;
//! mod m20220102_000002_some_other_migration;
//!
//! pub struct Migrator;
//!
//! #[async_trait::async_trait]
//! impl MigratorTrait for Migrator {
//!     fn migrations() -> Vec<Box<dyn MigrationTrait>> {
//!         vec![
//!             Box::new(m20220101_000001_sample_migration::Migration),
//!             Box::new(m20220102_000002_some_other_migration::Migration),
//!             Box::new(SessionTableMigration),
//!         ]
//!     }
//! }
//! ```
use async_session::async_trait;
#[doc(hidden)]
pub use sea_orm_migration::prelude::*;

use crate::sessions;

pub struct Migrator;

#[async_trait]
impl MigratorTrait for Migrator {
    fn migrations() -> Vec<Box<dyn MigrationTrait>> {
        vec![Box::new(SessionTableMigration)]
    }
}

pub struct SessionTableMigration;
impl MigrationName for SessionTableMigration {
    fn name(&self) -> &str {
        "create_session_table"
    }
}

#[async_trait]
impl MigrationTrait for SessionTableMigration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .create_table(
                sea_query::Table::create()
                    .table(sessions::Entity)
                    .if_not_exists()
                    .col(
                        ColumnDef::new(sessions::Column::Id)
                            .text()
                            .not_null()
                            .primary_key(),
                    )
                    .col(
                        ColumnDef::new(sessions::Column::Session)
                            .json_binary()
                            .not_null(),
                    )
                    .to_owned(),
            )
            .await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .drop_table(sea_query::Table::drop().table(sessions::Entity).to_owned())
            .await?;
        Ok(())
    }
}