138 lines
3.4 KiB
Rust
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
|
|
}
|