浏览代码

Add support for mutually-referential entity types.

Kestrel 1 年之前
父节点
当前提交
15c4d75bf9
共有 2 个文件被更改,包括 39 次插入4 次删除
  1. 9 4
      microrm/src/schema/entity.rs
  2. 30 0
      microrm/src/schema/tests.rs

+ 9 - 4
microrm/src/schema/entity.rs

@@ -92,15 +92,20 @@ pub struct EntityContext<'a> {
 
 impl<'a> EntityVisitor for EntityContext<'a> {
     fn visit<E: Entity>(&mut self) {
-        let entry = self
-            .container
-            .states
-            .entry((self.context, E::entity_name()));
         // three cases:
         // 1. we haven't seen this entity in this context before
         // 2. we've seen this entity in this context before
         // 3. we haven't seen this entity in this context before, but we've seen one with an identical name in the same context
 
+        if self.container.states.contains_key(&(self.context, E::entity_name())) {
+            return
+        }
+
+        let entry = self
+            .container
+            .states
+            .entry((self.context, E::entity_name()));
+
         let entry = entry.or_insert_with(|| EntityState::build::<E>(self.context));
         // sanity-check
         if entry.typeid != std::any::TypeId::of::<E>() {

+ 30 - 0
microrm/src/schema/tests.rs

@@ -227,3 +227,33 @@ mod derive_tests {
         });
     }
 }
+
+mod mutual_relationship {
+    #![allow(unused)]
+
+    use crate::schema::{AssocMap, Database, IDMap};
+    use microrm_macros::{Database, Entity};
+
+    #[derive(Entity)]
+    struct Customer {
+        name: String,
+        receipts: AssocMap<Receipt>,
+    }
+
+    #[derive(Entity)]
+    struct Receipt {
+        value: usize,
+        customers: AssocMap<Customer>,
+    }
+
+    #[derive(Database)]
+    struct ReceiptDB {
+        customers: IDMap<Customer>,
+        receipts: IDMap<Receipt>,
+    }
+
+    #[test]
+    fn check_schema_creation() {
+        let db = ReceiptDB::open_path(":memory:").expect("couldn't open in-memory database");
+    }
+}