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
use std::collections::HashMap;

use postgres::GenericClient;

use crate::{salmo_contex::SalmoContext, meta_table::{executions::ExecutedMigration, tries::TriedMigration}};

pub struct TryStatus {
  pub up_to_date: bool,
  pub id: String
}

pub struct StatusSummary {
  pub already_migrated: Vec<String>,
  pub pending_migration: Vec<String>,
  pub tries: Vec<TryStatus>,
  pub untried: Vec<String>
}


pub struct CommittedStatus {
  pub already_migrated: Vec<String>,
  pub pending_migration: Vec<String>
}

pub fn get_committed(ctx: &SalmoContext, client: &mut impl GenericClient) -> anyhow::Result<CommittedStatus> {
  let last_executed = ExecutedMigration::get_last(client)?;
  let commits = ctx.commits()?;
  let commit_ids = commits.commits.iter().map(|c| c.id.clone()).collect::<Vec<String>>();
  let (already_migrated, pending_migration) = if let Some(last) = last_executed {
    let (a, b) = commit_ids.split_at(last as usize);
    (a.to_vec(), b.to_vec())
  } else {
    (vec![], commit_ids)
  };
  Ok(CommittedStatus {
    already_migrated,
    pending_migration
  })
}

pub fn get_status(context: SalmoContext) -> anyhow::Result<HashMap<String, StatusSummary>> {
  context.environments.iter().map(|e| {
    let mut client = e.connect()?;
    let CommittedStatus {already_migrated, pending_migration} = get_committed(&context, &mut client)?;

    let migrations = context.migrations()?;
    let db_tries = TriedMigration::get_all(&mut client)?;

    let commits = context.commits()?;

    let mut tries = Vec::new();
    let mut untried = Vec::new();

    for (m_id, m) in migrations.db {
      if commits.commits.iter().map(|c| c.id.clone()).any(|x| x == m_id) {
        continue;
      }

      if let Some(tm) = db_tries.iter().find(|tm| tm.id == m_id) {
        tries.push(TryStatus {
            up_to_date: m.migrate_hash()? == tm.hash,
            id: m_id,
        })
      } else {
        untried.push(m_id)
      }
    }

    Ok((e.name.clone(), StatusSummary {
      already_migrated,
      pending_migration,
      tries,
      untried
    }))
  }).collect()
}