74 lines
1.8 KiB
Python
74 lines
1.8 KiB
Python
![]() |
import datetime
|
||
|
from typing import TypeAlias, Any, Annotated, Literal, Union
|
||
|
|
||
|
from django.db import models
|
||
|
from django.utils import timezone
|
||
|
from pydantic.config import ConfigDict
|
||
|
from pydantic.fields import Field
|
||
|
from pydantic.types import Discriminator
|
||
|
|
||
|
from c3nav.api.schema import BaseSchema
|
||
|
|
||
|
FieldValuesDict: TypeAlias = dict[str, Any]
|
||
|
|
||
|
|
||
|
class ObjectReference(BaseSchema):
|
||
|
model_config = ConfigDict(frozen=True)
|
||
|
model: str
|
||
|
id: int
|
||
|
|
||
|
@classmethod
|
||
|
def from_instance(cls, instance: models.Model):
|
||
|
"""
|
||
|
This method will not convert the ID yet!
|
||
|
"""
|
||
|
return cls(model=instance._meta.model_name, id=instance.pk)
|
||
|
|
||
|
|
||
|
class BaseOperation(BaseSchema):
|
||
|
obj: ObjectReference
|
||
|
datetime: Annotated[datetime.datetime, Field(default_factory=timezone.now)]
|
||
|
|
||
|
|
||
|
class CreateObjectOperation(BaseOperation):
|
||
|
type: Literal["create"] = "create"
|
||
|
fields: FieldValuesDict
|
||
|
|
||
|
|
||
|
class UpdateObjectOperation(BaseOperation):
|
||
|
type: Literal["update"] = "update"
|
||
|
fields: FieldValuesDict
|
||
|
|
||
|
|
||
|
class DeleteObjectOperation(BaseOperation):
|
||
|
type: Literal["delete"] = "delete"
|
||
|
|
||
|
|
||
|
class UpdateManyToManyOperation(BaseOperation):
|
||
|
type: Literal["m2m_add"] = "m2m_update"
|
||
|
field: str
|
||
|
add_values: set[int] = set()
|
||
|
remove_values: set[int] = set()
|
||
|
|
||
|
|
||
|
class ClearManyToManyOperation(BaseOperation):
|
||
|
type: Literal["m2m_clear"] = "m2m_clear"
|
||
|
field: str
|
||
|
|
||
|
|
||
|
DatabaseOperation = Annotated[
|
||
|
Union[
|
||
|
CreateObjectOperation,
|
||
|
UpdateObjectOperation,
|
||
|
DeleteObjectOperation,
|
||
|
UpdateManyToManyOperation,
|
||
|
ClearManyToManyOperation,
|
||
|
],
|
||
|
Discriminator("type"),
|
||
|
]
|
||
|
|
||
|
|
||
|
class CollectedChanges(BaseSchema):
|
||
|
prev_reprs: dict[ObjectReference, str] = {}
|
||
|
prev_values: dict[ObjectReference, FieldValuesDict] = {}
|
||
|
operations: list[DatabaseOperation] = []
|