6
0

Label.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. from __future__ import annotations
  2. from contextlib import closing
  3. from datetime import datetime
  4. from pycs import db
  5. from pycs.database.base import NamedBaseModel
  6. from pycs.database.util import commit_on_return
  7. def compare_children(start_label: Label, id: int):
  8. """ check for cyclic relationships """
  9. labels_to_check = [start_label]
  10. while labels_to_check:
  11. label = labels_to_check.pop(0)
  12. if label.id == id:
  13. return False
  14. labels_to_check.extend(label.children)
  15. return True
  16. class Label(NamedBaseModel):
  17. id = db.Column(db.Integer, primary_key=True)
  18. project_id = db.Column(
  19. db.Integer,
  20. db.ForeignKey("project.id", ondelete="CASCADE"),
  21. nullable=False)
  22. parent_id = db.Column(
  23. db.Integer,
  24. db.ForeignKey("label.id", ondelete="SET NULL"))
  25. created = db.Column(db.DateTime, default=datetime.utcnow,
  26. index=True, nullable=False)
  27. reference = db.Column(db.String)
  28. # contraints
  29. __table_args__ = (
  30. db.UniqueConstraint('project_id', 'reference'),
  31. )
  32. # relationships to other models
  33. parent = db.relationship("Label", backref="children", remote_side=[id])
  34. @commit_on_return
  35. def set_parent(self, parent_id: int, commit: bool = True):
  36. """
  37. set this labels parent
  38. :param parent_id: parent's id
  39. :return:
  40. """
  41. if not compare_children(self, parent_id):
  42. raise ValueError('Cyclic relationship detected!')
  43. self.parent_id = parent_id