summaryrefslogtreecommitdiff
path: root/ebus/datastore.py
diff options
context:
space:
mode:
Diffstat (limited to 'ebus/datastore.py')
-rw-r--r--ebus/datastore.py84
1 files changed, 84 insertions, 0 deletions
diff --git a/ebus/datastore.py b/ebus/datastore.py
new file mode 100644
index 0000000..88dcdc9
--- /dev/null
+++ b/ebus/datastore.py
@@ -0,0 +1,84 @@
+#
+
+import os
+from threading import Lock
+import tables
+
+class ValueFloat(tables.IsDescription):
+ timestamp = tables.Time32Col() #index on Time64 is broken on pytables 2.4
+ value = tables.Float32Col()
+
+class ValueInt(tables.IsDescription):
+ timestamp = tables.Time32Col()
+ value = tables.Int32Col()
+
+class ValueString(tables.IsDescription):
+ timestamp = tables.Time32Col()
+ value = tables.StringCol(20)
+
+
+class Datastore(object):
+ def __init__(self,basepath):
+ self.basepath = basepath
+ self.files = {}
+ self.fileLock = Lock()
+ self.tables = {}
+
+ # list all table in a dictionary { path.dot.name : object }
+ def listTables(self):
+ return dict(map(lambda e: (e.title, e), self.file.root))
+
+ def __enter__(self):
+ self.fileLock.__enter__()
+
+ def __exit__(self, *a):
+ self.fileLock.__exit__(*a)
+
+ def getTable(self, name, klass=None):
+ name = name.replace(".","_")
+ with self.fileLock:
+ if not name in self.files:
+ path = os.path.join(self.basepath, name+".hdf")
+ print "open {0}".format(path)
+ file = tables.openFile(path, "a", title = "eBus Datastore")
+ self.files[name] = file
+
+ if not name in self.tables:
+ t = None
+ try:
+ t = self.files[name].getNode("/"+name)
+ except tables.NoSuchNodeError,e:
+ if not klass: raise e
+ t = self.files[name].createTable("/",
+ name,
+ klass,
+ 'Description ' + name,
+ filters=tables.Filters(complevel=1),
+ createparents=True)
+ t.cols.timestamp.createCSIndex()
+ self.tables[name] = t
+
+ return self.tables[name]
+
+ def addValue(self, name, ts, value, klass,flush=False):
+ t = self.getTable(name, klass)
+ with self.fileLock:
+ t.row['timestamp'] = ts
+ t.row['value'] = value
+ t.row.append()
+ if flush: t.flush()
+
+ def addValueInt(self, name, ts, value): self.addValue(name, ts, value, ValueInt)
+ def addValueString(self, name, ts, value): self.addValue(name, ts, value, ValueString)
+ def addValueFloat(self, name, ts, value): self.addValue(name, ts, value, ValueFloat)
+
+ def flush(self):
+ with self.fileLock:
+ for file in self.files.values():
+ file.flush()
+
+ def close(self):
+ with self.fileLock:
+ for file in self.files.values():
+ file.close()
+