Skip to content

Instantly share code, notes, and snippets.

@Ploppz
Created October 13, 2022 07:07
Show Gist options
  • Save Ploppz/10784d853712b40501c8976273e3458f to your computer and use it in GitHub Desktop.
Save Ploppz/10784d853712b40501c8976273e3458f to your computer and use it in GitHub Desktop.
/// This is one of two sources of DB migrations.
/// The other one is pure SQL files found in the `migrations/` folder.
/// This module contains migrations made with Rust code.
use diesel::connection::BoxableConnection;
use diesel::migration::{Result as MResult, *};
use diesel::pg::Pg;
use diesel_migrations::EmbeddedMigrations;
use std::fmt::*;
mod scan_scope;
pub const MIGRATIONS: EmbeddedMigrations = diesel_migrations::embed_migrations!();
macro_rules! include_migration {
($migrations:ident, $mod_path:tt) => {
$migrations.push(Box::new(CodeMigration {
run: $mod_path::run,
revert: $mod_path::revert,
name: Name {
name: $mod_path::name(),
},
}))
};
}
pub struct AllMigrations;
impl MigrationSource<Pg> for AllMigrations {
fn migrations(&self) -> MResult<Vec<Box<dyn Migration<Pg>>>> {
let mut migrations = MIGRATIONS.migrations()?;
include_migration!(migrations, scan_scope);
Ok(migrations)
}
}
pub struct CodeMigration<Run, Revert>
where
Run: Fn(&mut dyn BoxableConnection<Pg>) -> MResult<()>,
Revert: Fn(&mut dyn BoxableConnection<Pg>) -> MResult<()>,
{
run: Run,
revert: Revert,
name: Name,
}
impl<Run, Revert> Migration<Pg> for CodeMigration<Run, Revert>
where
Run: Fn(&mut dyn BoxableConnection<Pg>) -> MResult<()>,
Revert: Fn(&mut dyn BoxableConnection<Pg>) -> MResult<()>,
{
fn run(&self, conn: &mut dyn BoxableConnection<Pg>) -> MResult<()> {
(self.run)(conn)
}
fn revert(&self, conn: &mut dyn BoxableConnection<Pg>) -> MResult<()> {
(self.revert)(conn)
}
fn metadata(&self) -> &dyn MigrationMetadata {
&Metadata
}
fn name(&self) -> &dyn MigrationName {
&self.name
}
}
struct Metadata;
impl MigrationMetadata for Metadata {}
struct Name {
name: &'static str,
}
impl Display for Name {
fn fmt(&self, f: &mut Formatter) -> std::result::Result<(), Error> {
write!(f, "{}", self.name)
}
}
impl MigrationName for Name {
fn version(&self) -> MigrationVersion<'_> {
self.name
.chars()
.filter(|c| c.is_numeric())
.collect::<String>()
.into()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment