@@ -4,14 +4,9 @@ use anyhow::anyhow;
44use serde::{Deserialize, Serialize};
55use version::version;
66
7−#[derive(Serialize, Deserialize, Debug)]
8−pub struct State {
9− pub status: Status,
10−}
11−
127#[derive(Serialize, Deserialize, Clone, Debug)]
13−#[serde(tag = "status")]
14−pub enum Status {
8+#[serde(tag = "state")]
9+pub enum State {
1510 #[serde(rename = "idle")]
1611 Idle,
1712
@@ -37,24 +32,23 @@ pub enum Status {
3732}
3833
3934impl State {
40− pub fn load(db: &mut impl Conn) -> State {
41− Self::ensure_schema_and_table(db);
35+ pub fn load(db: &mut impl Conn) -> anyhow::Result<State> {
36+ Self::ensure_schema_and_table(db)?;
4237
43− let results = db
44− .query("SELECT value FROM reshape.data WHERE key = 'state'")
45− .unwrap();
38+ let results = db.query("SELECT value FROM reshape.data WHERE key = 'state'")?;
4639
47− match results.first() {
40+ let state = match results.first() {
4841 Some(row) => {
4942 let json: serde_json::Value = row.get(0);
50− serde_json::from_value(json).unwrap()
43+ serde_json::from_value(json)?
5144 }
5245 None => Default::default(),
53− }
46+ };
47+ Ok(state)
5448 }
5549
5650 pub fn save(&self, db: &mut impl Conn) -> anyhow::Result<()> {
57− Self::ensure_schema_and_table(db);
51+ Self::ensure_schema_and_table(db)?;
5852
5953 let json = serde_json::to_value(self)?;
6054 db.query_with_params(
@@ -67,17 +61,17 @@ impl State {
6761 pub fn clear(&mut self, db: &mut impl Conn) -> anyhow::Result<()> {
6862 db.run("DROP SCHEMA reshape CASCADE")?;
6963
70− let default = Self::default();
71− self.status = default.status;
64+ *self = Self::default();
7265
7366 Ok(())
7467 }
7568
76− // Complete will change the status from Completing to Idle
69+ // Complete will change the state from Completing to Idle
7770 pub fn complete(&mut self, db: &mut impl Conn) -> anyhow::Result<()> {
78− let current_status = std::mem::replace(&mut self.status, Status::Idle);
79− match current_status {
80− Status::Completing { migrations, .. } => {
71+ let current_state = std::mem::replace(self, Self::Idle);
72+
73+ match current_state {
74+ Self::Completing { migrations, .. } => {
8175 // Add migrations and update state in a transaction to ensure atomicity
8276 let mut transaction = db.transaction()?;
8377 save_migrations(&mut transaction, &migrations)?;
@@ -85,8 +79,8 @@ impl State {
8579 transaction.commit()?;
8680 }
8781 _ => {
88− // Move old status back
89− self.status = current_status;
82+ // Move old state back
83+ *self = current_state;
9084
9185 return Err(anyhow!(
9286 "couldn't update state to be completed, not in Completing state"
@@ -98,13 +92,13 @@ impl State {
9892 }
9993
10094 pub fn applying(&mut self, new_migrations: Vec<Migration>) {
101− self.status = Status::Applying {
95+ *self = Self::Applying {
10296 migrations: new_migrations,
10397 };
10498 }
10599
106100 pub fn in_progress(&mut self, new_migrations: Vec<Migration>) {
107− self.status = Status::InProgress {
101+ *self = Self::InProgress {
108102 migrations: new_migrations,
109103 };
110104 }
@@ -115,7 +109,7 @@ impl State {
115109 current_migration_index: usize,
116110 current_action_index: usize,
117111 ) {
118− self.status = Status::Completing {
112+ *self = Self::Completing {
119113 migrations,
120114 current_migration_index,
121115 current_action_index,
@@ -128,20 +122,19 @@ impl State {
128122 last_migration_index: usize,
129123 last_action_index: usize,
130124 ) {
131− self.status = Status::Aborting {
125+ *self = Self::Aborting {
132126 migrations,
133127 last_migration_index,
134128 last_action_index,
135129 }
136130 }
137131
138− fn ensure_schema_and_table(db: &mut impl Conn) {
139− db.run("CREATE SCHEMA IF NOT EXISTS reshape").unwrap();
132+ fn ensure_schema_and_table(db: &mut impl Conn) -> anyhow::Result<()> {
133+ db.run("CREATE SCHEMA IF NOT EXISTS reshape")?;
140134
141135 // Create data table which will be a key-value table containing
142136 // the version and current state.
143− db.run("CREATE TABLE IF NOT EXISTS reshape.data (key TEXT PRIMARY KEY, value JSONB)")
144− .unwrap();
137+ db.run("CREATE TABLE IF NOT EXISTS reshape.data (key TEXT PRIMARY KEY, value JSONB)")?;
145138
146139 // Create migrations table which will store all completed migrations
147140 db.run(
@@ -154,11 +147,10 @@ impl State {
154147 completed_at TIMESTAMP DEFAULT NOW()
155148 )
156149 ",
157− )
158− .unwrap();
150+ )?;
159151
160152 // Update the current version
161− let encoded_version = serde_json::to_value(version!().to_string()).unwrap();
153+ let encoded_version = serde_json::to_value(version!().to_string())?;
162154 db.query_with_params(
163155 "
164156 INSERT INTO reshape.data (key, value)
@@ -166,16 +158,15 @@ impl State {
166158 ON CONFLICT (key) DO UPDATE SET value = $1
167159 ",
168160 &[&encoded_version],
169− )
170− .unwrap();
161+ )?;
162+
163+ Ok(())
171164 }
172165}
173166
174167impl Default for State {
175168 fn default() -> Self {
176− State {
177− status: Status::Idle,
178− }
169+ Self::Idle
179170 }
180171}
181172