"""
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}