Skip to content

Commit

Permalink
Merge pull request #6 from maxipavlovic/feature/LITE-12681
Browse files Browse the repository at this point in the history
LITE-12681 Added CQRS_SELECT_FOR_UPDATE to ReplicaMixin
  • Loading branch information
maxipavlovic authored Dec 1, 2020
2 parents 0105098 + 30068a5 commit 0c6b84f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
6 changes: 5 additions & 1 deletion dj_cqrs/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ def save_instance(self, master_data, previous_data=None, sync=False):
pk_value = mapped_data[pk_name]
f_kwargs = {pk_name: pk_value}

instance = self.model._default_manager.filter(**f_kwargs).first()
qs = self.model._default_manager.filter(**f_kwargs)
if self.model.CQRS_SELECT_FOR_UPDATE:
qs = qs.select_for_update()

instance = qs.first()

if instance:
return self.update_instance(
Expand Down
3 changes: 3 additions & 0 deletions dj_cqrs/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ class ReplicaMixin(Model, metaclass=ReplicaMeta):
CQRS_CUSTOM_SERIALIZATION = False
"""Set it to True to skip default data check."""

CQRS_SELECT_FOR_UPDATE = False
"""Set it to True to acquire lock on instance creation/update."""

objects = Manager()

cqrs = ReplicaManager()
Expand Down
7 changes: 7 additions & 0 deletions tests/dj_replica/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ class BadMappingModelRef(ReplicaMixin, models.Model):
name = models.CharField(max_length=200)


class LockModelRef(ReplicaMixin, models.Model):
CQRS_ID = 'lock'
CQRS_SELECT_FOR_UPDATE = True

id = models.IntegerField(primary_key=True)


class Event(models.Model):
pid = models.IntegerField()
cqrs_id = models.CharField(max_length=20)
Expand Down
18 changes: 17 additions & 1 deletion tests/test_replica/test_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest

from django.db.models import CharField, IntegerField
from django.db.models import CharField, IntegerField, QuerySet
from django.utils.timezone import now

from dj_cqrs.metas import ReplicaMeta
Expand Down Expand Up @@ -469,3 +469,19 @@ def test_tracked_fields_mapped(mocker):
_, kwargs = cqrs_update_mock.call_args
assert 'previous_data' in kwargs
assert kwargs['previous_data'] == {'name': 'text'}


@pytest.mark.django_db
def test_select_for_update_lock(mocker):
m = mocker.patch.object(
QuerySet, 'select_for_update', return_value=models.LockModelRef.objects.all(),
)

instance = models.LockModelRef.cqrs_save({
'id': 1,
'cqrs_revision': 0,
'cqrs_updated': now(),
})

assert instance.id == 1
m.assert_called_once()

0 comments on commit 0c6b84f

Please sign in to comment.