mnml/server/src/mtx.rs
2019-06-28 16:08:55 +10:00

138 lines
3.4 KiB
Rust

use uuid::Uuid;
// use rand::prelude::*;
use serde_cbor::{from_slice};
use postgres::transaction::Transaction;
use failure::Error;
use failure::err_msg;
#[derive(Debug,Copy,Clone,Serialize,Deserialize)]
pub enum MtxVariant {
ArchitectureMolecular,
ArchitectureInvader,
}
impl MtxVariant {
fn new(self, account: Uuid) -> Mtx {
match self {
MtxVariant::ArchitectureInvader => Mtx { id: Uuid::new_v4(), account, variant: self },
MtxVariant::ArchitectureMolecular => Mtx { id: Uuid::new_v4(), account, variant: self },
}
}
}
#[derive(Debug,Copy,Clone,Serialize,Deserialize)]
pub struct Mtx {
id: Uuid,
account: Uuid,
variant: MtxVariant,
}
impl Mtx {
pub fn account_list(tx: &mut Transaction, account: Uuid) -> Result<Vec<Mtx>, Error> {
let query = "
SELECT data, id
FROM mtx
WHERE account = $1
FOR UPDATE;
";
let result = tx
.query(query, &[&account])?;
let values = result.into_iter().filter_map(|row| {
let bytes: Vec<u8> = row.get(0);
// let id: Uuid = row.get(1);
match from_slice::<Mtx>(&bytes) {
Ok(i) => Some(i),
Err(e) => {
warn!("{:?}", e);
None
}
}
}).collect::<Vec<Mtx>>();
return Ok(values);
}
pub fn delete(tx: &mut Transaction, id: Uuid) -> Result<(), Error> {
let query = "
DELETE
FROM mtx
WHERE id = $1;
";
let result = tx
.execute(query, &[&id])?;
if result != 1 {
return Err(format_err!("unable to delete mtx {:?}", id));
}
info!("mtx deleted {:?}", id);
return Ok(());
}
pub fn insert(&self, tx: &mut Transaction) -> Result<&Mtx, Error> {
let query = "
INSERT INTO mtx (id, account, variant)
VALUES ($1, $2, $3)
RETURNING id, account;
";
let result = tx
.query(query, &[&self.id, &self.account, &format!("{:?}", self.variant)])?;
result.iter().next().ok_or(err_msg("mtx not written"))?;
info!("wrote mtx {:?}", self);
return Ok(self);
}
// pub fn update(&self, tx: &mut Transaction) -> Result<&Mtx, Error> {
// let query = "
// UPDATE mtx
// SET data = $1, updated_at = now()
// WHERE id = $2
// RETURNING id, data;
// ";
// let result = tx
// .query(query, &[&self.id, &to_vec(self)?])?;
// if let None = result.iter().next() {
// return Err(err_msg("mtx not written"));
// }
// info!("wrote mtx {:?}", self);
// return Ok(self);
// }
pub fn select(tx: &mut Transaction, id: Uuid, account: Uuid) -> Result<Option<Mtx>, Error> {
let query = "
SELECT data, id
FROM mtx
WHERE account = $1
AND id = $2
FOR UPDATE;
";
let result = tx
.query(query, &[&account, &id])?;
if let Some(row) = result.iter().next() {
let bytes: Vec<u8> = row.get(0);
Ok(Some(from_slice::<Mtx>(&bytes)?))
} else {
Err(format_err!("mtx not found {:?}", id))
}
}
// actual impl
}