Source code for ResearchNotes.database.documents

"""
All document related database schemes go here
"""

from dataclasses import dataclass
from datetime import datetime

# from typing import List, Set, Any  # Needs to be here for compatibility with python 3.8

# from ResearchNotes.search import add_to_index, remove_from_index, query_index, delete_index

from ResearchNotes.database import db
from ResearchNotes.database.mixins import SearchableMixin


# =============================================================================
# Many to many table for documents
# =============================================================================
DocGenerations = db.Table(
    "docsgeneration",
    db.Column("parent_id", db.Integer, db.ForeignKey("docs.id")),
    db.Column("child_id", db.Integer, db.ForeignKey("docs.id")),
)

# =============================================================================
# Documents database scheme for the Wki part
# =============================================================================


[docs]@dataclass(init=False, eq=False) class Documents(SearchableMixin, db.Model): # type: ignore """ Database structure for all the documents. Here we store all our documentation and use the data here to create the wiki. Backref and the function for children and parents relate the documents to each other. In praxis, we use the label to find the document and display title and body. Body can contain markdown and needs to be escaped before display. """ # id: int = field(init=False) # label: str # title: str # body: str # created: datetime = field(init=False) # updated: datetime = field(init=False) # # group_id: int # creator_id: int # updatetor_id: int __tablename__ = "docs" __searchable__ = ["title", "body", "label"] id: int = db.Column(db.Integer, primary_key=True) label: str = db.Column(db.String(80), nullable=False) title: str = db.Column(db.String(80), nullable=False) body: str = db.Column(db.Text, nullable=False) created: datetime = db.Column(db.DateTime, nullable=False, index=True, default=datetime.utcnow) updated: datetime = db.Column( db.DateTime, nullable=False, index=True, default=datetime.utcnow, onupdate=datetime.utcnow, ) group_id: int = db.Column(db.Integer, db.ForeignKey("groups.id")) creator_id: int = db.Column(db.Integer, db.ForeignKey("users.id")) updatetor_id: int = db.Column(db.Integer, db.ForeignKey("users.id")) children = db.relationship( "Documents", secondary="docsgeneration", primaryjoin=(DocGenerations.c.parent_id == id), secondaryjoin=(DocGenerations.c.child_id == id), backref="parent_docs", lazy="dynamic", ) def __repr__(self) -> str: """ Representation of the document class. Returns ------- str String containing id and label of document. """ return f"Document {self.id} with label: {self.label}"
[docs] def add_child(self, doc): """ Add document as a child to parent. Parameters ---------- doc : Document Document, we become a child from. Returns ------- None. """ if not self.is_child(doc): self.children.append(doc)
[docs] def remove_child(self, doc): """ Remove document form parent database entry. Parameters ---------- doc : Document Remove this document as child from parent document. Returns ------- None. """ if self.is_child(doc): self.children.remove(doc)
[docs] def is_child(self, doc) -> bool: """ Test, if a document is a child of document passed as doc. Parameters ---------- doc : Document Document to check, if we are already child from. Returns ------- bool True, if we are a child from. """ return self.children.filter(DocGenerations.c.child_id == doc.id).count() > 0
@property def childrenlist(self) -> set[int]: """ Create a list of all child documents ids. Returns ------- list[int] Children of the document. """ return {child.id for child in self.children}