JeuWeb - Crée ton jeu par navigateur
Bug d'enchainement de requêtes - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Bug d'enchainement de requêtes (/showthread.php?tid=5120)

Pages : 1 2 3


RE: Bug d'enchainement de requêtes - srm - 29-08-2010

Il ne doit pas afficher Peinture, car Peinture dépend de Superpuissance et le pays 1 ne connaît que Théâtre et Archérie.
Ce qu'il te renvoie et pour moi normale par rapport à l'énoncé du problème.

Il retourne Théâtre qui dépend de Archérie, le pays 1 connaît Archérie : Ok
Il retourne Superpuissance qui ne dépend de rien : Ok
Il ne retourne pas Peinture qui dépend de Superpuissance, pays 1 ne connaît pas Superpuissance : Ok


RE: Bug d'enchainement de requêtes - Hiztaar - 29-08-2010

En fait c'est l'inverse.

Théâtre ne dépend de rien et surtout il est déjà possédé : Il ne devrait pas apparaître dans les savoirs à rechercher.
Archérie est en cours de recherche et n'apparait pas : ok
Peinture ne dépend de rien et doit apparaitre : il n'apparait pourtant pas
Superpuissance dépend à la fois d'Archérie et de Peinture. On ne possède pas peinture : Problème, il apparait quand même


RE: Bug d'enchainement de requêtes - srm - 29-08-2010

utg_knowledge_links
id_knowledge_parent id_knowledge_child
1 2 1
2 4 1
3 4 1

Premier cas, tu dis que le id parent 1 à un id fils 2 donc :
que Théâtre est le parent de Archérie.
Donc il faut bien avoir Archérie pour avoir le Théâtre.

Tu as remplis ton modèle n'importe comment si c'est pas ce que tu voulais dire Smile


RE: Bug d'enchainement de requêtes - Hiztaar - 29-08-2010

Ben dans ma tête c'est le child qui dépend du parent. Les parents sont à la racine, les child dépendent des parents précédents. Donc c'est l'Archérie qui dépend du Théâtre <_<

> Ce qui n'empêche pas qu'on possède déjà Théâtre et qu'il ne devrait pas apparaitre, dans tous les cas Wink


RE: Bug d'enchainement de requêtes - srm - 29-08-2010

Ok soit.
Alors tu n'as pas compris ma requête, car tu ne dois pas mettre :
SELECT utg_knowledge_links.id_knowledge_parent
FROM utg_knowledge_links
WHERE utg_knowledge_links.id_knowledge_child
Mais :
SELECT utg_knowledge_links.id_knowledge_child
FROM utg_knowledge_links
WHERE utg_knowledge_links.id_knowledge_parent

Je te laisse réfléchir et corriger le reste si il y a besoin Smile


RE: Bug d'enchainement de requêtes - Hiztaar - 29-08-2010

J'ai donc remplacé les NOT IN par des IN, ça marche beaucoup mieux.

Maintenant j'ai une difficulté de boucle. Superpuissance nécessite deux savoirs et la requête n'en prend qu'un en compte. Je suppose que je vais devoir créer un curseur <_<


RE: Bug d'enchainement de requêtes - Hiztaar - 29-08-2010

Bon, je cale sur le cas où il y a plusieurs dépendances pour un même knowledge.

Pour le reste, la version remaniée fonctionnelle dans le cas d'un seul héritage :

Code PHP :
<?php 
$available_knowledges
= $this->db->query("
SELECT knowledge.id, knowledge.name, knowledge.family, knowledge.description, knowledge.img_url,
knowledge.time_to_discover, knowledge.price
FROM utg_knowledge knowledge
WHERE knowledge.active = 1
AND knowledge.id
IN (
SELECT utg_knowledge_links.id_knowledge_child
FROM utg_knowledge_links
WHERE utg_knowledge_links.id_knowledge_parent
IN (
SELECT ALL utg_country_knowledge.id_knowledge
FROM utg_country_knowledge
WHERE utg_country_knowledge.id_country =
$fief
)
)
AND knowledge.id
NOT IN (
SELECT utg_country_knowledge.id_knowledge
FROM utg_country_knowledge
WHERE utg_country_knowledge.id_country =
$fief
)
"
);

Merci pour l'aide en tout cas ! Mais je crois que le plus dur c'est ce que cette requête ne gère pas :wowowow:


RE: Bug d'enchainement de requêtes - srm - 29-08-2010

Je te laisse y réfléchir un peu Smile


RE: Bug d'enchainement de requêtes - Hiztaar - 30-08-2010

Je pense avoir réussi à contourner le problème en y allant un peu brutalement. Voici le code :

Code PHP :
<?php 
function Get_available_knowledges()
{

// On va chercher les savoirs disponibles.
// Les savoirs disponibles répondent a toutes les conditions de liaison et de descendance des autres savoirs
// Il faut d'abord récupérer tous les savoirs détenus par un country
$fief = $this->session->userdata('current_view_fief');

$available_knowledges = $this->db->query("
SELECT knowledge.id
FROM utg_knowledge knowledge
WHERE knowledge.active = 1
AND knowledge.id
IN (
SELECT utg_knowledge_links.id_knowledge_child
FROM utg_knowledge_links
WHERE utg_knowledge_links.id_knowledge_parent
IN (
SELECT ALL utg_country_knowledge.id_knowledge
FROM utg_country_knowledge
WHERE utg_country_knowledge.id_country =
$fief
)
)
AND knowledge.id
NOT IN (
SELECT utg_country_knowledge.id_knowledge
FROM utg_country_knowledge
WHERE utg_country_knowledge.id_country =
$fief
)
"
);

// On va tester tous les enfants pour s'assurer qu'on a bien tous les parents
$liste_rouge = array(); // Les child Evil
$liste_verte = array(); // Les child Good
$count_rouge = 0;
$count_vert = 0;

// On va tester tous les résultats
foreach($available_knowledges->result() as $row)
{
$child = $row->id;
if(!
in_array($child, $liste_rouge))
{
$query = $this->db->query("
SELECT id_knowledge_parent
FROM utg_knowledge_links
WHERE id_knowledge_parent =
$child
"
);

if(
$query == TRUE)
{
foreach(
$query->result() as $row)
{

$parent = $row->id_knowledge_parent;

$query2 = $this->db->query("
SELECT id_knowledge
FROM utg_country_knowledge
WHERE id_country =
$fief
AND id_knowledge =
$parent
"
);

if(
$query2 != TRUE)
{
$liste_rouge[$count_rouge] = $child;
$count_rouge++;
}

}
if(!
in_array($child, $liste_rouge))
{
$liste_verte[$count_vert] = $child;
$count_vert++;
}
}
}
}

// On a donc la liste des child valides (liste verte)
// On va reconstruire une requête pour récupérer les informations des child de la liste verte
$query = "
SELECT knowledge.id, knowledge.name, knowledge.family, knowledge.description, knowledge.img_url,
knowledge.time_to_discover, knowledge.price
FROM utg_knowledge knowledge "
;
$count = 0;

foreach(
$liste_verte as $key=>$row)
{
if(!
in_array($row, $liste_rouge))
{
if(
$count == 0)
{
$query = $query."WHERE knowledge.id = $row ";
}
if(
$count !=0)
{
$query = $query."AND knowledge.id = $row ";
}
}
$count++;
}
// On envoie finalement la requête
$available_knowledges = $this->db->query($query);

return
$available_knowledges;
}

Je testerai ce soir si ce code fonctionne ^^


RE: Bug d'enchainement de requêtes - Hiztaar - 30-08-2010

Bon allez zou, juste pour le plaisir, j'ai réussi a faire ce que je voulais avec quelques modifications. Je poste pour que ceux qui auraient un jour la même problématique puisse s'en inspirer.

Code PHP :
<?php 
function Get_available_knowledges()
{

// On va chercher les savoirs disponibles.
// Les savoirs disponibles répondent a toutes les conditions de liaison et de descendance des autres savoirs
// On va récupérer tous les child qui descendent d'au moins un savoir du country
$fief = $this->session->userdata('current_view_fief');

$potential_knowledges = $this->db->query("
SELECT knowledge.id
FROM utg_knowledge knowledge
WHERE knowledge.active = 1
AND knowledge.id
IN (
SELECT utg_knowledge_links.id_knowledge_child
FROM utg_knowledge_links
WHERE utg_knowledge_links.id_knowledge_parent
IN (
SELECT utg_country_knowledge.id_knowledge
FROM utg_country_knowledge
WHERE utg_country_knowledge.id_country =
$fief
AND utg_country_knowledge.knowledge_status = 2
)
)
AND knowledge.id
NOT IN (
SELECT utg_country_knowledge.id_knowledge
FROM utg_country_knowledge
WHERE utg_country_knowledge.id_country =
$fief
)
"
);

// On va tester tous les enfants pour isoler les evil !
$liste_rouge = array(); // Les child Evil !
$count_rouge = 0;

// On teste tous les résultats
foreach($potential_knowledges->result() as $row)
{
$child = $row->id;

// Si le child n'est pas dans la liste rouge, alors on continue, sinon inutile de faire la boucle
if(!in_array($child, $liste_rouge))
{
// On récupère l'id des parent (s)
$query = $this->db->query("
SELECT id_knowledge_parent
FROM utg_knowledge_links
WHERE id_knowledge_child =
$child "
);
// S'il y a bien un parent <_<
if($query == TRUE)
{
// Pour chaque parent récupéré pour le child
foreach($query->result() as $row)
{

$parent = $row->id_knowledge_parent;

// On va vérifier que le parent est bien dans la liste de ce qu'on possède
$query2 = $this->db->query("
SELECT id_knowledge
FROM utg_country_knowledge
WHERE id_country =
$fief
AND id_knowledge =
$parent
"
);

// Si la requete retourne un résultat négatif alors on met le child en liste rouge
if($query2->result() != TRUE)
{
$liste_rouge[$count_rouge] = $child;
$count_rouge++;
//DEBUG// echo "$child = bad ; ";
}
}
}
}
}

// On a donc la liste des child invalides ($liste_rouge)
// On va reconstruire une requête pour récupérer les informations des child qui ne sont PAS dans la liste rouge
// La requête est montée sous forme de string
$query = "
SELECT knowledge.id, knowledge.name, knowledge.family, knowledge.description, knowledge.img_url,
knowledge.time_to_discover, knowledge.price
FROM utg_knowledge knowledge "
;

// Compteur à 0
$count = 0;

// Pour chaque résultat (child) de la requete initiale
foreach($potential_knowledges->result() as $row)
{
// $row = l'id du child courrant
$row = $row->id;

//DEBUG// echo $row;
// Si le child N'EST PAS dans la liste rouge
if(!in_array($row, $liste_rouge))
{
//DEBUG// echo "compteur = $count ; ";

// Si le compteur est à 0 on met un WHERE
if($count == 0)
{
$query = $query."WHERE knowledge.id = $row ";
//DEBUG// echo $row;
}
// Si le compteur n'est plus à 0, on met un OR
if($count !=0)
{
$query = $query."OR knowledge.id = $row ";
//DEBUG// echo $row;
}
// Fin de tour, on augmente le compteur pour ne pas enchainer des WHERE
$count++;
}

}
//DEBUG// echo $query;
// On a notre requête $query qui est totalement finalisée sous forme de string

// On envoie finalement la requête
$available_knowledges = $this->db->query($query);

return
$available_knowledges;
}

Encore une fois, merci Oxman pour ton aide, j'aurais jamais pu avancer sur la requête d'origine sans toi ^^