#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Le module DBA.py permet l'acces à la base de donnée
"""
import pgdb
import pg
import random
import ConfigParser
#import gwa.main
from traceback import format_exc
[docs]class DBConnect:
"""
La base de donée s'appelle 'wifi' et se trouve sur la machine
"""
def __init__(self,main=None):
"""
Initialisation de l'objet DBConnect
"""
self.main_app=main
#lecture du fichier de configuration
config = ConfigParser.RawConfigParser()
#si on arrive a lire le fichier
if config.read(self.main_app.gwa_path + '/gwa.conf'):
self.host = config.get('BDD','ip')
self.password = config.get('BDD','password')
self.user = config.get('BDD','user')
self.dbname = config.get('BDD','base')
else: #sans fichier de conf
self.dbname = 'gwa'
self.host = 'localhost'
self.user = 'gwa_user'
self.password = 'gwa_pass'
self.connectionObject=None
self.table_col = {}
self.__create_dico()
def __connect(self):
"""
Cette fonction privée permet de se connecter à une base de donnée
"""
try:
self.connectionObject = pgdb.connect(host=self.host, database=self.dbname, user=self.user, password=self.password)
except pg.InternalError:
print "Impossible de se connecter sur la BDD, verifier les arguments\n", format_exc()
exit(0)
def __disconnect(self):
"""
Cette fonction privée permet de se déconnecter de la base de donnée.
"""
try:
self.connectionObject.close()
except pg.InternalError:
print "Erreur lors de la déconexion de la BDD\n", format_exc()
exit(0)
def __create_colonne_string(self,liste_colonne):
"""
Cette fonction privée permet de transformer une liste en chaine de caractère pour permettre
l'injection de requêtes SQL. Cette liste représente les table de la BDD.
"""
colonne = ''
for nom in liste_colonne:
colonne = colonne + nom + ','
colonne = colonne[:-1]
return colonne
def __create_values_string(self,liste_value):
"""
Cette fonction privée permet de transformer une liste en chaine de caractère pour permettre
l'injection de requêtes SQL. Cette liste représente les valeurs contenues dans une table.
"""
values = '('
for val in liste_value:
if type(val) == int:
values = '%s %i,' % (values, val)
elif type(val) == str:
values = values + "'" + val + "'" + ','
elif type(val) == unicode:
values = values + "'" + val.encode("latin1") + "'" + ","
values = values[:-1]
values = values + ')'
return values
def __create_condition_string(self,dico_condition):
"""
Cette fonction privée permet de mettre en forme les conditions stockées dans un dictionnaire pour qu'elles
soient insérée dans une requête SQL.
"""
condition = ''
for var in dico_condition:
condition = condition+var+'='+str(dico_condition[var])+' AND '
condition = condition[:-5]
return 'WHERE '+condition
def __create_order_string(self,order_by):
"""
Cette fonction privée permet de mettre en forme l'ordre dans lequel on souhaite recevoir les informations
de la base de données.
"""
order = 'ORDER BY '+order_by[0]+' '+order_by[1]
return order
[docs] def insert(self,table,col_value):
"""
La fonction "insert" permet d'ajouter dans la BDD un objet par l'intermediaire d'un dictionnaire
:arguments:
- table (type string)
Choix de la table qui va recvoir l'objet
- col_value (type dictionnaire)
Objet à inserer
**exemple**
>>> table = 'lieux'
>>> col_value={'nom':'Evry','largeur':13,'longueur':32,'coor_x':8,'coor_y':2,'description':'Evry'}
DBA.DBConnect().insert(table,col_value)
"""
self.__connect()
cursor = self.connectionObject.cursor()
col_names = []
col_vals = []
for key, value in col_value.items():
col_names.append(key)
col_vals.append(value)
#print col_names, col_vals
cursor.execute('INSERT INTO %s (%s) VALUES %s' % (table,self.__create_colonne_string(col_names),\
self.__create_values_string(col_vals)))
self.connectionObject.commit()
cursor.close()
self.__disconnect()
[docs] def insertAndReturn(self,table,col_value, value_return):
"""
La fonction "insertAndReturn" permet d'ajouter dans la BDD un objet par l'intermediaire d'un dictionnaire
:arguments:
- table (type string)
Choix de la table qui va recvoir l'objet
- col_value (type dictionnaire)
Objet à inserer
- value_return (type string)
Choix de la valeur de retour lors d'un INSERT
:return:
La fonction retourne une liste de liste
**exemple**
>>> value_return = 'id_lieu'
>>> table = 'lieux'
>>> col_value={'nom':'Evry','largeur':13,'longueur':32,'coor_x':8,'coor_y':2,'description':'Evry'}
id = DBA.DBConnect().insert(table,col_value,value_return )
"""
self.__connect()
cursor = self.connectionObject.cursor()
col_names = []
col_vals = []
for key, value in col_value.items():
col_names.append(key)
col_vals.append(value)
cursor.execute('INSERT INTO %s (%s) VALUES %s RETURNING %s' % (table,self.__create_colonne_string(col_names),\
self.__create_values_string(col_vals), value_return))
value = cursor.fetchall()
self.connectionObject.commit()
cursor.close()
self.__disconnect()
return value
[docs] def select(self,table,colonne='*',condition='',order_by=''):
"""
La fonction "select" permet de faire des recherches sur la BDD.
Ces recherches peuvent se faire avec des conditions précises et l'affichage peut être général ou restrictif.
:arguments:
-table (type string ou liste)
Choix de la table contenant l'objet
:arguments optionnels:
- colonne (type string ou liste)
Choix des colonnes souhaité. Par defaut, elles sont toutes retournée
- condition (type dictionnaire)
Insertion d'une condition dans la sélection
- order_by (type tuple)
Choix du paramètre sur lequel l'ordre de la requête sera appliquée avec le paramètre ASC ou DESC
:retour:
La fonction retourne une liste de liste
:infos:
Dans le cas d'une condition avec comparaison de string, mettre le champs string entre quote
**exemple**
>>> table = 'place'
>>> colonne = '*'
>>> condition = { 'name':'\'Evry\'' }
>>> order_by = ('id_place','DESC')
"DBA.DBConnect().select(table,colonne,condition,order_by)"
"""
self.__connect()
cursor = self.connectionObject.cursor()
if type(table) == list:
table = self.__create_colonne_string(table)
if type(colonne) == list:
colonne = self.__create_colonne_string(colonne)
if type(condition) == dict:
condition = self.__create_condition_string(condition)
if type(order_by) == tuple:
order_by = self.__create_order_string(order_by)
liste=[]
try:
cursor.execute('SELECT %s FROM %s %s %s' %(colonne,table,condition,order_by))
self.connectionObject.commit()
liste = cursor.fetchall()
except pg.DatabaseError:
print "Erreur sur la requete de selection dans la base de donnee", format_exc()
cursor.close()
self.__disconnect()
return liste
[docs] def delete(self,table,row):
"""
La fonction "delete" permet de supprimer des données dans la BDD.
:arguments:
- table (type string)
Choix de la table contenant l'objet
- row (type dico)
Dictionnaire avec en clé le nom de la colonne et en value la valeur...
**exemple**
>>> table = 'place'
>>> id_sup = 12
DBA.DBConnect().delete(table,{'id_place':id_sup})
"""
self.__connect()
cursor = self.connectionObject.cursor()
try:
contrainte = row.popitem()
requete = 'DELETE FROM %s WHERE %s = \'%s\'' % (table, contrainte[0], contrainte[1])
cursor.execute( requete )
self.connectionObject.commit()
except pg.DatabaseError:
print "Erreur sur la requette de suppression", format_exc()
cursor.close()
self.__disconnect()
def __create_dico(self):
"""
Cette fonction privée permet de récupérer les informations de la base de donnée sous forme de dictionnaire.
On y retrouvera donc chaque colonne de la base avec ses attributs.
"""
self.__connect()
cursor = self.connectionObject.cursor()
cursor.execute( 'SELECT tablename FROM pg_tables WHERE (tablename NOT LIKE \'pg_%\') AND (tablename NOT LIKE \'sql_%\')' )
self.connectionObject.commit()
liste = cursor.fetchall()
self.table_col = {}
for i in liste:
cursor.execute('SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=\'%s\'' % i[0])
self.connectionObject.commit()
liste_temp = []
for col_temp in cursor.fetchall():
liste_temp.append(col_temp[0])
self.table_col[i[0]]=liste_temp
cursor.close()
self.__disconnect()
[docs] def update(self,table,colonne,value,condition):
"""
La fonction "update" permet de mettre à jour des objets de la BDD
:arguments:
- table (type string ou liste)
Choix de la table contenant l'objet à mettre à jour
- colonne (type string ou liste)
Choix de la colonne à modifier
- value (type string ou integer)
Choix de la nouvelle valeur à inserer
- condition (type dictionnaire)
Paramétrage d'une condition
**exemple**
>>> table = 'measure'
>>> colonne = 'signal_level'
>>> value = -91
>>> condition = {'coor_x':'2', 'coor_y':'0'}
DBA.DBConnect().update(table,colonne,value,condition)
"""
self.__connect()
cursor = self.connectionObject.cursor()
if type(table) == list:
table = self.__create_colonne_string(table)
if type(colonne) == list:
colonne = self.__create_colonne_string(colonne)
if type(condition) == dict:
condition = self.__create_condition_string(condition)
cursor.execute('UPDATE %s SET %s = %s %s' % (table,colonne,value,condition))
self.connectionObject.commit()
cursor.close()
self.__disconnect()
[docs] def custom(self,requete):
"""
La fonction 'custom' permet d'envoyer une requête SQL de son choix sur la base de donnée
:argument:
-requete (type SQL)
"""
self.__connect()
cursor = self.connectionObject.cursor()
cursor.execute( requete )
self.connectionObject.commit()
try:
liste = cursor.fetchall()
except pgdb.DatabaseError, exc:
print "Exception dans requete custom:\n", format_exc()
liste =[]
cursor.close()
self.__disconnect()
return liste
[docs]class Fill:
"""
La classe 'Remp_mes' permet de remplir la table de mesure d'une campagne avec des valeurs à -100db.
Le remplissage des valeurs se fait par rapport à la campagne, à la taille du lieux et au step choisit.
Avant de remplir les valeurs dans la campagne, on supprime les eventuelles données existantes.
:argument:
id_campagne (parametre type integer)
ID de la campagne pour lequel les valeurs seront inserées
"""
def __init__(self, id_camp, matrice):
db = DBConnect()
coorX = coorY = 0
for x in matrice:
coorY = 0
for y in x:
if y == 0:
col_value={'id_campagne':id_camp,'coor_x':coorX,'coor_y':coorY,'power':-100}
db.insert('mesure', col_value)
coorY +=1
coorX += 1
if __name__=="__main__":
info = raw_input("Affichage de la base -> 0\n\
Remplissage de la base -> 1,\n\
Lecture de la base -> 2\n\
Suppression d'infos de la base -> 3\n\
Mise à jour des puissances -> 4\n")
db = DBConnect()
if info == '0':
print db.table_col
elif info == '1':
col_value={'id_area':100,'name':'Evry','width':13,'length':32,'height':5,'x_coordinate_area':8,'y_coordinate_area':34,'z_coordinate_area':5,'description':'Salle 3456 Evry','origin_info':'origine !!!'}
db.insert('area',col_value)
print "Objet ajouté dans la base de donnée"
elif info == '2':
dico_test = { 'name':'\'Evry\'' }
print db.select('area','*',dico_test,('id_area','DESC'))
print "Lecture de la table lieux"
elif info == '3':
db.delete('area',{'id_area':100})
print "Objet supprimé"
elif info == '4':
dico_test={'x_coordinate_area':'8', 'y_coordinate_area':'34'}
db.update('area','height',345678965,dico_test)
print "Objet modifié"