Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Silverlight : gérer une base de données locale

[new:31/05/2011]Tout le monde le sait, Silverlight ne gère pas de base de données, en tout cas directement. C’est une technologie “client” et si données il y a elles sont stockées côté serveur. La “glue” pour faire fonctionner l’ensemble s’appelle WCF, quelle qu’en soit la mouture. Or bien souvent les applications Silverlight tireraient profit d’une base de données purement locale. Il existe certaines solutions payantes, mais je vais vous présenter une solution simple, gratuite et open source : Silverlight Database (un nom vraiment dur à retenir !

Utiliser l’Isolated Storage

La première idée qui vient en tête est bien entendu d’utiliser l’Isolated Storage (IS) pour stocker la base de données. Mais ensuite ? Silverlight ne propose aucune des interfaces ni classes permettant de se connecter à moteur de base de données. Et il n’existe pas de solution out-of-the-box de “mini moteur de base de données” dans Silverlight.

Le cas de l’Out Of Browser (OOB)

Les applications Silverlight s’entendent aujourd’hui aussi bien en mode Web (le mode “classique”) qu’en mode OOB, nécessitant l’installation sur la machine cliente. Ce dernier mode offre au développeur bien plus de possibilités mais il ne permet pas plus de se connecter à un SGBD local. Le cas de Silverlight sur Windows Phone 7 est un peu particulier mais il s’agit en réalité d’une mode OOB spécifique proposant des possibilités identiques (notamment dans la relation avec le hardware client et le code natif de celui-ci) mais aussi affichant les mêmes lacunes quant aux bases de données locales.

Je m’intéresserai ici aux applications Silverlight “classiques”, Web. Mais la solution exposée peut fort bien être utilisée dans des applications OOB, sous Windows, Mac ou Windows Phone.

Les solutions payantes

Je me dois de les citer car certains d’entre vous auront peut-être besoin de plus de puissance que la solution que je vais exposer. Mais je dois avouer que je n’ai fait que survoler ces produits sans les tester à fond et je vous laisse vous faire votre avis tout seul...

Siaqodb

Elle se trouve là : http://siaqodb.com/

Il s’agit d’une base de données embarquée qui, sur le papier (je n’ai pas testé comme je le disais plus haut), semble offrir des possibilités assez riches. De $186 à $1822.50 selon les licences, c’est à la fois pas cher et fort couteux, tout dépend de l’usage qu’on doit en faire !

Perst

Elle se trouve ici : http://www.mcobject.com/perst

Il s’agit d’un produit commercial se voulant open source. Je dois être resté vieux jeu, mais pour moi de l’open source on doit pouvoir accéder au code source, et majoritairement cela implique la gratuité. Mais ici rien de tout cela. Je n’ai pas trouvé les sources (c’est de l’open closed...) et c’est payant, sauf la démo (of course). Le produit affiche des caractéristiques intéressantes, reste à le tester et à payer la licence (et à voir le fameux source qui est opened), $495 par développeur pour du SL classique, $395 pour du SL sur Windows Phone.

Effiproz SL

Elle est ici : http://www.effiproz.com/product_sl.aspx

Là encore le produit indique qu’il sait tout faire, reste donc à le comparer aux deux autres pour se forger un avis. A $490 la licence de base par développeur pour la version Silverlight à $950 pour la version qui marche partout (Windows Phone 7, Asp.NET, Mono, MonoTouch, Compact Framework), avec des intermédiaires aux prix différents sans raison technique (les autres le font aussi) selon la version spécifiques que vous désirez acquérir. Par exemple pourquoi $390 pour WP7 et $490 pour SL classique ? Ils ont tous copiés la même grille tarifaire a peu de choses près, mais on se demande bien pourquoi ces différences. Techniquement, once more, à vous de vous faire une idée.

Le vrai gratuit et open source

Il n’y a pas grand chose... le sujet ne semble pas passionner les développeurs de SourceForge, CodePlex ou autres, il est vrai que c’est moins “excitant” de prime abord que de lancer le centième projet de jeu hypra-cool-qui-tue ou de grosse-lib-qui-déchire-sa-mère, mais dont on ne voit jamais rien d’autre que les versions alpha sans release !

Pourtant les bases de données c’est un sujet passionnant. J’ai écris de gros articles sur la question il y a un moment déjà et je me rend compte que des années après il y a toujours autant de méconnaissance des mécanismes et des fondements de ces applications particulières. Elles sont donc utilisées à tort et à travers, et même de travers le plus souvent : aucune normalisation (“c’est quoi la normalisation ?”), absence de cohérence dans les schémas, relations incohérentes dans le meilleur des cas et inexistantes le plus souvent, index placés n’importe comment, pas de clé primaire, ou clés farfelues, mauvaise utilisation (voire aucune utilisation) des transactions, etc, etc... En plus de 25 ans de métier je croyais sincèrement qu’un jour la “culture base de données” finirait par passer tellement cet outil est devenu commun, mais il faut bien constater, hélas, que seul un développeur sur 10 sait de quoi il s’agit...

Bref, j’arrête de faire mon vieux ronchon, et je reviens au sujet. Sorry pour la digression, mais ça m’énerve cette méconnaissance d’un des piliers de la réalisation d’un logiciel professionnel, et pas chez les bricolos du dimanches ou les amateurs, mais bien chez des gens qui prétendent avoir un diplôme d’ingénieur... C’est bon j’arrête Sourire (mais ça m’énerve... ok! ok!).

Donc les bases données embarquées, light, locales, appelez-les comme vous voudrez, ça ne courre par les arcanes du Web. Surtout pour Silverlight.

Redéfinir le besoin

Quand je parle de base de données locales ou light ou embarquées, je parle de solutions extrêmement simples n’ajoutant pas 10 Mo de téléchargement à l’application et servant uniquement à persister des informations, donc des objets, de façon simple, afin de les retrouver tout aussi simplement à la prochaine exécution de l’application.

Je ne parle donc pas ici de “vraies” SGBD relationnel complexes supportant les transactions ni d’autres options luxueuses de type procédures stockées.

Il convient ainsi de redéfinir sérieusement le besoin. Quand on parle de base de données locale pour une application Silverlight classique (voir OOB), on évoque plus une zone de stockage qu'un vrai moteur SGBD. Une zone de stockage, il y en a une, elle s’appelle l’Isolated Storage, mais ce n’est qu’un File System dans une sandbox. On peut certes y ranger des données, mais ce n’est pas très structuré.

On a besoin en réalité d’une surcouche qui serait capable de persister des objets d’une façon intelligente, de telle sorte qu’on puisse retrouver ces objets plus tard. Et encore s’agit-il de petits groupes d’objets. Vouloir stocker des milliers ou des millions d’enregistrements dans l’IS serait pure folie. Dans un tel cas il est évident qu’il faut utiliser WCF avec un serveur de données en face.

Ainsi précisé, le besoin se résume à un système capable de lire et d’écrire des objets regroupés dans des tables. Si le système en question est capable de compresser les données, voire de les crypter, cela serait encore mieux (rappelons que l’IS n’est pas un espace invincible, c’est juste un répertoire bien caché dans les méandres de Windows mais qu’il est possible d’atteindre et de corrompre ou simplement de lire).

Silverlight Database

C’est un petit projet, pas récent, et pas mis à jour depuis un moment, qu’on peut trouver sur CodePlex ici : http://silverdb.codeplex.com/

Il implémente une mini base de données dans l’Isolated Storage pour Silverlight, c’est ce que nous cherchons. Les sources sont disponibles et sont légères. C’est aussi l’un de nos critères. La base de données sait persister des objets et les relire dans des tables, cela nous convient aussi. Mieux, les données peuvent être codées (sécurité) et compressées (gain de place dans l’IS).

Le projet est même complété d’un service WCF totalement transparent qui permet de stocker ou d’obtenir des “bases de données” sur ou depuis un serveur. Cela peut être intéressant pour créer des sortes de catalogues, pas trop gros à télécharger justement, et ne contenant que les données utiles. On peut aussi envisager de sauvegarder ainsi les bases locales sur un serveur pour les centraliser.

Bref, les fonctionnalités de cette librairie semblent correspondent au besoin (une fois celui-ci correctement redéfini comme nous l’avons fait plus haut).

Compatibilité ascendante

Bien que les dernières sources datent du 26 septembre 2009 (il faut télécharger celles-ci et non pas la version 1.0, donc il faut aller dans l’onglet “source code” et prendre les dernières sources), le projet passe très bien l’upgrade vers Silverlight 4 et .NET 4. A cela une raison : un code simple (une leçon à retenir pour vos projets !).

Les fonctionnalités

Comme je le disais notre besoin est simple, par force et par logique, sinon il faut mettre en place un serveur avec un vrai SGBD. Face à nos besoins rudimentaires, on retrouve donc un nombre restreint de fonctions assurant le minimum vital. J’aime le minimalisme, vous devez commencer à le comprendre au travers de mes billets ! Les grosses usines à gaz, les frameworks réclamant six mois de formation, tout cela je le rejette avec force, c’est l’une des causes des prises de pieds dans le tapis sournois du développement... Plus les librairies sont peu nombreuses et moins elles sont grosses, meilleur est le résultat.

Le mieux pour vous rendre compte étant bien entendu que vous téléchargiez le projet et que vous regardiez le code source ainsi que le code exemple. Mais pour vous donner un aperçu voici quelques extraits qui vous aiderons à comprendre l’esprit de la librairie :

Créer une base de données

if (Database.CreateDatabase("TestDatabase") != null) ... // c'est ok
    

 

Supprimer une base de données

Database.DeleteDatabase("test");

 

Créer une table

Supposons la classe suivante :

public class Person
   {
       public string FirstName { get; set; }
       public string LastName { get; set; }
       public DateTime? BirthDate { get; set; }
       public decimal Salary { get; set; }
   }

on créer une table des personnes dans une base de données de cette façon :

Database db = Database.CreateDatabase("test");
db.CreateTable<Person>();
if (db.Table<Person>() != null)
    {
        db.Table<Person>().Add(NewPerson());
        if (db.Table<Person>().Count == 1)
            {
              // base et table ok et une instance de Person ajoutée.
            }
        else
            {
              // erreur à gérer
            }
    }
    else
    {
        // erreur à gérer (IS plein par exemple)
    }

 

Créer une base cryptée, créer une table, persister des instances, sauvegarder le tout

Database db = Database.CreateDatabase("test", "password");
db.CreateTable<Person>();
 
if (db.Table<Person>() != null)
    {
       for (int i = 0; i < 20; i++)
          db.Table<Person>().Add(NewRandomPerson()); // ajout de 20 instances
       db.Save(); // sauvegarde de la base
    }
 else // gérer erreur

 

Supprimer un enregistrement

db.Table<Person>().Remove(person2);

Utiliser Linq

Database db = Database.CreateDatabase("test");
db.CreateTable<Person>();
 
Person person1 = new Person() { FirstName = "John ", ... };
Person person2 = new Person() { FirstName = "Robin ", ... };
Person person3 = new Person() { FirstName = "Joan ", ... };
 
db.Table<Person>().Add(person1);
db.Table<Person>().Add(person2);
db.Table<Person>().Add(person3);
 
var query = (from onePerson in db.Table<Person>()
             where onePerson.Salary == 2
             select onePerson);
 
foreach (var p in query) ...

Etc...

Enfin pour être honnête, le “etc...” se résume à deux ou trois autres combinaisons et à la partie WCF automatisée qui permet d’envoyer, de recevoir ou de mettre à jour une base de données avec un serveur distant (GetDatabase, PutDatabase, UpdateDatabase, encore des trucs compliqués à retenir !). SL Database supporte même une forme de Lazy Loading pour ne pas encombrer la mémoire inutilement. Le luxe !

Conclusion

Pourquoi payer plus cher ?

Si on reste cohérent, une base de données locale pour Silverlight ne doit rien faire de plus, sinon cela signifie qu’on a besoin de mettre en place un vrai circuit de gestion de données avec serveur distant, WCF Ria Services par exemple ou d’autres solutions (Web services) du même type.

Certes, avec “Silverlight Database” on reste dans le rudimentaire. Mais grâce à Linq To Object travailler sur des données prend tout de suite un air de SGBD même sur de simples listes... La séparation des données par classe (les tables) est pratique, l’encapsulation de tout cela dans un fichier unique est pratique, la compression et le cryptage sont de vrais plus dans le contexte de l’Isolated Storage, bref, minimaliste mais bien proportionné aux besoins.

Les données sont en mémoire, ne jamais l’oublier, jusqu’au “save” en tout cas. Mais même avec WCF Ria Services il en va de même.

Simple. Forcément performant (c’est en RAM), sécurisé et peu gourmand en place disque. L’option de transfert de bases avec un serveur est une cerise le gâteau...

En effet, pourquoi payer plus cher...

Bon Dev, et Stay Tuned !

blog comments powered by Disqus