Forums : Xul, Xbl, JS...

Aller à la discussion :  Plus récente Plus ancienne

# [Contourné?] Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : Raphael

Date : 05/11/2007 10:18

Bonjour, je dois dire que je me heurte au Bug le plus incompréhensible que j'ai vu en travaillant sur une BDD SQLite3 :

J'ai mon affichage d'un objet avec des Checkbox qui montrent le degré de raretés dans lequel l'objet existe, et je stocke les Raretés dans une table de liaison comme pour des Tags avec une double Clé (Card_ID, Rarity_ID).

Voici ma fonction d'édition de raretés de l'objet, très simple :

// Nettoyage (on efface toutes les liaisons)
var Sql_Query = "DELETE FROM cards_x_rarities WHERE Card_ID='"+Card_ID+"'";
var Success_Message = "[cards_x_rarities] " + $("i18n").getString("cleaned");
execute(Sql_Query, Success_Message);

// On recréé les nouvelles liaisons
for (var i = 0 ; i < Rarities.length ; i++) {
	var Sql_Query = "INSERT INTO cards_x_rarities VALUES("+Rarities[i]+","+Card_ID+")";
	var Success_Message = "1 " + $("i18n").getString("rarity") + " " + $("i18n").getString("linked");
	execute(Sql_Query, Success_Message);
}

Le Tableau Rarities contient les raretés dont les checkbox sont checkés, évidemment.

Voilà ce qui se passe :

  • Je check un checkbox, je save : OK
  • Je le decheck juste après, je save : Bug, message d'erreur SQLite
  • Je réessaie : Je le décheck, je save : OK, ça marche
  • Je le check, je save : OK
  • Je le Décheck, je save : Encore Bug
  • etc...

Pour infos, voici mon fichier connector.js si ça peut aider :

function connectsqlite(dbfile)
{
this.db = dbfile;
this.get = executeQuery;
this.do = executeUpdate;
this.getNextID = getNextID;
}
function getConnection(dbfile)
{
// get the storage service
var store = Components.classes["@mozilla.org/storage/service;1"].getService(Components.interfaces.mozIStorageService);
// get the profile directory
var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("CurProcD", Components.interfaces.nsILocalFile);
file.append("data");
file.append("databases");
file.append(dbfile);
var db = store.openDatabase(file);
return db;
}
function executeQuery(query)
{
var statement = Components.classes['@mozilla.org/storage/statement-wrapper;1'].createInstance(Components.interfaces.mozIStorageStatementWrapper);
var results = getConnection(this.db).createStatement(query);
return results;
}
function executeUpdate(query)
{
var statement = Components.classes['@mozilla.org/storage/statement-wrapper;1'].createInstance(Components.interfaces.mozIStorageStatementWrapper);
var s = getConnection(this.db).createStatement(query);
s.execute();
}

Est-ce un problème d'accès ou quelque chose du genre ? Pourtant ça fait 1 an que je manipule des SELECT, INSERT, UPDATE, DELETE avec cette fonction et ça marche avec XR 1.9... Je n'ai rien changé, hormis que je code des modules qui font plus d'écriture que de lecture en ce moment...

Mes écritures se passent bien dans 95 % de mes scripts mais on dirait que dès qu'il y a une fonction d'écriture dans une boucle, ça Bug complètement...

Je crois que ce Bug est récurrent dans certains de mes scripts qui devraient fonctionner mais qui Bug de façon bizarre et je n'arrive pas à trouver pourquoi.

Y a vraiment un truc que je saisis pas, je suis désespéré je me prends la tête depuis 1 semaine du matin au soir, j'en peux plus.

Merci d'avance à toute à toute âme charitable.

EDIT : Apparemment si je rajoute des alert() au milieu, n'importe quel changement fonctionne bien :

alert(Rarities.length);
// Nettoyage (on efface toutes les liaisons)
var Sql_Query = "DELETE FROM cards_x_rarities WHERE Card_ID='"+Card_ID+"'";
var Success_Message = "[cards_x_rarities] " + $("i18n").getString("cleaned");
execute(Sql_Query, Success_Message);

alert(Rarities.length);
// On recréé les nouvelles liaisons
for (var i = 0 ; i < Rarities.length ; i++) {
	var Sql_Query = "INSERT INTO cards_x_rarities VALUES("+Rarities[i]+","+Card_ID+")";
	var Success_Message = "1 " + $("i18n").getString("rarity") + " " + $("i18n").getString("linked");
	execute(Sql_Query, Success_Message);
}

Du coup, franchement, je comprends encore moins...

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : aMan

Date : 05/11/2007 10:28

J'ai juste survolé ton problème je suis un peu à la bourre.... Mais a mon avis avant d'essayer d'inserer ou modifier quelque chose dans ta base tu dois faire un reset de ton ou tes statements

 monstatement.reset();

reset découle de mozIStorageStatement.

A plus

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : Raphael

Date : 05/11/2007 10:33

C'est donc ici que je devrais faire quelque chose ?

function executeQuery(query)
{
var statement = Components.classes['@mozilla.org/storage/statement-wrapper;1'].createInstance(Components.interfaces.mozIStorageStatementWrapper);
var results = getConnection(this.db).createStatement(query);
return results;
}
function executeUpdate(query)
{
var statement = Components.classes['@mozilla.org/storage/statement-wrapper;1'].createInstance(Components.interfaces.mozIStorageStatementWrapper);
var s = getConnection(this.db).createStatement(query);
s.execute();
}

je reset où ? avant ? après ?

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : aMan

Date : 05/11/2007 10:48

le reset (comme son nom l'indique) reset ton statement ca veut dire le vide. Donc en générale tu l'utilise lorsque tu as fini de récupérer tes données.

Donc par exemple avant d'appeler executeUpdate(taquery) tu fait un .reset() sur le resultats (statement) retourner par ton executeQuery() (enfin si j'ai bien compris ton script).

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : aMan

Date : 05/11/2007 10:50

Pour info :

It is important to reset statements that are no longer being used. Un-reset write statements will keep a lock on the tables and will prevent other statements from accessing it. Un-reset read statements will prevent writes.

http://developer.mozilla.org/en/docs/ind(..)

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : aMan

Date : 05/11/2007 11:54

Alors quand est il ?

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : Raphael

Date : 05/11/2007 12:59

Oui, j'ai vu ça aussi sur MDC mais mon Bug m'échappe totalement.

J'ai essayé de rajouter dans tous mes scripts le reset, mais rien ne change.

Voici mes derniers Tests :

  • Je check, je sauve
  • Je decheck, je sauve
  • etc...

Et bien croyez-le ou non : Mon enregistrement marche une dizaine de fois, et genre à la 15ème sauvegarde, ben ça Bug : Message d'erreur !

Est-ce qu'il y quelque chose de logique là-dedans ? Est-ce la vitesse avec laquelle je sauvegarde à chaque fois ? Est-ce une mémoire tampon qui se remplie jusqu'à bugguer ?

A n'y rien comprendre...

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : Christophe Charron

Date : 05/11/2007 13:33

Bonjour, c'est peut-être un pis-aller dans ce cas, mais pourquoi ne pas faire une requête de forme :

INSERT INTO cards_x_rarities ('zone1','zone2') VALUES ("+Rarities[1]+","+Card_ID+")"+("+Rarities[2]+","+Card_ID+")+("+Rarities[3]+","+Card_ID+");

etc ...

Une seule requête, en dehors de la boucle, beaucoup plus rapide ... sauf si sqlite ne supporte pas mais ce serait étonnant !!

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : Raphael

Date : 05/11/2007 14:05

C'est intéressant, je ne connais pas cette méthode... et j'ai du mal à comprendre ce qu'elle fait ? Elle entre plusieurs lignes en même temps ?

Mon tableau Rarities est de dimension variable selon mes checkbox... Comment adapter ton exemple à mon cas ?

PS : Vraiment un grand merci à vous, aMan et Christophe, qui prenez de votre temps pour me venir un peu, j'apprécie grandement car je sèche sur ce truc.

EDIT : Un truc assez bizarre : Avant d'insérer mes nouvelles lignes, je les supprime d'abord toutes. Et quand mon opération se passe bien, mon "Sucess_Message" s'affiche dans ma console, à savoir quand toutes mes opérations passent bien (dans le cas où 2 raretés sont cochés :

1 carte édité  >>> [cards_x_rarities] nettoyé >>> 1 rareté lié  >>> 1 rareté lié  >>>

Cependant, comme je le dis, aléatoirement, j'ai des Bugs sur la modification d'une carte et dans ce cas, ma console affiche :

1 carte édité  >>>  1 rareté lié  >>>  

Il apparait donc que ce n'est pas forcément ma boucle d'insertion qui Bug mais la suppression suivante :

// Nettoyage (on efface toutes les liaisons)
var Sql_Query = "DELETE FROM cards_x_rarities WHERE Card_ID='"+Card_ID+"'";
var Success_Message = "[cards_x_rarities] " + $("i18n").getString("cleaned");
execute(Sql_Query, Success_Message);

Et je comprends pas comment cette Requête peut ne pas fonctionner par moments ???

Encore plus étrange, en rajoutant un alert(Card_ID) juste avant pour vérifier que le script n'est pas trop rapide à s'emparer de Card_ID, tout marche !!

alert(Card_ID);
// Nettoyage (on efface toutes les liaisons)
var Sql_Query = "DELETE FROM cards_x_rarities WHERE Card_ID='"+Card_ID+"'";
var Success_Message = "[cards_x_rarities] " + $("i18n").getString("cleaned");
execute(Sql_Query, Success_Message);

Et là,je peux modifier tout ce que je veux, ça marche tout le temps, aucun Bug... ni aléatoire, ni rien du tout... ça marche... Y-a-t-il une logique là-dessous ?

Je peux vous fournir mon soft pour Linux si vous voulez testez...

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : aMan

Date : 05/11/2007 16:40

Je sais toujours pas si ça peut rentrer en jeu, mais je te conseille....

de ne pas construire tes requete à la volée comme tu le fais.

à la place de

var Sql_Query = "DELETE FROM cards_x_rarities WHERE Card_ID='"+Card_ID+"'";

je ferais un

var SqlQuery = " DELETE FROM cards_x_rarities WHERE Card_ID=?1 ";
statement = db.createStatement(SqlQuery);
statement.bindInt32Parameter(0,Card_ID);
statement.execute();

Ps : oui je veux bien tester ton soft, mais je ne peux pas vraiment te promettre le meme resultat, je ne suis pas sous linux mais sous Leopard (os X) (mais bon si ma flemme n'est pas trop aigu, je peux démarrer une de mes machines sous nux.... mdr)

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : Raphael

Date : 05/11/2007 17:30

Ok, je vais essayer ta méthode aMan... en fait j'utilisais mon connector pour réduire le nombre de ligne et simplifier.

Y-a-t-il moyen d'utiliser ta méthode en codant un petit connecteur qui ferait gagner en place et simplicité ?

Voici une version "light" (sans images,...) de mon soft sous Linux : http://dl.free.fr/bAirC5uLw/yLife.tar.gz

  • Dans les Preferences, activer le module YCD Manager
  • Menu Modules, lancer un onglet de YCD Manager
  • Pour tester un peu, essayez de modifier la première carte : Les raretés uniquement... checkez, enregistrez, decheckez, re-enregistrez,... vous verrez un Bug au bout de quelques fois normalement.

Merci.

EDIT : En essayant avec ta méthode :

try {
var instruction = db.createStatement("DELETE FROM cards_x_rarities WHERE Card_ID= ?1");
instruction.bindInt32Parameter(0, Card_ID);
instruction.execute();
}catch(e) { alert(e); }

Toujours pareil, Bug complètement aléatoire : NS_ERROR_FAILURE, comme d'habitude. Ca marche, ça marche, puis ça marche plus... alors que je fais tout le temps la même action.

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : aMan

Date : 06/11/2007 02:46

ok je viens de le télécharger.... Je regarderai demain... (la je suis un peu mort quand même)

Y-a-t-il moyen d'utiliser ta méthode en codant un petit connecteur qui ferait gagner en place et simplicité ?

Oui c'est possible, j'en ai créer un que j'utilise dans mon framework qui sera bientot disponible pour tous le monde (dés que je l'aurais terminé, et donc dès que j'aurais du temps).

J'y pense aussi....

Il faut en fait.... faire des

try{
 //ta requete, ton statement et ton execute (ainsi que ton traitement des données)
}
catch(e){
  //Ton traitement d'erreur
}
finally{
  statement.reset();
}

Le finally permet de remettre à zero ton statement meme si la requete échou

# Re: Sqlite : De vrais Bugs venus d'ailleurs ! 1 semaine de prise de tête en vain.

Envoyé par : Raphael

Date : 06/11/2007 08:46

Bon, pour ce problème particulier, je vous disais que je sentais un Bug aléatoire, et bien je crois que j'avais raison : Ca doit être dû à un remplissement mémoire ou une mauvaise gestion de XULRunner car :

  • Lorsque j'ai 3500 cartes dans mon Treeview à côté, et que je modifie 3/4 fois... ça Bug de suite... En fait, après chaque modif, je recharge les données MAJ dans mon Treeview, et ça perturbe peut-être le reste du script
  • Lorsque je filtre pour n'avoir que 100 cartes et quelques, et bien je peux modifier une vingtaine de fois d'affilée mes raretés avant d'avoir un bug.
  • Lorsque je vire carrément mon "rafraichissement" en commentant filterCards() à la fin de mes modifs, il s'avère que ça ne semble plus bugguer... j'ai modifié une cinquantaine de fois me raretés sans Bug...

Donc je vais peut-être envisager de ne pas rafraichir mon interface en fonction des modifs, tant pis, si ça peut résoudre le problème.

Cet après-midi, je posterai mon second gros problème dans un autre topic, un problème non aléatoire cette fois, ça Bug à chaque fois et je ne comprends vraiment pas pourquoi, il y a peut-être un rapport avec ce problème-ci, il faut voir.

Il n'est plus possible de poster des messages dans ce forum.


Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.

Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.