IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

mise à jour automatique d'une appli fonctionnant avec une bdD locale [Débutant]


Sujet :

VB.NET

  1. #1
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut mise à jour automatique d'une appli fonctionnant avec une bdD locale
    Bonjour,

    Je suis en train de réfléchir aux problématiques de mise à jour automatique de mon appli auprès de l'utilisateur final.
    Cette appli interagit avec un fichier de base de données qui est créé chez l'utilisateur à la première utilisation (par recopie d'un fichier de BdD situé dans les ressources de mon projet, contenant toute la structure de la bdd mais vierge de tout enregistrement)
    Il faut prévoir le cas où une modification de mon appli s'accompagnerait d'une modification de la structure de la bdD (cas typique tout bête : l'ajout d'un champ dans une table)
    Il faut que, à la mise à jour chez l'utilisateur, son fichier de bdD en local soit importé dans la nouvelle structure et que ceci donne lieu à l'implémentation d'un nouveau fichier en lieu en place de son fichier.

    Quelle stratégie de programmation proposeriez-vous sachant que le logiciel est bien sur capable de trouver le chemin du fichier utilisateur ?

    Comment l'appli peut-elle tester si la structure de la bdd vierge située dans les ressources du projet est bien identique à celle du fichier de bdd de l'utilisateur ?
    Si structure identique : rien à faire
    Si structure différente : injecter les enregistrements du fichiers utilisateur dans une base vierge et remplacement du fichier utilisateur par cette nouvelle base ==> comment faire ?

  2. #2
    Membre expérimenté Avatar de Uranne-jimmy
    Homme Profil pro
    Bioinformatique
    Inscrit en
    Décembre 2012
    Messages
    778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Bioinformatique
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 778
    Points : 1 461
    Points
    1 461
    Par défaut
    Ce ne serait pas plus simple de travailler sur un seul fichier mais dont les autorisations sont unique pour chaque nouvel utilisateur ? (ça doit être possible j'imagine)

    Sinon une astuce pourrait être faire en sorte que quand l'utilisateur demande une modification structurale, la modification s'applique directement sur les deux fichiers concerné. La mise a jour se ferait alors en temps on ne plus réel.

  3. #3
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Salut,
    Je ne comprends pas bien ta réponse à moins que ce soit toi qui n'ait pas compris ma situation.
    Mon appli est un gestionnaire de bibliothèque perso.
    chaque utilisateur de l'appli crée son contenu.
    L'appli ne fournit que l'architecture de la BdD.
    C'est pourquoi, chaque utilisateur génère son propre fichier de bdd qui correspond à sa bibliothèque : le fichier vierge (contenant juste l'architecture de la base) est généré à la première utilisation de l'appli.
    Lors des utilisations suivantes, l'appli va lire le fichier à l'emplacement que lui aura indiqué l'utilisateur.
    Quand je fournis l'appli, je ne fournis pas le contenu de la bibliothèque. J'ai donc un fichier de bdd vierge de tout contenu dans mes ressources.
    Au lancement de l'appli celle-ci teste si une base a déjà été générée (en allant lire une clé dans la base de registre de l'utilisateur. Si cette clé n'existe pas c'est que le test est négatif)
    Si le test est négatif : création d'une clé dans la base de registre de l'utilisateur indiquant le path de l'emplacement du fichier de bdd et création du fichier de bdd vierge à cet emplacement par recopie du fichier vierge situé dans les ressources de l'appli
    si le test est positif: l'appli associe la base existante au fonctionnement de l'appli : lecture des données, écriture pour les ajouts/modifications de l'utilisateur

    Le pb est donc lorsque je crée une nouvelle version de mon appli. Si je veux pouvoir modifier l'architecture de ma base (le simple ajour d'un champ constitue à ce titre une modification de structure) à cette occasion, il faut pouvoir faire hériter tous mes utilisateurs de cette évolution en récupérant le contenu qu'ils ont créé avec la version précédente de l'appli.

  4. #4
    Membre expérimenté Avatar de Uranne-jimmy
    Homme Profil pro
    Bioinformatique
    Inscrit en
    Décembre 2012
    Messages
    778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Bioinformatique
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 778
    Points : 1 461
    Points
    1 461
    Par défaut
    J'avais en effet mal compris !

    Donc il faut en premier lieu un système qui détecte si une mise a jour est disponible, chose a effectuer de préférence dans le constructeur du programme, je pense. Ensuite il faudra faire les modifs sur le fichier du client, si j'ai bien compris.
    Là je vois deux solutions : soit la mise a jour s'accompagne d'un texte qui servira de directive pour les changements, soit si il y a mise a jour, le programme énumère les structures de ta bdd, les compare avec celle du client puis opère les changements.

    Je suis dans le bon ?

  5. #5
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Bonjour,

    Citation Envoyé par noftal Voir le message
    Au lancement de l'appli celle-ci teste si une base a déjà été générée (en allant lire une clé dans la base de registre de l'utilisateur. Si cette clé n'existe pas c'est que le test est négatif)
    Si le test est négatif : création d'une clé dans la base de registre de l'utilisateur indiquant le path de l'emplacement du fichier de bdd et création du fichier de bdd vierge à cet emplacement par recopie du fichier vierge situé dans les ressources de l'appli
    si le test est positif: l'appli associe la base existante au fonctionnement de l'appli : lecture des données, écriture pour les ajouts/modifications de l'utilisateur
    Tu donnes un numéro de version à la BDD.
    Quand tu fais une modif structurelle tu fais évoluer la version.
    Avec tes tests, si la base existe tu vérifies le numéro de version entre celle qui existe et celle que tu veux placer. (s'il est différent => évolution)

  6. #6
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    @ Uranne-jimmy

    La détection de l'existence d'une mise à jour de l'appli se fait automatiquement, si j'ai bien compris, par chaque licence d'appli (je me place dans le case d'une publication de l'appli sur internet avec la méthode click once).

    Cela dit, je parle de ce que je ne connais pas encore car je n'ai encore jamais publié d'appli, mais j'ai lu la doc !

    Ensuite, seule ta 2ème solution est envisageable. L'utilisateur n'a pas la main pour changer lui-même la structure de la BdD.

    @rv26t

    Je crois en effet que ta solution est celle qu'il me faut. Y a-t-il un moyen de donner un Id à une base de donnée sans créer une table spécifique avec juste un champ comportant cet Id ou bien est-ce la seule solution possible ?
    Ensuite, cela résout la question du test sur l'évolution. Ensuite ya-t-il une méthode simple pour importer le contenu de la base_old dans la base_new ?

  7. #7
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Citation Envoyé par noftal Voir le message
    Je crois en effet que ta solution est celle qu'il me faut. Y a-t-il un moyen de donner un Id à une base de donnée sans créer une table spécifique avec juste un champ comportant cet Id ou bien est-ce la seule solution possible ?
    Idées a creuser
    1) Tu as ta clé de registre indiquant si la base existe. Que mets tu dedans ? (Il pourrait y avoir le numero de version.)
    2) Ce qui peut se faire, dans la BDD on fait une table de paramètres banalisés (qui permet de configurer l'appli). Tu la mets dedans. (ca ne semble pas être ton cas)

  8. #8
    Membre expérimenté Avatar de Uranne-jimmy
    Homme Profil pro
    Bioinformatique
    Inscrit en
    Décembre 2012
    Messages
    778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Bioinformatique
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 778
    Points : 1 461
    Points
    1 461
    Par défaut
    Pour ce qui est de ma première solution, j'ai mal exprimé mon idée ^^ les directives dont je parle ce serait des directives lu directement par ton programme, pas par l'utilisateur (en 2013 tout de même !). Ces directives seraient composé de l'ensemble des informations nécessaire à la mise à jour.

    Mais rv26t est bien plus compétent que moi

  9. #9
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Citation Envoyé par rv26t Voir le message
    Idées a creuser
    1) Tu as ta clé de registre indiquant si la base existe. Que mets tu dedans ? (Il pourrait y avoir le numero de version.)
    Actuellement j'y mets un string qui représente le Path.
    Je pourrais effectivement créer une 2ème clé indiquant l'Id de la BdD. Cette solution me semble la plus simple.

    2) Ce qui peut se faire, dans la BDD on fait une table de paramètres banalisés (qui permet de configurer l'appli). Tu la mets dedans. (ca ne semble pas être ton cas)
    J'utilise aussi une table "paramètres" pour stocker les paramètres d'affichage de l'utilisateur. Je peux en effet aussi rajouter un champ avec l'Id de la base.

    Il y a juste un soucis : Dans les 2 cas, il s'agit de paramètres stockés pour chaque utilisateur Windows de l'appli (et non pour l'appli tous utilisateurs confondus). Je peux donc avoir un pb dans le cas où un premier utilisateur installe l'appli et choisit de localiser sa bdd à C:/users/.../Documents partagés, puis un 2ème utilisateur sur le même ordi se logue et lance l'appli qui détecte donc un nouvel utilisateur (clé registre inexistante) et lui demande donc le chemin d'accès à un fichier existant (ou d'en créer une nouvelle mais ce n'est pas le cas qui nous intéresse ici). Cet utilisateur indique donc le chemin c:/users.../documents partagés où se trouve le fichier créé par l'utilisateur n°1.
    Pour les 2 utilisateurs, je stocke l'ID (appelons-là ID0) de la base pour chaque user (soit dans le registre, soit dans le fichier de Bdd)
    Imaginons maintenant que j'envoie une mise à jour de l'appli avec une nouvelle structure de bdd que j'identifie ID1. Le user n°1 se logue et lance l'appli. Cellec-ci détecte l'existence d'une bdd existante et compare l'Id stockée (ID0) à ID1 ==> mise à jour de la Bdd
    Puis User 2 se logue et lance l'appli. Là aussi, l'appli détecte l'existence d'une bdd existante et compare l'ID stockée (ID0 pour ce user) à ID1 ==> mise à jour de la Bdd alors qu'en fait la Bdd a déjà été mise à jour par user1

    Pour savoir si ce pb est bloquant, il me reste à savoir comment concrètement importer bdd_old dans bdd_new (tu ne m'as pas dit comment tu voyais les choses pour ce point). Au pire, si c'est bloquant, il y a toujours la possibilité de créer une table avec un champ id sans l'associer au user.

  10. #10
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    s'il n'y a qu'une base pour 2 users ca ne posera pas de soucis, après la migration de la structure de la base tu enregistre le nouvel id
    le 2ème utilisateur lancant l'appli fera qu'elle verra la base avec l'id à jour et ne fera rien

  11. #11
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    @pol63
    Pas tout à fait. Si tu lis bien mon scénario (mais peut-être n'est-ce pas très clair), lorsque le user2 lance l'appli, l'appli recherche la clé de registre dans la base de registre de user2, pas de user1 (On est donc en aval de HKEY_CURRENT_USER ou qqch comme ça - je ne suis pas devant mon ordi de dvpt - les clés sont donc spécifiques au current user ). Donc l'appli voit l'ancien Id et relance l'importation des données.

  12. #12
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    [mode humour]Ca sent l'usine à gaz [/mode humour]
    Citation Envoyé par noftal Voir le message
    Je peux donc avoir un pb dans le cas où un premier utilisateur installe l'appli et choisit de localiser sa bdd à C:/users/.../Documents partagés, puis un 2ème utilisateur sur le même ordi se logue et lance l'appli qui détecte donc un nouvel utilisateur (clé registre inexistante) et lui demande donc le chemin d'accès à un fichier existant (ou d'en créer une nouvelle mais ce n'est pas le cas qui nous intéresse ici). Cet utilisateur indique donc le chemin c:/users.../documents partagés où se trouve le fichier créé par l'utilisateur n°1.
    Donc tester tous les user si même chemin mettre id à jour

    Citation Envoyé par noftal Voir le message
    J'utilise aussi une table "paramètres" pour stocker les paramètres d'affichage de l'utilisateur. Je peux en effet aussi rajouter un champ avec l'Id de la base.
    Je ne sais pas comment ta table est construite mais "Je peux en effet aussi rajouter un champ" me laisse penser que chaque fois que tu voudras rajouter un élément de config => ajout colonne => exportation base.

    C'est là qu'une table de paramètres banalisés est utile. En fait c'est une table de table virtuelle.
    du genre
    | Typ | Id | Libelle | val texte | val num |
    ou Typ représente un ensemble de paramètre de même type et id l'identifiant pour chaque type. Donc typ peux être vu comme une table virtuelle et id le code identifiant dans la table.
    Si tu veux détailler par utilisateur tu rajoutes une colonne Type intervenant (Appli, Utilisateur, ...)
    | TypeIntervenant | Typ | Libelle | Id | val texte | val num |

    ainsi tu auras comme données
    | Appli | VerBDD | v1 | Base de donnnées version 1 | 1.0 | 1 |
    | user1 | Aff | btFond | Couleur de fond des boutons | Blue | #FF0000FF |
    | user2 | Aff | btFond | Couleur de fond des boutons | Green | #FF008000 |
    ...

    Ou faire les 2 tables pour rester simple, une config générale, et une config user (la colonne Type intervenant devient user).

    Ainsi dans cette table tu peux placer tous types de paramètres, et cela t'évite de créer x tables qui contient 2 ou 3 ou 10 valeurs.

    A mon avis c'est ce qui te permettra des évolutions simple de ta BDD sans tout transférer au moindre petit changement.

  13. #13
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Je ne sais pas comment ta table est construite mais "Je peux en effet aussi rajouter un champ" me laisse penser que chaque fois que tu voudras rajouter un élément de config => ajout colonne => exportation base.

    Bien vu, je suis exactement dans ce cas. Actuellement j'ai juste une table "Settings" avec une ligne et des colonnes pour chaque paramètre (+ de 100 colonnes actuellement). La première colonne est le champ "user" qui sert de clé primaire pour la lecture et la mise à jour des paramètres pour un user donné.

    J'ai bien compris ton alerte et je pense avoir compris ta suggestion. Je vais y réfléchir. J'ai pas mal de choses à changer dans mon code relatif à la lecture écriture de ces paramètres si je suis ton conseil. Mais je suis assez tenté en effet.

    Sinon, personne ne m'a fait de suggestion sur la façon d'importer l'ancienne base dans la nouvelle. Est-ce à dire que la seule solution est de lire chaque enregistrement de chaque table dans l'ancienne base pour le copier dans la nouvelle chaque table de la nouvelle base ?

  14. #14
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    migrer les données d'une base à l'autre n'est pas forcément la meilleure solution

    tu peux garder dans ton exe (y compris les nouveaux) la base d'origine
    et sur un changement de version exécuter des scripts de modification du genre
    ALTER TABLE machin ADD newColonne varchar(50)

  15. #15
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Merci Pol63,
    Je n'avais pas pensé à cela, probablement parce qu'on aborde ainsi des instructions SQL que je ne maîtrise pas encore.
    Je suppose que ces instructions se font via les SQLcommand, SQLconnexion etc.. , comme pour une requête SELECT ?

  16. #16
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    oui avec executenonquery

    si tu es sur sql server, tout ce que tu fais dans management studio est traduit en requetes, donc tout est faisable
    tu peux même obtenir les requêtes générées avec sql server profiler

    sinon tu peux aussi avoir des scripts pour la création de table (clic droit / générer le script CREATE)

    le mieux reste de lire l'aide sur alter table et autres pour savoir les écrire

  17. #17
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Bon, alors finalement, j'ai opté pour la méthode bourrine à savoir créer une nouvelle base et y importer tous les enregistrements de l'utilisateur. En effet, le pb de la méthode de Pol63 c'est qu'elle suppose que je connais le delta de structure entre ma mise à jour et celle de l'utilisateur. Ce serait vrai si j'étais sûr que chaque utilisateur met bien à jour son appli dès que je publie une MAJ. Ainsi tous les utilisateurs auraient la version N-1.

    Mais rien ne peut me le garantir.

    Donc l'algo retenu est (après avoir vérifié qu'il y a bien une modification de structure de base) :
    1°/ je crée un fichier vierge de BdD (BaseNew) contenant la structure mais pas les enregistrements
    2°/ j'importe les enregistrements de la BdD utilisateur (BaseOld) vers BaseNeW
    3°/ Je supprime BaseOld
    4°/ Je renome BaseNew en BaseOld

    Pb à l'étape 3: l'appli utilise BaseOld pour fonctionner (création d'un dataset fortement typé utilisant BaseOld comme source) donc n'autorise pas la suppression du fichier correspondant lors de son utilisation (erreur : "fichier utilisé par un autre processus"). Comment déconnecter mon appli de la BdD provisoirement ?

  18. #18
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    Citation Envoyé par noftal Voir le message
    En effet, le pb de la méthode de Pol63 c'est qu'elle suppose que je connais le delta de structure entre ma mise à jour et celle de l'utilisateur. Ce serait vrai si j'étais sûr que chaque utilisateur met bien à jour son appli dès que je publie une MAJ. Ainsi tous les utilisateurs auraient la version N-1.
    manque d'imagination
    rien n'empeche d'avoir une base n-4 et une mise à jour n qui voyant la base en version 1.2 execute les scripts de maj 1.2 vers 1.3, puis 1.3 vers 1.4 etc... jusqu'à n

  19. #19
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Exact

    Sûrement plus élégant.

  20. #20
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    disons que des logiciels qui font ca j'en connais plein
    des logiciels qui perdent du temps à recopier des données par contre ce n'est pas le cas

    il faut aussi regarder ce qui existe et comprendre ce que ca fait, ca donne des idées

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/01/2013, 14h01
  2. faire tourner une appli .NET avec une référence manquante
    Par Nico57 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 21/03/2012, 15h36
  3. Réponses: 2
    Dernier message: 31/03/2009, 10h59
  4. Réponses: 1
    Dernier message: 06/03/2009, 10h02
  5. Réponses: 4
    Dernier message: 04/08/2006, 01h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo