|
|
@@ -175,14 +175,14 @@ class NilmDB(object): |
|
|
|
return iset |
|
|
|
|
|
|
|
def _sql_interval_insert(self, id, start, end, start_pos, end_pos): |
|
|
|
"""Add interval to the SQL database only""" |
|
|
|
"""Helper that adds interval to the SQL database only""" |
|
|
|
self.con.execute("INSERT INTO ranges " |
|
|
|
"(stream_id,start_time,end_time,start_pos,end_pos) " |
|
|
|
"VALUES (?,?,?,?,?)", |
|
|
|
(id, start, end, start_pos, end_pos)) |
|
|
|
|
|
|
|
def _sql_interval_delete(self, id, start, end, start_pos, end_pos): |
|
|
|
"""Remove interval from the SQL database only""" |
|
|
|
"""Helper that removes interval from the SQL database only""" |
|
|
|
self.con.execute("DELETE FROM ranges WHERE " |
|
|
|
"stream_id=? AND start_time=? AND " |
|
|
|
"end_time=? AND start_pos=? AND end_pos=?", |
|
|
@@ -215,10 +215,8 @@ class NilmDB(object): |
|
|
|
# database |
|
|
|
iset -= adjacent |
|
|
|
self._sql_interval_delete(stream_id, |
|
|
|
adjacent.db_start, |
|
|
|
adjacent.db_end, |
|
|
|
adjacent.db_startpos, |
|
|
|
adjacent.db_endpos) |
|
|
|
adjacent.db_start, adjacent.db_end, |
|
|
|
adjacent.db_startpos, adjacent.db_endpos) |
|
|
|
|
|
|
|
# Now update our interval so the fallthrough add is |
|
|
|
# correct. |
|
|
@@ -236,7 +234,7 @@ class NilmDB(object): |
|
|
|
|
|
|
|
self.con.commit() |
|
|
|
|
|
|
|
def _remove_interval(self, stream_id, original, to_remove): |
|
|
|
def _remove_interval(self, stream_id, original, remove): |
|
|
|
""" |
|
|
|
Remove an interval from the internal cache and the database. |
|
|
|
|
|
|
@@ -244,12 +242,40 @@ class NilmDB(object): |
|
|
|
original: original DBInterval; must be already present in DB |
|
|
|
to_remove: DBInterval to remove; must be subset of 'original' |
|
|
|
""" |
|
|
|
#DBInterval(1332496800.0, 1332496919.991668, |
|
|
|
# 1332496800.0, 1332496919.991668, |
|
|
|
# 14400L, 28800L) |
|
|
|
#Interval(1332496830.0, 1332496830.0) |
|
|
|
# Just return if we have nothing to remove |
|
|
|
if remove.start == remove.end: # pragma: no cover |
|
|
|
return |
|
|
|
|
|
|
|
# Load this stream's intervals |
|
|
|
iset = self._get_intervals(stream_id) |
|
|
|
|
|
|
|
# Remove existing interval from the cached set and the database |
|
|
|
iset -= original |
|
|
|
self._sql_interval_delete(stream_id, |
|
|
|
original.db_start, original.db_end, |
|
|
|
original.db_startpos, original.db_endpos) |
|
|
|
|
|
|
|
# Add back the intervals that would be left over if the |
|
|
|
# requested interval is removed. There may be two of them, if |
|
|
|
# the removed piece was in the middle. |
|
|
|
def add(iset, start, end, start_pos, end_pos): |
|
|
|
iset += DBInterval(start, end, start, end, start_pos, end_pos) |
|
|
|
self._sql_interval_insert(stream_id, start, end, start_pos, end_pos) |
|
|
|
|
|
|
|
if original.start != remove.start: |
|
|
|
# Interval before the removed region |
|
|
|
add(iset, original.start, remove.start, |
|
|
|
original.db_startpos, remove.db_startpos) |
|
|
|
|
|
|
|
if original.end != remove.end: |
|
|
|
# Interval after the removed region |
|
|
|
add(iset, remove.end, original.end, |
|
|
|
remove.db_endpos, original.db_endpos) |
|
|
|
|
|
|
|
# Commit SQL changes |
|
|
|
self.con.commit() |
|
|
|
|
|
|
|
return |
|
|
|
raise NotImplementedError(repr((stream_id, original, to_remove))) |
|
|
|
|
|
|
|
def stream_list(self, path = None, layout = None): |
|
|
|
"""Return list of [path, layout] lists of all streams |
|
|
@@ -291,7 +317,7 @@ class NilmDB(object): |
|
|
|
intervals = self._get_intervals(stream_id) |
|
|
|
requested = Interval(start or 0, end or 1e12) |
|
|
|
result = [] |
|
|
|
for n, (i, orig) in enumerate(intervals.intersection(requested)): |
|
|
|
for n, i in enumerate(intervals.intersection(requested)): |
|
|
|
if n >= self.max_results: |
|
|
|
restart = i.start |
|
|
|
break |
|
|
@@ -466,7 +492,7 @@ class NilmDB(object): |
|
|
|
matched = 0 |
|
|
|
remaining = self.max_results |
|
|
|
restart = 0 |
|
|
|
for (interval, orig) in intervals.intersection(requested): |
|
|
|
for interval in intervals.intersection(requested): |
|
|
|
# Reading single rows from the table is too slow, so |
|
|
|
# we use two bisections to find both the starting and |
|
|
|
# ending row for this particular interval, then |
|
|
@@ -513,19 +539,23 @@ class NilmDB(object): |
|
|
|
if start == end: |
|
|
|
return 0 |
|
|
|
|
|
|
|
for (interval, orig) in intervals.intersection(to_remove): |
|
|
|
# Can't remove intervals from within the iterator, so we need to |
|
|
|
# remember what's currently in the intersection now. |
|
|
|
all_candidates = list(intervals.intersection(to_remove, orig = True)) |
|
|
|
|
|
|
|
for (dbint, orig) in all_candidates: |
|
|
|
# Find row start and end |
|
|
|
row_start = self._find_start(table, interval) |
|
|
|
row_end = self._find_end(table, interval) |
|
|
|
row_start = self._find_start(table, dbint) |
|
|
|
row_end = self._find_end(table, dbint) |
|
|
|
|
|
|
|
# Adjust the DBInterval to match the newly found ends |
|
|
|
interval.db_start = interval.start |
|
|
|
interval.db_end = interval.end |
|
|
|
interval.db_startpos = row_start |
|
|
|
interval.db_endpos = row_end |
|
|
|
dbint.db_start = dbint.start |
|
|
|
dbint.db_end = dbint.end |
|
|
|
dbint.db_startpos = row_start |
|
|
|
dbint.db_endpos = row_end |
|
|
|
|
|
|
|
# Remove interval from the database |
|
|
|
self._remove_interval(stream_id, orig, interval) |
|
|
|
self._remove_interval(stream_id, orig, dbint) |
|
|
|
|
|
|
|
# Remove data from the underlying table storage |
|
|
|
table.remove(row_start, row_end) |
|
|
|