|
2 | 2 | //! Has methods for saving resources and getting properties inside them. |
3 | 3 |
|
4 | 4 | use crate::commit::{CommitOpts, CommitResponse}; |
| 5 | +use crate::storelike::Query; |
5 | 6 | use crate::urls; |
6 | 7 | use crate::utils::random_string; |
7 | 8 | use crate::values::{SubResource, Value}; |
@@ -47,15 +48,30 @@ impl Resource { |
47 | 48 | } |
48 | 49 |
|
49 | 50 | /// Removes / deletes the resource from the store by performing a Commit. |
| 51 | + /// Recursively deletes the resource's children. |
50 | 52 | pub fn destroy( |
51 | 53 | &mut self, |
52 | 54 | store: &impl Storelike, |
53 | 55 | ) -> AtomicResult<crate::commit::CommitResponse> { |
| 56 | + let children = self.get_children(store); |
| 57 | + |
| 58 | + if let Ok(children) = children { |
| 59 | + for mut child in children { |
| 60 | + child.destroy(store)?; |
| 61 | + } |
| 62 | + } |
| 63 | + |
54 | 64 | self.commit.destroy(true); |
55 | 65 | self.save(store) |
56 | 66 | .map_err(|e| format!("Failed to destroy {} : {}", self.subject, e).into()) |
57 | 67 | } |
58 | 68 |
|
| 69 | + /// Gets the children of this resource. |
| 70 | + pub fn get_children(&self, store: &impl Storelike) -> AtomicResult<Vec<Resource>> { |
| 71 | + let result = store.query(&Query::new_prop_val(urls::PARENT, self.get_subject()))?; |
| 72 | + Ok(result.resources) |
| 73 | + } |
| 74 | + |
59 | 75 | pub fn from_propvals(propvals: PropVals, subject: String) -> Resource { |
60 | 76 | Resource { |
61 | 77 | propvals, |
@@ -544,6 +560,8 @@ impl Resource { |
544 | 560 |
|
545 | 561 | #[cfg(test)] |
546 | 562 | mod test { |
| 563 | + use ntest::assert_panics; |
| 564 | + |
547 | 565 | use super::*; |
548 | 566 | use crate::{test_utils::init_store, urls}; |
549 | 567 |
|
@@ -772,4 +790,78 @@ mod test { |
772 | 790 | .unwrap(); |
773 | 791 | assert_eq!(new_val.first().unwrap(), append_value); |
774 | 792 | } |
| 793 | + |
| 794 | + #[test] |
| 795 | + fn get_children() { |
| 796 | + let store = init_store(); |
| 797 | + let mut resource1 = Resource::new_generate_subject(&store); |
| 798 | + let subject1 = resource1.get_subject().to_string(); |
| 799 | + resource1.save_locally(&store).unwrap(); |
| 800 | + |
| 801 | + let mut resource2 = Resource::new_generate_subject(&store); |
| 802 | + resource2 |
| 803 | + .set_propval(urls::PARENT.into(), Value::AtomicUrl(subject1), &store) |
| 804 | + .unwrap(); |
| 805 | + let subject2 = resource2.get_subject().to_string(); |
| 806 | + resource2.save_locally(&store).unwrap(); |
| 807 | + |
| 808 | + let children = resource1.get_children(&store).unwrap(); |
| 809 | + |
| 810 | + assert_eq!(children.len(), 1); |
| 811 | + assert_eq!(children[0].get_subject(), &subject2); |
| 812 | + } |
| 813 | + |
| 814 | + #[test] |
| 815 | + fn destroy() { |
| 816 | + let store = init_store(); |
| 817 | + // Create 3 resources in a tree structure. |
| 818 | + |
| 819 | + let mut resource1 = Resource::new_generate_subject(&store); |
| 820 | + let subject1 = resource1.get_subject().to_string(); |
| 821 | + resource1.save_locally(&store).unwrap(); |
| 822 | + |
| 823 | + let mut resource2 = Resource::new_generate_subject(&store); |
| 824 | + resource2 |
| 825 | + .set_propval( |
| 826 | + urls::PARENT.into(), |
| 827 | + Value::AtomicUrl(subject1.clone()), |
| 828 | + &store, |
| 829 | + ) |
| 830 | + .unwrap(); |
| 831 | + let subject2 = resource2.get_subject().to_string(); |
| 832 | + resource2.save_locally(&store).unwrap(); |
| 833 | + |
| 834 | + let mut resource3 = Resource::new_generate_subject(&store); |
| 835 | + resource3 |
| 836 | + .set_propval( |
| 837 | + urls::PARENT.into(), |
| 838 | + Value::AtomicUrl(subject2.clone()), |
| 839 | + &store, |
| 840 | + ) |
| 841 | + .unwrap(); |
| 842 | + let subject3 = resource3.get_subject().to_string(); |
| 843 | + resource3.save_locally(&store).unwrap(); |
| 844 | + |
| 845 | + // Check if all 3 resources exist in the store. |
| 846 | + |
| 847 | + assert_eq!( |
| 848 | + store.get_resource(&subject1).unwrap().get_subject(), |
| 849 | + &subject1 |
| 850 | + ); |
| 851 | + assert_eq!( |
| 852 | + store.get_resource(&subject2).unwrap().get_subject(), |
| 853 | + &subject2 |
| 854 | + ); |
| 855 | + assert_eq!( |
| 856 | + store.get_resource(&subject3).unwrap().get_subject(), |
| 857 | + &subject3 |
| 858 | + ); |
| 859 | + |
| 860 | + // Destroy the first resource, and check if all 3 resources are gone. |
| 861 | + resource1.destroy(&store).unwrap(); |
| 862 | + |
| 863 | + assert_panics!({ store.get_resource(&subject1).unwrap() }); |
| 864 | + assert_panics!({ store.get_resource(&subject2).unwrap() }); |
| 865 | + assert_panics!({ store.get_resource(&subject3).unwrap() }); |
| 866 | + } |
775 | 867 | } |
0 commit comments