Source code for platzky.db.db

"""Abstract base classes for database implementations."""

from abc import ABC, abstractmethod
from collections.abc import Callable
from functools import partial
from typing import Any

from pydantic import BaseModel, Field

from platzky.models import MenuItem, Page, Post
from platzky.plugin.plugin_config import PluginConfigBase


[docs] class DB(ABC): """Abstract base class for all database implementations.""" db_name: str = "DB" module_name: str = "db" config_type: type def __init_subclass__(cls, *args, **kw): """Check that all methods defined in the subclass exist in the superclasses. This is to prevent subclasses from splitting up DB interface. """ super().__init_subclass__(*args, **kw) for name in cls.__dict__: if name.startswith("_"): continue for superclass in cls.__mro__[1:]: if name in dir(superclass): break else: raise TypeError( f"Method {name} defined in {cls.__name__} does not exist in superclasses" )
[docs] def extend(self, function_name: str, function: Callable[..., Any]) -> None: """ Add a function to the DB object. The function must take the DB object as first parameter. Parameters: function_name (str): The name of the function to add. function (Callable): The function to add to the DB object. """ if not callable(function): raise ValueError(f"The provided func for '{function_name}' is not callable.") try: bound_function = partial(function, self) setattr(self, function_name, bound_function) except Exception as e: raise ValueError(f"Failed to extend DB with function {function_name}: {e}")
[docs] @abstractmethod def get_app_description(self, lang: str) -> str: """Retrieve the application description for a specific language. Args: lang: Language code (e.g., 'en', 'pl') """ pass
[docs] @abstractmethod def get_all_posts(self, lang: str) -> list[Post]: """Retrieve all posts for a specific language. Args: lang: Language code (e.g., 'en', 'pl') """ pass
[docs] @abstractmethod def get_menu_items_in_lang(self, lang: str) -> list[MenuItem]: """Retrieve menu items for a specific language. Args: lang: Language code (e.g., 'en', 'pl') """ pass
[docs] @abstractmethod def get_post(self, slug: str) -> Post: """Retrieve a single post by its slug. Args: slug: URL-friendly identifier for the post """ pass
[docs] @abstractmethod def get_page(self, slug: str) -> Page: """Retrieve a page by its slug. Args: slug: URL-friendly identifier for the page """ pass
[docs] @abstractmethod def get_posts_by_tag(self, tag: str, lang: str) -> list[Post]: """Retrieve posts filtered by tag and language. Args: tag: Tag name to filter by lang: Language code (e.g., 'en', 'pl') """ pass
[docs] @abstractmethod def add_comment(self, author_name: str, comment: str, post_slug: str) -> None: """Add a new comment to a post. Args: author_name: Name of the comment author comment: Comment text content post_slug: URL-friendly identifier of the post """ pass
[docs] @abstractmethod def get_logo_url(self) -> str: # TODO: Provide alternative text along with the URL of logo """Retrieve the URL of the application logo.""" pass
[docs] @abstractmethod def get_favicon_url(self) -> str: """Retrieve the URL of the application favicon.""" pass
[docs] @abstractmethod def get_primary_color(self) -> str: """Retrieve the primary color for the application theme.""" pass
[docs] @abstractmethod def get_secondary_color(self) -> str: """Retrieve the secondary color for the application theme.""" pass
[docs] @abstractmethod def get_plugins_data(self) -> list[PluginConfigBase]: """Retrieve configuration data for all plugins.""" pass
[docs] @abstractmethod def get_font(self) -> str: """Get the font configuration for the application.""" pass
[docs] @abstractmethod def health_check(self) -> None: """Perform a health check on the database. Should raise an exception if the database is not healthy. This should be a lightweight operation suitable for health checks. """ pass
[docs] class DBConfig(BaseModel): """Base configuration class for database connections.""" type: str = Field(alias="TYPE")