pensieve/memos/models.py
2024-06-02 00:25:02 +08:00

136 lines
4.8 KiB
Python

from sqlalchemy import (
create_engine,
Integer,
String,
Text,
DateTime,
Enum,
ForeignKey,
func,
)
from datetime import datetime
from sqlalchemy.orm import relationship, DeclarativeBase, Mapped, mapped_column
from typing import List
from .config import get_database_path
from .schemas import MetadataSource, MetadataType
class Base(DeclarativeBase):
id: Mapped[int] = mapped_column(Integer, primary_key=True)
created_at: Mapped[datetime] = mapped_column(
DateTime, server_default=func.now(), nullable=False
)
updated_at: Mapped[datetime] = mapped_column(
DateTime, server_default=func.now(), onupdate=func.now(), nullable=False
)
class LibraryModel(Base):
__tablename__ = "libraries"
name: Mapped[str] = mapped_column(String, nullable=False)
folders: Mapped[List["FolderModel"]] = relationship(
"FolderModel", back_populates="library", lazy="joined"
)
plugins: Mapped[List["PluginModel"]] = relationship(
"LibraryPluginModel", back_populates="library", lazy="joined"
)
class FolderModel(Base):
__tablename__ = "folders"
path: Mapped[str] = mapped_column(String, nullable=False)
library_id: Mapped[int] = mapped_column(
Integer, ForeignKey("libraries.id"), nullable=False
)
library: Mapped["LibraryModel"] = relationship(
"LibraryModel", back_populates="folders"
)
entities: Mapped[List["EntityModel"]] = relationship(
"EntityModel", back_populates="folder"
)
class EntityModel(Base):
__tablename__ = "entities"
filepath: Mapped[str] = mapped_column(String, nullable=False)
filename: Mapped[str] = mapped_column(String, nullable=False)
size: Mapped[int] = mapped_column(Integer, nullable=False)
file_created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
file_last_modified_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
file_type: Mapped[str] = mapped_column(String, nullable=False)
last_scan_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
library_id: Mapped[int] = mapped_column(
Integer, ForeignKey("libraries.id"), nullable=False
)
folder_id: Mapped[int] = mapped_column(
Integer, ForeignKey("folders.id"), nullable=False
)
folder: Mapped["FolderModel"] = relationship(
"FolderModel", back_populates="entities"
)
metadata_entries: Mapped[List["EntityMetadataModel"]] = relationship(
"EntityMetadataModel"
)
tags: Mapped[List["TagModel"]] = relationship("EntityTagModel")
class TagModel(Base):
__tablename__ = "tags"
name: Mapped[str] = mapped_column(String, nullable=False)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
color: Mapped[str | None] = mapped_column(String, nullable=True)
source: Mapped[str | None] = mapped_column(String, nullable=True)
class EntityTagModel(Base):
__tablename__ = "entity_tags"
entity_id: Mapped[int] = mapped_column(
Integer, ForeignKey("entities.id"), nullable=False
)
tag_id: Mapped[int] = mapped_column(Integer, ForeignKey("tags.id"), nullable=False)
source: Mapped[MetadataSource] = mapped_column(Enum(MetadataSource), nullable=False)
class EntityMetadataModel(Base):
__tablename__ = "metadata_entries"
entity_id: Mapped[int] = mapped_column(
Integer, ForeignKey("entities.id"), nullable=False
)
key: Mapped[str] = mapped_column(String, nullable=False)
value: Mapped[str] = mapped_column(Text, nullable=False)
source_type: Mapped[MetadataSource] = mapped_column(
Enum(MetadataSource), nullable=False
)
source: Mapped[str | None] = mapped_column(String, nullable=True)
date_type: Mapped[MetadataType] = mapped_column(Enum(MetadataType), nullable=False)
entity = relationship("EntityModel", back_populates="metadata_entries")
class PluginModel(Base):
__tablename__ = "plugins"
name: Mapped[str] = mapped_column(String, nullable=False)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
webhook_url: Mapped[str] = mapped_column(String, nullable=False)
libraries = relationship("LibraryPluginModel", back_populates="plugin")
class LibraryPluginModel(Base):
__tablename__ = "library_plugins"
library_id: Mapped[int] = mapped_column(
Integer, ForeignKey("libraries.id"), nullable=False
)
plugin_id: Mapped[int] = mapped_column(
Integer, ForeignKey("plugins.id"), nullable=False
)
library: Mapped["LibraryModel"] = relationship(
"LibraryModel", back_populates="plugins"
)
plugin: Mapped["PluginModel"] = relationship(
"PluginModel", back_populates="libraries"
)
# Create the database engine with the path from config
engine = create_engine(f"sqlite:///{get_database_path()}")
Base.metadata.create_all(engine)