create and write construct skeletons

This commit is contained in:
ntr 2019-09-06 16:40:03 +10:00
parent 8a771240b1
commit 6b84fe92d7
2 changed files with 49 additions and 50 deletions

View File

@ -10,7 +10,7 @@ use postgres::transaction::Transaction;
use http::MnmlHttpError; use http::MnmlHttpError;
use names::{name as generate_name}; use names::{name as generate_name};
use construct::{Construct, construct_recover, construct_spawn}; use construct::{Construct, ConstructSkeleton, construct_spawn};
use instance::{Instance, instance_delete}; use instance::{Instance, instance_delete};
use mtx::{Mtx, FREE_MTX}; use mtx::{Mtx, FREE_MTX};
use pg::Db; use pg::Db;
@ -350,23 +350,20 @@ pub fn constructs(tx: &mut Transaction, account: &Account) -> Result<Vec<Constru
let result = tx let result = tx
.query(query, &[&account.id])?; .query(query, &[&account.id])?;
let constructs: Result<Vec<Construct>, _> = result.iter() let mut constructs = result.iter()
.map(|row| { .filter_map(|row| {
let construct_bytes: Vec<u8> = row.get(0); let construct_bytes: Vec<u8> = row.get(0);
match from_slice::<Construct>(&construct_bytes) { match from_slice::<ConstructSkeleton>(&construct_bytes) {
Ok(c) => Ok(c), Ok(s) => Some(s),
Err(_e) => construct_recover(construct_bytes, tx), Err(e) => {
warn!("{:?}", e);
None
},
} }
}) })
.collect(); .map(|sk| Construct::from_skeleton(&sk))
.collect::<Vec<Construct>>();
// catch any errors
if constructs.is_err() {
warn!("{:?}", constructs);
return Err(err_msg("could not deserialise a construct"));
}
let mut constructs = constructs.unwrap();
constructs.sort_by_key(|c| c.id); constructs.sort_by_key(|c| c.id);
return Ok(constructs); return Ok(constructs);
} }
@ -382,23 +379,19 @@ pub fn team(tx: &mut Transaction, account: &Account) -> Result<Vec<Construct>, E
let result = tx let result = tx
.query(query, &[&account.id])?; .query(query, &[&account.id])?;
let constructs: Result<Vec<Construct>, _> = result.iter() let mut constructs = result.iter()
.map(|row| { .filter_map(|row| {
let construct_bytes: Vec<u8> = row.get(0); let construct_bytes: Vec<u8> = row.get(0);
match from_slice::<Construct>(&construct_bytes) { match from_slice::<ConstructSkeleton>(&construct_bytes) {
Ok(c) => Ok(c), Ok(s) => Some(s),
Err(_e) => construct_recover(construct_bytes, tx), Err(e) => {
warn!("{:?}", e);
None
},
} }
}) })
.collect(); .map(|sk| Construct::from_skeleton(&sk))
.collect::<Vec<Construct>>();
// catch any errors
if constructs.is_err() {
warn!("{:?}", constructs);
return Err(err_msg("could not deserialise a construct"));
}
let mut constructs = constructs.unwrap();
if constructs.len() != 3 { if constructs.len() != 3 {
return Err(format_err!("team not size 3 account={:?}", account)); return Err(format_err!("team not size 3 account={:?}", account));

View File

@ -187,9 +187,10 @@ impl ConstructStat {
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct ConstructRecover { pub struct ConstructSkeleton {
pub id: Uuid, pub id: Uuid,
pub account: Uuid, pub account: Uuid,
pub img: Uuid,
pub name: String, pub name: String,
} }
@ -236,6 +237,27 @@ impl Construct {
}; };
} }
pub fn from_skeleton(skeleton: &ConstructSkeleton) -> Construct {
return Construct {
id: skeleton.id,
account: skeleton.id,
img: skeleton.img,
name: skeleton.name.clone(),
.. Construct::new()
};
}
pub fn to_skeleton(&self) -> ConstructSkeleton {
ConstructSkeleton {
id: self.id,
account: self.id,
img: self.img,
name: self.name.clone(),
}
}
pub fn named(mut self, name: &String) -> Construct { pub fn named(mut self, name: &String) -> Construct {
self.name = name.clone(); self.name = name.clone();
self self
@ -827,10 +849,9 @@ pub fn construct_get(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result
let result = result.iter().next().ok_or(format_err!("construct {:} not found", id))?; let result = result.iter().next().ok_or(format_err!("construct {:} not found", id))?;
let construct_bytes: Vec<u8> = result.get(0); let construct_bytes: Vec<u8> = result.get(0);
let construct = from_slice::<Construct>(&construct_bytes) let skeleton = from_slice::<ConstructSkeleton>(&construct_bytes)?;
.or_else(|_| construct_recover(construct_bytes, tx))?;
return Ok(construct); return Ok(Construct::from_skeleton(&skeleton));
} }
pub fn construct_select(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result<Construct, Error> { pub fn construct_select(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result<Construct, Error> {
@ -847,10 +868,9 @@ pub fn construct_select(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Res
let result = result.iter().next().ok_or(format_err!("construct {:} not found", id))?; let result = result.iter().next().ok_or(format_err!("construct {:} not found", id))?;
let construct_bytes: Vec<u8> = result.get(0); let construct_bytes: Vec<u8> = result.get(0);
let construct = from_slice::<Construct>(&construct_bytes) let skeleton = from_slice::<ConstructSkeleton>(&construct_bytes)?;
.or_else(|_| construct_recover(construct_bytes, tx))?;
return Ok(construct); return Ok(Construct::from_skeleton(&skeleton));
} }
pub fn construct_spawn(tx: &mut Transaction, account: Uuid, name: String, team: bool) -> Result<Construct, Error> { pub fn construct_spawn(tx: &mut Transaction, account: Uuid, name: String, team: bool) -> Result<Construct, Error> {
@ -878,7 +898,7 @@ pub fn construct_spawn(tx: &mut Transaction, account: Uuid, name: String, team:
} }
pub fn construct_write(tx: &mut Transaction, construct: Construct) -> Result<Construct, Error> { pub fn construct_write(tx: &mut Transaction, construct: Construct) -> Result<Construct, Error> {
let construct_bytes = to_vec(&construct)?; let construct_bytes = to_vec(&construct.to_skeleton())?;
let query = " let query = "
UPDATE constructs UPDATE constructs
@ -897,20 +917,6 @@ pub fn construct_write(tx: &mut Transaction, construct: Construct) -> Result<Con
return Ok(construct); return Ok(construct);
} }
pub fn construct_recover(construct_bytes: Vec<u8>, tx: &mut Transaction) -> Result<Construct, Error> {
let c = from_slice::<ConstructRecover>(&construct_bytes)?;
let mut construct = Construct::new()
.named(&c.name)
.set_account(c.account);
construct.id = c.id;
info!("recovered construct {:?}", c.name);
return construct_write(tx, construct);
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use construct::*; use construct::*;