Laureline's Wiki

Laureline's Wiki

Moteurs de Stockage

Moteurs de Stockage

La librarie implémente actuellement deux moteurs de stockage: XML et SQLite. Ces deux moteurs se conforment à l'API définie en implémentant les interfaces fournies.

Moteur XML

Le moteur de stockage XML permet de stocker les métadonnées sous la forme d'un ou plusieurs fichiers XML. Les fichiers de ce moteur peuvent être modifiés à la main par un utilisateur expérimenté. Le moteur de stockage XML se démarque par sa simplicité en terme d'implémentation.

L'avantage de ce moteur de stockage est qu'il peut être utilisé pour aussi bien des catalogues locaux que distants. Il est même possible de simplement transférer un catalogue XML d'un emplacement local sur un serveur HTTP et de le rendre disponnible comme catalogue distant.

Le catalogue est entièrement chargé en mémoire lors de sa lecture depuis le disque. Le parsing s'effectue à l'aide de l'API DOM fournie par java en utilisant principalement des requètes XPath pour facilement trier les défférent types de noeuds.

L'écriture s'effectue à l'aide de la librairie dom4j car l'API DOM java est difficile d'utilisation. Lors de son écriture, un catalogue est complétement ré-écrit sur le disque.

Un exemple de catalogue XML peut être trouvé sur le CD-ROM.

Moteur SQLite

Le moteur SQLite permet d'enregistrer des informations sur les catalogues sur une base de données SQLite.

Il se base sur le framework OrmLite. Voici son modèle UML:

<uml> hide empty fields hide empty methods

class category {

+ id: int {id}
+ parent_id: int {fk}
+ name: string

}

class series {

+ id: int {id}
+ parent_id: int {fk}
+ metadata_id: int {fk}
+ name: string

}

class series_metadata {

+ id: int {id}
+ summary: string
+ released: int
+ author: string
+ artist: string
+ tag: string

}

class volume_metadata {

+ id: int {id}
+ series_parent_id: int {fk}
+ category_parent_id: int {fk}
+ number: int
+ name: string

}

category – “*” category category – “*” series

series → series_metadata

category – “*” volume_metadata series – “*” volume_metadata </uml>

Malheureusement, l'utilisation d'OrmLite n'a pas apporté les résultats souhaités car les objets actifs liés à la base de données fonctionnent de manière particulière, ce qui est incompatible avec le fonctionnement de la libVCL.

Une solution possible est de créer, depuis nos objets actifs SQLite, des objets contenant les informations mais sans liaison à la base de données. Notre application pourrait alors travailler dessus en faisant abstraction de ces problèmes. Puis, lors de la sauvegarde, notre moteur n'aurait plus qu'à parcourir ces objets et les enregistrer.

Cette solution n'a pas été utilisée pour ce projet car elle était jugée plus compliquée que de travailler sur des objets actifs. Cependant, il s'est avéré, après avoir résolu les problèmes liés aux objets actifs, qu'elle était en réalité bien plus simple. Voici ci-dessous une description des problèmes rencontrés et la solution apportée.

Tout d'abord, il est impossible de créer des relations entre des objets qui ne sont pas enregistrés dans la base de données. Par exemple, si on crée un volume qui doit appartenir à une série et que celle-ci n'a pas encore été enregistrée dans la base de données, cela va lever une exception. La solution est qu'à chaque création d'objets, il faut immédiatement l'enregistrer dans la base de données. Ce qui a pour désavantage qu'il n'est pas possible de travailler sur des objets temporaires n'étant pas enregistrés.

Ensuite, une catégorie doit pouvoir contenir à la fois des séries et d'autres catégories. Cependant depuis SQLite, cela se traduit par deux collections distinctes, alors que notre API veut que nous puissions récupérer d'une fois la liste contenant les deux et de pouvoir ajouter un élément depuis celle-ci sans savoir lequel. Il a donc été nécessaire de créer un objet qui émule une liste contenant les deux listes et qui, à l'ajout d'un élément, récupère le type de celui-ci et l'ajoute à la bonne liste.

Enfin, lorsque l'on modifie des informations sur un enregistrement, il faut appeler une méthode qui met à jour cet élément sur la base de données et l'enregistrement lui-même. Le problème vient de cette dernière opération car quand OrmLite met à jour un élément il change les références vers les objets parents, ce qui a pour conséquence de corrompre la hiérarchie du catalogue.

Le dernier problème n'a pas été résolu car le seul moyen de le résoudre est d'implémenter une autre solution qui ne travaille pas avec des objets actifs. Ce qui reviendrait à recommencer le développement du début, alors que ce problème a été découvert à la fin du projet, après de longues heures de recherche.

Il en résulte que les catalogues SQLite ne sont accessibles qu'en lecture et qu'il faut redémarrer l'application à chaque modification du catalogue.