Skip to content

Commit

Permalink
Save it
Browse files Browse the repository at this point in the history
  • Loading branch information
horia141 committed Feb 24, 2024
1 parent 086c1cb commit b3c9784
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from jupiter.core.domain.big_plans.big_plan import BigPlan
from jupiter.core.domain.core.recurring_task_period import RecurringTaskPeriod
from jupiter.core.domain.core.timeline import infer_timeline
from jupiter.core.domain.gamification.infra.score_period_best_repository import ScorePeriodBestRepository
from jupiter.core.domain.gamification.infra.score_stats_repository import ScoreStatsRepository
from jupiter.core.domain.gamification.score_log import ScoreLog
from jupiter.core.domain.gamification.score_log_entry import ScoreLogEntry
from jupiter.core.domain.gamification.score_period_best import ScorePeriodBest
Expand Down Expand Up @@ -42,7 +44,7 @@ async def record_task(

# Record the accomplishment of the task in the score log.

score_log = await uow.score_log_repository.load_by_parent(user.ref_id)
score_log = await uow.repository_for(ScoreLog).load_by_parent(user.ref_id)

if isinstance(task, InboxTask):
new_score_log_entry = ScoreLogEntry.new_from_inbox_task(
Expand All @@ -58,7 +60,7 @@ async def record_task(
)

try:
await uow.score_log_entry_repository.create(new_score_log_entry)
await uow.repository_for(ScoreLogEntry).create(new_score_log_entry)
except EntityAlreadyExistsError:
# The score log entry already exists. This entity has already been marked as done
# or not done, and we won't do it again!
Expand Down Expand Up @@ -248,7 +250,7 @@ async def _update_current_stats(
score_log_entry: ScoreLogEntry,
) -> ScoreStats:
timeline = infer_timeline(period, ctx.action_timestamp)
score_stats = await uow.score_stats_repository.load_by_key_optional(
score_stats = await uow.get_r(ScoreStatsRepository).load_by_key_optional(
(score_log.ref_id, period, timeline)
)

Expand All @@ -262,13 +264,13 @@ async def _update_current_stats(
ctx,
score_log_entry,
)
score_stats = await uow.score_stats_repository.create(score_stats)
score_stats = await uow.get_r(ScoreStatsRepository).create(score_stats)
else:
score_stats = score_stats.merge_score(
ctx,
score_log_entry,
)
score_stats = await uow.score_stats_repository.save(score_stats)
score_stats = await uow.get_r(ScoreStatsRepository).save(score_stats)

return score_stats

Expand All @@ -282,7 +284,7 @@ async def _update_best(
score_log: ScoreLog,
) -> ScorePeriodBest:
timeline = infer_timeline(period, ctx.action_timestamp)
score_period_best = await uow.score_period_best_repository.load_by_key_optional(
score_period_best = await uow.get_r(ScorePeriodBestRepository).load_by_key_optional(
(score_log.ref_id, period, timeline, sub_period)
)

Expand All @@ -294,15 +296,15 @@ async def _update_best(
timeline,
sub_period,
).update_to_max(ctx, score_stats)
score_period_best = await uow.score_period_best_repository.create(
score_period_best = await uow.get_r(ScorePeriodBestRepository).create(
score_period_best
)
else:
score_period_best = score_period_best.update_to_max(
ctx,
score_stats,
)
score_period_best = await uow.score_period_best_repository.save(
score_period_best = await uow.get_r(ScorePeriodBestRepository).save(
score_period_best
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

from jupiter.core.domain.core.adate import ADate
from jupiter.core.domain.core.recurring_task_period import RecurringTaskPeriod
from jupiter.core.domain.gamification.infra.score_stats_repository import ScoreStatsRepository
from jupiter.core.domain.gamification.score_log import ScoreLog
from jupiter.core.domain.gamification.score_stats import ScoreStats
from jupiter.core.domain.gamification.user_score_history import UserScoreHistory
from jupiter.core.domain.storage_engine import DomainUnitOfWork
from jupiter.core.domain.user.user import User
Expand All @@ -15,24 +18,24 @@ async def do_it(
self, uow: DomainUnitOfWork, user: User, right_now: Timestamp
) -> UserScoreHistory:
"""Retrieve the history of scores for a user."""
score_log = await uow.score_log_repository.load_by_parent(user.ref_id)
score_log = await uow.repository_for(ScoreLog).load_by_parent(user.ref_id)

today = ADate.from_date(right_now.as_date())
daily_lower_limit = today.subtract_days(90)
weekly_lower_limit = today.subtract_days(365)
monthly_lower_limit = today.subtract_days(365 * 2)
quarterly_lower_limit = today.subtract_days(365 * 5)

daily_score_stats = await uow.score_stats_repository.find_all_in_timerange(
daily_score_stats = await uow.get_r(ScoreStatsRepository).find_all_in_timerange(
score_log.ref_id, RecurringTaskPeriod.DAILY, daily_lower_limit, today
)
weekly_score_stats = await uow.score_stats_repository.find_all_in_timerange(
weekly_score_stats = await uow.get_r(ScoreStatsRepository).find_all_in_timerange(
score_log.ref_id, RecurringTaskPeriod.WEEKLY, weekly_lower_limit, today
)
monthly_score_stats = await uow.score_stats_repository.find_all_in_timerange(
monthly_score_stats = await uow.get_r(ScoreStatsRepository).find_all_in_timerange(
score_log.ref_id, RecurringTaskPeriod.MONTHLY, monthly_lower_limit, today
)
quarterly_score_stats = await uow.score_stats_repository.find_all_in_timerange(
quarterly_score_stats = await uow.get_r(ScoreStatsRepository).find_all_in_timerange(
score_log.ref_id,
RecurringTaskPeriod.QUARTERLY,
quarterly_lower_limit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

from jupiter.core.domain.core.recurring_task_period import RecurringTaskPeriod
from jupiter.core.domain.core.timeline import infer_timeline
from jupiter.core.domain.gamification.infra.score_period_best_repository import ScorePeriodBestRepository
from jupiter.core.domain.gamification.infra.score_stats_repository import ScoreStatsRepository
from jupiter.core.domain.gamification.score_log import ScoreLog
from jupiter.core.domain.gamification.score_period_best import ScorePeriodBest
from jupiter.core.domain.gamification.score_stats import ScoreStats
from jupiter.core.domain.gamification.user_score_overview import (
UserScore,
UserScoreOverview,
Expand All @@ -20,7 +24,7 @@ async def do_it(
self, uow: DomainUnitOfWork, user: User, right_now: Timestamp
) -> UserScoreOverview:
"""Get the scores overview for a user."""
score_log = await uow.score_log_repository.load_by_parent(user.ref_id)
score_log = await uow.repository_for(ScoreLog).load_by_parent(user.ref_id)

(
daily_score,
Expand Down Expand Up @@ -155,7 +159,7 @@ async def _load_stats(
right_now: Timestamp,
) -> UserScore:
timeline = infer_timeline(period, right_now)
score_stats = await uow.score_stats_repository.load_by_key_optional(
score_stats = await uow.get_r(ScoreStatsRepository).load_by_key_optional(
(score_log.ref_id, period, timeline)
)
return score_stats.to_user_score() if score_stats else UserScore.new()
Expand All @@ -169,7 +173,7 @@ async def _load_period_best(
sub_period: RecurringTaskPeriod,
) -> UserScore:
timeline = infer_timeline(period, right_now)
score_period_best = await uow.score_period_best_repository.load_by_key_optional(
score_period_best = await uow.get_r(ScorePeriodBestRepository).load_by_key_optional(
(score_log.ref_id, period, timeline, sub_period)
)
return (
Expand Down
42 changes: 10 additions & 32 deletions src/core/jupiter/core/domain/storage_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,11 @@
WorkspaceRepository,
)
from jupiter.core.framework.entity import CrownEntity, Entity, RootEntity, StubEntity, TrunkEntity
from jupiter.core.framework.repository import CrownEntityRepository, EntityRepository, RootEntityRepository, StubEntityRepository, TrunkEntityRepository
from jupiter.core.framework.record import Record
from jupiter.core.framework.repository import CrownEntityRepository, EntityRepository, RecordRepository, RootEntityRepository, StubEntityRepository, TrunkEntityRepository

_EntityRepositoryT = TypeVar("_EntityRepositoryT", bound=EntityRepository[Any], covariant=True) # type: ignore
_RecordRepositoryT = TypeVar("_RecordRepositoryT", bound=RecordRepository[Any, Any, Any], covariant=True) # type: ignore
_RootEntityT = TypeVar("_RootEntityT", bound=RootEntity)
_StubEntityT = TypeVar("_StubEntityT", bound=StubEntity)
_TrunkEntityT = TypeVar("_TrunkEntityT", bound=TrunkEntity)
Expand All @@ -117,36 +119,6 @@
class DomainUnitOfWork(abc.ABC):
"""A transactional unit of work from an engine."""

@property
@abc.abstractmethod
def score_log_repository(self) -> ScoreLogRepository:
"""The score log repository."""

@property
@abc.abstractmethod
def score_log_entry_repository(self) -> ScoreLogEntryRepository:
"""The score log entry repository."""

@property
@abc.abstractmethod
def score_stats_repository(self) -> ScoreStatsRepository:
"""The score stats repository."""

@property
@abc.abstractmethod
def score_period_best_repository(self) -> ScorePeriodBestRepository:
"""The score period best repository."""

@property
@abc.abstractmethod
def workspace_repository(self) -> WorkspaceRepository:
"""The workspace repository."""

@property
@abc.abstractmethod
def user_workspace_link_repository(self) -> UserWorkspaceLinkRepository:
"""The user workspace link repository."""

@property
@abc.abstractmethod
def inbox_task_collection_repository(self) -> InboxTaskCollectionRepository:
Expand Down Expand Up @@ -333,11 +305,17 @@ def gc_log_entry_repository(self) -> GCLogEntryRepository:
"""The GC log entry repository."""

@abc.abstractmethod
def get(
def get( # type: ignore
self, repository_type: Type[_EntityRepositoryT]
) -> _EntityRepositoryT:
"""Retrieve a repository."""

@abc.abstractmethod
def get_r( # type: ignore
self, repository_type: Type[_RecordRepositoryT]
) -> _RecordRepositoryT:
"""Retrieve a repository."""

@overload
@abc.abstractmethod
def repository_for(
Expand Down
56 changes: 27 additions & 29 deletions src/core/jupiter/core/repository/sqlite/domain/storage_engine.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""The real implementation of an engine."""
from contextlib import asynccontextmanager
from types import TracebackType
from typing import AsyncIterator, Final, Mapping, Optional, Type, TypeVar, cast, overload
from typing import Any, AsyncIterator, Final, Mapping, Optional, Type, TypeVar, cast, overload
from jupiter.core.domain.auth.auth import Auth

from jupiter.core.domain.auth.infra.auth_repository import AuthRepository
Expand Down Expand Up @@ -44,6 +44,8 @@
)
from jupiter.core.domain.gamification.score_log import ScoreLog
from jupiter.core.domain.gamification.score_log_entry import ScoreLogEntry
from jupiter.core.domain.gamification.score_period_best import ScorePeriodBest
from jupiter.core.domain.gamification.score_stats import ScoreStats
from jupiter.core.domain.gc.gc_log import GCLog
from jupiter.core.domain.gc.gc_log_entry import GCLogEntry
from jupiter.core.domain.gc.infra.gc_log_entry_repository import GCLogEntryRepository
Expand Down Expand Up @@ -155,7 +157,8 @@
from jupiter.core.domain.workspaces.workspace import Workspace
from jupiter.core.framework.entity import CrownEntity, Entity, RootEntity, StubEntity, TrunkEntity
from jupiter.core.framework.realm import RealmCodecRegistry
from jupiter.core.framework.repository import CrownEntityRepository, EntityRepository, RootEntityRepository, StubEntityRepository, TrunkEntityRepository
from jupiter.core.framework.record import Record
from jupiter.core.framework.repository import CrownEntityRepository, EntityRepository, RecordRepository, RootEntityRepository, StubEntityRepository, TrunkEntityRepository
from jupiter.core.repository.sqlite.connection import SqliteConnection
from jupiter.core.repository.sqlite.domain.auths import SqliteAuthRepository
from jupiter.core.repository.sqlite.domain.big_plans import (
Expand Down Expand Up @@ -248,6 +251,7 @@


_EntityRepositoryT = TypeVar("_EntityRepositoryT", bound=EntityRepository[Entity])
_RecordRepositoryT = TypeVar("_RecordRepositoryT", bound=RecordRepository[Record, Any, Any]) # type: ignore
_RootEntityT = TypeVar("_RootEntityT", bound=RootEntity)
_StubEntityT = TypeVar("_StubEntityT", bound=StubEntity)
_TrunkEntityT = TypeVar("_TrunkEntityT", bound=TrunkEntity)
Expand All @@ -257,7 +261,8 @@ class SqliteDomainUnitOfWork(DomainUnitOfWork):
"""A Sqlite specific unit of work."""

_entity_repositories: Final[dict[type[Entity], EntityRepository[Entity]]]
_repositories_by_type: Final[dict[type[EntityRepository[Entity]], EntityRepository[Entity]]]
_entity_repositories_by_type: Final[dict[type[EntityRepository[Entity]], EntityRepository[Entity]]]
_record_repositories_by_type: Final[dict[type[RecordRepository[Record, Any, Any]], RecordRepository[Record, Any, Any]]] # type: ignore

_auth_repository: Final[SqliteAuthRepository]
_score_log_repository: Final[SqliteScoreLogRepository]
Expand Down Expand Up @@ -397,7 +402,7 @@ def __init__(
GCLog: gc_log_repository,
GCLogEntry: gc_log_entry_repository,
}
self._repositories_by_type = {
self._entity_repositories_by_type = {
UserRepository: user_repository,
AuthRepository: auth_repository,
ScoreLogRepository: score_log_repository,
Expand Down Expand Up @@ -442,6 +447,10 @@ def __init__(
GCLogRepository: gc_log_repository,
GCLogEntryRepository: gc_log_entry_repository,
}
self._record_repositories_by_type = {
ScoreStatsRepository: score_stats_repository,
ScorePeriodBestRepository: score_period_best_repository,
}
self._auth_repository = auth_repository
self._score_log_repository = score_log_repository
self._score_log_entry_repository = score_log_entry_repository
Expand Down Expand Up @@ -499,26 +508,6 @@ def __exit__(
) -> None:
"""Exit context."""

@property
def score_log_repository(self) -> ScoreLogRepository:
"""The score log repository."""
return self._score_log_repository

@property
def score_log_entry_repository(self) -> ScoreLogEntryRepository:
"""The score log entry repository."""
return self._score_log_entry_repository

@property
def score_stats_repository(self) -> ScoreStatsRepository:
"""The score stats repository."""
return self._score_stats_repository

@property
def score_period_best_repository(self) -> ScorePeriodBestRepository:
"""The score period best repository."""
return self._score_period_best_repository

@property
def workspace_repository(self) -> WorkspaceRepository:
"""The workspace repository."""
Expand Down Expand Up @@ -714,14 +703,23 @@ def gc_log_entry_repository(self) -> GCLogEntryRepository:
"""The gc log entry repository."""
return self._gc_log_entry_repository

def get(
def get( # type: ignore
self, repository_type: Type[_EntityRepositoryT]
) -> _EntityRepositoryT:
"""Retrieve a repository."""
if repository_type not in self._repositories_by_type:
if repository_type not in self._entity_repositories_by_type:
raise ValueError(f"No repository for type: {repository_type}")
return cast(_EntityRepositoryT, self._repositories_by_type[repository_type])

return cast(_EntityRepositoryT, self._entity_repositories_by_type[repository_type])


def get_r( # type: ignore
self, repository_type: Type[_RecordRepositoryT]
) -> _RecordRepositoryT:
"""Retrieve a repository."""
if repository_type not in self._record_repositories_by_type:
raise ValueError(f"No repository for type: {repository_type}")
return cast(_RecordRepositoryT, self._record_repositories_by_type[repository_type]) # type: ignore

@overload
def repository_for(
self, entity_type: Type[_RootEntityT]
Expand All @@ -748,7 +746,7 @@ def repository_for(

def repository_for(
self, entity_type: Type[_RootEntityT] | Type[_StubEntityT] | Type[_TrunkEntityT] | Type[_CrownEntityT]
) -> RootEntityRepository[_RootEntityT] | StubEntityRepository[_StubEntityT] | TrunkEntityRepository[_TrunkEntityT] | CrownEntityRepository[_CrownEntityT]:
) -> RootEntityRepository[_RootEntityT] | StubEntityRepository[_StubEntityT] | TrunkEntityRepository[_TrunkEntityT] | CrownEntityRepository[_CrownEntityT]:
"""Return a repository for a particular entity."""
if entity_type not in self._entity_repositories:
raise ValueError(f"No repository for entity type: {entity_type}")
Expand Down
3 changes: 2 additions & 1 deletion src/core/jupiter/core/use_cases/gc/do_all.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""The command for doing garbage collection for all workspaces."""

from jupiter.core.domain.gc.service.gc_service import GCService
from jupiter.core.domain.workspaces.workspace import Workspace
from jupiter.core.framework.context import DomainContext
from jupiter.core.framework.event import EventSource
from jupiter.core.framework.use_case import (
Expand All @@ -25,7 +26,7 @@ async def _execute(
) -> None:
"""Execute the command's action."""
async with self._domain_storage_engine.get_unit_of_work() as uow:
workspaces = await uow.workspace_repository.find_all(allow_archived=False)
workspaces = await uow.repository_for(Workspace).find_all(allow_archived=False)

ctx = DomainContext(EventSource.GC_CRON, self._time_provider.get_current_time())

Expand Down
7 changes: 5 additions & 2 deletions src/core/jupiter/core/use_cases/gen/do_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

from jupiter.core.domain.gen.service.gen_service import GenService
from jupiter.core.domain.user.user import User
from jupiter.core.domain.user_workspace_link.infra.user_workspace_link_repository import UserWorkspaceLinkRepository
from jupiter.core.domain.user_workspace_link.user_workspace_link import UserWorkspaceLink
from jupiter.core.domain.workspaces.workspace import Workspace
from jupiter.core.framework.context import DomainContext
from jupiter.core.framework.event import EventSource
from jupiter.core.framework.use_case import (
Expand All @@ -26,10 +29,10 @@ async def _execute(
) -> None:
"""Execute the command's action."""
async with self._domain_storage_engine.get_unit_of_work() as uow:
workspaces = await uow.workspace_repository.find_all(allow_archived=False)
workspaces = await uow.repository_for(Workspace).find_all(allow_archived=False)
users = await uow.repository_for(User).find_all(allow_archived=False)
users_by_id = {u.ref_id: u for u in users}
user_workspace_links = await uow.user_workspace_link_repository.find_all(
user_workspace_links = await uow.repository_for(UserWorkspaceLink).find_all(
allow_archived=False
)
users_id_by_workspace_id = {
Expand Down
Loading

0 comments on commit b3c9784

Please sign in to comment.