Skip to content

Commit

Permalink
feat: add datastore API for fetching a single event by ID
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikBjare committed Mar 2, 2022
1 parent 0629e84 commit 9ca348e
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 10 deletions.
5 changes: 5 additions & 0 deletions aw_datastore/datastore.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ def get(
self.bucket_id, limit, starttime, endtime
)

def get_by_id(self, event_id) -> Event:
return self.ds.storage_strategy.get_event(
self.bucket_id, event_id
)

def get_eventcount(
self, starttime: datetime = None, endtime: datetime = None
) -> int:
Expand Down
8 changes: 8 additions & 0 deletions aw_datastore/storages/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ def delete_bucket(self, bucket_id: str) -> None:
def get_metadata(self, bucket_id: str) -> dict:
raise NotImplementedError

@abstractmethod
def get_event(
self,
bucket_id: str,
event_id: int,
) -> List[Event]:
raise NotImplementedError

@abstractmethod
def get_events(
self,
Expand Down
13 changes: 13 additions & 0 deletions aw_datastore/storages/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ def buckets(self):
buckets[bucket_id] = self.get_metadata(bucket_id)
return buckets

def get_event(
self,
bucket_id: str,
event_id: int,
) -> List[Event]:
event = self._get_event(bucket_id, event_id)
return copy.deepcopy(event)

def get_events(
self,
bucket: str,
Expand Down Expand Up @@ -117,6 +125,11 @@ def delete(self, bucket_id, event_id):
return True
return False

def _get_event(self, bucket_id, event_id):
events = [event for idx, event in reversed(list(enumerate(self.db[bucket_id]))) if event.id == event_id]
assert len(events) == 1
return events[0]

def replace(self, bucket_id, event_id, event):
for idx in (
idx
Expand Down
11 changes: 11 additions & 0 deletions aw_datastore/storages/peewee.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ def replace(self, bucket_id, event_id, event):
event.id = e.id
return event

def get_event(
self,
bucket_id: str,
event_id: int,
):
"""
Fetch a single event from a bucket.
"""
res = self._get_event(bucket_id, event_id)
return Event(**EventModel.json(res))

def get_events(
self,
bucket_id: str,
Expand Down
42 changes: 32 additions & 10 deletions aw_datastore/storages/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@
"""


def _rows_to_events(rows: list) -> Event:
events = []
for row in rows:
eid = row[0]
starttime = datetime.fromtimestamp(row[1] / 1000000, timezone.utc)
endtime = datetime.fromtimestamp(row[2] / 1000000, timezone.utc)
duration = endtime - starttime
data = json.loads(row[3])
events.append(
Event(id=eid, timestamp=starttime, duration=duration, data=data)
)
return events


class SqliteStorage(AbstractStorage):
sid = "sqlite"

Expand Down Expand Up @@ -256,6 +270,23 @@ def replace(self, bucket_id, event_id, event) -> bool:
self.conditional_commit(1)
return True

def get_event(
self,
bucket_id: str,
event_id: str,
):
self.commit()
c = self.conn.cursor()
query = """
SELECT id, starttime, endtime, datastr
FROM events
WHERE bucketrow = (SELECT rowid FROM buckets WHERE id = ?) AND id = ?
LIMIT 1
"""
rows = c.execute(query, [bucket_id, event_id])
events = _rows_to_events(rows)
return events[0]

def get_events(
self,
bucket_id: str,
Expand All @@ -279,16 +310,7 @@ def get_events(
ORDER BY endtime DESC LIMIT ?
"""
rows = c.execute(query, [bucket_id, starttime_i, endtime_i, limit])
events = []
for row in rows:
eid = row[0]
starttime = datetime.fromtimestamp(row[1] / 1000000, timezone.utc)
endtime = datetime.fromtimestamp(row[2] / 1000000, timezone.utc)
duration = endtime - starttime
data = json.loads(row[3])
events.append(
Event(id=eid, timestamp=starttime, duration=duration, data=data)
)
events = _rows_to_events(rows)
return events

def get_eventcount(
Expand Down
19 changes: 19 additions & 0 deletions tests/test_datastore.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,25 @@ def test_get_datefilter_simple(bucket_cm):
assert 1 == len(fetched_events)


@pytest.mark.parametrize("bucket_cm", param_testing_buckets_cm())
def test_get_event_by_id(bucket_cm):
"""Test that we can retrieve single events by their IDs"""
with bucket_cm as bucket:
eventcount = 2
# Create 1-day long events
events = [
Event(timestamp=now + i * td1d, duration=td1d) for i in range(eventcount)
]
bucket.insert(events)

# Retrieve stored events
events = bucket.get()
for e in events:
# Query them one-by-one
event = bucket.get_by_id(e.id)
assert e == event


@pytest.mark.parametrize("bucket_cm", param_testing_buckets_cm())
def test_get_event_trimming(bucket_cm):
"""Test that event trimming works correctly (when querying events that intersect with the query range)"""
Expand Down

0 comments on commit 9ca348e

Please sign in to comment.