s/ejdb/tinydb, clear eventmodel, some testing

towards a better db!
This commit is contained in:
boyska 2015-01-24 00:33:09 +01:00
parent b6e9fa8492
commit 6f0c335d2d
No known key found for this signature in database
GPG key ID: 7395DCAE58289CA9
4 changed files with 82 additions and 34 deletions

View file

@ -16,7 +16,7 @@ Software stack
* python2 * python2
* gevent as an async framework * gevent as an async framework
* flask to provide web interface and rpc * flask to provide web interface and rpc
* ejdb as an embedded database * tinydb as an embedded database
Why? (aka design features) Why? (aka design features)
-------------------------- --------------------------

View file

@ -12,21 +12,50 @@ from datetime import datetime, timedelta
import gevent import gevent
from gevent.queue import Queue from gevent.queue import Queue
from tinydb import TinyDB
from eventutils import ParentedLet from eventutils import ParentedLet
from timegen import timegenerate from timegen import timegenerate
from audiogen import audiogenerate from audiogen import audiogenerate
class EventModel(object):
def __init__(self, uri):
self.uri = uri
self.db = TinyDB(uri)
self.actions = self.db.table('actions')
self.alarms = self.db.table('alarms')
def get_action_by_id(self, action_id):
return self.actions.get(eid=action_id)
def get_alarm_by_id(self, alarm_id):
return self.alarms.get(eid=alarm_id)
def get_actions_by_alarm(self, alarm):
for action_id in alarm.get('actions', []):
yield self.get_action_by_id(action_id)
def get_all_alarms(self):
return self.alarms.all()
def get_all_alarms_expanded(self):
for alarm in self.get_all_alarms():
for action in self.get_actions_by_alarm(alarm):
yield alarm, action
def add_event(self, alarm, actions):
action_ids = [self.actions.insert(a) for a in actions]
alarm['actions'] = action_ids
return self.alarms.insert(alarm)
class EventSource(ParentedLet): class EventSource(ParentedLet):
def __init__(self, queue, uri): def __init__(self, queue, uri):
ParentedLet.__init__(self, queue) ParentedLet.__init__(self, queue)
import pyejdb
self.log = logging.getLogger(self.__class__.__name__) self.log = logging.getLogger(self.__class__.__name__)
self.log.debug('uri is %s' % uri) self.log.debug('uri is %s' % uri)
self.ejdb = pyejdb.EJDB(uri, self.model = EventModel(uri)
pyejdb.JBOREADER | pyejdb.JBOLCKNB |
pyejdb.JBOTRUNC)
self.log.debug('opened %s' % uri) self.log.debug('opened %s' % uri)
def parent_msg(self, kind, *args): def parent_msg(self, kind, *args):
@ -38,40 +67,16 @@ class EventSource(ParentedLet):
msg = ParentedLet.parent_msg(self, kind, *args) msg = ParentedLet.parent_msg(self, kind, *args)
return msg return msg
def _get_actions_by_alarm(self, alarm): def reload_id(self, alarm_id):
if 'actions' not in alarm:
return
for action_id in alarm['actions']:
with self.ejdb.find('actions',
{'_id': action_id}) as subcur:
for action in subcur:
yield action
def _get_by_alarmid(self, alarmid):
with self.ejdb.find('alarms', {'_id': alarmid}) as cur:
if len(cur) > 1:
self.log.warn("Found more than one alarm with given id")
for alarm in cur:
for action in self._get_actions_by_alarm(alarm):
yield alarm, action
def reload(self):
with self.ejdb.find('alarms', {}) as cur:
for alarm in cur:
self.log.info('%s\t%s' % (alarm['kind'],
', '.join(alarm.keys())))
for action in self._get_actions_by_alarm(alarm):
yield alarm, action
def reload_id(self, event_id):
''' '''
Check if the event is still valid, and put "add" messages on queue Check if the event is still valid, and put "add" messages on queue
''' '''
for alarm, action in self._get_by_alarmid(event_id): alarm = self.model.get_alarm_by_id(alarm_id)
for action in self.model.get_actions_by_alarm(alarm):
self.send_to_parent('add', alarm, action) self.send_to_parent('add', alarm, action)
def do_business(self): def do_business(self):
for alarm, action in self.reload(): for alarm, action in self.model.get_all_alarms_expanded():
yield ('add', alarm, action) yield ('add', alarm, action)

43
larigira/tests/test_db.py Normal file
View file

@ -0,0 +1,43 @@
from __future__ import print_function
import tempfile
import os
from gevent import monkey
monkey.patch_all(subprocess=True)
import pytest
from larigira.event import EventModel
@pytest.yield_fixture
def db():
fname = tempfile.mktemp(suffix='.json', prefix='larigira-test')
yield EventModel(uri=fname)
os.unlink(fname)
def test_empty(db):
assert len(db.get_all_alarms()) == 0
def test_add_basic(db):
assert len(db.get_all_alarms()) == 0
alarm_id = db.add_event(dict(kind='frequency', interval=60*3, start=1),
[dict(kind='mpd', paths=['foo.mp3'], howmany=1)])
assert len(db.get_all_alarms()) == 1
assert db.get_alarm_by_id(alarm_id) is not None
assert len(tuple(db.get_actions_by_alarm(
db.get_alarm_by_id(alarm_id)))) == 1
def test_add_multiple_alarms(db):
assert len(db.get_all_alarms()) == 0
alarm_id = db.add_event(dict(kind='frequency', interval=60*3, start=1),
[dict(kind='mpd', paths=['foo.mp3'], howmany=1),
dict(kind='foo', a=3)])
assert len(db.get_all_alarms()) == 1
assert db.get_alarm_by_id(alarm_id) is not None
assert len(db.actions.all()) == 2
assert len(tuple(db.get_actions_by_alarm(
db.get_alarm_by_id(alarm_id)))) == 2

View file

@ -40,7 +40,7 @@ setup(name='larigira',
'gevent', 'gevent',
'flask', 'flask',
'python-mpd2', 'python-mpd2',
'pyejdb' 'tinydb'
], ],
tests_require=['pytest', 'pytest-timeout'], tests_require=['pytest', 'pytest-timeout'],
cmdclass={'test': PyTest}, cmdclass={'test': PyTest},