Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,19 @@ db
.. automodule:: hobbit_core.flask_hobbit.db
:members:
:undoc-members:
:exclude-members: SurrogatePK
:exclude-members: SurrogatePK, EnumExt

.. autoclass:: SurrogatePK
:members: __repr__

.. autoclass:: EnumExt
:members:

.. automethod:: strict_dump
.. automethod:: dump
.. automethod:: load
.. automethod:: to_opts

pagination
^^^^^^^^^^

Expand Down
78 changes: 70 additions & 8 deletions hobbit_core/flask_hobbit/db.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- encoding: utf-8 -*-
import enum
import six

from sqlalchemy import Integer, Column, ForeignKey, func, DateTime

Expand Down Expand Up @@ -61,29 +62,90 @@ def reference_col(tablename, nullable=False, pk_name='id', **kwargs):


class EnumExt(enum.Enum):
""" serialize/deserialize sqlalchemy enum field
""" Extension for serialize/deserialize sqlalchemy enum field.

Be sure ``type(key)`` is ``int`` and ``type(value)`` is ``str``
(``label = (key, value)``).

Examples::

class TaskState(EnumExt):
# label = (key, value)
CREATED = (0, '新建')
PENDING = (1, '等待')
STARTING = (2, '开始')
RUNNING = (3, '运行中')
FINISHED = (4, '已完成')
FAILED = (5, '失败')
"""

@classmethod
def strict_dump(cls, key, verbose=False):
pos = 1 if verbose else 0
return cls[key].value[pos]
def strict_dump(cls, label, verbose=False):
"""Get key or value by label.

Examples::

TaskState.strict_dump('CREATED') # 0
TaskState.strict_dump('CREATED', verbose=True) # '新建'

Returns:
int|str: Key or value, If label not exist, raise ``KeyError``.
"""

return cls[label].value[1 if verbose else 0]

@classmethod
def dump(cls, key, verbose=False):
ret = {'key': cls[key].value[0], 'value': cls[key].value[1]}
def dump(cls, label, verbose=False):
"""Dump one label to option.

Examples::

TaskState.dump('CREATED') # {'key': 0, 'value': '新建'}

Returns:

dict: Dict of label's key and value. If label not exist,
raise ``KeyError``.
"""

ret = {'key': cls[label].value[0], 'value': cls[label].value[1]}
if verbose:
ret.update({'label': key})
ret.update({'label': label})
return ret

@classmethod
def load(cls, val):
pos = 1 if isinstance(val, str) else 0
"""Get label by key or value.

Examples::

TaskState.load(4) # 'FINISHED'
TaskState.load('新建') # 'CREATED'

Returns:
str|None: Label.
"""

pos = 1 if isinstance(val, six.string_types) else 0
for elem in cls:
if elem.value[pos] == val:
return elem.name

@classmethod
def to_opts(cls, verbose=False):
"""Enum to options.

Examples::

opts = TaskState.to_opts(verbose=True)
print(opts)

[{'key': 0, 'label': 'CREATED', 'value': u'新建'}, ...]

Returns:
list: List of dict which key is `key`, `value`, label.
"""

opts = []
for elem in cls:
opt = {'key': elem.value[0], 'value': elem.value[1]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
env =
LASK_APP=app/run.py
FLASK_ENV=testing
addopts = --cov . --cov-report term-missing -s -x -v -p no:warnings
addopts = --cov . --cov-report term-missing -s -x -vv -p no:warnings
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[pytest]
addopts = --cov hobbit_core --cov=tests --cov-report term-missing -s -x -v -p no:warnings
addopts = --cov hobbit_core --cov=tests --cov-report term-missing -s -x -vv -p no:warnings
40 changes: 40 additions & 0 deletions tests/test_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- encoding: utf-8 -*-
import pytest

from hobbit_core.flask_hobbit import db

from . import BaseTest


class TestEnumExt(BaseTest):

@pytest.fixture
def TaskState(self):
class _TaskState(db.EnumExt):
CREATED = (0, u'新建')
FINISHED = (1, u'已完成')
return _TaskState

def test_strict_dump(self, TaskState):
assert 0 == TaskState.strict_dump('CREATED')
assert u'新建' == TaskState.strict_dump('CREATED', True)

def test_dump(self, TaskState):
assert {'key': 0, 'value': u'新建'} == TaskState.dump('CREATED')

def test_load(self, TaskState):
assert 'FINISHED' == TaskState.load(1)
assert 'CREATED' == TaskState.load(u'新建')
assert TaskState.load(100) is None

def test_to_opts(self, TaskState):
opts = TaskState.to_opts()
assert opts == [
{'key': 0, 'value': u'新建'},
{'key': 1, 'value': u'已完成'},
]
opts = TaskState.to_opts(verbose=True)
assert opts == [
{'key': 0, 'label': 'CREATED', 'value': u'新建'},
{'key': 1, 'label': 'FINISHED', 'value': u'已完成'},
]
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ deps =
py27: ipython==5.8.0
commands =
flake8 .
py.test --cov=hobbit_core --cov=tests --cov-report term-missing -s
py.test