This commit is contained in:
2024-04-21 20:46:17 +00:00
parent 0e2ecd3449
commit 2ca7787dcb
17 changed files with 249 additions and 72 deletions

View File

@@ -0,0 +1,4 @@
class TransactionContextManagerError(Exception):
def __init__(self, message: str, *args: object) -> None:
self.message = message
super().__init__(*args)

View File

@@ -1,13 +1,13 @@
import uuid
from sqlalchemy import UUID
from sqlalchemy import UUID, ForeignKey
from sqlalchemy.orm import Mapped, mapped_column
from api.infrastructure.persistence.models.base import Base
class CompanyModel(Base):
__tablename__ = "companies"
__tablename__ = "company"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
@@ -15,3 +15,45 @@ class CompanyModel(Base):
)
name: Mapped[str]
email: Mapped[str] = mapped_column(unique=True)
address: Mapped[str]
owner_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("users.id", ondelete="CASCADE"),
)
class DepartmentModel(Base):
__tablename__ = "department"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
primary_key=True,
)
name: Mapped[str]
address: Mapped[str]
company_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("company.id", ondelete="CASCADE")
)
class CompanyDepartmentModel(Base):
__tablename__ = "company_department_m2m"
company_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("company.id", ondelete="CASCADE"),
primary_key=True,
)
department_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("department.id", ondelete="CASCADE"),
primary_key=True,
)
class DepartmentUserModel(Base):
__tablename__ = "department_user_m2m"
department_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("department.id", ondelete="CASCADE"),
primary_key=True,
)
user_id: Mapped[uuid.UUID] = mapped_column(
ForeignKey("users.id"),
primary_key=True,
)

View File

@@ -14,5 +14,6 @@ class UserModel(Base):
primary_key=True,
)
name: Mapped[str]
last_name: Mapped[str]
email: Mapped[str] = mapped_column(unique=True)
hashed_password: Mapped[str]

View File

@@ -1,30 +1,33 @@
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from api.domain.company.model import Company, CompanyEmail, CompanyId, CompanyName
from api.domain.company.model import (Company, CompanyAddress, CompanyEmail,
CompanyId, CompanyName)
from api.domain.company.repository import CompanyRepository
from api.domain.user.model import UserId
class SqlAlchemyCompanyRepository(CompanyRepository):
def __init__(self, session: AsyncSession) -> None:
self.session = session
# async def create_user(self, user: User) -> None:
# stmt = text(
# """INSERT INTO users (id, name, email, hashed_password)
# VALUES(:id, :name, :email, :hashed_password)
# """
# )
# await self.session.execute(
# stmt,
# {
# "id": str(user.id.value),
# "name": user.name.value,
# "email": user.email.value,
# "hashed_password": user.hashed_password,
# },
# )
#
async def create_company(self, company: Company) -> None:
stmt = text(
"""INSERT INTO company (id, name, email, address, owner_id)
VALUES(:id, :name, :email, :address, :owner_id)
"""
)
await self.session.execute(
stmt,
{
"id": str(company.id.value),
"name": company.name.value,
"email": company.email.value,
"address": company.address.value,
"owner_id": str(company.owner_id.value),
},
)
async def get_companies_by_owner_email(self, filter: dict) -> list[Company]:
stmt = text("""SELECT * FROM companies WHERE email = :val""")
result = await self.session.execute(stmt, {"val": filter["email"]})
@@ -36,6 +39,8 @@ class SqlAlchemyCompanyRepository(CompanyRepository):
id=CompanyId(c.id),
name=CompanyName(c.name),
email=CompanyEmail(c.email),
address=CompanyAddress(c.address),
owner_id=UserId(c.owner_id),
)
for c in result
]

View File

@@ -2,7 +2,8 @@ from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from api.domain.user import User, UserRepository
from api.domain.user.model import UserEmail, UserFirstName, UserId
from api.domain.user.model import (UserEmail, UserFirstName, UserId,
UserLastName)
class SqlAlchemyUserRepository(UserRepository):
@@ -11,8 +12,8 @@ class SqlAlchemyUserRepository(UserRepository):
async def create_user(self, user: User) -> None:
stmt = text(
"""INSERT INTO users (id, name, email, hashed_password)
VALUES(:id, :name, :email, :hashed_password)
"""INSERT INTO users (id, name, last_name, email, hashed_password)
VALUES(:id, :name, :last_name, :email, :hashed_password)
"""
)
await self.session.execute(
@@ -20,6 +21,7 @@ class SqlAlchemyUserRepository(UserRepository):
{
"id": str(user.id.value),
"name": user.name.value,
"last_name": user.last_name.value,
"email": user.email.value,
"hashed_password": user.hashed_password,
},
@@ -37,6 +39,7 @@ class SqlAlchemyUserRepository(UserRepository):
return User(
id=UserId(result.id),
name=UserFirstName(result.name),
last_name=UserLastName(result.last_name),
email=UserEmail(result.email),
hashed_password=result.hashed_password,
)

View File

@@ -0,0 +1,29 @@
from types import TracebackType
from sqlalchemy.ext.asyncio import AsyncSession
from api.infrastructure.persistence.error import TransactionContextManagerError
class SqlalchemyTransactionContextManager:
def __init__(self, session: AsyncSession):
self._session = session
async def __aenter__(self):
return self
async def __aexit__(
self,
exc_type: type[BaseException],
exc_val: BaseException,
exc_tb: TracebackType,
) -> None:
if exc_type:
await self.rollback()
raise TransactionContextManagerError(message="Transaction Error")
async def commit(self):
await self._session.commit()
async def rollback(self):
await self._session.rollback()