@@ -4,14 +4,9 @@ use anyhow::anyhow;
4use serde::{Deserialize, Serialize};
4use serde::{Deserialize, Serialize};
5use version::version;
5use version::version;
7−#[derive(Serialize, Deserialize, Debug)]
12#[derive(Serialize, Deserialize, Clone, Debug)]
7#[derive(Serialize, Deserialize, Clone, Debug)]
13−#[serde(tag = "status")]
8+#[serde(tag = "state")]
14−pub enum Status {
9+pub enum State {
15 #[serde(rename = "idle")]
10 #[serde(rename = "idle")]
@@ -37,24 +32,23 @@ pub enum Status {
39impl State {
34impl State {
40− pub fn load(db: &mut impl Conn) -> State {
35+ pub fn load(db: &mut impl Conn) -> anyhow::Result<State> {
41− Self::ensure_schema_and_table(db);
36+ Self::ensure_schema_and_table(db)?;
44− .query("SELECT value FROM reshape.data WHERE key = 'state'")
38+ let results = db.query("SELECT value FROM reshape.data WHERE key = 'state'")?;
47− match results.first() {
40+ let state = match results.first() {
48 Some(row) => {
41 Some(row) => {
49 let json: serde_json::Value = row.get(0);
42 let json: serde_json::Value = row.get(0);
50− serde_json::from_value(json).unwrap()
43+ serde_json::from_value(json)?
52 None => Default::default(),
45 None => Default::default(),
56 pub fn save(&self, db: &mut impl Conn) -> anyhow::Result<()> {
50 pub fn save(&self, db: &mut impl Conn) -> anyhow::Result<()> {
57− Self::ensure_schema_and_table(db);
51+ Self::ensure_schema_and_table(db)?;
59 let json = serde_json::to_value(self)?;
53 let json = serde_json::to_value(self)?;
60 db.query_with_params(
54 db.query_with_params(
@@ -67,17 +61,17 @@ impl State {
67 pub fn clear(&mut self, db: &mut impl Conn) -> anyhow::Result<()> {
61 pub fn clear(&mut self, db: &mut impl Conn) -> anyhow::Result<()> {
68 db.run("DROP SCHEMA reshape CASCADE")?;
62 db.run("DROP SCHEMA reshape CASCADE")?;
70− let default = Self::default();
64+ *self = Self::default();
71− self.status = default.status;
76− // Complete will change the status from Completing to Idle
69+ // Complete will change the state from Completing to Idle
77 pub fn complete(&mut self, db: &mut impl Conn) -> anyhow::Result<()> {
70 pub fn complete(&mut self, db: &mut impl Conn) -> anyhow::Result<()> {
78− let current_status = std::mem::replace(&mut self.status, Status::Idle);
71+ let current_state = std::mem::replace(self, Self::Idle);
79− match current_status {
72+
73+ match current_state {
80− Status::Completing { migrations, .. } => {
74+ Self::Completing { migrations, .. } => {
81 // Add migrations and update state in a transaction to ensure atomicity
75 // Add migrations and update state in a transaction to ensure atomicity
82 let mut transaction = db.transaction()?;
76 let mut transaction = db.transaction()?;
83 save_migrations(&mut transaction, &migrations)?;
77 save_migrations(&mut transaction, &migrations)?;
@@ -85,8 +79,8 @@ impl State {
85 transaction.commit()?;
79 transaction.commit()?;
88− // Move old status back
82+ // Move old state back
89− self.status = current_status;
83+ *self = current_state;
91 return Err(anyhow!(
85 return Err(anyhow!(
92 "couldn't update state to be completed, not in Completing state"
86 "couldn't update state to be completed, not in Completing state"
@@ -98,13 +92,13 @@ impl State {
100 pub fn applying(&mut self, new_migrations: Vec<Migration>) {
94 pub fn applying(&mut self, new_migrations: Vec<Migration>) {
101− self.status = Status::Applying {
95+ *self = Self::Applying {
102 migrations: new_migrations,
96 migrations: new_migrations,
106 pub fn in_progress(&mut self, new_migrations: Vec<Migration>) {
100 pub fn in_progress(&mut self, new_migrations: Vec<Migration>) {
107− self.status = Status::InProgress {
101+ *self = Self::InProgress {
108 migrations: new_migrations,
102 migrations: new_migrations,
@@ -115,7 +109,7 @@ impl State {
115 current_migration_index: usize,
109 current_migration_index: usize,
116 current_action_index: usize,
110 current_action_index: usize,
118− self.status = Status::Completing {
112+ *self = Self::Completing {
119 migrations,
113 migrations,
120 current_migration_index,
114 current_migration_index,
121 current_action_index,
115 current_action_index,
@@ -128,20 +122,19 @@ impl State {
128 last_migration_index: usize,
122 last_migration_index: usize,
129 last_action_index: usize,
123 last_action_index: usize,
131− self.status = Status::Aborting {
125+ *self = Self::Aborting {
132 migrations,
126 migrations,
133 last_migration_index,
127 last_migration_index,
134 last_action_index,
128 last_action_index,
138− fn ensure_schema_and_table(db: &mut impl Conn) {
132+ fn ensure_schema_and_table(db: &mut impl Conn) -> anyhow::Result<()> {
139− db.run("CREATE SCHEMA IF NOT EXISTS reshape").unwrap();
133+ db.run("CREATE SCHEMA IF NOT EXISTS reshape")?;
141 // Create data table which will be a key-value table containing
135 // Create data table which will be a key-value table containing
142 // the version and current state.
136 // the version and current state.
143− db.run("CREATE TABLE IF NOT EXISTS reshape.data (key TEXT PRIMARY KEY, value JSONB)")
137+ db.run("CREATE TABLE IF NOT EXISTS reshape.data (key TEXT PRIMARY KEY, value JSONB)")?;
146 // Create migrations table which will store all completed migrations
139 // Create migrations table which will store all completed migrations
@@ -154,11 +147,10 @@ impl State {
154 completed_at TIMESTAMP DEFAULT NOW()
147 completed_at TIMESTAMP DEFAULT NOW()
160 // Update the current version
152 // 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())?;
162 db.query_with_params(
154 db.query_with_params(
164 INSERT INTO reshape.data (key, value)
156 INSERT INTO reshape.data (key, value)
@@ -166,16 +158,15 @@ impl State {
166 ON CONFLICT (key) DO UPDATE SET value = $1
158 ON CONFLICT (key) DO UPDATE SET value = $1
168 &[&encoded_version],
160 &[&encoded_version],
174impl Default for State {
167impl Default for State {
175 fn default() -> Self {
168 fn default() -> Self {
176− State {
169+ Self::Idle
177− status: Status::Idle,