using Humanizer; using MycroForge.CLI.Extensions; using MycroForge.Core; namespace MycroForge.CLI.CodeGen; public class CrudServiceGenerator { private static readonly string[] Template = [ "from typing import Any, Dict, List, Optional", "from sqlalchemy import select", $"from {Features.Db.FeatureName}.engine.async_session import async_session", "from %entity_import_path% import %entity_class_name%", "", "class %entity_class_name%Service:", "\tasync def list(self) -> List[%entity_class_name%]:", "\t\tasync with async_session() as session:", "\t\t\tstmt = select(%entity_class_name%)", "\t\t\tresults = (await session.scalars(stmt)).all()", "\t\t\treturn results", "", "\tasync def get_by_id(self, id: int) -> Optional[%entity_class_name%]:", "\t\tasync with async_session() as session:", "\t\t\tstmt = select(%entity_class_name%).where(%entity_class_name%.id == id)", "\t\t\tresult = (await session.scalars(stmt)).first()", "\t\t\treturn result", "", "\tasync def create(self, data: Dict[str, Any]) -> None:", "\t\tasync with async_session() as session:", "\t\t\tentity = %entity_class_name%(**data)", "\t\t\tsession.add(entity)", "\t\t\tawait session.commit()", "", "\tasync def update(self, id: int, data: Dict[str, Any]) -> bool:", "\t\tasync with async_session() as session:", "\t\t\tstmt = select(%entity_class_name%).where(%entity_class_name%.id == id)", "\t\t\tentity = (await session.scalars(stmt)).first()", "", "\t\t\tif entity is None:", "\t\t\t\treturn False", "\t\t\telse:", "\t\t\t\tfor key, value in data.items():", "\t\t\t\t\tsetattr(entity, key, value)", "\t\t\t\tawait session.commit()", "\t\t\t\treturn True", "", "\tasync def delete(self, id: int) -> bool:", "\t\tasync with async_session() as session:", "\t\t\tstmt = select(%entity_class_name%).where(%entity_class_name%.id == id)", "\t\t\tentity = (await session.scalars(stmt)).first()", "", "\t\t\tif entity is None:", "\t\t\t\treturn False", "\t\t\telse:", "\t\t\t\tawait session.delete(entity)", "\t\t\t\tawait session.commit()", "\t\t\t\treturn True", ]; private readonly ProjectContext _context; public CrudServiceGenerator(ProjectContext context) { _context = context; } public async Task Generate(string path, string entity) { var entitySnakeCaseName = entity.Underscore().ToLower(); var entityClassName = entity.Pascalize(); var entitiesFolderPath = $"{Features.Db.FeatureName}/entities/{path}"; var entityFilePath = $"{entitiesFolderPath}/{entitySnakeCaseName}.py"; var entityImportPath = entityFilePath .Replace('/', '.') .Replace('\\', '.') .Replace(".py", string.Empty) .DeduplicateDots() .Trim(); var servicesFolderPath = $"{Features.Api.FeatureName}/services/{path}"; var serviceFilePath = $"{servicesFolderPath}/{entity.Underscore().ToLower()}_service.py"; var service = string.Join("\n", Template) .Replace("%entity_import_path%", entityImportPath) .Replace("%entity_class_name%", entityClassName) ; await _context.CreateFile(serviceFilePath, service); } }