Skip to content

Commit

Permalink
feat: implement separate unit of work pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
ShahriyarR committed Oct 23, 2022
1 parent bdc416d commit a83b5ef
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 100 deletions.
50 changes: 0 additions & 50 deletions src/jobboard/adapters/db/unit_of_work.py

This file was deleted.

6 changes: 2 additions & 4 deletions src/jobboard/adapters/repositories/jobs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from src.jobboard.domain.model import model
from src.jobboard.domain.ports.repositories.jobs import (
JobRepositoryInterface,
)
from src.jobboard.domain.ports.repositories.jobs import JobRepositoryInterface


class JobSqlAlchemyRepository(JobRepositoryInterface):
Expand All @@ -25,4 +23,4 @@ def _get_all(self) -> list[model.Job]:
return self.session.query(model.Job).all()

def _search(self, query: str) -> list[model.Job]:
return self.session.query(model.Job).filter(model.Job.title.contains(query))
return self.session.query(model.Job).filter(model.Job.title.contains(query))
6 changes: 2 additions & 4 deletions src/jobboard/adapters/repositories/users.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from src.jobboard.domain.model import model
from src.jobboard.domain.ports.repositories.users import (
UserRepositoryInterface,
)
from src.jobboard.domain.ports.repositories.users import UserRepositoryInterface


class UserSqlAlchemyRepository(UserRepositoryInterface):
Expand All @@ -19,4 +17,4 @@ def _get_by_email(self, email: str) -> model.User:
return self.session.query(model.User).filter_by(email=email).first()

def _get_by_id(self, id: int) -> model.User:
return self.session.query(model.User).filter_by(id=id).first()
return self.session.query(model.User).filter_by(id=id).first()
26 changes: 26 additions & 0 deletions src/jobboard/adapters/unit_of_works/jobs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import Any, Callable

from sqlalchemy.orm.session import Session

from src.jobboard.adapters.repositories.jobs import JobSqlAlchemyRepository
from src.jobboard.domain.ports.unit_of_works.jobs import JobUnitOfWorkInterface


class JobSqlAlchemyUnitOfWork(JobUnitOfWorkInterface):
def __init__(self, session_factory: Callable[[], Any]):
self.session_factory = session_factory()

def __enter__(self):
self.session = self.session_factory() # type: Session
self.jobs = JobSqlAlchemyRepository(self.session)
return super().__enter__()

def __exit__(self, *args):
super().__exit__(*args)
self.session.close()

def _commit(self):
self.session.commit()

def rollback(self):
self.session.rollback()
26 changes: 26 additions & 0 deletions src/jobboard/adapters/unit_of_works/users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import Any, Callable

from sqlalchemy.orm.session import Session

from src.jobboard.adapters.repositories.users import UserSqlAlchemyRepository
from src.jobboard.domain.ports.unit_of_works.users import UserUnitOfWorkInterface


class UserSqlAlchemyUnitOfWork(UserUnitOfWorkInterface):
def __init__(self, session_factory: Callable[[], Any]):
self.session_factory = session_factory()

def __enter__(self):
self.session = self.session_factory() # type: Session
self.users = UserSqlAlchemyRepository(self.session)
return super().__enter__()

def __exit__(self, *args):
super().__exit__(*args)
self.session.close()

def _commit(self):
self.session.commit()

def rollback(self):
self.session.rollback()
2 changes: 1 addition & 1 deletion src/jobboard/adapters/use_cases/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
ResponseSuccess,
ResponseTypes,
)
from src.jobboard.domain.ports.unit_of_work import JobUnitOfWorkInterface
from src.jobboard.domain.ports.unit_of_works.jobs import JobUnitOfWorkInterface
from src.jobboard.domain.ports.use_cases.jobs import JobServiceInterface
from src.jobboard.domain.schemas.jobs import JobCreateInputDto, JobOutputDto

Expand Down
2 changes: 1 addition & 1 deletion src/jobboard/adapters/use_cases/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
ResponseSuccess,
ResponseTypes,
)
from src.jobboard.domain.ports.unit_of_work import UserUnitOfWorkInterface
from src.jobboard.domain.ports.unit_of_works.users import UserUnitOfWorkInterface
from src.jobboard.domain.ports.use_cases.users import UserServiceInterface
from src.jobboard.domain.schemas.users import (
UserCreateInputDto,
Expand Down
6 changes: 2 additions & 4 deletions src/jobboard/configurator/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from src.jobboard.adapters.db.unit_of_work import (
JobSqlAlchemyUnitOfWork,
UserSqlAlchemyUnitOfWork,
)
from src.jobboard.adapters.unit_of_works.jobs import JobSqlAlchemyUnitOfWork
from src.jobboard.adapters.unit_of_works.users import UserSqlAlchemyUnitOfWork
from src.jobboard.adapters.use_cases.jobs import JobService
from src.jobboard.adapters.use_cases.users import UserService
from src.jobboard.configurator import config
Expand Down
32 changes: 32 additions & 0 deletions src/jobboard/domain/ports/unit_of_works/jobs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import abc

from src.jobboard.domain.ports.common import messagebus
from src.jobboard.domain.ports.repositories.jobs import JobRepositoryInterface


class JobUnitOfWorkInterface(abc.ABC):
jobs: JobRepositoryInterface

def __enter__(self) -> "JobUnitOfWorkInterface":
return self

def __exit__(self, *args):
self.rollback()

def commit(self):
self._commit()
self.publish_events()

def publish_events(self):
for job in self.jobs.seen:
while job.events:
event = job.events.pop(0)
messagebus.handle(event)

@abc.abstractmethod
def _commit(self):
raise NotImplementedError

@abc.abstractmethod
def rollback(self):
raise NotImplementedError
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import abc

from src.jobboard.domain.ports.repositories.users import UserRepositoryInterface
from src.jobboard.domain.ports.repositories.jobs import JobRepositoryInterface
from src.jobboard.domain.ports.common import messagebus
from src.jobboard.domain.ports.repositories.users import UserRepositoryInterface


class UserUnitOfWorkInterface(abc.ABC):
Expand Down Expand Up @@ -31,31 +30,3 @@ def _commit(self):
@abc.abstractmethod
def rollback(self):
raise NotImplementedError


class JobUnitOfWorkInterface(abc.ABC):
jobs: JobRepositoryInterface

def __enter__(self) -> "JobUnitOfWorkInterface":
return self

def __exit__(self, *args):
self.rollback()

def commit(self):
self._commit()
self.publish_events()

def publish_events(self):
for job in self.jobs.seen:
while job.events:
event = job.events.pop(0)
messagebus.handle(event)

@abc.abstractmethod
def _commit(self):
raise NotImplementedError

@abc.abstractmethod
def rollback(self):
raise NotImplementedError
2 changes: 1 addition & 1 deletion src/jobboard/domain/ports/use_cases/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Union

from src.jobboard.domain.ports.common.responses import ResponseFailure, ResponseSuccess
from src.jobboard.domain.ports.unit_of_work import JobUnitOfWorkInterface
from src.jobboard.domain.ports.unit_of_works.jobs import JobUnitOfWorkInterface
from src.jobboard.domain.schemas.jobs import JobCreateInputDto


Expand Down
2 changes: 1 addition & 1 deletion src/jobboard/domain/ports/use_cases/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Union

from src.jobboard.domain.ports.common.responses import ResponseFailure, ResponseSuccess
from src.jobboard.domain.ports.unit_of_work import UserUnitOfWorkInterface
from src.jobboard.domain.ports.unit_of_works.users import UserUnitOfWorkInterface
from src.jobboard.domain.schemas.users import (
UserCreateInputDto,
UserLoginInputDto,
Expand Down
6 changes: 2 additions & 4 deletions tests/fake_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from src.jobboard.adapters.db.unit_of_work import (
JobSqlAlchemyUnitOfWork,
UserSqlAlchemyUnitOfWork,
)
from src.jobboard.adapters.unit_of_works.jobs import JobSqlAlchemyUnitOfWork
from src.jobboard.adapters.unit_of_works.users import UserSqlAlchemyUnitOfWork
from src.jobboard.adapters.use_cases.jobs import JobService
from src.jobboard.adapters.use_cases.users import UserService

Expand Down

0 comments on commit a83b5ef

Please sign in to comment.