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 :
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...
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
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 ?
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).
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.
Envoyé par : aMan
Date : 05/11/2007 11:54
Alors quand est il ?
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 :
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...
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 !!
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...
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)
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
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.
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
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 :
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.