forked from youknowone/ring
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
55fb267
commit 2026320
Showing
6 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
dist | ||
.env | ||
*.pyc | ||
*.egg-info | ||
MANIFEST | ||
|
||
.cache | ||
.eggs | ||
.idea | ||
.tox | ||
.ropeproject | ||
/build | ||
setup.cfg |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
|
||
|
||
class Key(object): | ||
|
||
def __init__(self, key): | ||
self.key = key | ||
|
||
def build(self, args): | ||
raise NotImplementedError | ||
|
||
|
||
class FormatKey(Key): | ||
|
||
def build(self, args): | ||
return self.key.format(**args) | ||
|
||
|
||
class CallableKey(Key): | ||
|
||
def build(self, args): | ||
return self.key(**args) | ||
|
||
|
||
class Ring(object): | ||
|
||
def __init__(self, storage, key): | ||
self.storage = storage | ||
if not isinstance(key, Key): | ||
if isinstance(key, (str, unicode)): | ||
key = FormatKey(key) | ||
elif callable(key): | ||
key = CallableKey(key) | ||
else: | ||
raise TypeError | ||
self.key = key | ||
|
||
@staticmethod | ||
def _key_args(args, kwargs): | ||
if args and kwargs: | ||
raise TypeError | ||
if args and len(args) > 1: | ||
raise TypeError | ||
if args: | ||
key = args[0] | ||
else: | ||
key = kwargs | ||
return key | ||
|
||
def get(self, *args, **kwargs): | ||
key_args = self._key_args(args, kwargs) | ||
return self.get_by_key(key_args) | ||
|
||
def get_by_key(self, key_args): | ||
built_key = self.key.build(key_args) | ||
return self.storage.get(built_key) | ||
|
||
def set(self, _value, *args, **kwargs): | ||
key_args = self._key_args(args, kwargs) | ||
if callable(_value): | ||
_value = _value(**key_args) | ||
return self.set_by_key(_value, key_args) | ||
|
||
def set_by_key(self, value, key_args): | ||
built_key = self.key.build(key_args) | ||
return self.storage.set(built_key, value) | ||
|
||
def get_or_set(self, _value, *args, **kwargs): | ||
key_args = self._key_args(args, kwargs) | ||
value = self.get_by_key(key_args) | ||
if value is None: | ||
value = _value(**key_args) | ||
self.set_by_key(value, key_args) | ||
return value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
|
||
class Storage(object): | ||
|
||
def get(self, key): | ||
raise NotImplementedError | ||
|
||
def set(self, key, value, expire=None): | ||
raise NotImplementedError | ||
|
||
|
||
class DictStorage(Storage): | ||
|
||
def __init__(self, storage): | ||
self.storage = storage | ||
|
||
def get(self, key): | ||
return self.storage.get(key) | ||
|
||
def set(self, key, value, expire=None): | ||
assert expire is None, 'expire is not supported' | ||
return self.storage.update({key: value}) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
from cachain.storage import DictStorage | ||
from cachain.ingredient import Ring | ||
|
||
|
||
import pytest | ||
|
||
|
||
@pytest.fixture | ||
def fx_ring(): | ||
storage = DictStorage({}) | ||
ring = Ring(storage, 'user_id:{user_id}') | ||
return ring | ||
|
||
|
||
def test_ring_get_set(fx_ring): | ||
assert fx_ring.get({'user_id': 1}) is None | ||
fx_ring.set(lambda user_id: 100, {'user_id': 1}) | ||
|
||
|
||
def test_ring_get_or_set(fx_ring): | ||
assert fx_ring.get({'user_id': 1}) is None | ||
assert fx_ring.get_or_set(lambda user_id: 100, {'user_id': 1}) == 100 | ||
assert fx_ring.get({'user_id': 1}) == 100 | ||
|
||
|