1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
use diesel::prelude::*; use diesel::result::Error; use diesel::SqliteConnection; use std::collections::HashMap; use std::str::FromStr; use uuid::Uuid; use crate::models::BlockProperty; pub type BlockProperties = HashMap<String, Vec<u8>>; pub trait BlockPropertyCrud { fn create_block_properties(&self, block_id: &str, properties: BlockProperties) -> Vec<BlockProperty>; fn retrieve_block_properties(&self, block_id: &str) -> Vec<BlockProperty>; fn update_block_property(&self, block_id: &str, name: String, data: &[u8]) -> BlockProperty; fn update_block_properties(&self, block_id: &str, properties: BlockProperties) -> Vec<BlockProperty>; fn delete_block_property(&self, block_id: &str, name: String); } impl BlockPropertyCrud for SqliteConnection { fn create_block_properties(&self, block_id: &str, properties: BlockProperties) -> Vec<BlockProperty> { use crate::schema::block_properties::dsl; let block_uuid = Uuid::from_str(&block_id).unwrap().as_bytes().to_vec(); self.transaction::<(), Error, _>(|| { for (name, data) in properties { let new_property = BlockProperty { block_id: block_uuid.clone(), name, data: data.to_vec(), }; diesel::insert_into(dsl::block_properties) .values(new_property) .execute(self)?; } Ok(()) }) .expect("Could not insert new properties"); dsl::block_properties .filter(dsl::block_id.eq(block_uuid)) .get_results(self) .expect("Could not retrieve the block properties") } fn retrieve_block_properties(&self, block_id: &str) -> Vec<BlockProperty> { use crate::schema::block_properties::dsl; let block_uuid = Uuid::from_str(&block_id).unwrap().as_bytes().to_vec(); dsl::block_properties .filter(dsl::block_id.eq(block_uuid)) .get_results(self) .expect(&format!("Could not retrieve properties from block {}", block_id)) } fn update_block_property(&self, block_id: &str, name: String, data: &[u8]) -> BlockProperty { use crate::schema::block_properties::dsl; let block_uuid = Uuid::from_str(&block_id).unwrap().as_bytes().to_vec(); diesel::update(dsl::block_properties.find((&block_uuid, &name))) .set(dsl::data.eq(data.to_vec())) .execute(self) .and_then(|_| dsl::block_properties.find((&block_uuid, &name)).first(self)) .expect(&format!("Could not update property {} of block {}", name, block_id)) } fn update_block_properties(&self, block_id: &str, properties: BlockProperties) -> Vec<BlockProperty> { let blocks_properties = self .transaction::<Vec<BlockProperty>, Error, _>(|| { let block_properties: Vec<BlockProperty> = properties .iter() .map(|(name, data)| self.update_block_property(block_id, name.clone(), data)) .collect(); Ok(block_properties) }) .expect(&format!("Could not update properties of block {}", block_id)); blocks_properties } fn delete_block_property(&self, block_id: &str, name: String) { use crate::schema::block_properties::dsl; let block_uuid = Uuid::from_str(&block_id).unwrap().as_bytes().to_vec(); diesel::delete(dsl::block_properties.find((&block_uuid, &name))) .execute(self) .expect(&format!("Could not delete property {} of block {}", name, block_id)); } }