diff options
author | Simo Sorce <simo@redhat.com> | 2014-04-04 10:34:21 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2014-04-04 12:38:41 -0400 |
commit | c67d1a3583a6eda8c626c6d1d9cb42547d7a5b68 (patch) | |
tree | 50b2b9ca2dca9f4b5f15efd4b6c7afdafdab9e23 | |
parent | 5a6c713fda1a4052051566984c0b489e286aa502 (diff) | |
download | ipsilon-c67d1a3583a6eda8c626c6d1d9cb42547d7a5b68.tar.gz ipsilon-c67d1a3583a6eda8c626c6d1d9cb42547d7a5b68.tar.xz ipsilon-c67d1a3583a6eda8c626c6d1d9cb42547d7a5b68.zip |
Add racefree way to add a new unique data point
Our schema gathers together data related to a service by using an ID
column. This column cannot be unique or a primary key as the ID is
repeated for each key/value pair in the datum group.
Use a unique identifier to make sure we can let dqlite generate a new
ID internally and then find out wat it is as race-free as possible.
We keep this method in the data module so it can be changed later
without affecting application logic.
Signed-off-by: Simo Sorce <simo@redhat.com>
-rwxr-xr-x | ipsilon/util/data.py | 30 | ||||
-rwxr-xr-x | ipsilon/util/plugin.py | 3 |
2 files changed, 33 insertions, 0 deletions
diff --git a/ipsilon/util/data.py b/ipsilon/util/data.py index ec32b43..52dfa78 100755 --- a/ipsilon/util/data.py +++ b/ipsilon/util/data.py @@ -20,6 +20,8 @@ import os import sqlite3 import cherrypy +from random import randint +import sys class Store(object): @@ -366,6 +368,34 @@ class Store(object): if con: con.close() + def new_datum(self, plugin, datum): + ID = "(SELECT IFNULL(MAX(id), 0) + 1 FROM %s_data)" % plugin + INSERT_NEW = "INSERT INTO %s_data VALUES(%s,?,?)" % (plugin, ID) + INSERT = "INSERT INTO %s_data VALUES(?,?,?)" % plugin + SELECT = "SELECT id FROM %s_data WHERE name=? AND value=?" % plugin + DELETE = "DELETE FROM %s_data WHERE name=? AND value=?" % plugin + con = None + try: + con = sqlite3.connect(self._admin_dbname) + cur = con.cursor() + tmpid = ('new', str(randint(0, sys.maxint))) + cur.execute(INSERT_NEW, tmpid) + cur.execute(SELECT, tmpid) + rows = cur.fetchall() + idval = rows[0][0] + for name in datum: + cur.execute(INSERT, (idval, name, datum[name])) + cur.execute(DELETE, tmpid) + con.commit() + except sqlite3.Error, e: + if con: + con.rollback() + cherrypy.log.error("Failed to store %s data: [%s]" % (plugin, e)) + raise + finally: + if con: + con.close() + def wipe_data(self, plugin): # Try to backup old data first, just in case try: diff --git a/ipsilon/util/plugin.py b/ipsilon/util/plugin.py index 6c329d6..cdf997e 100755 --- a/ipsilon/util/plugin.py +++ b/ipsilon/util/plugin.py @@ -157,6 +157,9 @@ class PluginObject(object): def save_data(self, data): self._data.save_data(self.name, data) + def new_datum(self, datum): + self._data.new_datum(self.name, datum) + def wipe_config_values(self, facility): self._data.wipe_plugin_config(facility, self.name) |