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
use crate::{salmo_contex::SalmoContext, migration_data::committed::{Commit, CommittedFile}, meta_table::{tries::TriedMigration, executions::ExecutedMigration}};
use anyhow::anyhow;

pub fn commit_migration(ctx: &SalmoContext, migration_id: &str) -> anyhow::Result<Commit> {
  let migrations = ctx.migrations()?;
  let migration = &migrations.db[migration_id];
  let hash = migration.migrate_hash()?;
  let tries = ctx.environments.iter().map(|e| {
      let mut client = e.connect()?;
      TriedMigration::get(&mut client, migration_id)
  }).collect::<anyhow::Result<Vec<Option<TriedMigration>>>>()?;

  if !tries.iter().all(|t| t.is_some()) {
      return Err(anyhow!("Migration `{}` has not been tried. Commit aborted.", migration_id))
  }

  if !tries.iter().all(|opt| opt.as_ref().map(|t| t.hash == hash).unwrap_or(false) ) {
      return Err(anyhow!("Migration `{}` was changed after last being tried. Retry it in order to commit. Commit aborted.", migration_id))
  }
  let mut clients = ctx.environments.iter()
      .map(|e| e.connect())
      .collect::<Result<Vec<_>, anyhow::Error>>()?;
  let mut transactions = clients.iter_mut()
      .map(|client| { Ok(client.transaction()?) })
      .collect::<Result<Vec<_>, anyhow::Error>>()?;
  let old_commit_count = ctx.commits()?.commits.len() as i32;

  for t in transactions.iter_mut() {
      ExecutedMigration::insert(t, migration, old_commit_count + 1)?;
      TriedMigration::delete(t, migration)?;
  }
  let commit = CommittedFile::add_commit(ctx, migration_id)?;
  for t in transactions {
      t.commit()?
  }
  Ok(commit)
}