Refactor/define repository layer (#883)

* move data access layer

* rename dal -> repo
This commit is contained in:
Hayden 2021-12-18 20:52:36 -09:00 committed by GitHub
parent ea7c4771ee
commit 74e13682cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 371 additions and 369 deletions

View File

@ -10,8 +10,8 @@ from jose import JWTError, jwt
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_dirs, get_app_settings from mealie.core.config import get_app_dirs, get_app_settings
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.user import LongLiveTokenInDB, PrivateUser, TokenData from mealie.schema.user import LongLiveTokenInDB, PrivateUser, TokenData
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/token")
@ -74,7 +74,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme), session=Depends(
except JWTError: except JWTError:
raise credentials_exception raise credentials_exception
db = get_database(session) db = get_repositories(session)
user = db.users.get(token_data.username, "email", any_case=True) user = db.users.get(token_data.username, "email", any_case=True)
if user is None: if user is None:
@ -89,7 +89,7 @@ async def get_admin_user(current_user=Depends(get_current_user)) -> PrivateUser:
def validate_long_live_token(session: Session, client_token: str, id: int) -> PrivateUser: def validate_long_live_token(session: Session, client_token: str, id: int) -> PrivateUser:
db = get_database(session) db = get_repositories(session)
tokens: list[LongLiveTokenInDB] = db.api_tokens.get(id, "user_id", limit=9999) tokens: list[LongLiveTokenInDB] = db.api_tokens.get(id, "user_id", limit=9999)

View File

@ -8,8 +8,8 @@ from jose import jwt
from passlib.context import CryptContext from passlib.context import CryptContext
from mealie.core.config import get_app_settings from mealie.core.config import get_app_settings
from mealie.db.data_access_layer.access_model_factory import Database from mealie.repos.all_repositories import get_repositories
from mealie.db.database import get_database from mealie.repos.repository_factory import AllRepositories
from mealie.schema.user import PrivateUser from mealie.schema.user import PrivateUser
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@ -38,7 +38,7 @@ def create_recipe_slug_token(file_path: str) -> str:
return create_access_token(token_data, expires_delta=timedelta(minutes=30)) return create_access_token(token_data, expires_delta=timedelta(minutes=30))
def user_from_ldap(db: Database, session, username: str, password: str) -> PrivateUser: def user_from_ldap(db: AllRepositories, session, username: str, password: str) -> PrivateUser:
"""Given a username and password, tries to authenticate by BINDing to an """Given a username and password, tries to authenticate by BINDing to an
LDAP server LDAP server
@ -81,7 +81,7 @@ def user_from_ldap(db: Database, session, username: str, password: str) -> Priva
def authenticate_user(session, email: str, password: str) -> PrivateUser | bool: def authenticate_user(session, email: str, password: str) -> PrivateUser | bool:
settings = get_app_settings() settings = get_app_settings()
db = get_database(session) db = get_repositories(session)
user: PrivateUser = db.users.get(email, "email", any_case=True) user: PrivateUser = db.users.get(email, "email", any_case=True)
if not user: if not user:

View File

@ -1 +0,0 @@
from .access_model_factory import Database

View File

@ -1,178 +0,0 @@
from functools import cached_property
from sqlalchemy.orm import Session
from mealie.db.models.event import Event, EventNotification
from mealie.db.models.group import Group, GroupMealPlan, ReportEntryModel, ReportModel
from mealie.db.models.group.cookbook import CookBook
from mealie.db.models.group.exports import GroupDataExportsModel
from mealie.db.models.group.invite_tokens import GroupInviteToken
from mealie.db.models.group.preferences import GroupPreferencesModel
from mealie.db.models.group.webhooks import GroupWebhooksModel
from mealie.db.models.recipe.category import Category
from mealie.db.models.recipe.comment import RecipeComment
from mealie.db.models.recipe.ingredient import IngredientFoodModel, IngredientUnitModel
from mealie.db.models.recipe.recipe import RecipeModel
from mealie.db.models.recipe.shared import RecipeShareTokenModel
from mealie.db.models.recipe.tag import Tag
from mealie.db.models.recipe.tool import Tool
from mealie.db.models.server.task import ServerTaskModel
from mealie.db.models.sign_up import SignUp
from mealie.db.models.users import LongLiveToken, User
from mealie.db.models.users.password_reset import PasswordResetModel
from mealie.schema.cookbook.cookbook import ReadCookBook
from mealie.schema.events import Event as EventSchema
from mealie.schema.events import EventNotificationIn
from mealie.schema.group.group_exports import GroupDataExport
from mealie.schema.group.group_preferences import ReadGroupPreferences
from mealie.schema.group.invite_token import ReadInviteToken
from mealie.schema.group.webhook import ReadWebhook
from mealie.schema.meal_plan.new_meal import ReadPlanEntry
from mealie.schema.recipe import Recipe, RecipeCategoryResponse, RecipeCommentOut, RecipeTagResponse, RecipeTool
from mealie.schema.recipe.recipe_ingredient import IngredientFood, IngredientUnit
from mealie.schema.recipe.recipe_share_token import RecipeShareToken
from mealie.schema.reports.reports import ReportEntryOut, ReportOut
from mealie.schema.server import ServerTask
from mealie.schema.user import GroupInDB, LongLiveTokenInDB, PrivateUser, SignUpOut
from mealie.schema.user.user_passwords import PrivatePasswordResetToken
from ._access_model import AccessModel
from .group_access_model import GroupDataAccessModel
from .meal_access_model import MealDataAccessModel
from .recipe_access_model import RecipeDataAccessModel
from .user_access_model import UserDataAccessModel
pk_id = "id"
pk_slug = "slug"
pk_token = "token"
pk_group_id = "group_id"
class CategoryDataAccessModel(AccessModel):
def get_empty(self):
return self.session.query(Category).filter(~Category.recipes.any()).all()
class TagsDataAccessModel(AccessModel):
def get_empty(self):
return self.session.query(Tag).filter(~Tag.recipes.any()).all()
class Database:
def __init__(self, session: Session) -> None:
"""
`DatabaseAccessLayer` class is the data access layer for all database actions within
Mealie. Database uses composition from classes derived from AccessModel. These
can be substantiated from the AccessModel class or through inheritance when
additional methods are required.
"""
self.session = session
# ================================================================
# Recipe Items
@cached_property
def recipes(self) -> RecipeDataAccessModel:
return RecipeDataAccessModel(self.session, pk_slug, RecipeModel, Recipe)
@cached_property
def ingredient_foods(self) -> AccessModel[IngredientFood, IngredientFoodModel]:
return AccessModel(self.session, pk_id, IngredientFoodModel, IngredientFood)
@cached_property
def ingredient_units(self) -> AccessModel[IngredientUnit, IngredientUnitModel]:
return AccessModel(self.session, pk_id, IngredientUnitModel, IngredientUnit)
@cached_property
def tools(self) -> AccessModel[RecipeTool, Tool]:
return AccessModel(self.session, pk_id, Tool, RecipeTool)
@cached_property
def comments(self) -> AccessModel[RecipeCommentOut, RecipeComment]:
return AccessModel(self.session, pk_id, RecipeComment, RecipeCommentOut)
@cached_property
def categories(self) -> CategoryDataAccessModel:
return CategoryDataAccessModel(self.session, pk_slug, Category, RecipeCategoryResponse)
@cached_property
def tags(self) -> TagsDataAccessModel:
return TagsDataAccessModel(self.session, pk_slug, Tag, RecipeTagResponse)
@cached_property
def recipe_share_tokens(self) -> AccessModel[RecipeShareToken, RecipeShareTokenModel]:
return AccessModel(self.session, pk_id, RecipeShareTokenModel, RecipeShareToken)
# ================================================================
# Site Items
@cached_property
def sign_up(self) -> AccessModel[SignUpOut, SignUp]:
return AccessModel(self.session, pk_id, SignUp, SignUpOut)
@cached_property
def event_notifications(self) -> AccessModel[EventNotificationIn, EventNotification]:
return AccessModel(self.session, pk_id, EventNotification, EventNotificationIn)
@cached_property
def events(self) -> AccessModel[EventSchema, Event]:
return AccessModel(self.session, pk_id, Event, EventSchema)
# ================================================================
# User Items
@cached_property
def users(self) -> UserDataAccessModel:
return UserDataAccessModel(self.session, pk_id, User, PrivateUser)
@cached_property
def api_tokens(self) -> AccessModel[LongLiveTokenInDB, LongLiveToken]:
return AccessModel(self.session, pk_id, LongLiveToken, LongLiveTokenInDB)
@cached_property
def tokens_pw_reset(self) -> AccessModel[PrivatePasswordResetToken, PasswordResetModel]:
return AccessModel(self.session, pk_token, PasswordResetModel, PrivatePasswordResetToken)
# ================================================================
# Group Items
@cached_property
def server_tasks(self) -> AccessModel[ServerTask, ServerTaskModel]:
return AccessModel(self.session, pk_id, ServerTaskModel, ServerTask)
@cached_property
def groups(self) -> GroupDataAccessModel:
return GroupDataAccessModel(self.session, pk_id, Group, GroupInDB)
@cached_property
def group_invite_tokens(self) -> AccessModel[ReadInviteToken, GroupInviteToken]:
return AccessModel(self.session, pk_token, GroupInviteToken, ReadInviteToken)
@cached_property
def group_preferences(self) -> AccessModel[ReadGroupPreferences, GroupPreferencesModel]:
return AccessModel(self.session, pk_group_id, GroupPreferencesModel, ReadGroupPreferences)
@cached_property
def group_exports(self) -> AccessModel[GroupDataExport, GroupDataExportsModel]:
return AccessModel(self.session, pk_id, GroupDataExportsModel, GroupDataExport)
@cached_property
def meals(self) -> MealDataAccessModel:
return MealDataAccessModel(self.session, pk_id, GroupMealPlan, ReadPlanEntry)
@cached_property
def cookbooks(self) -> AccessModel[ReadCookBook, CookBook]:
return AccessModel(self.session, pk_id, CookBook, ReadCookBook)
@cached_property
def webhooks(self) -> AccessModel[ReadWebhook, GroupWebhooksModel]:
return AccessModel(self.session, pk_id, GroupWebhooksModel, ReadWebhook)
@cached_property
def group_reports(self) -> AccessModel[ReportOut, ReportModel]:
return AccessModel(self.session, pk_id, ReportModel, ReportOut)
@cached_property
def group_report_entries(self) -> AccessModel[ReportEntryOut, ReportEntryModel]:
return AccessModel(self.session, pk_id, ReportEntryModel, ReportEntryOut)

View File

@ -1,7 +0,0 @@
from sqlalchemy.orm import Session
from .data_access_layer.access_model_factory import Database
def get_database(session: Session):
return Database(session)

View File

@ -1,11 +1,11 @@
from mealie.core import root_logger from mealie.core import root_logger
from mealie.core.config import get_app_settings from mealie.core.config import get_app_settings
from mealie.db.data_access_layer.access_model_factory import Database
from mealie.db.data_initialization.init_units_foods import default_recipe_unit_init
from mealie.db.data_initialization.init_users import default_user_init
from mealie.db.database import get_database
from mealie.db.db_setup import create_session, engine from mealie.db.db_setup import create_session, engine
from mealie.db.models._model_base import SqlAlchemyBase from mealie.db.models._model_base import SqlAlchemyBase
from mealie.repos.all_repositories import get_repositories
from mealie.repos.repository_factory import AllRepositories
from mealie.repos.seed.init_units_foods import default_recipe_unit_init
from mealie.repos.seed.init_users import default_user_init
from mealie.schema.user.user import GroupBase from mealie.schema.user.user import GroupBase
from mealie.services.events import create_general_event from mealie.services.events import create_general_event
from mealie.services.group_services.group_utils import create_new_group from mealie.services.group_services.group_utils import create_new_group
@ -21,13 +21,13 @@ def create_all_models():
SqlAlchemyBase.metadata.create_all(engine) SqlAlchemyBase.metadata.create_all(engine)
def init_db(db: Database) -> None: def init_db(db: AllRepositories) -> None:
default_group_init(db) default_group_init(db)
default_user_init(db) default_user_init(db)
default_recipe_unit_init(db) default_recipe_unit_init(db)
def default_group_init(db: Database): def default_group_init(db: AllRepositories):
logger.info("Generating Default Group") logger.info("Generating Default Group")
create_new_group(db, GroupBase(name=settings.DEFAULT_GROUP)) create_new_group(db, GroupBase(name=settings.DEFAULT_GROUP))
@ -36,7 +36,7 @@ def main():
create_all_models() create_all_models()
session = create_session() session = create_session()
db = get_database(session) db = get_repositories(session)
try: try:
init_user = db.users.get_all() init_user = db.users.get_all()

1
mealie/repos/__init__.py Normal file
View File

@ -0,0 +1 @@
from .repository_factory import AllRepositories

View File

@ -0,0 +1,7 @@
from sqlalchemy.orm import Session
from .repository_factory import AllRepositories
def get_repositories(session: Session):
return AllRepositories(session)

View File

@ -0,0 +1,178 @@
from functools import cached_property
from sqlalchemy.orm import Session
from mealie.db.models.event import Event, EventNotification
from mealie.db.models.group import Group, GroupMealPlan, ReportEntryModel, ReportModel
from mealie.db.models.group.cookbook import CookBook
from mealie.db.models.group.exports import GroupDataExportsModel
from mealie.db.models.group.invite_tokens import GroupInviteToken
from mealie.db.models.group.preferences import GroupPreferencesModel
from mealie.db.models.group.webhooks import GroupWebhooksModel
from mealie.db.models.recipe.category import Category
from mealie.db.models.recipe.comment import RecipeComment
from mealie.db.models.recipe.ingredient import IngredientFoodModel, IngredientUnitModel
from mealie.db.models.recipe.recipe import RecipeModel
from mealie.db.models.recipe.shared import RecipeShareTokenModel
from mealie.db.models.recipe.tag import Tag
from mealie.db.models.recipe.tool import Tool
from mealie.db.models.server.task import ServerTaskModel
from mealie.db.models.sign_up import SignUp
from mealie.db.models.users import LongLiveToken, User
from mealie.db.models.users.password_reset import PasswordResetModel
from mealie.schema.cookbook.cookbook import ReadCookBook
from mealie.schema.events import Event as EventSchema
from mealie.schema.events import EventNotificationIn
from mealie.schema.group.group_exports import GroupDataExport
from mealie.schema.group.group_preferences import ReadGroupPreferences
from mealie.schema.group.invite_token import ReadInviteToken
from mealie.schema.group.webhook import ReadWebhook
from mealie.schema.meal_plan.new_meal import ReadPlanEntry
from mealie.schema.recipe import Recipe, RecipeCategoryResponse, RecipeCommentOut, RecipeTagResponse, RecipeTool
from mealie.schema.recipe.recipe_ingredient import IngredientFood, IngredientUnit
from mealie.schema.recipe.recipe_share_token import RecipeShareToken
from mealie.schema.reports.reports import ReportEntryOut, ReportOut
from mealie.schema.server import ServerTask
from mealie.schema.user import GroupInDB, LongLiveTokenInDB, PrivateUser, SignUpOut
from mealie.schema.user.user_passwords import PrivatePasswordResetToken
from .repository_generic import RepositoryGeneric
from .repository_group import RepositoryGroup
from .repository_meals import RepositoryMeals
from .repository_recipes import RepositoryRecipes
from .repository_users import RepositoryUsers
pk_id = "id"
pk_slug = "slug"
pk_token = "token"
pk_group_id = "group_id"
class RepositoryCategories(RepositoryGeneric):
def get_empty(self):
return self.session.query(Category).filter(~Category.recipes.any()).all()
class RepositoryTags(RepositoryGeneric):
def get_empty(self):
return self.session.query(Tag).filter(~Tag.recipes.any()).all()
class AllRepositories:
def __init__(self, session: Session) -> None:
"""
`AllRepositories` class is the data access layer for all database actions within
Mealie. Database uses composition from classes derived from AccessModel. These
can be substantiated from the AccessModel class or through inheritance when
additional methods are required.
"""
self.session = session
# ================================================================
# Recipe Items
@cached_property
def recipes(self) -> RepositoryRecipes:
return RepositoryRecipes(self.session, pk_slug, RecipeModel, Recipe)
@cached_property
def ingredient_foods(self) -> RepositoryGeneric[IngredientFood, IngredientFoodModel]:
return RepositoryGeneric(self.session, pk_id, IngredientFoodModel, IngredientFood)
@cached_property
def ingredient_units(self) -> RepositoryGeneric[IngredientUnit, IngredientUnitModel]:
return RepositoryGeneric(self.session, pk_id, IngredientUnitModel, IngredientUnit)
@cached_property
def tools(self) -> RepositoryGeneric[RecipeTool, Tool]:
return RepositoryGeneric(self.session, pk_id, Tool, RecipeTool)
@cached_property
def comments(self) -> RepositoryGeneric[RecipeCommentOut, RecipeComment]:
return RepositoryGeneric(self.session, pk_id, RecipeComment, RecipeCommentOut)
@cached_property
def categories(self) -> RepositoryCategories:
return RepositoryCategories(self.session, pk_slug, Category, RecipeCategoryResponse)
@cached_property
def tags(self) -> RepositoryTags:
return RepositoryTags(self.session, pk_slug, Tag, RecipeTagResponse)
@cached_property
def recipe_share_tokens(self) -> RepositoryGeneric[RecipeShareToken, RecipeShareTokenModel]:
return RepositoryGeneric(self.session, pk_id, RecipeShareTokenModel, RecipeShareToken)
# ================================================================
# Site Items
@cached_property
def sign_up(self) -> RepositoryGeneric[SignUpOut, SignUp]:
return RepositoryGeneric(self.session, pk_id, SignUp, SignUpOut)
@cached_property
def event_notifications(self) -> RepositoryGeneric[EventNotificationIn, EventNotification]:
return RepositoryGeneric(self.session, pk_id, EventNotification, EventNotificationIn)
@cached_property
def events(self) -> RepositoryGeneric[EventSchema, Event]:
return RepositoryGeneric(self.session, pk_id, Event, EventSchema)
# ================================================================
# User Items
@cached_property
def users(self) -> RepositoryUsers:
return RepositoryUsers(self.session, pk_id, User, PrivateUser)
@cached_property
def api_tokens(self) -> RepositoryGeneric[LongLiveTokenInDB, LongLiveToken]:
return RepositoryGeneric(self.session, pk_id, LongLiveToken, LongLiveTokenInDB)
@cached_property
def tokens_pw_reset(self) -> RepositoryGeneric[PrivatePasswordResetToken, PasswordResetModel]:
return RepositoryGeneric(self.session, pk_token, PasswordResetModel, PrivatePasswordResetToken)
# ================================================================
# Group Items
@cached_property
def server_tasks(self) -> RepositoryGeneric[ServerTask, ServerTaskModel]:
return RepositoryGeneric(self.session, pk_id, ServerTaskModel, ServerTask)
@cached_property
def groups(self) -> RepositoryGroup:
return RepositoryGroup(self.session, pk_id, Group, GroupInDB)
@cached_property
def group_invite_tokens(self) -> RepositoryGeneric[ReadInviteToken, GroupInviteToken]:
return RepositoryGeneric(self.session, pk_token, GroupInviteToken, ReadInviteToken)
@cached_property
def group_preferences(self) -> RepositoryGeneric[ReadGroupPreferences, GroupPreferencesModel]:
return RepositoryGeneric(self.session, pk_group_id, GroupPreferencesModel, ReadGroupPreferences)
@cached_property
def group_exports(self) -> RepositoryGeneric[GroupDataExport, GroupDataExportsModel]:
return RepositoryGeneric(self.session, pk_id, GroupDataExportsModel, GroupDataExport)
@cached_property
def meals(self) -> RepositoryMeals:
return RepositoryMeals(self.session, pk_id, GroupMealPlan, ReadPlanEntry)
@cached_property
def cookbooks(self) -> RepositoryGeneric[ReadCookBook, CookBook]:
return RepositoryGeneric(self.session, pk_id, CookBook, ReadCookBook)
@cached_property
def webhooks(self) -> RepositoryGeneric[ReadWebhook, GroupWebhooksModel]:
return RepositoryGeneric(self.session, pk_id, GroupWebhooksModel, ReadWebhook)
@cached_property
def group_reports(self) -> RepositoryGeneric[ReportOut, ReportModel]:
return RepositoryGeneric(self.session, pk_id, ReportModel, ReportOut)
@cached_property
def group_report_entries(self) -> RepositoryGeneric[ReportEntryOut, ReportEntryModel]:
return RepositoryGeneric(self.session, pk_id, ReportEntryModel, ReportEntryOut)

View File

@ -16,7 +16,7 @@ T = TypeVar("T")
D = TypeVar("D") D = TypeVar("D")
class AccessModel(Generic[T, D]): class RepositoryGeneric(Generic[T, D]):
"""A Generic BaseAccess Model method to perform common operations on the database """A Generic BaseAccess Model method to perform common operations on the database
Args: Args:
@ -40,12 +40,12 @@ class AccessModel(Generic[T, D]):
def subscribe(self, func: Callable) -> None: def subscribe(self, func: Callable) -> None:
self.observers.append(func) self.observers.append(func)
def by_user(self, user_id: UUID4) -> AccessModel: def by_user(self, user_id: UUID4) -> RepositoryGeneric:
self.limit_by_user = True self.limit_by_user = True
self.user_id = user_id self.user_id = user_id
return self return self
def by_group(self, group_id: UUID) -> AccessModel: def by_group(self, group_id: UUID) -> RepositoryGeneric:
self.limit_by_group = True self.limit_by_group = True
self.group_id = group_id self.group_id = group_id
return self return self

View File

@ -4,10 +4,10 @@ from mealie.db.models.group import Group
from mealie.schema.meal_plan.meal import MealPlanOut from mealie.schema.meal_plan.meal import MealPlanOut
from mealie.schema.user.user import GroupInDB from mealie.schema.user.user import GroupInDB
from ._access_model import AccessModel from .repository_generic import RepositoryGeneric
class GroupDataAccessModel(AccessModel[GroupInDB, Group]): class RepositoryGroup(RepositoryGeneric[GroupInDB, Group]):
def get_meals(self, session: Session, match_value: str, match_key: str = "name") -> list[MealPlanOut]: def get_meals(self, session: Session, match_value: str, match_key: str = "name") -> list[MealPlanOut]:
"""A Helper function to get the group from the database and return a sorted list of """A Helper function to get the group from the database and return a sorted list of

View File

@ -4,10 +4,10 @@ from uuid import UUID
from mealie.db.models.group import GroupMealPlan from mealie.db.models.group import GroupMealPlan
from mealie.schema.meal_plan.new_meal import ReadPlanEntry from mealie.schema.meal_plan.new_meal import ReadPlanEntry
from ._access_model import AccessModel from .repository_generic import RepositoryGeneric
class MealDataAccessModel(AccessModel[ReadPlanEntry, GroupMealPlan]): class RepositoryMeals(RepositoryGeneric[ReadPlanEntry, GroupMealPlan]):
def get_slice(self, start: date, end: date, group_id: UUID) -> list[ReadPlanEntry]: def get_slice(self, start: date, end: date, group_id: UUID) -> list[ReadPlanEntry]:
start = start.strftime("%Y-%m-%d") start = start.strftime("%Y-%m-%d")
end = end.strftime("%Y-%m-%d") end = end.strftime("%Y-%m-%d")

View File

@ -8,10 +8,10 @@ from mealie.db.models.recipe.recipe import RecipeModel
from mealie.db.models.recipe.settings import RecipeSettings from mealie.db.models.recipe.settings import RecipeSettings
from mealie.schema.recipe import Recipe from mealie.schema.recipe import Recipe
from ._access_model import AccessModel from .repository_generic import RepositoryGeneric
class RecipeDataAccessModel(AccessModel[Recipe, RecipeModel]): class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
def get_all_public(self, limit: int = None, order_by: str = None, start=0, override_schema=None): def get_all_public(self, limit: int = None, order_by: str = None, start=0, override_schema=None):
eff_schema = override_schema or self.schema eff_schema = override_schema or self.schema

View File

@ -4,10 +4,10 @@ import shutil
from mealie.assets import users as users_assets from mealie.assets import users as users_assets
from mealie.schema.user.user import PrivateUser, User from mealie.schema.user.user import PrivateUser, User
from ._access_model import AccessModel from .repository_generic import RepositoryGeneric
class UserDataAccessModel(AccessModel[PrivateUser, User]): class RepositoryUsers(RepositoryGeneric[PrivateUser, User]):
def update_password(self, id, password: str): def update_password(self, id, password: str):
entry = self._query_one(match_value=id) entry = self._query_one(match_value=id)
entry.update_password(password) entry.update_password(password)

View File

@ -2,7 +2,7 @@ import json
from pathlib import Path from pathlib import Path
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.data_access_layer.access_model_factory import Database from mealie.repos.repository_factory import AllRepositories
from mealie.schema.recipe import CreateIngredientFood, CreateIngredientUnit from mealie.schema.recipe import CreateIngredientFood, CreateIngredientUnit
CWD = Path(__file__).parent CWD = Path(__file__).parent
@ -21,7 +21,7 @@ def get_default_units() -> dict[str, str]:
return units return units
def default_recipe_unit_init(db: Database) -> None: def default_recipe_unit_init(db: AllRepositories) -> None:
for unit in get_default_units().values(): for unit in get_default_units().values():
try: try:
db.ingredient_units.create( db.ingredient_units.create(

View File

@ -1,7 +1,7 @@
from mealie.core import root_logger from mealie.core import root_logger
from mealie.core.config import get_app_settings from mealie.core.config import get_app_settings
from mealie.core.security import hash_password from mealie.core.security import hash_password
from mealie.db.data_access_layer.access_model_factory import Database from mealie.repos.repository_factory import AllRepositories
logger = root_logger.get_logger("init_users") logger = root_logger.get_logger("init_users")
settings = get_app_settings() settings = get_app_settings()
@ -44,7 +44,7 @@ def dev_users() -> list[dict]:
] ]
def default_user_init(db: Database): def default_user_init(db: AllRepositories):
default_user = { default_user = {
"full_name": "Change Me", "full_name": "Change Me",
"username": "admin", "username": "admin",

View File

@ -2,8 +2,8 @@ from fastapi import Depends
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter from mealie.routes.routers import AdminAPIRouter
from mealie.schema.events import EventsOut from mealie.schema.events import EventsOut
@ -15,7 +15,7 @@ logger = get_logger()
@router.get("", response_model=EventsOut) @router.get("", response_model=EventsOut)
async def get_events(session: Session = Depends(generate_session)): async def get_events(session: Session = Depends(generate_session)):
"""Get event from the Database""" """Get event from the Database"""
db = get_database(session) db = get_repositories(session)
return EventsOut(total=db.events.count_all(), events=db.events.get_all(order_by="time_stamp")) return EventsOut(total=db.events.count_all(), events=db.events.get_all(order_by="time_stamp"))
@ -23,7 +23,7 @@ async def get_events(session: Session = Depends(generate_session)):
@router.delete("") @router.delete("")
async def delete_events(session: Session = Depends(generate_session)): async def delete_events(session: Session = Depends(generate_session)):
"""Get event from the Database""" """Get event from the Database"""
db = get_database(session) db = get_repositories(session)
db.events.delete_all() db.events.delete_all()
return {"message": "All events deleted"} return {"message": "All events deleted"}
@ -31,5 +31,5 @@ async def delete_events(session: Session = Depends(generate_session)):
@router.delete("/{id}") @router.delete("/{id}")
async def delete_event(id: int, session: Session = Depends(generate_session)): async def delete_event(id: int, session: Session = Depends(generate_session)):
"""Delete event from the Database""" """Delete event from the Database"""
db = get_database(session) db = get_repositories(session)
return db.events.delete(id) return db.events.delete(id)

View File

@ -4,8 +4,8 @@ from fastapi import Depends, status
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter from mealie.routes.routers import AdminAPIRouter
from mealie.schema.events import EventNotificationIn, EventNotificationOut, TestEvent from mealie.schema.events import EventNotificationIn, EventNotificationOut, TestEvent
from mealie.services.events import test_notification from mealie.services.events import test_notification
@ -21,7 +21,7 @@ async def create_event_notification(
session: Session = Depends(generate_session), session: Session = Depends(generate_session),
): ):
"""Create event_notification in the Database""" """Create event_notification in the Database"""
db = get_database(session) db = get_repositories(session)
return db.event_notifications.create(event_data) return db.event_notifications.create(event_data)
@ -32,7 +32,7 @@ async def test_notification_route(
session: Session = Depends(generate_session), session: Session = Depends(generate_session),
): ):
"""Create event_notification in the Database""" """Create event_notification in the Database"""
db = get_database(session) db = get_repositories(session)
if test_data.id: if test_data.id:
event_obj: EventNotificationIn = db.event_notifications.get(test_data.id) event_obj: EventNotificationIn = db.event_notifications.get(test_data.id)
@ -48,7 +48,7 @@ async def test_notification_route(
@router.get("/notifications", response_model=list[EventNotificationOut]) @router.get("/notifications", response_model=list[EventNotificationOut])
async def get_all_event_notification(session: Session = Depends(generate_session)): async def get_all_event_notification(session: Session = Depends(generate_session)):
"""Get all event_notification from the Database""" """Get all event_notification from the Database"""
db = get_database(session) db = get_repositories(session)
return db.event_notifications.get_all(override_schema=EventNotificationOut) return db.event_notifications.get_all(override_schema=EventNotificationOut)
@ -63,5 +63,5 @@ async def update_event_notification(id: int, session: Session = Depends(generate
async def delete_event_notification(id: int, session: Session = Depends(generate_session)): async def delete_event_notification(id: int, session: Session = Depends(generate_session)):
"""Delete event_notification from the Database""" """Delete event_notification from the Database"""
# Delete Item # Delete Item
db = get_database(session) db = get_repositories(session)
return db.event_notifications.delete(id) return db.event_notifications.delete(id)

View File

@ -4,8 +4,8 @@ from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_settings from mealie.core.config import get_app_settings
from mealie.core.release_checker import get_latest_version from mealie.core.release_checker import get_latest_version
from mealie.core.settings.static import APP_VERSION from mealie.core.settings.static import APP_VERSION
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.admin.about import AdminAboutInfo, AppStatistics, CheckAppConfig from mealie.schema.admin.about import AdminAboutInfo, AppStatistics, CheckAppConfig
router = APIRouter(prefix="/about") router = APIRouter(prefix="/about")
@ -31,7 +31,7 @@ async def get_app_info():
@router.get("/statistics", response_model=AppStatistics) @router.get("/statistics", response_model=AppStatistics)
async def get_app_statistics(session: Session = Depends(generate_session)): async def get_app_statistics(session: Session = Depends(generate_session)):
db = get_database(session) db = get_repositories(session)
return AppStatistics( return AppStatistics(
total_recipes=db.recipes.count_all(), total_recipes=db.recipes.count_all(),
uncategorized_recipes=db.recipes.count_uncategorized(), uncategorized_recipes=db.recipes.count_uncategorized(),

View File

@ -3,8 +3,8 @@ from sqlalchemy.orm.session import Session
from mealie.core.dependencies import is_logged_in from mealie.core.dependencies import is_logged_in
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse
@ -17,14 +17,14 @@ logger = get_logger()
@public_router.get("") @public_router.get("")
async def get_all_recipe_categories(session: Session = Depends(generate_session)): async def get_all_recipe_categories(session: Session = Depends(generate_session)):
"""Returns a list of available categories in the database""" """Returns a list of available categories in the database"""
db = get_database(session) db = get_repositories(session)
return db.categories.get_all_limit_columns(fields=["slug", "name"]) return db.categories.get_all_limit_columns(fields=["slug", "name"])
@public_router.get("/empty") @public_router.get("/empty")
def get_empty_categories(session: Session = Depends(generate_session)): def get_empty_categories(session: Session = Depends(generate_session)):
"""Returns a list of categories that do not contain any recipes""" """Returns a list of categories that do not contain any recipes"""
db = get_database(session) db = get_repositories(session)
return db.categories.get_empty() return db.categories.get_empty()
@ -33,7 +33,7 @@ def get_all_recipes_by_category(
category: str, session: Session = Depends(generate_session), is_user: bool = Depends(is_logged_in) category: str, session: Session = Depends(generate_session), is_user: bool = Depends(is_logged_in)
): ):
"""Returns a list of recipes associated with the provided category.""" """Returns a list of recipes associated with the provided category."""
db = get_database(session) db = get_repositories(session)
category_obj = db.categories.get(category) category_obj = db.categories.get(category)
category_obj = RecipeCategoryResponse.from_orm(category_obj) category_obj = RecipeCategoryResponse.from_orm(category_obj)
@ -47,7 +47,7 @@ def get_all_recipes_by_category(
@user_router.post("") @user_router.post("")
async def create_recipe_category(category: CategoryIn, session: Session = Depends(generate_session)): async def create_recipe_category(category: CategoryIn, session: Session = Depends(generate_session)):
"""Creates a Category in the database""" """Creates a Category in the database"""
db = get_database(session) db = get_repositories(session)
try: try:
return db.categories.create(category.dict()) return db.categories.create(category.dict())
@ -58,7 +58,7 @@ async def create_recipe_category(category: CategoryIn, session: Session = Depend
@admin_router.put("/{category}", response_model=RecipeCategoryResponse) @admin_router.put("/{category}", response_model=RecipeCategoryResponse)
async def update_recipe_category(category: str, new_category: CategoryIn, session: Session = Depends(generate_session)): async def update_recipe_category(category: str, new_category: CategoryIn, session: Session = Depends(generate_session)):
"""Updates an existing Tag in the database""" """Updates an existing Tag in the database"""
db = get_database(session) db = get_repositories(session)
try: try:
return db.categories.update(category, new_category.dict()) return db.categories.update(category, new_category.dict())
@ -74,7 +74,7 @@ async def delete_recipe_category(category: str, session: Session = Depends(gener
category does not impact a recipe. The category will be removed category does not impact a recipe. The category will be removed
from any recipes that contain it from any recipes that contain it
""" """
db = get_database(session) db = get_repositories(session)
try: try:
db.categories.delete(category) db.categories.delete(category)

View File

@ -1,8 +1,8 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.recipe import RecipeSummary from mealie.schema.recipe import RecipeSummary
router = APIRouter() router = APIRouter()
@ -10,11 +10,11 @@ router = APIRouter()
@router.get("/summary/untagged", response_model=list[RecipeSummary]) @router.get("/summary/untagged", response_model=list[RecipeSummary])
async def get_untagged_recipes(count: bool = False, session: Session = Depends(generate_session)): async def get_untagged_recipes(count: bool = False, session: Session = Depends(generate_session)):
db = get_database(session) db = get_repositories(session)
return db.recipes.count_untagged(count=count, override_schema=RecipeSummary) return db.recipes.count_untagged(count=count, override_schema=RecipeSummary)
@router.get("/summary/uncategorized", response_model=list[RecipeSummary]) @router.get("/summary/uncategorized", response_model=list[RecipeSummary])
async def get_uncategorized_recipes(count: bool = False, session: Session = Depends(generate_session)): async def get_uncategorized_recipes(count: bool = False, session: Session = Depends(generate_session)):
db = get_database(session) db = get_repositories(session)
return db.recipes.count_uncategorized(count=count, override_schema=RecipeSummary) return db.recipes.count_uncategorized(count=count, override_schema=RecipeSummary)

View File

@ -1,8 +1,8 @@
from fastapi import Depends from fastapi import Depends
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.schema.recipe.recipe_comments import RecipeCommentOut from mealie.schema.recipe.recipe_comments import RecipeCommentOut
@ -15,6 +15,6 @@ async def get_recipe_comments(
session: Session = Depends(generate_session), session: Session = Depends(generate_session),
): ):
"""Get all comments for a recipe""" """Get all comments for a recipe"""
db = get_database(session) db = get_repositories(session)
recipe = db.recipes.get_one(slug) recipe = db.recipes.get_one(slug)
return db.comments.multi_query({"recipe_id": recipe.id}) return db.comments.multi_query({"recipe_id": recipe.id})

View File

@ -5,8 +5,8 @@ from fastapi.datastructures import UploadFile
from slugify import slugify from slugify import slugify
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.schema.recipe import CreateRecipeByUrl, Recipe, RecipeAsset from mealie.schema.recipe import CreateRecipeByUrl, Recipe, RecipeAsset
from mealie.services.image.image import scrape_image, write_image from mealie.services.image.image import scrape_image, write_image
@ -29,7 +29,7 @@ def update_recipe_image(
session: Session = Depends(generate_session), session: Session = Depends(generate_session),
): ):
"""Removes an existing image and replaces it with the incoming file.""" """Removes an existing image and replaces it with the incoming file."""
db = get_database(session) db = get_repositories(session)
write_image(slug, image, extension) write_image(slug, image, extension)
new_version = db.recipes.update_image(slug, extension) new_version = db.recipes.update_image(slug, extension)
@ -56,7 +56,7 @@ def upload_recipe_asset(
if not dest.is_file(): if not dest.is_file():
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR) raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
db = get_database(session) db = get_repositories(session)
recipe: Recipe = db.recipes.get(slug) recipe: Recipe = db.recipes.get(slug)
recipe.assets.append(asset_in) recipe.assets.append(asset_in)

View File

@ -6,7 +6,7 @@ from sqlalchemy.orm.session import Session
from mealie.core.dependencies import temporary_zip_path from mealie.core.dependencies import temporary_zip_path
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.database import get_database from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.schema.recipe import CreateRecipeByUrl, Recipe from mealie.schema.recipe import CreateRecipeByUrl, Recipe
from mealie.schema.recipe.recipe import CreateRecipe, CreateRecipeByUrlBulk, RecipeSummary from mealie.schema.recipe.recipe import CreateRecipe, CreateRecipeByUrlBulk, RecipeSummary
@ -53,7 +53,7 @@ def parse_recipe_url_bulk(
"""Takes in a URL and attempts to scrape data and load it into the database""" """Takes in a URL and attempts to scrape data and load it into the database"""
def bulk_import_func(task_id: int, session: Session) -> None: def bulk_import_func(task_id: int, session: Session) -> None:
database = get_database(session) database = get_repositories(session)
task = database.server_tasks.get_one(task_id) task = database.server_tasks.get_one(task_id)
task.append_log("test task has started") task.append_log("test task has started")

View File

@ -9,8 +9,8 @@ from mealie.core.dependencies import temporary_zip_path
from mealie.core.dependencies.dependencies import temporary_dir, validate_recipe_token from mealie.core.dependencies.dependencies import temporary_dir, validate_recipe_token
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.core.security import create_recipe_slug_token from mealie.core.security import create_recipe_slug_token
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.schema.recipe import Recipe, RecipeImageTypes from mealie.schema.recipe import Recipe, RecipeImageTypes
from mealie.services.recipe.recipe_service import RecipeService from mealie.services.recipe.recipe_service import RecipeService
@ -68,7 +68,7 @@ async def get_recipe_as_zip(
if slug != slug: if slug != slug:
raise HTTPException(status_code=400, detail="Invalid Slug") raise HTTPException(status_code=400, detail="Invalid Slug")
db = get_database(session) db = get_repositories(session)
recipe: Recipe = db.recipes.get(slug) recipe: Recipe = db.recipes.get(slug)
image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value) image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value)
with ZipFile(temp_path, "w") as myzip: with ZipFile(temp_path, "w") as myzip:

View File

@ -2,8 +2,8 @@ from fastapi import APIRouter, Depends
from pydantic import UUID4 from pydantic import UUID4
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.recipe import Recipe from mealie.schema.recipe import Recipe
router = APIRouter() router = APIRouter()
@ -11,7 +11,7 @@ router = APIRouter()
@router.get("/shared/{token_id}", response_model=Recipe) @router.get("/shared/{token_id}", response_model=Recipe)
def get_shared_recipe(token_id: UUID4, session: Session = Depends(generate_session)): def get_shared_recipe(token_id: UUID4, session: Session = Depends(generate_session)):
db = get_database(session) db = get_repositories(session)
token_summary = db.recipe_share_tokens.get_one(token_id) token_summary = db.recipe_share_tokens.get_one(token_id)

View File

@ -2,8 +2,8 @@ from fastapi import Depends
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user from mealie.core.dependencies import get_current_user
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.schema.meal_plan import ShoppingListIn, ShoppingListOut from mealie.schema.meal_plan import ShoppingListIn, ShoppingListOut
from mealie.schema.user import PrivateUser from mealie.schema.user import PrivateUser
@ -18,7 +18,7 @@ async def create_shopping_list(
session: Session = Depends(generate_session), session: Session = Depends(generate_session),
): ):
"""Create Shopping List in the Database""" """Create Shopping List in the Database"""
db = get_database(session) db = get_repositories(session)
list_in.group = current_user.group list_in.group = current_user.group
return db.shopping_lists.create(list_in) return db.shopping_lists.create(list_in)
@ -27,19 +27,19 @@ async def create_shopping_list(
@router.get("/{id}", response_model=ShoppingListOut) @router.get("/{id}", response_model=ShoppingListOut)
async def get_shopping_list(id: int, session: Session = Depends(generate_session)): async def get_shopping_list(id: int, session: Session = Depends(generate_session)):
"""Get Shopping List from the Database""" """Get Shopping List from the Database"""
db = get_database(session) db = get_repositories(session)
return db.shopping_lists.get(id) return db.shopping_lists.get(id)
@router.put("/{id}", response_model=ShoppingListOut) @router.put("/{id}", response_model=ShoppingListOut)
async def update_shopping_list(id: int, new_data: ShoppingListIn, session: Session = Depends(generate_session)): async def update_shopping_list(id: int, new_data: ShoppingListIn, session: Session = Depends(generate_session)):
"""Update Shopping List in the Database""" """Update Shopping List in the Database"""
db = get_database(session) db = get_repositories(session)
return db.shopping_lists.update(id, new_data) return db.shopping_lists.update(id, new_data)
@router.delete("/{id}") @router.delete("/{id}")
async def delete_shopping_list(id: int, session: Session = Depends(generate_session)): async def delete_shopping_list(id: int, session: Session = Depends(generate_session)):
"""Delete Shopping List from the Database""" """Delete Shopping List from the Database"""
db = get_database(session) db = get_repositories(session)
return db.shopping_lists.delete(id) return db.shopping_lists.delete(id)

View File

@ -2,8 +2,8 @@ from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user from mealie.core.dependencies import get_current_user
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter from mealie.routes.routers import AdminAPIRouter
from mealie.schema.user import GroupInDB, PrivateUser from mealie.schema.user import GroupInDB, PrivateUser
from mealie.utils.post_webhooks import post_webhooks from mealie.utils.post_webhooks import post_webhooks
@ -15,7 +15,7 @@ admin_router = AdminAPIRouter(prefix="/api/site-settings", tags=["Settings"])
@public_router.get("") @public_router.get("")
def get_main_settings(session: Session = Depends(generate_session)): def get_main_settings(session: Session = Depends(generate_session)):
"""Returns basic site settings""" """Returns basic site settings"""
db = get_database(session) db = get_repositories(session)
return db.settings.get(1) return db.settings.get(1)
@ -26,7 +26,7 @@ def test_webhooks(
session: Session = Depends(generate_session), session: Session = Depends(generate_session),
): ):
"""Run the function to test your webhooks""" """Run the function to test your webhooks"""
db = get_database(session) db = get_repositories(session)
group_entry: GroupInDB = db.groups.get(current_user.group, "name") group_entry: GroupInDB = db.groups.get(current_user.group, "name")
try: try:

View File

@ -2,8 +2,8 @@ from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from mealie.core.dependencies import is_logged_in from mealie.core.dependencies import is_logged_in
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
from mealie.schema.recipe import RecipeTagResponse, TagIn from mealie.schema.recipe import RecipeTagResponse, TagIn
@ -15,14 +15,14 @@ admin_router = AdminAPIRouter()
@public_router.get("") @public_router.get("")
async def get_all_recipe_tags(session: Session = Depends(generate_session)): async def get_all_recipe_tags(session: Session = Depends(generate_session)):
"""Returns a list of available tags in the database""" """Returns a list of available tags in the database"""
db = get_database(session) db = get_repositories(session)
return db.tags.get_all_limit_columns(["slug", "name"]) return db.tags.get_all_limit_columns(["slug", "name"])
@public_router.get("/empty") @public_router.get("/empty")
def get_empty_tags(session: Session = Depends(generate_session)): def get_empty_tags(session: Session = Depends(generate_session)):
"""Returns a list of tags that do not contain any recipes""" """Returns a list of tags that do not contain any recipes"""
db = get_database(session) db = get_repositories(session)
return db.tags.get_empty() return db.tags.get_empty()
@ -31,7 +31,7 @@ def get_all_recipes_by_tag(
tag: str, session: Session = Depends(generate_session), is_user: bool = Depends(is_logged_in) tag: str, session: Session = Depends(generate_session), is_user: bool = Depends(is_logged_in)
): ):
"""Returns a list of recipes associated with the provided tag.""" """Returns a list of recipes associated with the provided tag."""
db = get_database(session) db = get_repositories(session)
tag_obj = db.tags.get(tag) tag_obj = db.tags.get(tag)
tag_obj = RecipeTagResponse.from_orm(tag_obj) tag_obj = RecipeTagResponse.from_orm(tag_obj)
@ -44,14 +44,14 @@ def get_all_recipes_by_tag(
@user_router.post("") @user_router.post("")
async def create_recipe_tag(tag: TagIn, session: Session = Depends(generate_session)): async def create_recipe_tag(tag: TagIn, session: Session = Depends(generate_session)):
"""Creates a Tag in the database""" """Creates a Tag in the database"""
db = get_database(session) db = get_repositories(session)
return db.tags.create(tag.dict()) return db.tags.create(tag.dict())
@admin_router.put("/{tag}", response_model=RecipeTagResponse) @admin_router.put("/{tag}", response_model=RecipeTagResponse)
async def update_recipe_tag(tag: str, new_tag: TagIn, session: Session = Depends(generate_session)): async def update_recipe_tag(tag: str, new_tag: TagIn, session: Session = Depends(generate_session)):
"""Updates an existing Tag in the database""" """Updates an existing Tag in the database"""
db = get_database(session) db = get_repositories(session)
return db.tags.update(tag, new_tag.dict()) return db.tags.update(tag, new_tag.dict())
@ -62,7 +62,7 @@ async def delete_recipe_tag(tag: str, session: Session = Depends(generate_sessio
from any recipes that contain it""" from any recipes that contain it"""
try: try:
db = get_database(session) db = get_repositories(session)
db.tags.delete(tag) db.tags.delete(tag)
except Exception: except Exception:
raise HTTPException(status.HTTP_400_BAD_REQUEST) raise HTTPException(status.HTTP_400_BAD_REQUEST)

View File

@ -6,8 +6,8 @@ from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user from mealie.core.dependencies import get_current_user
from mealie.core.security import create_access_token from mealie.core.security import create_access_token
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.schema.user import CreateToken, LoingLiveTokenIn, LongLiveTokenInDB, PrivateUser from mealie.schema.user import CreateToken, LoingLiveTokenIn, LongLiveTokenInDB, PrivateUser
@ -33,7 +33,7 @@ async def create_api_token(
user_id=current_user.id, user_id=current_user.id,
) )
db = get_database(session) db = get_repositories(session)
new_token_in_db = db.api_tokens.create(token_model) new_token_in_db = db.api_tokens.create(token_model)
@ -48,7 +48,7 @@ async def delete_api_token(
session: Session = Depends(generate_session), session: Session = Depends(generate_session),
): ):
"""Delete api_token from the Database""" """Delete api_token from the Database"""
db = get_database(session) db = get_repositories(session)
token: LongLiveTokenInDB = db.api_tokens.get(token_id) token: LongLiveTokenInDB = db.api_tokens.get(token_id)
if not token: if not token:

View File

@ -5,8 +5,8 @@ from sqlalchemy.orm.session import Session
from mealie.core import security from mealie.core import security
from mealie.core.dependencies import get_current_user from mealie.core.dependencies import get_current_user
from mealie.core.security import hash_password from mealie.core.security import hash_password
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed from mealie.routes.users._helpers import assert_user_change_allowed
from mealie.schema.user import PrivateUser, UserBase, UserIn, UserOut from mealie.schema.user import PrivateUser, UserBase, UserIn, UserOut
@ -18,7 +18,7 @@ admin_router = AdminAPIRouter(prefix="")
@admin_router.get("", response_model=list[UserOut]) @admin_router.get("", response_model=list[UserOut])
async def get_all_users(session: Session = Depends(generate_session)): async def get_all_users(session: Session = Depends(generate_session)):
db = get_database(session) db = get_repositories(session)
return db.users.get_all() return db.users.get_all()
@ -35,13 +35,13 @@ async def create_user(
create_user_event, "User Created", f"Created by {current_user.full_name}", session=session create_user_event, "User Created", f"Created by {current_user.full_name}", session=session
) )
db = get_database(session) db = get_repositories(session)
return db.users.create(new_user.dict()) return db.users.create(new_user.dict())
@admin_router.get("/{id}", response_model=UserOut) @admin_router.get("/{id}", response_model=UserOut)
async def get_user(id: UUID4, session: Session = Depends(generate_session)): async def get_user(id: UUID4, session: Session = Depends(generate_session)):
db = get_database(session) db = get_repositories(session)
return db.users.get(id) return db.users.get(id)
@ -60,7 +60,7 @@ def delete_user(
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="SUPER_USER") raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="SUPER_USER")
try: try:
db = get_database(session) db = get_repositories(session)
db.users.delete(id) db.users.delete(id)
background_tasks.add_task(create_user_event, "User Deleted", f"User ID: {id}", session=session) background_tasks.add_task(create_user_event, "User Deleted", f"User ID: {id}", session=session)
except Exception: except Exception:
@ -92,7 +92,7 @@ async def update_user(
# prevent an admin from demoting themself # prevent an admin from demoting themself
raise HTTPException(status.HTTP_403_FORBIDDEN) raise HTTPException(status.HTTP_403_FORBIDDEN)
db = get_database(session) db = get_repositories(session)
db.users.update(id, new_data.dict()) db.users.update(id, new_data.dict())
if current_user.id == id: if current_user.id == id:

View File

@ -2,8 +2,8 @@ from fastapi import Depends
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user from mealie.core.dependencies import get_current_user
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed from mealie.routes.users._helpers import assert_user_change_allowed
from mealie.schema.user import PrivateUser, UserFavorites from mealie.schema.user import PrivateUser, UserFavorites
@ -14,7 +14,7 @@ user_router = UserAPIRouter()
@user_router.get("/{id}/favorites", response_model=UserFavorites) @user_router.get("/{id}/favorites", response_model=UserFavorites)
async def get_favorites(id: str, session: Session = Depends(generate_session)): async def get_favorites(id: str, session: Session = Depends(generate_session)):
"""Get user's favorite recipes""" """Get user's favorite recipes"""
db = get_database(session) db = get_repositories(session)
return db.users.get(id, override_schema=UserFavorites) return db.users.get(id, override_schema=UserFavorites)
@ -27,7 +27,7 @@ def add_favorite(
"""Adds a Recipe to the users favorites""" """Adds a Recipe to the users favorites"""
current_user.favorite_recipes.append(slug) current_user.favorite_recipes.append(slug)
db = get_database(session) db = get_repositories(session)
db.users.update(current_user.id, current_user) db.users.update(current_user.id, current_user)
@ -42,7 +42,7 @@ def remove_favorite(
assert_user_change_allowed(id, current_user) assert_user_change_allowed(id, current_user)
current_user.favorite_recipes = [x for x in current_user.favorite_recipes if x != slug] current_user.favorite_recipes = [x for x in current_user.favorite_recipes if x != slug]
db = get_database(session) db = get_repositories(session)
db.users.update(current_user.id, current_user) db.users.update(current_user.id, current_user)
return return

View File

@ -9,8 +9,8 @@ from sqlalchemy.orm.session import Session
from mealie import utils from mealie import utils
from mealie.core.dependencies import get_current_user from mealie.core.dependencies import get_current_user
from mealie.core.dependencies.dependencies import temporary_dir from mealie.core.dependencies.dependencies import temporary_dir
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed from mealie.routes.users._helpers import assert_user_change_allowed
from mealie.schema.user import PrivateUser from mealie.schema.user import PrivateUser
@ -41,7 +41,7 @@ def update_user_image(
shutil.copyfile(image, dest) shutil.copyfile(image, dest)
db = get_database(session) db = get_repositories(session)
db.users.patch(id, {"cache_key": utils.new_cache_key()}) db.users.patch(id, {"cache_key": utils.new_cache_key()})

View File

@ -3,8 +3,8 @@ from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_settings from mealie.core.config import get_app_settings
from mealie.core.security import hash_password from mealie.core.security import hash_password
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
from mealie.routes.routers import UserAPIRouter from mealie.routes.routers import UserAPIRouter
from mealie.schema.user import ChangePassword from mealie.schema.user import ChangePassword
from mealie.schema.user.user_passwords import ForgotPassword, ResetPassword from mealie.schema.user.user_passwords import ForgotPassword, ResetPassword
@ -20,7 +20,7 @@ settings = get_app_settings()
async def reset_user_password(id: int, session: Session = Depends(generate_session)): async def reset_user_password(id: int, session: Session = Depends(generate_session)):
new_password = hash_password(settings.DEFAULT_PASSWORD) new_password = hash_password(settings.DEFAULT_PASSWORD)
db = get_database(session) db = get_repositories(session)
db.users.update_password(id, new_password) db.users.update_password(id, new_password)

View File

@ -7,9 +7,9 @@ from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_dirs, get_app_settings from mealie.core.config import get_app_dirs, get_app_settings
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.database import get_database
from mealie.db.db_setup import SessionLocal from mealie.db.db_setup import SessionLocal
from mealie.lang import get_locale_provider from mealie.lang import get_locale_provider
from mealie.repos.all_repositories import get_repositories
from mealie.schema.user.user import PrivateUser from mealie.schema.user.user import PrivateUser
logger = get_logger() logger = get_logger()
@ -62,7 +62,7 @@ class BaseHttpService(Generic[T, D], ABC):
self.background_tasks = background_tasks self.background_tasks = background_tasks
# Static Globals Dependency Injection # Static Globals Dependency Injection
self.db = get_database(session) self.db = get_repositories(session)
self.app_dirs = get_app_dirs() self.app_dirs = get_app_dirs()
self.settings = get_app_settings() self.settings = get_app_settings()
self.t = get_locale_provider().t self.t = get_locale_provider().t

View File

@ -9,13 +9,13 @@ from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.data_access_layer._access_model import AccessModel from mealie.repos.repository_generic import RepositoryGeneric
from mealie.schema.response import ErrorResponse from mealie.schema.response import ErrorResponse
C = TypeVar("C", bound=BaseModel) C = TypeVar("C", bound=BaseModel)
R = TypeVar("R", bound=BaseModel) R = TypeVar("R", bound=BaseModel)
U = TypeVar("U", bound=BaseModel) U = TypeVar("U", bound=BaseModel)
DAL = TypeVar("DAL", bound=AccessModel) DAL = TypeVar("DAL", bound=RepositoryGeneric)
logger = get_logger() logger = get_logger()
@ -25,16 +25,16 @@ class CrudHttpMixins(Generic[C, R, U], ABC):
@property @property
@abstractmethod @abstractmethod
def dal(self) -> DAL: def repo(self) -> DAL:
... ...
def populate_item(self, id: int) -> R: def populate_item(self, id: int) -> R:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def _create_one(self, data: C, default_msg="generic-create-error", exception_msgs: dict | None = None) -> R: def _create_one(self, data: C, default_msg="generic-create-error", exception_msgs: dict | None = None) -> R:
try: try:
self.item = self.dal.create(data) self.item = self.repo.create(data)
except Exception as ex: except Exception as ex:
logger.exception(ex) logger.exception(ex)
self.session.rollback() self.session.rollback()
@ -58,13 +58,13 @@ class CrudHttpMixins(Generic[C, R, U], ABC):
return return
target_id = item_id or self.item.id target_id = item_id or self.item.id
self.item = self.dal.update(target_id, data) self.item = self.repo.update(target_id, data)
return self.item return self.item
def _patch_one(self, data: U, item_id: int) -> None: def _patch_one(self, data: U, item_id: int) -> None:
try: try:
self.item = self.dal.patch(item_id, data.dict(exclude_unset=True, exclude_defaults=True)) self.item = self.repo.patch(item_id, data.dict(exclude_unset=True, exclude_defaults=True))
except IntegrityError: except IntegrityError:
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail={"message": "generic-patch-error"}) raise HTTPException(status.HTTP_400_BAD_REQUEST, detail={"message": "generic-patch-error"})
@ -73,7 +73,7 @@ class CrudHttpMixins(Generic[C, R, U], ABC):
logger.info(f"Deleting item with id {target_id}") logger.info(f"Deleting item with id {target_id}")
try: try:
self.item = self.dal.delete(target_id) self.item = self.repo.delete(target_id)
except Exception as ex: except Exception as ex:
logger.exception(ex) logger.exception(ex)
raise HTTPException( raise HTTPException(

View File

@ -23,15 +23,15 @@ class AdminGroupService(
_schema = GroupInDB _schema = GroupInDB
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.groups return self.db.groups
def populate_item(self, id: UUID4) -> GroupInDB: def populate_item(self, id: UUID4) -> GroupInDB:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[GroupInDB]: def get_all(self) -> list[GroupInDB]:
return self.dal.get_all() return self.repo.get_all()
def create_one(self, data: GroupBase) -> GroupInDB: def create_one(self, data: GroupBase) -> GroupInDB:
return create_new_group(self.db, data) return create_new_group(self.db, data)
@ -46,7 +46,7 @@ class AdminGroupService(
if data.name not in ["", self.item.name]: if data.name not in ["", self.item.name]:
self.item.name = data.name self.item.name = data.name
self.item = self.dal.update(target_id, self.item) self.item = self.repo.update(target_id, self.item)
return self.item return self.item

View File

@ -16,15 +16,15 @@ class AdminUserService(
_schema = UserOut _schema = UserOut
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.users return self.db.users
def populate_item(self, id: int) -> UserOut: def populate_item(self, id: int) -> UserOut:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[UserOut]: def get_all(self) -> list[UserOut]:
return self.dal.get_all() return self.repo.get_all()
def create_one(self, data: UserIn) -> UserOut: def create_one(self, data: UserIn) -> UserOut:
return self._create_one(data) return self._create_one(data)

View File

@ -12,7 +12,7 @@ from mealie.core import root_logger
from mealie.core.config import get_app_dirs from mealie.core.config import get_app_dirs
app_dirs = get_app_dirs() app_dirs = get_app_dirs()
from mealie.db.database import get_database from mealie.repos.all_repositories import get_repositories
logger = root_logger.get_logger() logger = root_logger.get_logger()
@ -113,7 +113,7 @@ def backup_all(
): ):
db_export = ExportDatabase(tag=tag, templates=templates) db_export = ExportDatabase(tag=tag, templates=templates)
db = get_database(session) db = get_repositories(session)
if export_users: if export_users:
all_users = db.users.get_all() all_users = db.users.get_all()

View File

@ -8,7 +8,7 @@ from pydantic.main import BaseModel
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.core.config import get_app_dirs from mealie.core.config import get_app_dirs
from mealie.db.database import get_database from mealie.repos.all_repositories import get_repositories
from mealie.schema.admin import CommentImport, GroupImport, NotificationImport, RecipeImport, UserImport from mealie.schema.admin import CommentImport, GroupImport, NotificationImport, RecipeImport, UserImport
from mealie.schema.events import EventNotificationIn from mealie.schema.events import EventNotificationIn
from mealie.schema.recipe import Recipe, RecipeCommentOut from mealie.schema.recipe import Recipe, RecipeCommentOut
@ -38,7 +38,7 @@ class ImportDatabase:
""" """
self.user = user self.user = user
self.session = session self.session = session
self.db = get_database(session) self.db = get_repositories(session)
self.archive = app_dirs.BACKUP_DIR.joinpath(zip_archive) self.archive = app_dirs.BACKUP_DIR.joinpath(zip_archive)
self.force_imports = force_import self.force_imports = force_import

View File

@ -1,8 +1,8 @@
import apprise import apprise
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import create_session from mealie.db.db_setup import create_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.events import Event, EventCategory from mealie.schema.events import Event, EventCategory
@ -37,7 +37,7 @@ def post_notifications(event: Event, notification_urls=list[str], hard_fail=Fals
def save_event(title, text, category, session: Session, attachment=None): def save_event(title, text, category, session: Session, attachment=None):
event = Event(title=title, text=text, category=category) event = Event(title=title, text=text, category=category)
session = session or create_session() session = session or create_session()
db = get_database(session) db = get_repositories(session)
db.events.create(event.dict()) db.events.create(event.dict())
notification_objects = db.event_notifications.get(match_value=True, match_key=category, limit=9999) notification_objects = db.event_notifications.get(match_value=True, match_key=category, limit=9999)

View File

@ -8,7 +8,7 @@ from uuid import UUID
from pydantic import BaseModel from pydantic import BaseModel
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.database import Database from mealie.repos.all_repositories import AllRepositories
from mealie.schema.reports.reports import ReportEntryCreate from mealie.schema.reports.reports import ReportEntryCreate
from .._base_service import BaseService from .._base_service import BaseService
@ -29,7 +29,7 @@ class ExportedItem:
class ABCExporter(BaseService): class ABCExporter(BaseService):
write_dir_to_zip: Callable[[Path, str, Optional[list[str]]], None] write_dir_to_zip: Callable[[Path, str, Optional[list[str]]], None]
def __init__(self, db: Database, group_id: UUID) -> None: def __init__(self, db: AllRepositories, group_id: UUID) -> None:
self.logger = get_logger() self.logger = get_logger()
self.db = db self.db = db
self.group_id = group_id self.group_id = group_id

View File

@ -4,7 +4,7 @@ import zipfile
from pathlib import Path from pathlib import Path
from uuid import UUID, uuid4 from uuid import UUID, uuid4
from mealie.db.database import Database from mealie.repos.all_repositories import AllRepositories
from mealie.schema.group.group_exports import GroupDataExport from mealie.schema.group.group_exports import GroupDataExport
from mealie.schema.user import GroupInDB from mealie.schema.user import GroupInDB
from mealie.utils.fs_stats import pretty_size from mealie.utils.fs_stats import pretty_size
@ -21,7 +21,7 @@ class Exporter(BaseService):
self.temp_path = temp_zip self.temp_path = temp_zip
self.exporters = exporters self.exporters = exporters
def run(self, db: Database) -> GroupDataExport: def run(self, db: AllRepositories) -> GroupDataExport:
# Create Zip File # Create Zip File
self.temp_path.touch() self.temp_path.touch()

View File

@ -1,14 +1,14 @@
from typing import Iterator from typing import Iterator
from uuid import UUID from uuid import UUID
from mealie.db.database import Database from mealie.repos.all_repositories import AllRepositories
from mealie.schema.recipe import Recipe from mealie.schema.recipe import Recipe
from ._abc_exporter import ABCExporter, ExportedItem from ._abc_exporter import ABCExporter, ExportedItem
class RecipeExporter(ABCExporter): class RecipeExporter(ABCExporter):
def __init__(self, db: Database, group_id: UUID, recipes: list[str]) -> None: def __init__(self, db: AllRepositories, group_id: UUID, recipes: list[str]) -> None:
""" """
RecipeExporter is used to export a list of recipes to a zip file. The zip RecipeExporter is used to export a list of recipes to a zip file. The zip
file is then saved to a temporary directory and then available for a one-time file is then saved to a temporary directory and then available for a one-time

View File

@ -21,7 +21,7 @@ class CookbookService(
_schema = ReadCookBook _schema = ReadCookBook
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.cookbooks return self.db.cookbooks
def populate_item(self, item_id: int) -> RecipeCookBook: def populate_item(self, item_id: int) -> RecipeCookBook:
@ -31,13 +31,13 @@ class CookbookService(
pass pass
if isinstance(item_id, int): if isinstance(item_id, int):
self.item = self.dal.get_one(item_id, override_schema=RecipeCookBook) self.item = self.repo.get_one(item_id, override_schema=RecipeCookBook)
else: else:
self.item = self.dal.get_one(item_id, key="slug", override_schema=RecipeCookBook) self.item = self.repo.get_one(item_id, key="slug", override_schema=RecipeCookBook)
def get_all(self) -> list[ReadCookBook]: def get_all(self) -> list[ReadCookBook]:
items = self.dal.get(self.group_id, "group_id", limit=999) items = self.repo.get(self.group_id, "group_id", limit=999)
items.sort(key=lambda x: x.position) items.sort(key=lambda x: x.position)
return items return items
@ -52,7 +52,7 @@ class CookbookService(
updated = [] updated = []
for cookbook in data: for cookbook in data:
cb = self.dal.update(cookbook.id, cookbook) cb = self.repo.update(cookbook.id, cookbook)
updated.append(cb) updated.append(cb)
return updated return updated

View File

@ -1,11 +1,11 @@
from uuid import uuid4 from uuid import uuid4
from mealie.db.data_access_layer.access_model_factory import Database from mealie.repos.repository_factory import AllRepositories
from mealie.schema.group.group_preferences import CreateGroupPreferences from mealie.schema.group.group_preferences import CreateGroupPreferences
from mealie.schema.user.user import GroupBase, GroupInDB from mealie.schema.user.user import GroupBase, GroupInDB
def create_new_group(db: Database, g_base: GroupBase, g_preferences: CreateGroupPreferences = None) -> GroupInDB: def create_new_group(db: AllRepositories, g_base: GroupBase, g_preferences: CreateGroupPreferences = None) -> GroupInDB:
created_group = db.groups.create(g_base) created_group = db.groups.create(g_base)
# Assign Temporary ID before group is created # Assign Temporary ID before group is created

View File

@ -21,19 +21,19 @@ class MealService(CrudHttpMixins[CreatePlanEntry, ReadPlanEntry, UpdatePlanEntry
item: ReadPlanEntry item: ReadPlanEntry
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.meals return self.db.meals
def populate_item(self, id: int) -> ReadPlanEntry: def populate_item(self, id: int) -> ReadPlanEntry:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_slice(self, start: date = None, end: date = None) -> list[ReadPlanEntry]: def get_slice(self, start: date = None, end: date = None) -> list[ReadPlanEntry]:
# 2 days ago # 2 days ago
return self.dal.get_slice(start, end, group_id=self.group_id) return self.repo.get_slice(start, end, group_id=self.group_id)
def get_today(self) -> list[ReadPlanEntry]: def get_today(self) -> list[ReadPlanEntry]:
return self.dal.get_today(group_id=self.group_id) return self.repo.get_today(group_id=self.group_id)
def create_one(self, data: CreatePlanEntry) -> ReadPlanEntry: def create_one(self, data: CreatePlanEntry) -> ReadPlanEntry:
data = self.cast(data, SavePlanEntry) data = self.cast(data, SavePlanEntry)

View File

@ -23,7 +23,7 @@ class GroupMigrationService(UserHttpService[int, ReportOut]):
_schema = ReportOut _schema = ReportOut
@cached_property @cached_property
def dal(self): def repo(self):
raise NotImplementedError raise NotImplementedError
def populate_item(self, _: UUID4) -> ReportOut: def populate_item(self, _: UUID4) -> ReportOut:

View File

@ -17,15 +17,15 @@ class GroupReportService(CrudHttpMixins[ReportOut, ReportCreate, ReportCreate],
_schema = ReportOut _schema = ReportOut
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.group_reports return self.db.group_reports
def populate_item(self, id: int) -> ReportOut: def populate_item(self, id: int) -> ReportOut:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def _get_all(self, report_type: ReportCategory = None) -> list[ReportSummary]: def _get_all(self, report_type: ReportCategory = None) -> list[ReportSummary]:
return self.dal.multi_query({"group_id": self.group_id, "category": report_type}, limit=9999) return self.repo.multi_query({"group_id": self.group_id, "category": report_type}, limit=9999)
def delete_one(self, id: int = None) -> ReportOut: def delete_one(self, id: int = None) -> ReportOut:
return self._delete_one(id) return self._delete_one(id)

View File

@ -18,15 +18,15 @@ class WebhookService(CrudHttpMixins[ReadWebhook, CreateWebhook, CreateWebhook],
_schema = ReadWebhook _schema = ReadWebhook
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.webhooks return self.db.webhooks
def populate_item(self, id: int) -> ReadWebhook: def populate_item(self, id: int) -> ReadWebhook:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[ReadWebhook]: def get_all(self) -> list[ReadWebhook]:
return self.dal.get(self.group_id, match_key="group_id", limit=9999) return self.repo.get(self.group_id, match_key="group_id", limit=9999)
def create_one(self, data: CreateWebhook) -> ReadWebhook: def create_one(self, data: CreateWebhook) -> ReadWebhook:
data = self.cast(data, SaveWebhook) data = self.cast(data, SaveWebhook)

View File

@ -5,7 +5,7 @@ from uuid import UUID
from pydantic import UUID4 from pydantic import UUID4
from mealie.core import root_logger from mealie.core import root_logger
from mealie.db.database import Database from mealie.repos.all_repositories import AllRepositories
from mealie.schema.recipe import Recipe from mealie.schema.recipe import Recipe
from mealie.schema.reports.reports import ( from mealie.schema.reports.reports import (
ReportCategory, ReportCategory,
@ -29,7 +29,9 @@ class BaseMigrator(BaseService):
report_id: int report_id: int
report: ReportOut report: ReportOut
def __init__(self, archive: Path, db: Database, session, user_id: UUID4, group_id: UUID, add_migration_tag: bool): def __init__(
self, archive: Path, db: AllRepositories, session, user_id: UUID4, group_id: UUID, add_migration_tag: bool
):
self.archive = archive self.archive = archive
self.db = db self.db = db
self.session = session self.session = session

View File

@ -4,8 +4,8 @@ from pydantic import UUID4, BaseModel
from slugify import slugify from slugify import slugify
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from mealie.db.data_access_layer.access_model_factory import AccessModel from mealie.repos.all_repositories import AllRepositories
from mealie.db.database import Database from mealie.repos.repository_factory import RepositoryGeneric
from mealie.schema.recipe import RecipeCategory from mealie.schema.recipe import RecipeCategory
from mealie.schema.recipe.recipe import RecipeTag from mealie.schema.recipe.recipe import RecipeTag
@ -13,13 +13,13 @@ T = TypeVar("T", bound=BaseModel)
class DatabaseMigrationHelpers: class DatabaseMigrationHelpers:
def __init__(self, db: Database, session: Session, group_id: int, user_id: UUID4) -> None: def __init__(self, db: AllRepositories, session: Session, group_id: int, user_id: UUID4) -> None:
self.group_id = group_id self.group_id = group_id
self.user_id = user_id self.user_id = user_id
self.session = session self.session = session
self.db = db self.db = db
def _get_or_set_generic(self, accessor: AccessModel, items: list[str], out_model: T) -> list[T]: def _get_or_set_generic(self, accessor: RepositoryGeneric, items: list[str], out_model: T) -> list[T]:
""" """
Utility model for getting or setting categories or tags. This will only work for those two cases. Utility model for getting or setting categories or tags. This will only work for those two cases.

View File

@ -25,7 +25,7 @@ class RecipeCommentsService(
_schema = RecipeCommentOut _schema = RecipeCommentOut
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.comments return self.db.comments
def _check_comment_belongs_to_user(self) -> None: def _check_comment_belongs_to_user(self) -> None:
@ -33,11 +33,11 @@ class RecipeCommentsService(
raise HTTPException(detail="Comment does not belong to user") raise HTTPException(detail="Comment does not belong to user")
def populate_item(self, id: UUID) -> RecipeCommentOut: def populate_item(self, id: UUID) -> RecipeCommentOut:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[RecipeCommentOut]: def get_all(self) -> list[RecipeCommentOut]:
return self.dal.get_all() return self.repo.get_all()
def create_one(self, data: RecipeCommentCreate) -> RecipeCommentOut: def create_one(self, data: RecipeCommentCreate) -> RecipeCommentOut:
save_data = RecipeCommentSave(text=data.text, user_id=self.user.id, recipe_id=data.recipe_id) save_data = RecipeCommentSave(text=data.text, user_id=self.user.id, recipe_id=data.recipe_id)

View File

@ -17,15 +17,15 @@ class RecipeFoodService(
_schema = IngredientFood _schema = IngredientFood
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.ingredient_foods return self.db.ingredient_foods
def populate_item(self, id: int) -> IngredientFood: def populate_item(self, id: int) -> IngredientFood:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[IngredientFood]: def get_all(self) -> list[IngredientFood]:
return self.dal.get_all() return self.repo.get_all()
def create_one(self, data: CreateIngredientFood) -> IngredientFood: def create_one(self, data: CreateIngredientFood) -> IngredientFood:
return self._create_one(data) return self._create_one(data)

View File

@ -11,7 +11,7 @@ from sqlalchemy import exc
from mealie.core.dependencies.grouped import UserDeps from mealie.core.dependencies.grouped import UserDeps
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.db.data_access_layer.recipe_access_model import RecipeDataAccessModel from mealie.repos.repository_recipes import RepositoryRecipes
from mealie.schema.recipe.recipe import CreateRecipe, Recipe, RecipeSummary from mealie.schema.recipe.recipe import CreateRecipe, Recipe, RecipeSummary
from mealie.schema.recipe.recipe_settings import RecipeSettings from mealie.schema.recipe.recipe_settings import RecipeSettings
from mealie.services._base_http_service.crud_http_mixins import CrudHttpMixins from mealie.services._base_http_service.crud_http_mixins import CrudHttpMixins
@ -40,7 +40,7 @@ class RecipeService(CrudHttpMixins[CreateRecipe, Recipe, Recipe], UserHttpServic
return {exc.IntegrityError: self.t("recipe.unique-name-error")} return {exc.IntegrityError: self.t("recipe.unique-name-error")}
@cached_property @cached_property
def dal(self) -> RecipeDataAccessModel: def repo(self) -> RepositoryRecipes:
return self.db.recipes.by_group(self.group_id) return self.db.recipes.by_group(self.group_id)
@classmethod @classmethod

View File

@ -17,15 +17,15 @@ class RecipeToolService(
_schema = RecipeTool _schema = RecipeTool
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.tools return self.db.tools
def populate_item(self, id: int) -> RecipeTool: def populate_item(self, id: int) -> RecipeTool:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[RecipeTool]: def get_all(self) -> list[RecipeTool]:
return self.dal.get_all() return self.repo.get_all()
def create_one(self, data: RecipeToolCreate) -> RecipeTool: def create_one(self, data: RecipeToolCreate) -> RecipeTool:
return self._create_one(data) return self._create_one(data)

View File

@ -17,15 +17,15 @@ class RecipeUnitService(
_schema = IngredientUnit _schema = IngredientUnit
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.ingredient_units return self.db.ingredient_units
def populate_item(self, id: int) -> IngredientUnit: def populate_item(self, id: int) -> IngredientUnit:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[IngredientUnit]: def get_all(self) -> list[IngredientUnit]:
return self.dal.get_all() return self.repo.get_all()
def create_one(self, data: CreateIngredientUnit) -> IngredientUnit: def create_one(self, data: CreateIngredientUnit) -> IngredientUnit:
return self._create_one(data) return self._create_one(data)

View File

@ -4,8 +4,8 @@ import requests
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.core import root_logger from mealie.core import root_logger
from mealie.db.database import get_database
from mealie.db.db_setup import create_session from mealie.db.db_setup import create_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.group.webhook import ReadWebhook from mealie.schema.group.webhook import ReadWebhook
from ..scheduled_func import Cron, ScheduledFunc from ..scheduled_func import Cron, ScheduledFunc
@ -16,7 +16,7 @@ logger = root_logger.get_logger()
def post_webhooks(webhook_id: int, session: Session = None): def post_webhooks(webhook_id: int, session: Session = None):
session = session or create_session() session = session or create_session()
db = get_database(session) db = get_repositories(session)
webhook: ReadWebhook = db.webhooks.get_one(webhook_id) webhook: ReadWebhook = db.webhooks.get_one(webhook_id)
if not webhook.enabled: if not webhook.enabled:
@ -39,7 +39,7 @@ def post_webhooks(webhook_id: int, session: Session = None):
def update_group_webhooks(): def update_group_webhooks():
session = create_session() session = create_session()
db = get_database(session) db = get_repositories(session)
webhooks: list[ReadWebhook] = db.webhooks.get_all() webhooks: list[ReadWebhook] = db.webhooks.get_all()

View File

@ -4,7 +4,7 @@ from typing import Any, Callable
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from mealie.db.database import get_database from mealie.repos.all_repositories import get_repositories
from mealie.schema.server.tasks import ServerTask, ServerTaskCreate, ServerTaskNames from mealie.schema.server.tasks import ServerTask, ServerTaskCreate, ServerTaskNames
from .._base_http_service.http_services import UserHttpService from .._base_http_service.http_services import UserHttpService
@ -32,7 +32,7 @@ class BackgroundExecutor(UserHttpService):
def test_executor_func(task_id: int, session: Session) -> None: def test_executor_func(task_id: int, session: Session) -> None:
database = get_database(session) database = get_repositories(session)
task = database.server_tasks.get_one(task_id) task = database.server_tasks.get_one(task_id)
task.append_log("test task has started") task.append_log("test task has started")

View File

@ -9,15 +9,15 @@ class ServerTasksHttpService(UserHttpService[int, ServerTask]):
_schema = ServerTask _schema = ServerTask
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.server_tasks return self.db.server_tasks
def populate_item(self, id: int) -> ServerTask: def populate_item(self, id: int) -> ServerTask:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[ServerTask]: def get_all(self) -> list[ServerTask]:
return self.dal.multi_query(query_by={"group_id": self.group_id}, order_by="created_at") return self.repo.multi_query(query_by={"group_id": self.group_id}, order_by="created_at")
class AdminServerTasks(AdminHttpService[int, ServerTask]): class AdminServerTasks(AdminHttpService[int, ServerTask]):
@ -25,12 +25,12 @@ class AdminServerTasks(AdminHttpService[int, ServerTask]):
_schema = ServerTask _schema = ServerTask
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.server_tasks return self.db.server_tasks
def populate_item(self, id: int) -> ServerTask: def populate_item(self, id: int) -> ServerTask:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self) -> list[ServerTask]: def get_all(self) -> list[ServerTask]:
return self.dal.get_all(order_by="created_at") return self.repo.get_all(order_by="created_at")

View File

@ -22,11 +22,11 @@ class SharedRecipeService(
_schema = RecipeShareToken _schema = RecipeShareToken
@cached_property @cached_property
def dal(self): def repo(self):
return self.db.recipe_share_tokens return self.db.recipe_share_tokens
def populate_item(self, id: UUID4) -> RecipeShareToken: def populate_item(self, id: UUID4) -> RecipeShareToken:
self.item = self.dal.get_one(id) self.item = self.repo.get_one(id)
return self.item return self.item
def get_all(self, recipe_id=None) -> list[RecipeShareTokenSummary]: def get_all(self, recipe_id=None) -> list[RecipeShareTokenSummary]:
@ -48,4 +48,4 @@ class SharedRecipeService(
def delete_one(self, item_id: UUID4 = None) -> None: def delete_one(self, item_id: UUID4 = None) -> None:
item_id = item_id or self.item.id item_id = item_id or self.item.id
return self.dal.delete(item_id) return self.repo.delete(item_id)

View File

@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
from mealie.core.root_logger import get_logger from mealie.core.root_logger import get_logger
from mealie.core.security import hash_password, url_safe_token from mealie.core.security import hash_password, url_safe_token
from mealie.db.database import get_database from mealie.repos.all_repositories import get_repositories
from mealie.schema.user.user_passwords import SavePasswordResetToken from mealie.schema.user.user_passwords import SavePasswordResetToken
from mealie.services._base_service import BaseService from mealie.services._base_service import BaseService
from mealie.services.email import EmailService from mealie.services.email import EmailService
@ -13,7 +13,7 @@ logger = get_logger(__name__)
class PasswordResetService(BaseService): class PasswordResetService(BaseService):
def __init__(self, session: Session) -> None: def __init__(self, session: Session) -> None:
self.db = get_database(session) self.db = get_repositories(session)
super().__init__() super().__init__()
def generate_reset_token(self, email: str) -> SavePasswordResetToken: def generate_reset_token(self, email: str) -> SavePasswordResetToken:

View File

@ -3,15 +3,15 @@ import json
import requests import requests
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from mealie.db.database import get_database
from mealie.db.db_setup import create_session from mealie.db.db_setup import create_session
from mealie.repos.all_repositories import get_repositories
from mealie.schema.user import GroupInDB from mealie.schema.user import GroupInDB
from mealie.services.events import create_scheduled_event from mealie.services.events import create_scheduled_event
def post_webhooks(group: int, session: Session = None, force=True): def post_webhooks(group: int, session: Session = None, force=True):
session = session or create_session() session = session or create_session()
db = get_database(session) db = get_repositories(session)
group_settings: GroupInDB = db.groups.get(group) group_settings: GroupInDB = db.groups.get(group)
if not group_settings.webhook_enable and not force: if not group_settings.webhook_enable and not force:

View File

@ -1,14 +1,14 @@
import pytest import pytest
from mealie.db.database import Database, get_database
from mealie.db.db_setup import SessionLocal from mealie.db.db_setup import SessionLocal
from mealie.repos.all_repositories import AllRepositories, get_repositories
@pytest.fixture() @pytest.fixture()
def database() -> Database: def database() -> AllRepositories:
try: try:
db = SessionLocal() db = SessionLocal()
yield get_database(db) yield get_repositories(db)
finally: finally:
db.close() db.close()

View File

@ -1,9 +1,9 @@
from mealie.db.database import Database from mealie.repos.all_repositories import AllRepositories
from mealie.schema.user import PrivateUser from mealie.schema.user import PrivateUser
from tests.utils.fixture_schemas import TestUser from tests.utils.fixture_schemas import TestUser
def test_user_directory_deleted_on_delete(database: Database, unique_user: TestUser) -> None: def test_user_directory_deleted_on_delete(database: AllRepositories, unique_user: TestUser) -> None:
user_dir = PrivateUser.get_directory(unique_user.user_id) user_dir = PrivateUser.get_directory(unique_user.user_id)
assert user_dir.exists() assert user_dir.exists()
database.users.delete(unique_user.user_id) database.users.delete(unique_user.user_id)