|
|
|
@ -2,44 +2,64 @@ import psycopg2 as psy
|
|
|
|
|
import regles
|
|
|
|
|
|
|
|
|
|
def verifRegle(co):
|
|
|
|
|
''' verifRegle takes a connection to a database, from which it'll go through the data in the current transaction
|
|
|
|
|
to see if the data correlate to a possible rule violation.
|
|
|
|
|
'''
|
|
|
|
|
cur=co.cursor()
|
|
|
|
|
cur.execute('''SELECT type,addresse,valeur FROM Status ORDER BY type,addresse;''')
|
|
|
|
|
res=cur.fetchall()
|
|
|
|
|
# res contains all the data from the current transaction. The entirety of the status table is loaded.
|
|
|
|
|
dataState={}
|
|
|
|
|
for row in res:
|
|
|
|
|
dataState[(row[0],int(row[1]))]=int(row[2])
|
|
|
|
|
# the dictionnary dataState is a litteral representation of the database, with the key being a tuple of the address and the type of data,
|
|
|
|
|
# dataState's values are the values of the statuses.
|
|
|
|
|
listRules=regles.getRegles()
|
|
|
|
|
# listRules contains all the rules created in regles.py, and getRegles is called to get a copy of the rules' list.
|
|
|
|
|
for rule in listRules:
|
|
|
|
|
# we check each rule one by one, to see if they aren't violated
|
|
|
|
|
ruleWarning=0
|
|
|
|
|
condition=len(rule[0])
|
|
|
|
|
for i in rule[0]:
|
|
|
|
|
if (i[0],i[1]) in dataState:
|
|
|
|
|
if dataState[(i[0],i[1])]==i[2]:
|
|
|
|
|
ruleWarning+=1
|
|
|
|
|
# we first verify if the conditions aren't violated.
|
|
|
|
|
if ruleWarning>=condition:
|
|
|
|
|
# if all the conditions of the rule are matched, we check to see if the request tries to update the forbidden value.
|
|
|
|
|
if (rule[1][0],rule[1][1]) in dataState:
|
|
|
|
|
if dataState[(rule[1][0],rule[1][1])]==rule[1][2]:
|
|
|
|
|
return False
|
|
|
|
|
# The boolean False is returned in the case where one rule is violated.
|
|
|
|
|
return True
|
|
|
|
|
# If True is returned, it's because there's no rule that is violated, so the request isn't problematic for the system.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def ecritureBDD(lStatus,connec):
|
|
|
|
|
''' ecritureBDD is the function that is called to upsert (insert or update) the values of the status given in lStatus
|
|
|
|
|
connec contains the information needed to create a connection to the database
|
|
|
|
|
'''
|
|
|
|
|
co = None
|
|
|
|
|
try:
|
|
|
|
|
co = psy.connect(host=connec[0],database=connec[1],user=connec[2],password=connec[3])
|
|
|
|
|
# the connection to the database is now created in co.
|
|
|
|
|
cur = co.cursor()
|
|
|
|
|
# cur is a cursor on the connection to the database, it lets us perform actions on co's transaction.
|
|
|
|
|
for i in lStatus:
|
|
|
|
|
cur.execute("INSERT INTO Status VALUES (%s,%s,%s ) ON CONFLICT (addresse,type) DO UPDATE SET valeur=%s;",(i[1],i[0],i[2],i[2]))
|
|
|
|
|
if verifRegle(co):
|
|
|
|
|
co.commit()
|
|
|
|
|
else:
|
|
|
|
|
# each statuses in lStatus is now upserted in the database on the current transaction, until commited, they aren't actually inside the database.
|
|
|
|
|
if verifRegle(co)!=True:
|
|
|
|
|
# verifRegle is executed with the current connection, so it has access to the transaction in order to verify if rules are violated.
|
|
|
|
|
print("A rule has been violated. The system is endangered. The database hasn't been updated.")
|
|
|
|
|
co.rollback()
|
|
|
|
|
# A message is shown to the user to make him aware of the rule that is violated.
|
|
|
|
|
# a co.rollback() would be called if we managed to block the client request in order to prevent the server to be updated.
|
|
|
|
|
co.commit()
|
|
|
|
|
cur.close()
|
|
|
|
|
except(Exception,psy.DatabaseError) as error:
|
|
|
|
|
print(error)
|
|
|
|
|
# In case of an exception, like the failure of the creation of the connection, details are shown to tell the user about it.
|
|
|
|
|
finally:
|
|
|
|
|
if co is not None:
|
|
|
|
|
co.close()
|
|
|
|
|