Преглед изворни кода

Add reverse relationship loading

theenglishway@shineon пре 6 година
родитељ
комит
f1ed8d91ce

+ 2 - 0
planner/models/comments.py

@@ -7,6 +7,8 @@ from .items import Item
 
 @dataclass(repr=False)
 class Comment(SchemaMixin, DbMixin):
+    cache_keys = ('item_id', 'date_added')
+
     document: dict
     text: str
     item_id: int = None

+ 9 - 0
planner/models/items.py

@@ -1,17 +1,22 @@
 from dataclasses import dataclass, field
 from datetime import datetime
+from typing import List
 
 from .mixins import SchemaMixin, DbMixin
 from .milestones import Milestone
 from .sprints import Sprint
+from planner import db
 
 
 @dataclass(repr=False)
 class Item(SchemaMixin, DbMixin):
+    cache_keys = ('name', 'milestone_id', 'sprint_id')
+
     document: dict
     name: str
     description: str
     category: str
+    comments: List['Comment'] = None
     milestone_id: int = None
     milestone: Milestone = field(init=False)
     sprint_id: int = None
@@ -61,6 +66,10 @@ class Item(SchemaMixin, DbMixin):
         self.milestone = Milestone.fetch(self.milestone_id) if self.milestone_id else None
         self.sprint = Sprint.fetch(self.sprint_id) if self.sprint_id else None
 
+    def load_reverse(self):
+        from .comments import Comment
+        self.comments = [Comment.get(d) for d in db.table(Comment.class_name()).all()]
+
     @classmethod
     def class_name(cls):
         return 'item'

+ 12 - 1
planner/models/milestones.py

@@ -1,16 +1,21 @@
 import click
+from typing import List
 
 from dataclasses import dataclass, field
 from datetime import datetime
 
+from planner import db
 from .mixins import SchemaMixin, DbMixin
 
 
 @dataclass(repr=False)
 class Milestone(SchemaMixin, DbMixin):
+    cache_keys = ('name',)
     document: dict
     name: str
     description: str
+    sprints: List['Sprint'] = None
+    items: List['Item'] = None
     uuid: str = None
     date_added: datetime = None
     date_expected: datetime = None
@@ -33,8 +38,14 @@ class Milestone(SchemaMixin, DbMixin):
             type: date
     """
 
+    def load_reverse(self):
+        from .items import Item
+        from .sprints import Sprint
+        self.items = [Item.get(d) for d in db.table(Item.class_name()).all()]
+        self.sprints = [Sprint.get(d) for d in db.table(Sprint.class_name()).all()]
+
     def __repr__(self):
         return "{}(name='{}')".format(self.__class__.__qualname__, self.name)
 
     def __terminal__(self):
-        return click.style(f"Milestone : {self.name}")
+        return click.style(f"Milestone : {self.name}, {self.sprints}, {self.items}")

+ 22 - 1
planner/models/mixins.py

@@ -23,13 +23,34 @@ class SchemaMixin:
 
 
 class DbMixin:
+    cache = {}
+    cache_keys = ()
+
     @classmethod
     def list(cls):
         return [cls.get(doc) for doc in db.table(cls.class_name()).all()]
 
+    @classmethod
+    def _get_cache_key(cls, document):
+        return tuple([cls] + [document[k] for k in cls.cache_keys])
+
+    def load_reverse(self):
+        ...
+
     @classmethod
     def get(cls, document):
-        return cls(document=document, **document)
+        key = cls._get_cache_key(document)
+        if key in cls.cache:
+            instance = cls.cache[key]
+        else:
+            instance = cls(document=document, **document)
+            # The cache is updated a first time so that instances looking up
+            # for this instance during the load_reverse can find it
+            cls.cache[key] = instance
+            instance.load_reverse()
+            # The cache value is updated with its final value
+            cls.cache[key] = instance
+        return instance
 
     @classmethod
     def fetch(cls, doc_id=None):

+ 11 - 2
planner/models/sprints.py

@@ -1,18 +1,22 @@
 from dataclasses import dataclass, field
 from datetime import datetime
-from copy import deepcopy
+from typing import List
 
 from .mixins import SchemaMixin, DbMixin
 from .milestones import Milestone
+from planner import db
 
 
 @dataclass(repr=False)
 class Sprint(SchemaMixin, DbMixin):
+    cache_keys = ('name',)
+
     document: dict
     name: str
     description: str
     milestone_id: int
     milestone: Milestone = field(init=False)
+    items: List['Item'] = None
     uuid: str = None
     date_added: datetime = None
     date_expected: datetime = None
@@ -36,11 +40,16 @@ class Sprint(SchemaMixin, DbMixin):
             type: datetime
             default_setter: utcnow
     """
+
     def __post_init__(self):
         self.milestone = Milestone.fetch(self.milestone_id)
 
+    def load_reverse(self):
+        from .items import Item
+        self.items = [Item.get(d) for d in db.table('item').all()]
+
     def __repr__(self):
         return "{}(name='{}', milestone='{}')".format(self.__class__.__qualname__, self.name, repr(self.milestone))
 
     def __terminal__(self):
-        return f"Sprint : {self.name}"
+        return f"Sprint : {self.name} ({self.items})"