[spip-dev] requète pour récupérer la hierarchie

Une petite proposition en passant sur la façon de récuper la
hierarchie d'une rubrique.
  Actuellement il y a une série de requète pour sortir les pere/fils,
puis une autre pour choper les détails.
  Dans un projet similaire (sur ce point là en tous cas), on avait
fait ça autrement.
  L'idée est d'avoir une table "arbo" qui contient une version
"dépliée" de l'arbo de rubriques, c'est à dire la liste de tous les
liens rubrique->ascendant (donc, père mais aussi grand père,
arrière ...) avec la distance entre les 2 (1 pour père, 2 pour
grand père ...).
  C'est assez chaud à mettre à jour quand il y a ajout, suppression et
surtout déplacement d'une rubrique, mais ensuite, pour sortir
la hiérarchie, il suffit d'une seule requète.
  Ça parait sauvage, mais on gérait comme ça plus de 1000 rubriques
sans problèmes de perfs.

  Comme je n'ai pas regardé le code de plus près que ça, avant
d'expliquer plus en détail, j'aimerais savoir si vous pensez que c'est
un point "à optimiser" où si l'existant est très bien comme ça.

À+, Pif.

:

  Une petite proposition en passant sur la façon de récuper la
hierarchie d'une rubrique.

....

j'aimerais savoir si vous pensez que c'est
un point "à optimiser" où si l'existant est très bien comme ça.

Ayant réécrit le compilateur, il me parait clair que l'existant
"n'est pas très bien comme ça": j'ai tenté d'harmoniser la compilation
de cette boucle avec les autres, mais ça reste dérogatoire et lent.
Cela dit, je ne suis pas sûr que maintenir une table des arborescences
soit la bonne solution: il faudrait regarder SQL + en détail voir si on
peut agir au niveau des requetes elles-mêmes ce qui serait l'idéal (peut-etre
inatteignable).

      Emmanuel

Ayant réécrit le compilateur,

Ça donne quoi ?

il me parait clair que l'existant
"n'est pas très bien comme ça": j'ai tenté d'harmoniser la compilation
de cette boucle avec les autres, mais ça reste dérogatoire et lent.
Cela dit, je ne suis pas sûr que maintenir une table des arborescences
soit la bonne solution: il faudrait regarder SQL + en détail voir si on
peut agir au niveau des requetes elles-mêmes ce qui serait l'idéal

  On arrive tôt ou tard à une récursivité qu'on ne sait pas faire en
sql, et encore moins sans procédures stockées et/ou curseurs.

  La mise à jour d'une table des liens entre descendants est assez
space à coder, mais ça n'est en fait qu'un seul insert/select lors de
l'ajout d'une rubrique.

  Le seul cas chiant, c'est le déplacement de rubrique, mais même ça,
c'est pas irréalisable (dans le projet ou j'ai fait ça, il n'y avait pas
cette fonctionnalité, je n'avais donc pas essayé d'écrire le sql
associé, mais ça paraissait jouable).

  À cote de ça, récupérer la hierarchie par un select (presque)
aussi simple que celui pour récupérer les fils d'une rubrique par
exemple, ça simplifierait pas mal le compilateur de squelettes.

À+, Pif.

Christian Lefebvre wrote:

sql, et encore moins sans procédures stockées et/ou curseurs.

La mise à jour d'une table des liens entre descendants est assez
space à coder, mais ça n'est en fait qu'un seul insert/select lors de
l'ajout d'une rubrique.

Le seul cas chiant, c'est le déplacement de rubrique, mais même ça,
c'est pas irréalisable (dans le projet ou j'ai fait ça, il n'y avait pas
cette fonctionnalité, je n'avais donc pas essayé d'écrire le sql
associé, mais ça paraissait jouable).

À cote de ça, récupérer la hierarchie par un select (presque)
aussi simple que celui pour récupérer les fils d'une rubrique par
exemple, ça simplifierait pas mal le compilateur de squelettes.

À+, Pif.

et pourquoi ne pas regarder vers ca : Tree

en ce moment, je galere un max avec SPIP. Qui me genere des erreurs aléatoires, pour les
plus curieux, c'est dans Mantis.

Du coup, sur un coup de tete, je me suis amusé a réecrire : inc-calcul-squelette qui fait 2300 lignes.
Je l'ai découpé en plusieurs classes qui sont plus fonctionnelles que objets. Mais pour l'instant
c'est plutot prometteur. Je suis dans la meme foulé en train de couper les variables globales. J'espere
que je vais aboutir a qq chose de concret rapidement, puisque j'ai pas bcp de temps.

en gros la fonction principale donne ca :

function calculer_squelette($squelette, $fichier) {

  include_once('SpipParser.php');
  include_once('SpipEngine.php');

   $parser = new SpipParser();
   $engine = new SpipEngine();

   $html = join(file("$squelette.html"), "");
   $tree = $parser->parse($html);
    // on pourrait serialiser l'arbre que ca serait pas si mal, rapide et pas du tout casse pied.
  // et le restaurer a l'execution plutot que de passer par un fichier intermediaire.

  $data = $engine->run($tree);
  $engine->write_file($data);

}

- j'ai essayé de regrouper toutes les procedures qui vont ensemble dans la meme classe.
- de supprimer au fure et a mesure les variables glabales.
- de bien séparer l'analyseur du moteur (engine et parser).

je suis plutot vers la fin. J'ai fait comme Christian, un switch pour faire marcher les
2 en paralelle et etre en mesure de comparer les executions.

je suis parti sur un version SPIP de dev 1.7*, pas tres récente. Mais pour l'instant j'ai pas bcp
changé le code il est assez facile de faire les mises a jours.

et pourquoi ne pas regarder vers ca : Tree

bof ...
- ça implique d'utiliser toute une gestion d'arbre pour une seule
  fonctionnalité (la hiérarchie), puisque pour le reste, les requètes
  actuelles sont mieux (dans le sens où aller chercher les articles
  d'une rubriques, ou les sous-rubriques d'une rubrique, c'est codé
  pareil)
- c'est du php4
- ça implique d'utiliser Pear::DB pour l'accès bdd
- j'ai pas vérifié si y'a pas des contraintes sur la façon de coder les
  liens pere/fils en base

Du coup, sur un coup de tete, je me suis amusé a réecrire :
inc-calcul-squelette qui fait 2300 lignes.

Ouaip, c'est vrai que c'est quand même un gros morceau cet include :slight_smile:

en gros la fonction principale donne ca :

function calculer_squelette($squelette, $fichier) {

  include_once('SpipParser.php');

  attention : php4 => Il faudrait relancer la question du php4, car
visiblement, le débat lancé par ... Arno* ? Antoine ? semble tombé dans
l'oreille d'un paquet de sourds :wink:
  perso, j'm'en fous, et j'suis même plutôt pour car je trouve foreach
plus lisible que while(each) par exemple, mais c'est vrai que ça sera
pas "compatible ascendant" (ou descendant, j'sais jamais dans quel sens
ça se dit) pour certains hébergeurs.

  include_once('SpipEngine.php');

   $parser = new SpipParser();
   $engine = new SpipEngine();

   $html = join(file("$squelette.html"), "");
   $tree = $parser->parse($html);

C'est avec ma version ça ? ça marche bien finallement ?

  // on pourrait serialiser l'arbre que ca serait pas si mal, rapide et
pas du tout casse pied.
  // et le restaurer a l'execution plutot que de passer par un fichier
intermediaire.

Quel fichier ? je comprend pas ce que tu veux dire.

  $data = $engine->run($tree);
  $engine->write_file($data);

  Plus globalement, il faudrait voir avec les 3 mousquetaires ce qu'il
pensent de ce genre de ré-écriture.
  Ça serait con qu'on passe du temps à faire ça pour que ça tombe aux
oubliettes (et je me sens pas de taille à maintenir un fork :wink:

  Le moment est mal venu, puisque visiblement, la 1.7 leur bouffe pas
mal de temps, et c'est peut être pas le moment de tout bousculer.
  Mais est-ce que ça parait jouable de prévoir ça dans la 1.7.x ? voire
dans une 1.8 qui serait iso-fonctionnalités avec la 1.7, mais avec un
nettoyage de certains morceaux.

À+, Pif.

Christian Lefebvre wrote:

C'est avec ma version ça ? ça marche bien finallement ?

non, désolé, c'est juste un copier-coller pseudo intelligent

- qui prend le code SPIP tel quel et
- qui le met sous forme de classe,
- transforme certaines variables globales en alias sur des attributs de la classe,
- pour toutes les fonctions internes transformet fonction_truc() en $this->fonction_truc()
- le compilateur php m'aide bcp, puisqu'il annonce tout ce qu'on doit faire
au fur et a mesure.
- avec error_reporting(E_ALL), ca permet de pallier a tous les oublis.
- chose intéressante, j'essaie de bousculer au minimum SPIP de facon
a s'intégrer dans l'existant.

Cette maipulation permet simplement de séparer un peu les choses, avant
d'amorcer un démarche plsu complete.

// on pourrait serialiser l'arbre que ca serait pas si mal, rapide et pas du tout casse pied.
// et le restaurer a l'execution plutot que de passer par un fichier intermediaire.

Quel fichier ? je comprend pas ce que tu veux dire.

$data = $engine->run($tree);
$engine->write_file($data);

quand je parle de sérialisation, c'est simplement qu'on dispose de toute
la description du template (pardon squelette) dans un grosse structure ($tree)

cette description, elle peut servir a 2 choses :

  - realiser un fichier intermédiaire en php qui sera la version compilée du template
  - ou enregistrer directement cette structure pour s'en servir plus tard comme
generateur de code HTML.

Christian Lefebvre wrote:

  Une petite proposition en passant sur la façon de récuper la
hierarchie d'une rubrique.
  Actuellement il y a une série de requète pour sortir les pere/fils,
puis une autre pour choper les détails.
  Dans un projet similaire (sur ce point là en tous cas), on avait
fait ça autrement.
  L'idée est d'avoir une table "arbo" qui contient une version
"dépliée" de l'arbo de rubriques, c'est à dire la liste de tous les
liens rubrique->ascendant (donc, père mais aussi grand père,
arrière ...) avec la distance entre les 2 (1 pour père, 2 pour
grand père ...).

Un article sur le sujet par le Pro du SQL sur le Web :
http://sqlpro.developpez.com/Tree/SQL_tree.html
Tout y est expliqué.
Cordialement,
Jacques PYRAT - www.pyrat.net

Sympa comme truc. C'est pas du tout à ça que je pensais, mais
pourquoi pas.

À+, Pif.

Christian Lefebvre wrote:

@ Christian Lefebvre <christian.lefebvre@atosorigin.com> :

  attention : php4 => Il faudrait relancer la question du php4, car
visiblement, le débat lancé par ... Arno* ? Antoine ? semble tombé dans
l'oreille d'un paquet de sourds :wink:

Je pense qu'on va lâcher cette exigence après la 1.7.

> $data = $engine->run($tree);
> $engine->write_file($data);

  Plus globalement, il faudrait voir avec les 3 mousquetaires ce qu'il
pensent de ce genre de ré-écriture.
  Ça serait con qu'on passe du temps à faire ça pour que ça tombe aux
oubliettes (et je me sens pas de taille à maintenir un fork :wink:

  Le moment est mal venu, puisque visiblement, la 1.7 leur bouffe pas
mal de temps, et c'est peut être pas le moment de tout bousculer.
  Mais est-ce que ça parait jouable de prévoir ça dans la 1.7.x ? voire
dans une 1.8 qui serait iso-fonctionnalités avec la 1.7, mais avec un
nettoyage de certains morceaux.

Si le code est plus lisible, plus efficace, et plus extensible, je ne vois
pas pour quelle raison on se priverait de l'intégrer :wink: Par contre si on ne
comprend rien à ce que vous faites, ça ne marchera évidemment pas. Et si
c'est entre ces deux brones, il faudra prendre le temps de converger, soit
en éclaircissant le code ou en le commentant, etc.

-- Fil

Fil wrote:

Si le code est plus lisible, plus efficace, et plus extensible, je ne vois
pas pour quelle raison on se priverait de l'intégrer :wink: Par contre si on ne
comprend rien à ce que vous faites, ça ne marchera évidemment pas. Et si
c'est entre ces deux brones, il faudra prendre le temps de converger, soit
en éclaircissant le code ou en le commentant, etc.

-- Fil

ca n'avance pas tres viete en ce moment, mais c'est tres facile a comprendre,
il suffit simplement de comprendre ce que j'ai ecrit dans le main(), enfin
mon truc avec les instances de chaques objets.

je vous presente ca des que ca marche, si ca marche un jour :wink: et progressivement
on fera mieux.

Pour placid, plus efficace, c'est pas gagné. Mais à mon avis, c'est
pas là qu'il y a le plus à optimiser.
  À ce propos, placid version 2 est sorti (faut que je mette à jour du
coté de spip d'ailleurs) : http://piif.lautre.net/DEV/placid/readme.html
le tar est là : http://piif.lautre.net/DEV/placid/placid.tgz
  Il n'y a plus de mot clé "prefixe" dans la grammaire.

À+, Pif.

:

Ayant réécrit le compilateur,

Ça donne quoi ?

Ca donne:

http://www.uzine.net/spip_contrib/ecrire/articles.php3?id_article=269

Bonne lecture à tous!

      Emmanuel