karideo/back/src/data_interface.py

246 lines
7.0 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import tools
import json
from realog import debug
import random
import copy
from sanic.exceptions import ServerError
from psycopg2.extras import RealDictCursor
import db
def is_str(s, authorise):
if s == None:
if authorise == True:
return True
return False;
if type(s) == str:
return True
return False
def is_boolean(s, authorise):
if s == None:
if authorise == True:
return True
return False;
if s == True or s == False:
return True
return False
def is_int(s, authorise):
if s == None:
if authorise == True:
return True
return False;
try:
int(s)
return True
except ValueError:
return False
return False
def is_float(s, authorise):
if s == None:
if authorise == True:
return True
return False;
try:
float(s)
return True
except ValueError:
return False
return False
##
## @breif Generic interface to access to the BDD (no BDD, direct file IO)
##
class DataInterface():
def __init__(self, _name, _base_name, _name_view):
self.model = None
self.name = _name
self.name_view = _name_view
self.extract_base = "*"
self.base_name = _base_name
self.connection = db.connect_bdd();
self.need_save = False
self.where_expand = "";
#self.conn = self.connection.cursor()
def __del__(self):
db.remove_connection();
def set_data_model(self, _data_model):
self.model = _data_model
"""
self.extract_base = ""
for elem in self.model:
if elem["visible"] == True:
if self.extract_base != "":
self.extract_base += ","
self.extract_base += elem["name"]
"""
def set_add_where(self, _expand):
self.where_expand = _expand
##
## @brief Mark the current BDD to store all in File system (sync)
##
def mark_to_store(self):
self.need_save = True
##
## @brief Check if the Bdd need to be stored. It is stored if it has been requested.
## The BDD is store in a separate file and move in the old one. Safe way to store
##
def check_save(self):
if self.need_save == False:
return
debug.warning("Save bdd: ")
self.connection.commit()
def gets(self, filter=None):
debug.info("gets " + self.name)
cursor = self.connection.cursor(cursor_factory=RealDictCursor)
cursor.execute('SELECT * FROM ' + self.name_view + '')
results = cursor.fetchall()
#debug.info("gets data = " + json.dumps(results, indent=4))
if filter == None:
return results
debug.warning("BDD does not suppor filter now ...");
self.connection.commit()
return results
def get(self, _id):
if type(_id) != int:
debug.warning("get wrong input type...")
debug.info("get " + self.name + ": " + str(_id))
cursor = self.connection.cursor(cursor_factory=RealDictCursor)
#cursor.execute('SELECT * FROM data WHERE deleted=0')
#results = cursor.fetchall()
#debug.info("display data = " + json.dumps(results, indent=4))
req = (_id,)
cursor.execute('SELECT * FROM ' + self.name_view + ' WHERE id=%s', req)
results = cursor.fetchone()
self.connection.commit()
#debug.info("get specific data = " + json.dumps(results))
return results;
def find(self, _key, _value):
debug.info("get " + self.name + ": " + str(_value))
cursor = self.connection.cursor(cursor_factory=RealDictCursor)
req = (_value,)
cursor.execute('SELECT * FROM ' + self.name_view + ' WHERE ' + _key + '=%s', req)
results = cursor.fetchone()
self.connection.commit()
#debug.info("get specific data = " + json.dumps(results))
return results;
def find2(self, _key1, _value1, _key2, _value2):
debug.info("get " + self.name + ": " + str(_value1))
cursor = self.connection.cursor(cursor_factory=RealDictCursor)
req = (_value1,_value2)
cursor.execute('SELECT * FROM ' + self.name_view + ' WHERE ' + _key1 + '=%s AND ' + _key2 + '=%s', req)
results = cursor.fetchone()
self.connection.commit()
#debug.info("get specific data = " + json.dumps(results))
return results;
def delete(self, _id):
debug.info("delete " + self.name + ": " + str(_id))
cursor = self.connection.cursor()
req = (_id,)
cursor.execute('UPDATE ' + self.base_name + ' SET deleted=true WHERE id=%s' + self.where_expand, req)
self.mark_to_store();
self.connection.commit()
return True
def is_value_modifiable_and_good_type(self, _key, _value, _check_with="modifiable"):
if self.model == None:
return True
for elem in self.model:
if _key == elem["name"]:
if elem[_check_with] == False:
debug.warning("Try to set an input '" + str(_key) + "' but the element is not modifiable ... ");
raise ServerError("FORBIDDEN Try to set an input '" + str(_key) + "' but the element is not modifiable", status_code=403)
if elem["type"] == "str":
if is_str(_value, elem["can_be_null"]) == True:
return True
elif elem["type"] == "int":
if is_int(_value, elem["can_be_null"]) == True:
return True
elif elem["type"] == "float":
if is_float(_value, elem["can_be_null"]) == True:
return True
elif elem["type"] == "boolean":
if is_boolean(_value, elem["can_be_null"]) == True:
return True
else:
return True;
debug.warning("get element type == '" + str(type(_value)) + "' but request " + str(elem["type"]));
raise ServerError("FORBIDDEN get element type == '" + str(type(_value)) + "' but request " + str(elem["type"]), status_code=403)
# The key does not exist ...
debug.warning("The KEY: '" + str(_key) + "' Is not in the list of availlable keys");
raise ServerError("FORBIDDEN The KEY: '" + str(_key) + "' Is not in the list of availlable keys", status_code=403)
return False
def put(self, _id, _value):
debug.info("put in " + self.name + ": " + str(_id))
cursor = self.connection.cursor()
request = 'UPDATE ' + self.base_name + ' SET'
list_data = []
first = True;
for elem in _value.keys():
if elem == "id":
continue
if self.is_value_modifiable_and_good_type(elem, _value[elem]) == False:
return;
if first == True:
first = False
else:
request += " , "
list_data.append(_value[elem])
request += " " + elem + " = %s"
request += " WHERE id = %s " + self.where_expand
list_data.append(_id)
debug.info("Request executed : '" + request + "'")
cursor.execute(request, list_data)
self.mark_to_store();
return self.get(iddd);
def post(self, _value):
debug.info("post " + self.name)
cursor = self.connection.cursor()
request = 'INSERT INTO ' + self.base_name
list_data = []
first = True;
aaa = ""
bbb = ""
for elem in _value.keys():
if elem == "id":
continue
if self.is_value_modifiable_and_good_type(elem, _value[elem], "creatable") == False:
return;
if aaa != "":
aaa += " , "
if bbb != "":
bbb += " , "
aaa += elem
bbb += "%s"
list_data.append(_value[elem])
request += " ( " + aaa + ") VALUES ( " + bbb + ") RETURNING id"
debug.info("Request executed : '" + request + "'")
cursor.execute(request, list_data)
id_of_new_row = cursor.fetchone()[0]
self.mark_to_store();
return self.get(id_of_new_row);