Module `repository` - Hexoplanete/Projet-Furet GitHub Wiki

Correspond au dossier src/furet/repository

La base de données est stockée en local, mais à déplacer sur le SharePoint à terme. Les informations sont stockées dans des fichiers .csv.

Structure

Le module est composé de deux parties: 

  • __init__.py: l'interface publique utilisé par les autres modules
  • csvdb.py: le module de gestion des CSV.

Interface publique

Ce module expose de nombreuses fonctions permettant de récurer/ajouter/modifier des instances des modèles :

def getRaas() -> list[RAA]: ...
def getRaaById(id: int) -> RAA | None: ...
def updateRaa(id: int, raa: RAA): ...
def addRaa(raa: RAA): ...
def addRaas(raas: list[RAA]): ...
def alreadyImported(fileHash: str) -> bool: ...
def getRaaByHash(fileHash: str) -> RAA | None: ...
def getDecrees(filters: DecreeFilters | None = None) -> list[Decree]: ...
def getDecreeById(id: int) -> Decree | None: ...
def getDecreesByRaa(raaId: int) -> list[Decree]: ...
def updateDecree(id: int, decree: Decree): ...
def addDecree(decree: Decree | list[Decree]): ...
def getDepartments() -> list[Department]: ...
def getDepartmentById(id: int) -> Department | None: ...
def getDocumentTypes() -> list[DocumentType]: ...
def getDocumentTypeById(id: int) -> DocumentType | None: ...
def getCampaigns() -> list[Campaign]: ...
def getCampaignById(id: int) -> Campaign | None: ...
def updateCampaign(id: int, campaign: Campaign): ...
def addCampaign(campaign: Campaign): ...
def getCampaignFromTopic(topic: Topic) -> list[Campaign]: ...
def getTopics() -> list[Topic]: ...
def getTopicById(id: int) -> Topic | None: ...
def updateTopic(id: int, topic: Topic): ...
def addTopic(topic: Topic): ...

Il expose aussi une fonction setup permettant de se "connecter" à la DB.

csvdb

Ce module sert d'interface entre des fichiers CSV et des classes python.

Il expose une classe TableObject qui doit être dérivée pour ajouter des classes à la base. Il faut ensuite appeler la fonction connect avec le chemin d'accès de la DB.

Une fois cela fait, il faut appeler fonctions suivants pour interagir avec les données :

def insert(objects: T | list[T]): ...
def update(object: TableObject): ...
def fetch(table: type[T]) -> list[T]: ...
def fetchById(table: type[T], id: int) -> T | None: ...
def delete(object: TableObject): ...

Ajout d'une table

Pour ajouter une table, il suffit de créer une classe qui dérive de TableObject et de @dataclass

@dataclass(eq=False)
class Decree(TableObject): ...

Lors de l'import du fichier contenant cette classe, la fonction addTable de csvdb sera appelé et ajoutera la classe à la base et un fichier <classeName>.csv sera créé.

Découpage en fichiers

Il est possible de découper une table en plusieurs fichiers .csv en surchargeant la fonction fileSubPath.

Fonctionnement interne

Le fonctionnement du module repose sur 4 fonctions clés :

def serialize(value: Any) -> str: ...
def deserialize(value: str, valueType: type[TS] | _TypeAnnotation) -> TS: ...
def saveToCsv(objects: list[T], path: str) -> None: ...
def loadFromCsv(table: type[T], path: str) -> list[T]: ...

serialize et deserialize

Ces deux fonctions permettent de convertir des str (cellules de CSV) en objet python et vice versa grâce à des sérialiseurs. Ce sont des fonctions customs qui réalisent la conversion et sont enregistré au lancement de l'application et lors de l'ajout d'une table à la base, par ex. :

setSerializer(list, lambda v: LIST_SEP.join([serialize(i) for i in v]), lambda s, t: [] if len(s) == 0 else [deserialize(i, get_args(t)[0]) for i in s.split(LIST_SEP)])
setSerializer(cls, lambda v: str(getId(v, cls)), lambda s, t: fetchById(cls, int(s))) # lors de l'ajout d'une table `cls`

saveToCsv et loadFromCsv

Ces deux fonctions permettent de convertir des fichiers CSV en liste d'objets python grâce au deux fonctions ci-dessus. Elles sont appelées par les fonctions insert, fetch, etc.

Elles prennent en entrée une table table qui sert de modèle pour les colonnes et les types des cellules.

Afin d'améliorer les performances, les résultats de loadFromCsv ne sont recalculés que lorsque le ficher est modifié.

⚠️ **GitHub.com Fallback** ⚠️