From b8c09eea8918958db09e19ef9756c7cdc3211d41 Mon Sep 17 00:00:00 2001 From: Guillaume Raffy Date: Tue, 6 Feb 2018 17:37:15 +0000 Subject: [PATCH] Bug 1978 - trouver un moyen de rationaliser l'achat du r930 cper 2017 - refactored so that it now abstracts the database provider ; this way, accessing the inventory database through a database server instead of a sdl dump file is mostly transparent --- SimpaDbUtil.py | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/SimpaDbUtil.py b/SimpaDbUtil.py index 867a4eb..fecc6e1 100644 --- a/SimpaDbUtil.py +++ b/SimpaDbUtil.py @@ -7,6 +7,9 @@ from wol import * import os import signal from Util import * +import abc +import sqlite3 +from mysql2sqlite import mysql_to_sqlite def isMachineResponding(machineName): (returnCode, stdout, stderr) = executeProgram( [ 'ping', '-o', '-t', '1', machineName ] ) @@ -30,6 +33,105 @@ def isMachineResponding(machineName): assert(False) return False +class ISqlDatabaseBackend(object): + def __init__(self): + pass + + @abc.abstractmethod + def query(self, sql_query): + """ + :param str sql_query: the sql query to perform + """ + pass + +class RemoteMysqlDb(ISqlDatabaseBackend): + def __init__(self, db_server_fqdn, db_user, db_name): + """ + :param str db_server_fqdn: the fully qualified domain name of the server hosting the database, eg simpatix10.univ-rennes1.fr + :param str db_user: the user for accessing the inventory database, eg simpadb_reader + :param str db_name: the name of the inventory database, eg simpadb + """ + self._db_server_fqdn = db_server_fqdn + self._db_user = db_user + self._db_name = db_name + self._connect() + + def _connect(self): + self._conn = MySQLdb.connect(self._db_server_fqdn, self._db_user, '', self._db_name) + assert(self._conn) + + def query(self, sql_query): + """ + :param str sql_query: the sql query to perform + """ + self._conn.query( sql_query ) + rows = conn.store_result() + return rows + + +class SqlFile(ISqlDatabaseBackend): + def __init__(self, sql_file_path): + """ + :param str sql_file_path: the path of the sql file containing the inventory database + """ + self._sql_file_path = sql_file_path + self._cur = None # sqlite cursor + + sqlite_db_path=':memory:' # sqlite-specific special name for a file stored in memory. We could use something like '/tmp/simpadb.sqlite' here but this would make parsing really slow (1 minute instead of 1s), unless either : + # - proper fix : group of INSERT statements are surrounded by BEGIN and COMMIT (see http://stackoverflow.com/questions/4719836/python-and-sqlite3-adding-thousands-of-rows) + # - the file is stored on a solid state disk + try: + os.remove(sqlite_db_path) + except: + pass + self._con = sqlite3.connect(sqlite_db_path) + f = open(self._sql_file_path, 'r') + sql = f.read() # watch out for built-in `str` + #print(sql) + self._cur = self._con.cursor() + #print(mysql_to_sqlite(sql)) + self._cur.executescript(mysql_to_sqlite(sql)) + + def query(self, sql_query): + """ + :param str sql_query: the sql query to perform + """ + pass + self._cur.execute( sql_query ) + rows = self._cur.fetchall() + return rows + + +class SqlDatabaseReader(object): + + def __init__(self, inv_provider): + """ + :param ISqlDatabaseBackend inv_provider: the input that provides the inventory data + """ + self._inv_provider = inv_provider + + def query(self, sql_query): + """ + performs a query on the sql database + + :param str sql_query: the sql query to perform + """ + return self._inv_provider.query(sql_query) + + def get_table_attr(self, table, key_name, key_value, attr_name ): + """ + reads the value of the fiven attribute of the given item in the given table + + :param str table: the name of the table to read + :param str key_name: the name of the column that stores the id of the item to read + :param str key_value: the id of the item to read + :param str attr_name: the name of the attribute to read from the item + """ + attr_value = None + rows = self.query("SELECT "+attr_name+" FROM "+table+" WHERE "+key_name+"='"+key_value+"'") + if len(rows) > 0: + attr_value = rows[0][0] + return attr_value def machineNameToMacAddress( machineName ): conn = MySQLdb.connect('simpatix10', 'simpadb_reader', '', 'simpadb')