Skip to content

Commit

Permalink
Merge pull request #26 from openvstorage/assert_range
Browse files Browse the repository at this point in the history
allows AssertRange in a sequence
  • Loading branch information
toolslive authored Apr 30, 2019
2 parents e114535 + 387a46e commit 78d9c11
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 5 deletions.
7 changes: 6 additions & 1 deletion pyrakoon/compat/client/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from .socket import ArakoonSocketClient
from ..consistency import Consistency, Consistent, NoGuarantee, AtLeast
from ..utils import convert_exceptions as _convert_exceptions, validate_signature as _validate_signature
from ..sequence import Set, Delete, DeletePrefix, Assert, AssertExists, Replace, Sequence
from ..sequence import Set, Delete, DeletePrefix, Assert, AssertExists, Replace, Sequence, AssertRange
from ..errors import ArakoonException
from ... import utils, consistency, sequence, protocol
from ...constants.logging import PYRAKOON_COMPAT_LOGGER
Expand Down Expand Up @@ -160,6 +160,9 @@ def convert_assert_exists(step):
def convert_replace(step):
return sequence.Replace(step._key, step._wanted)

def convert_assert_range(step):
return sequence.AssertRange(step._prefix, step._rangeAssertion)

def convert_sequence(sequence_):
steps = []

Expand All @@ -178,6 +181,8 @@ def convert_sequence(sequence_):
steps.append(convert_sequence(step))
elif isinstance(step, Replace):
steps.append(convert_replace(step))
elif isinstance(step, AssertRange):
steps.append(convert_assert_range(step))
else:
raise TypeError

Expand Down
17 changes: 16 additions & 1 deletion pyrakoon/compat/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# This file is part of Open vStorage. For license information, see <LICENSE.txt>
from .. import utils
from .utils import validate_signature as _validate_signature

from abc import ABCMeta, abstractmethod

class Update(object):
def write(self, fob):
Expand Down Expand Up @@ -41,6 +41,17 @@ def __init__(self, key, wanted):
self._key = key
self._wanted = wanted

class RangeAssertion:
__metaclass__ = ABCMeta

class ContainsExactly(RangeAssertion):
def __init__(self, keys):
self._keys = keys

class AssertRange(Update):
def __init__(self, prefix, rangeAssertion):
self._prefix = prefix
self._rangeAssertion = rangeAssertion

class Sequence(Update):
def __init__(self):
Expand Down Expand Up @@ -76,3 +87,7 @@ def addAssertExists(self, key):
@_validate_signature('string', 'string_option')
def addReplace(self, key, wanted):
self._updates.append(Replace(key, wanted))

def addAssertPrefixContainsExactly(self, prefix, keys):
ar = AssertRange(prefix, ContainsExactly(keys))
self.addUpdate(ar)
2 changes: 1 addition & 1 deletion pyrakoon/protocol/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from .communication import Result, Request, RESULT_SUCCESS, PROTOCOL_VERSION
from .types import Type, String, UnsignedInteger, SignedInteger, Float, Bool, Unit, Step, Option, List, Array, Product,\
NamedField, StatisticsType, Consistency,\
STRING, UINT32, UINT64, INT8, INT32, INT64, FLOAT, BOOL, UNIT, STEP, STATISTICS, CONSISTENCY, CONSISTENCY_ARG
STRING, UINT32, UINT64, INT8, INT32, INT64, FLOAT, BOOL, UNIT, STEP, STATISTICS, CONSISTENCY, CONSISTENCY_ARG, RANGE_ASSERTION
from .messages import Message,\
Get, Set, Delete, TestAndSet, Sequence, Confirm, DeletePrefix, Replace,\
Exists, Assert, AssertExists,\
Expand Down
2 changes: 2 additions & 0 deletions pyrakoon/protocol/messages/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,5 @@ class AssertExists(KeyConsistencyMessage):

def __init__(self, consistency, key):
super(AssertExists, self).__init__(consistency, key)


20 changes: 20 additions & 0 deletions pyrakoon/protocol/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,24 @@ def receive(self):

yield Result(result['arakoon_stats'])

class RangeAssertionType(Type):
def check(self, value):
pass #TODO

def serialize(self, value):
for bytes_ in INT32.serialize(1):
yield bytes_

keys = value._keys
n_keys = len(keys)

for bytes_ in INT32.serialize(n_keys):
yield bytes_

for k in keys:
for data in STRING.serialize(k):
yield data


class Consistency(Type):
"""
Expand Down Expand Up @@ -676,3 +694,5 @@ def receive(self):

# Well-known `consistency` argument
CONSISTENCY_ARG = ('consistency', CONSISTENCY, None)

RANGE_ASSERTION = RangeAssertionType()
2 changes: 1 addition & 1 deletion pyrakoon/sequence/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from __future__ import absolute_import

from .steps import Step, Step, Set, Delete, Assert, AssertExists, Replace, DeletePrefix
from .steps import Step, Step, Set, Delete, Assert, AssertExists, Replace, DeletePrefix, AssertRange
from .. import protocol


Expand Down
43 changes: 42 additions & 1 deletion pyrakoon/sequence/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from __future__ import absolute_import

from .. import protocol

from abc import ABCMeta, abstractmethod

class Step(object):
"""
Expand Down Expand Up @@ -234,3 +234,44 @@ def prefix(self):
:return:
"""
return self._prefix

class RangeAssertion:
__metaclass__ = ABCMeta

def write(self, fob):
raise NotImplementedError()

class ContainsExactly(RangeAssertion):
def __init__(self,
keys # type: List(str)
):
self._keys = keys

def write(self, fob):
fob.write(_packInt(1))
fob.write(_packInt(len(self._keys)))
for s in self._keys:
fob.write(_packString(s))


class AssertRange(Step):

TAG = 17
ARGS = ('prefix', protocol.STRING), ('rangeAssertion', protocol.RANGE_ASSERTION)

def __init__(self,
prefix, # type: str
rangeAssertion # type: RangeAssertion
):
super(AssertRange, self).__init__(prefix, rangeAssertion)

self._prefix = prefix
self._rangeAssertion = rangeAssertion

@property
def prefix(self):
return self._prefix

@property
def rangeAssertion(self):
return self._rangeAssertion

0 comments on commit 78d9c11

Please sign in to comment.