From c67d1a3583a6eda8c626c6d1d9cb42547d7a5b68 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 4 Apr 2014 10:34:21 -0400 Subject: [PATCH] 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 --- ipsilon/util/data.py | 30 ++++++++++++++++++++++++++++++ ipsilon/util/plugin.py | 3 +++ 2 files changed, 33 insertions(+) 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) -- 2.20.1