La bibliothèque Silverlight Database

J’avais évoqué dans un précédent post les mécanismes de persistance de données dans Windows Phone 7 via l’IsolatedStorage. J’avais ainsi terminé l’article sur le fait que Silverlight pour Windows Phone manquait encore de réel gestionnaire de base de données tel que SQL CE. Il existe en revanche plusieurs API Open Source qui comblent ce manque. L’une d’entre elles est la bibliothèque Silverlight Database, projet hébergé sur la plateforme de projets Open Source de Microsoft, CodePlex. Vous pouvez télécharger le projet sur sa page : http://silverdb.codeplex.com

Fonctionnalités de Silverlight Database

L’API est en réalité très simple à utiliser, avec seulement quelques classes importantes, en particulier Database et Table<T>. Grâce à ses classes vous allez pouvoir créer une représentation objet de votre base de données et la sauvegarder sur l’IsolatedStorage de votre client (que cela soit du Silverlight pour navigateur ou du Silverlight pour Windows Phone 7). Toute la manipulation de l’IsolatedStorage sont effectué par Silverlight Database sans que vous ayez à vous préoccuper de quoi que ce soit. Les fonctionnalités de l’API sont les suivantes :

  • Création et suppression d’une ou plusieurs bases
  • Ajout et suppression d’une ou plusieurs tables
  • Récupération des données avec possibilité d’utiliser du Lazy Loading (c’est-à-dire que les données ne seront récupérées que lorsque le programme en aura vraiment besoin)
  • Compression des données via la bibliothèque Open Source Silverlight SharpZipLib (également hébergée sur CodePlex : http://slsharpziplib.codeplex.com/)
  • Chiffrage des données par l’algorithme de chiffrage symétrique AES (via la classe AESManaged)

Ce que Silverlight Database n’est pas

Contrairement à ce que le nom suggère Silverlight Database n’est pas un vrai gestionnaire de base de données. En effet si j’ai une entité A reliée à une ou plusieurs entités B, on aura en fait une classe A qui contient un IEnumerable<B> ; cette liste sera sérialisée en même temps que l’objet de type A, et tous ces objets seront contenu dans la table de A, hors dans un véritable SGBD les instances de B devraient être conservées à part dans une table contenant tous les B.

Ce n’est pas vraiment une limitation, mais cela peut donner des choses étranges si on n’y fait pas attention. C’est pourquoi je pense que Silverlight Database est plus un gestionnaire de conteneur d’objets persisté plutôt qu’un SGBD. Silverlight Database n’en ai pas moins très facile et agréable à utiliser.

Utilisation de l’API

Pour commencer, vous devez créer une base via la méthode statique Database.CreateDatabase qui prend en argument un identifiant (pour retrouver la base plus tard) et optionnellement un mot de passe qui servira de clé de chiffrage. Si vous avez déjà créé une base vous pouvez la charger via la méthode statique Database.LoadDatabase qui prend les mêmes arguments que pour la création.

Depuis l’instance de Database que vous venez de récupérer vous pouvez ajouter une table (ou plus exactement un conteneur pour un certain type d’objet) en appelant la méthode CreateTable<ObjectType> ou récupérer une table déjà créée via la méthode Table<ObjectType>.

Le type Table<T> renvoyé par ces deux méthodes est une classe bien pratique, qui dérive d’ObservableCollection<T>. Cela signifie que vous pouvez par exemple lier une Table<T> directement par Binding à une ListBox dans votre XAML. Comme l’ObservableCollection<T> lève des évènements lors d’ajouts et de suppressions, la ListBox sera ainsi directement mise à jour en fonction de vos traitements métiers sans aucun effort supplémentaire.

Bien évidemment, qui dit ObservableCollection dit Collection et donc possibilité d’utiliser les méthodes d’extensions de LINQ. Vous pourrez donc exécuter des requêtes sur vos tables en utilisant les méthodes Where, Any, Take et ainsi de suite. Pour terminer un appel à la méthode Save de la classe Database vous permettra de sauvegarder les modifications.

Conclusion

Pour conclure Silverlight Database est une bibliothèque très pratique qui permet de persister dans l’IsolatedStorage des objets managés de manière simple et profite de fonctionnalités intéressantes telles que la compression ou le chiffrage. Ce n’est pas exactement un SGBD comme le serait l’hypothétique SQL CE pour Windows Phone 7, mais néanmoins il permet d’abstraire une tâche peu intéressante que l’on retrouve dans un vaste panel d’application et d’ainsi accélérer vos développements.

Comment persister les données sous WP7 ?

Conserver des données sur le téléphone est le commun d’une grande majorité des applications, pour ne pas dire toutes les applications mobiles. Dans Windows Mobile, l’application avait accès à l’intégralité du système de fichiers du terminal, ce qui rendait la tâche assez similaire à ce qui se fait sous Windows. Sous Windows Phone 7, on se rapproche plus de ce qui se fait dans Silverlight pour PC / Mac ; aucun accès au système de fichiers, et encore moins à la base de registre de l’appareil. Tout, ou presque, passe par l’IsolatedStorage.

L’IsolatedStorage est un espace de stockage qui comme son nom le suggère est isolé des espaces de stockage des autres applications. Il ne sera donc pas question de partager les fichiers de l’application A avec l’application B. Ou presque. En effet certains fichiers gérés par les hubs de Windows Phone 7, pourront être accessibles par toutes les applications qui veulent étendre le hub en question. Pour l’instant il est surtout question du Hub photos, mais qui sait peut-être sera-t-il possible à l’avenir d’étendre d’autre hubs, voir même d’étendre les applications.

Pour cet article je vais uniquement m’intéresser à l’accès à l’IsolatedStorage et à la configuration des applications grâce à l’IsolatedStorageSettings.

L’Isolated Storage

Tout ce qui concerne l’utilisation de l’IsolatedStorage se trouve dans l’espace de nom System.IO.IsolatedStorage. Pour commencer il faut récupérer la racine des fichiers ; pour cela une seule façon de faire, appeler la méthode statique GetUserStoreForApplication de la classe IsolatedStorageFile qui renvoie une instance de cette même classe.

IsolatedStorageFile root = IsolatedStorageFile.GetUserStoreForApplication();

Cet objet remplace les traditionnelles classes File et Directory du framework .NET. On peut par exemple vérifier la présence d’un fichier ou d’un dossier avec les méthodes FileExists et DirectoryExists. On peut également créer de nouveaux dossiers et fichiers (CreateDirectory et CreateFile), obtenir la liste des fichiers et dossiers (GetFileNames et GetDirectoryNames) et finalement ouvrir un fichier en lecture ou en écriture à l’aide de la méthode OpenFile et de la classe IsolatedStorageFileStream.

IsolatedStorageFileStream fs = root.OpenFile("file.xml", System.IO.FileMode.Open);

L’IsolatedStorageFileStream s’apparente à un FileStream classique et permet donc d’exécuter toutes les opérations habituelles, lire, écrire, repositionner le curseur, et pour finir fermer le flux. Il peut également être utilisé au travers d’un StreamWriter ou d’un StreamReader, respectivement pour lire ou écrire plus facilement dans le fichier.

L’IsolatedStorageFile permet donc de gérer tout l’espace de fichier réservé à l’application. Il s’apparente en beaucoup d’aspects aux APIs de .NET en matière de gestion de fichiers. En revanche, l’IsolatedStorage d’une application est limitée en taille. Il est donc nécessaire de vérifier le Quota via la propriété du même nom. A priori une application ne devra pas dépasser les 2Go de mémoire sur le téléphone, ce qui paraît déjà être une limite assez haute. Attention également, quand l’utilisateur supprimera l’application, il effacera du même coup toutes les données de l’application.

La configuration des applications

Pour gérer les paramètres de l’application, la solution que je viens de détailler paraît un peu lourde. C’est pour cela qu’existe l’IsolatedStorageSettings. Ce n’est ni plus ni moins qu’un dictionnaire persisté sur l’IsolatedStorage. Les clés sont des chaînes de caractères, et les valeurs sont les objets à persister. La classe IsolatedStorageSettings est donc idéale pour conserver la configuration de vos applications.

IsolatedStorageSettings.ApplicationSettings["Key"] = "Value";

Pour toute autre information, la MSDN est comme toujours d’une grande aide : http://msdn.microsoft.com/en-us/library/ff402541%28VS.92%29.aspx

Qu’en est-il de SQL Compact ?

Enfin la grande question, existe-t-il une version de SQL Compact disponible sur WP7 ? Hélas non, du moins pas pour le moment. Il existe en revanche un certain nombre de personnes qui se sont penché sur le sujet, en open-source ou non.