Code source de ReadDatabase

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Définition de quelques méthodes de recherche/accès à la base de données."""

import psycopg2
import psycopg2.extras
import datetime

# module qui définit les erreurs
import ExceptionsNote
# module qui définit des fonctions essentielles
import BaseFonctions

[docs]def _get_compte(quelparam, valeurparam): """Pour usage interne. Récupère le compte par idbde ou par pseudo""" req = "SELECT * FROM comptes WHERE %s = %%s;" % (quelparam) con, curseur = BaseFonctions.getcursor() curseur.execute(req, (valeurparam,)) result = curseur.fetchone() if (result == None): raise ExceptionsNote.Error404((u"%s Unknown : %s" % (quelparam, valeurparam)).encode("utf-8")) else: for (k, v) in result.items(): if (type(v) == str): result[k] = v.decode("utf-8") return result
[docs]def get_compte(idbde): """Récupère les infos du compte n° ``idbde`` dans la base de données et le renvoie sous forme d'un dictionnaire. Prend soin de transformer les champs texte en unicode. """ try: idbde = int(idbde) except: raise ExceptionsNote.TuTeFousDeMaGueule( "l'idbde fourni (%s) n'est pas convertible en entier..." % idbde) return _get_compte("idbde", idbde)
[docs]def get_display_info(idbde): """ Retourne les infos d'un compte en rajoutant le tag negatif donnant des infos sur la négativité du compte : * 0 : en positif * 1 : solde_negatif > solde > solde_tres_negatif * 2 : solde_tres_negatif > solde > solde_pas_plus_negatif (forced sera nécessaire) * 3 : solde_pas_plus_negatif > solde (overforced sera nécessaire)""" compte = dict(get_compte(idbde)) con, cur = BaseFonctions.getcursor() cur.execute("SELECT solde_negatif, solde_tres_negatif, solde_pas_plus_negatif FROM configurations WHERE used = true;") neg, tres_neg, pas_plus_neg = cur.fetchone() solde = compte["solde"] if solde >= neg: compte["negatif"] = 0 elif solde >= tres_neg: compte["negatif"] = 1 elif solde >= pas_plus_neg: compte["negatif"] = 2 else: compte["negatif"] = 3 return compte
[docs]def get_compte_by_pseudo(pseudo): """Récupère un compte par son pseudo.""" return _get_compte("pseudo", pseudo)
[docs]def like_replace(chain): """Échappe les % et _ avec = (et donc = avec ==) pour pouvoir faire un LIKE.""" # _ et % étant des caractères spéciaux pour LIKE, on a besoin de les échapper, # on choisit par convention de les échapper avec =, qu'on doit donc lui-même échapper (fais au moins semblant de suivre ce que je dis) # La syntaxe est "LIKE 'a==10=%%' ESCAPE '='" return chain.replace('=', '==').replace('%', '=%').replace('_', '=_')
[docs]def _is_pg_regexp(pattern): """Renvoie ``True`` si ``pattern`` est une regexp correcte au sens de PostGreSQL.""" assert(isinstance(pattern, basestring)) con, cur = BaseFonctions.getcursor() try: cur.execute("SELECT '' ~ %s;", (pattern,)) except psycopg2.DataError: return False else: return True
[docs]def _forge_test(test_field, include_regex=False): """Construit le test WHERE faisant un matching ILIKE entre ``test_field`` et le terme de recherche. Il faudra utiliser la clé ``"term_liked"`` pour le term LIKE-échapé avec un ``'"'``. Si ``include_regex`` est à ``True``, le test fera un OR avec un matching regex case-insensitive de la clé ``"term_regex"``. Il faut penser à like-échapper correctement ``term_liked`` et ajouter ^ à ``term_regex`` avant l'exécution de la requête. """ test = "%(test_field)s ILIKE %%(term_liked)s ESCAPE '='" if include_regex: test = "(" + test + " OR %(test_field)s ~* %%(term_regex)s)" return test % {"test_field" : test_field}
[docs]def _forge_request(skeleton, pieces): """Construit la requête de recherche en plaçant dans le squelette ``skeleton`` les morceaux du dico ``pieces``.""" # On ajoute les séparateurs nécessaires si les morceaux spécifiques ne sont pas vides for k in pieces.keys(): if k.startswith("specific"): if pieces[k]: separator = " AND " if k.endswith("where") else ", " pieces[k] = separator + pieces[k] return skeleton % pieces