Browse Source

Added wrapper functions for AssocInterface to Assoc*.

Kestrel 1 year ago
parent
commit
0af97f4f42
3 changed files with 67 additions and 10 deletions
  1. 6 2
      microrm/src/query.rs
  2. 33 5
      microrm/src/schema.rs
  3. 28 3
      microrm/src/schema/tests.rs

+ 6 - 2
microrm/src/query.rs

@@ -318,7 +318,7 @@ pub(crate) trait AssocInterface {
     fn get_distinguishing_name(&self) -> DBResult<&'static str>;
     const SIDE: LocalSide;
 
-    fn get_all(&self) -> DBResult<Vec<Self::RemoteEntity>>
+    fn get_all(&self) -> DBResult<Vec<IDWrap<Self::RemoteEntity>>>
     where
         Self: Sized,
     {
@@ -358,11 +358,15 @@ pub(crate) trait AssocInterface {
                 // now we grab the statement outputs
                 let mut rows = vec![];
                 while stmt.next()? == sqlite::State::Row {
+                    let id = stmt.read::<i64, _>(0)?;
                     let datum_list = <<Self::RemoteEntity as Entity>::Parts>::build_datum_list(
                         &adata.conn,
                         stmt,
                     )?;
-                    rows.push(Self::RemoteEntity::build(datum_list));
+                    rows.push(IDWrap::new(
+                        <Self::RemoteEntity as Entity>::ID::from_raw(id),
+                        Self::RemoteEntity::build(datum_list),
+                    ));
                 }
 
                 Ok(rows)

+ 33 - 5
microrm/src/schema.rs

@@ -161,13 +161,17 @@ impl<T: Entity> AssocMap<T> {
         }
     }
 
-    /*pub fn get_all(&self) -> DBResult<Vec<T>> {
-        query::select_assoc(self)
+    pub fn get_all(&self) -> DBResult<Vec<IDWrap<T>>> {
+        <Self as AssocInterface>::get_all(self)
     }
 
-    pub fn insert(&self, value: T) -> DBResult<()> {
-        query::insert_assoc(self, value)
-    }*/
+    pub fn associate_with(&self, remote_id: T::ID) -> DBResult<()> {
+        <Self as AssocInterface>::associate_with(self, remote_id)
+    }
+
+    pub fn insert(&self, value: T) -> DBResult<T::ID> {
+        <Self as AssocInterface>::insert(self, value)
+    }
 }
 
 impl<T: Entity> EntityMap for AssocMap<T> {
@@ -235,6 +239,18 @@ impl<R: Relation> AssocDomain<R> {
             _ghost: Default::default(),
         }
     }
+
+    pub fn get_all(&self) -> DBResult<Vec<IDWrap<R::Range>>> {
+        <Self as AssocInterface>::get_all(self)
+    }
+
+    pub fn associate_with(&self, remote_id: <R::Range as Entity>::ID) -> DBResult<()> {
+        <Self as AssocInterface>::associate_with(self, remote_id)
+    }
+
+    pub fn insert(&self, value: R::Range) -> DBResult<<R::Range as Entity>::ID> {
+        <Self as AssocInterface>::insert(self, value)
+    }
 }
 
 impl<R: Relation> AssocInterface for AssocDomain<R> {
@@ -319,6 +335,18 @@ impl<R: Relation> AssocRange<R> {
             _ghost: Default::default(),
         }
     }
+
+    pub fn get_all(&self) -> DBResult<Vec<IDWrap<R::Domain>>> {
+        <Self as AssocInterface>::get_all(self)
+    }
+
+    pub fn associate_with(&self, remote_id: <R::Domain as Entity>::ID) -> DBResult<()> {
+        <Self as AssocInterface>::associate_with(self, remote_id)
+    }
+
+    pub fn insert(&self, value: R::Domain) -> DBResult<<R::Domain as Entity>::ID> {
+        <Self as AssocInterface>::insert(self, value)
+    }
 }
 
 impl<R: Relation> AssocInterface for AssocRange<R> {

+ 28 - 3
microrm/src/schema/tests.rs

@@ -271,7 +271,11 @@ mod mutual_relationship {
     #[test]
     fn check_schema_creation() {
         let db = open_test_db::<ReceiptDB>("mutual_relationship_create");
-        // let db = ReceiptDB::open_path(":memory:").expect("couldn't open in-memory database");
+    }
+
+    #[test]
+    fn simple_operations() {
+        let db = open_test_db::<ReceiptDB>("mutual_relationship_simple");
 
         let ca = db
             .customers
@@ -309,12 +313,33 @@ mod mutual_relationship {
             .associate_with(rb)
             .expect("couldn't associate customer with receipt");
 
+        // technically this can fail if sqlite gives ra and rb back in the opposite order, which is
+        // valid behaviour
         assert_eq!(
             e_ca.receipts
                 .get_all()
                 .expect("couldn't get receipts associated with customer")
-                .len(),
-            2
+                .into_iter()
+                .map(|x| x.id())
+                .collect::<Vec<_>>(),
+            vec![ra, rb]
+        );
+
+        // check that the reverse direction was also added
+        let e_ra = db
+            .receipts
+            .by_id(ra)
+            .expect("couldn't retreieve receipt record")
+            .expect("no receipt record");
+
+        assert_eq!(
+            e_ra.customers
+                .get_all()
+                .expect("couldn't get associated customers")
+                .into_iter()
+                .map(|x| x.id())
+                .collect::<Vec<_>>(),
+            vec![ca]
         );
     }
 }