[SPIP Zone] r18394 - in /_plugins_/_dev_/spipBB: Changelog.txt inc/spipbb_inc_config.php

chryjs-GANU6spQydw@public.gmane.org a écrit :

* Suite : problemes de compatibilite PostGres (simplification des controles) cf Bug Report Adeline D

+ $champ=preg_replace("/^mediumtext/","text",$champ); //mediumtext == text

Peut-on savoir où est ce 'bug report' et qu'elle est l'imcompatibilité ?

MM.

Matthieu Marcillaud wrote:

chryjs@free.fr a écrit :

* Suite : problemes de compatibilite PostGres (simplification des controles) cf Bug Report Adeline D

+ $champ=preg_replace("/^mediumtext/","text",$champ); //mediumtext == text

Peut-on savoir où est ce 'bug report' et qu'elle est l'imcompatibilité ?

MM.

Réponse oui : dans ma boite mail.
L'incompatibilité réside dans la façon dont j'ai conçu le test de contrôle. Il était basé sur une réponse qui n'était "compatible" qu'avec MySQL et excluait Postgresql.
Comme j'ai qq1 qui contribue dans ce domaine et me permet de valider le bon fonctionnement de ce que j'ai écrit j'en profite pour tenter de rendre le plugin compatible aussi avec cette base.

Mon plus gros soucis actuellement c'est que mes courtes recherches ne m'ont pas permis (en survolant la doc de PG) de trouver quelles étaient les structures de données existantes dans PG et les correspondances avec celles de MySQL, ainsi que ce qui est décrit dans la table des tables qui est semble t il plutot orienté MySQL...

J'espère avoir satisfait ta curiosité :wink:

--
Chryjs

chryjs a écrit :

Matthieu Marcillaud wrote:

chryjs@free.fr a écrit :

* Suite : problemes de compatibilite PostGres (simplification des controles) cf Bug Report Adeline D
+ $champ=preg_replace("/^mediumtext/","text",$champ); //mediumtext == text

Peut-on savoir où est ce 'bug report' et qu'elle est l'imcompatibilité ?

MM.

Réponse oui : dans ma boite mail.
L'incompatibilité réside dans la façon dont j'ai conçu le test de contrôle. J'espère avoir satisfait ta curiosité :wink:

Ce n'est pas de la curiosité, c'est du besoin; Tu le sais certainement, la version en développement de SPIP peut fonctionner avec PostgreSQL et SQLite. Les plugins aussi à condition que ceux-ci utilisent les nouvelles fonctions d'accès à la base de données sql_* (insert, insertq, select, replace, update, updateq, alter, create...) et en dernier ressort car c'est la fonction la moins 'portable' sql_query().

Lorsque l'on passe des requetes en utilisant ces fonctions, SPIP, à travers les fichiers /req/pg.php ou req/sqlite_generique.php 'traduit' en quelque sorte ce qu'il reçoit pour créer un requete compatible avec le serveur de base de donnée. Grosso modo, il traduit un langage orienté mysql vers ces autres langages proches.

D'où ma question, quelle était l'incompatibilité ici ? mediumtext n'est pas supporté par pg ?

MM.

Matthieu Marcillaud wrote:

Ce n'est pas de la curiosité, c'est du besoin; Tu le sais certainement, la version en développement de SPIP peut fonctionner avec PostgreSQL et SQLite. Les plugins aussi à condition que ceux-ci utilisent les nouvelles fonctions d'accès à la base de données sql_* (insert, insertq, select, replace, update, updateq, alter, create...) et en dernier ressort car c'est la fonction la moins 'portable' sql_query().

Lorsque l'on passe des requetes en utilisant ces fonctions, SPIP, à travers les fichiers /req/pg.php ou req/sqlite_generique.php 'traduit' en quelque sorte ce qu'il reçoit pour créer un requete compatible avec le serveur de base de donnée. Grosso modo, il traduit un langage orienté mysql vers ces autres langages proches.

D'où ma question, quelle était l'incompatibilité ici ? mediumtext n'est pas supporté par pg ?

MM.

Non pas qu'il ne soit pas supporté mais que lors de la création ou du retour de la description ce type ne s'appelle plus mediumtext .

<LONG>
Ci après un exemple que j'espère plus explicite sur une table de ce plugin.

== Description de la table (cf spipbb/base/spipbb.php) ==
$spip_spam_words_log = array(
  "id_spam_log" => "bigint(21) NOT NULL auto_increment",
  "id_auteur" => "bigint(21) NOT NULL",
  "ip_auteur" => "varchar(16) default NULL",
  "login" => "varchar(255) default NULL",
  "log_date" => "timestamp", // NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP"
  "titre" => "text",
  "message" => "mediumtext",
  "id_forum" => "bigint(21) NOT NULL",
  "id_article" => "bigint(21) NOT NULL"
    );
$spip_spam_words_log_key = array( 'PRIMARY KEY' => "id_spam_log" );

$tables_principales['spip_spam_words_log'] = array(
    'field' => &$spip_spam_words_log,
    'key' => &$spip_spam_words_log_key );

== Comparaison (de version de description en base) (cf spipbb/inc/spipbb_inc_config.php:spipbb_check_une_table() ) ==

Pour contrôler la bonne création des tables ainsi qu'une éventuelle ancienne version du schéma en base, j'utilise la fonction sql_showtable par ex :
    sql_showtable('spip_spam_words_log',true);
pour le comparer au tableau ci_dessus.

Or dans mon exemple (comparaison de Mysql avec Pgsql)
* message est "transformé" en text
* login en varcharacter (sans spécification de longueur)
* id_forum reste en bigint mais sans spécification de longueur

J'aurais apprécié que le retour de sql_showtable s'approche de la description originale mais ce n'est pas le cas. Donc pour le moment, le patch que tu as vu passer transforme au moins disant pour comparer... ce qui en l'espèce réduit l'efficacité de la comparaison, puisque on ne peut plus comparer les longueurs et qu'il y a des approximations sur les types. Mais bon c'est déjà ça : on vérifie la liste des champs ainsi que leur "type global" (en supposant par ex que mediumtext en MySQL est proche de text en PG).

==> Pistes possibles

- Approfondir les doc de pgsql et faire des tests en local (remis à plus tard faute de temps)... il me faudrait faire de même avec sqlite
- Voir s'il n'existe pas une autre fonction que sql_showtable ou proposer une adaptation de celle-ci pour un retour plus... proche du schéma original => à réfléchir :wink: peut être a l'image de ce que fait spip_pg_frommysql... mais dans le sens inverse... est-ce vraiment possible...
- Temporairement rendre les tests plus "lâches" et convertir les dizaines de requêtes qui le ne sont pas encore, et vérifier que cela fonctionne toujours avec SPIP 1.9.2 (absence de régressions). Obj : être vraiment compatible "autres SGBD". En cours
- Garder le plugin incompatible, tant que... -> je ne peux m'y résoudre donc pour le moment cette piste est abandonnée !

==>> Autres problèmes rencontrés du même ordre

Pour le moment :
- m'assurer que dans sql_select() la syntaxe pour le paramètre $limit est bien "a,b" : cf en Mysql LIMIT a,b qui doit être traduit en OFFSET a + LIMIT b en pgsql...

- vérifier la syntaxe exacte du tableau $where de sql_select pour la liste des contraintes pour la conversion de sql_query en sql_select

- je peine a trouver un substitutif pour "SHOW TABLES LIKE..." que je passe en sql_query

</LONG>

J'ose et je m'en excuse, regretter que le code manque d'une microligne de doc et de noms de variables moins obscurs pour rendre les fonctions (notamment d'abstraction) un peu moins cryptiques, cf la recherche de l'opérateur pour décrypter la structure requise de $where : $op = str_replace('REGEXP', '~', array_shift($v)) en fait $v c'est le $where de la fonction en dessous de pile... etc etc. <troll> En même temps c'est plus rigolo d'appeler ses variables $ti $ta $to ou $titi $tata et $toto (il y en a qui doivent bien rire) </troll>

Trêve de plaisanterie : y a-t-il un moyen _simple_ pour un "amateur" comme moi de documenter le code parce que je n'ai jamais réussi à ajouter quoique ce soit dans doc.spip.org (même pas une mauvaise information) ?

--
Chryjs

chryjs a écrit :

Pour contrôler la bonne création des tables ainsi qu'une éventuelle ancienne version du schéma en base, j'utilise la fonction sql_showtable par ex :
     sql_showtable('spip_spam_words_log',true);
pour le comparer au tableau ci_dessus.

OK. sql_showtable retourne la description de la table créée. Or, la table créée n'est pas 'forcément' exactement ce qui peut avoir été demandé, en fonction des contraintes des différents serveurs. SQLite est exactement dans le même cas, il lui faut pour tout ce qui est 'autoincrement' pas autre chose que 'INTEGER NOT NULL PRIMARY KEY' donc tous les bigint, smallint qui sont primary key autoincrement, sqlite va les transformer integer tout court, et avec le sql_showtable() tu verras effectivement ce que sqlite a enregistré. C'est un exemple.

Or dans mon exemple (comparaison de Mysql avec Pgsql)
* message est "transformé" en text
* login en varcharacter (sans spécification de longueur)
* id_forum reste en bigint mais sans spécification de longueur

Je connais mieux sqlite, et par exemple, si tu lui donnes une indication de longueur, il la garde dans sa description des tables, mais n'en tient pas compte !

J'aurais apprécié que le retour de sql_showtable s'approche de la description originale mais ce n'est pas le cas.

Ce n'est à proprement parler pas vraiment possible. Que se passe t-il alors si tu fais des modifications de la table via phpmyadmin ou phppgadmin ? qu'est-ce que sql_showtable() doit retourner ? ce qu'il croit avoir ou ce qu'il a ? !

==> Pistes possibles

- Approfondir les doc de pgsql et faire des tests en local (remis à plus tard faute de temps)... il me faudrait faire de même avec sqlite
- Voir s'il n'existe pas une autre fonction que sql_showtable ou proposer une adaptation de celle-ci pour un retour plus... proche du schéma original => à réfléchir :wink: peut être a l'image de ce que fait spip_pg_frommysql... mais dans le sens inverse... est-ce vraiment possible...

A mon sens pas possible. Comment peut-tu savoir qu'un champ 'text' de pg était un champ 'text' ou 'mediumtext' en mysql ?

- Temporairement rendre les tests plus "lâches" et convertir les dizaines de requêtes qui le ne sont pas encore, et vérifier que cela fonctionne toujours avec SPIP 1.9.2 (absence de régressions). Obj : être vraiment compatible "autres SGBD". En cours

Tes retours seront forts appréciés !

==>> Autres problèmes rencontrés du même ordre

Pour le moment :
- m'assurer que dans sql_select() la syntaxe pour le paramètre $limit est bien "a,b" : cf en Mysql LIMIT a,b qui doit être traduit en OFFSET a + LIMIT b en pgsql...

oui, c'est a,b. Par ailleurs, il y a une doc sur ces fonctions (non publiée) sur spip.net
http://www.spip.net/ecrire/?exec=articles&id_article=3683

- vérifier la syntaxe exacte du tableau $where de sql_select pour la liste des contraintes pour la conversion de sql_query en sql_select

array("titre","description") ou
array("titre as T","description as D") ou
array("T"=>"titre","D"=>"description") de mémoire (ou l'inverse)

- je peine a trouver un substitutif pour "SHOW TABLES LIKE..." que je passe en sql_query

Qu'est ce que ça doit faire ? lister les tables en fonction de leur nom ?

J'ose et je m'en excuse, regretter que le code manque d'une microligne de doc et de noms de variables moins obscurs pour rendre les fonctions (notamment d'abstraction) un peu moins cryptiques,

On fait ce qu'on peut !

Trêve de plaisanterie : y a-t-il un moyen _simple_ pour un "amateur" comme moi de documenter le code parce que je n'ai jamais réussi à ajouter quoique ce soit dans doc.spip.org (même pas une mauvaise information) ?

Bien, tu peux écrire un article dedans au pire... C'est vrai qu'il manque les crayons dessus et les squelettes sont plus à jour sur la zone que sur le site... le webmaster semble disparu !

MM.

Matthieu Marcillaud wrote:

OK. sql_showtable retourne la description de la table créée. Or, la table créée n'est pas 'forcément' exactement ce qui peut avoir été demandé, en fonction des contraintes des différents serveurs. SQLite est exactement dans le même cas, il lui faut pour tout ce qui est 'autoincrement' pas autre chose que 'INTEGER NOT NULL PRIMARY KEY' donc tous les bigint, smallint qui sont primary key autoincrement, sqlite va les transformer integer tout court, et avec le sql_showtable() tu verras effectivement ce que sqlite a enregistré. C'est un exemple.

On est d'accord. Donc contrôles "relachés".

Je connais mieux sqlite, et par exemple, si tu lui donnes une indication de longueur, il la garde dans sa description des tables, mais n'en tient pas compte !

D'où le "lite" :slight_smile:

Ce n'est à proprement parler pas vraiment possible. Que se passe t-il alors si tu fais des modifications de la table via phpmyadmin ou phppgadmin ? qu'est-ce que sql_showtable() doit retourner ? ce qu'il croit avoir ou ce qu'il a ? !

Heu joker :wink:

- Voir s'il n'existe pas une autre fonction que sql_showtable ou proposer une adaptation de celle-ci pour un retour plus... proche du schéma original => à réfléchir :wink: peut être a l'image de ce que fait spip_pg_frommysql... mais dans le sens inverse... est-ce vraiment possible...

A mon sens pas possible. Comment peut-tu savoir qu'un champ 'text' de pg était un champ 'text' ou 'mediumtext' en mysql ?

Peux pas a priori d'où mon auto-interrogation sur la faisabilité...

- Temporairement rendre les tests plus "lâches" et convertir les dizaines de requêtes qui le ne sont pas encore, et vérifier que cela fonctionne toujours avec SPIP 1.9.2 (absence de régressions). Obj : être vraiment compatible "autres SGBD". En cours

Tes retours seront forts appréciés !

A quel type de retour t'attendrais tu ? Ha la validation des fonctions de virtualisation ? Si c'est ça ok.. Pour le moment j'ai quelques lignes de code à adapter et quelques procédures aussi.

oui, c'est a,b. Par ailleurs, il y a une doc sur ces fonctions (non publiée) sur spip.net
SPIP

Je vais regarder dès que j'y aurai accès :slight_smile:

- vérifier la syntaxe exacte du tableau $where de sql_select pour la liste des contraintes pour la conversion de sql_query en sql_select

array("titre","description") ou
array("titre as T","description as D") ou
array("T"=>"titre","D"=>"description") de mémoire (ou l'inverse)

Heu je n'ai pas compris : WHERE pas les colonnes hein (rows) array("champ='valeur'","and","...","or",...) ou de ce style... mais justement je n'ai pas encore la bonne syntaxe...

- je peine a trouver un substitutif pour "SHOW TABLES LIKE..." que je passe en sql_query

Qu'est ce que ça doit faire ? lister les tables en fonction de leur nom ?

Oui, zut c'est pas ANSI ce truc.
A priori mes recherches s'orientent vers :
- SELECT * FROM pg_tables WHERE tablename NOT LIKE 'pg_%'
- ou describe tables
- ou alors préférentiellement : SELECT table_name FROM information_schema.tables WHERE table_schema = 'public AND table_name LIKE ...

Dès que j'ai un truc propre je peux même proposer une fonction de virtualisation :slight_smile: enfin faudrait que je teste sqlite

J'ose et je m'en excuse, regretter que le code manque d'une microligne de doc et de noms de variables moins obscurs pour rendre les fonctions (notamment d'abstraction) un peu moins cryptiques,

On fait ce qu'on peut !

:-))))))))) des fois c'est limite de l'obfuscation contest de perl.. niark

Trêve de plaisanterie : y a-t-il un moyen _simple_ pour un "amateur" comme moi de documenter le code parce que je n'ai jamais réussi à ajouter quoique ce soit dans doc.spip.org (même pas une mauvaise information) ?

Bien, tu peux écrire un article dedans au pire... C'est vrai qu'il manque les crayons dessus et les squelettes sont plus à jour sur la zone que sur le site... le webmaster semble disparu !

Bah la dernière fois que j'ai essayé je ne pouvais pas. Sinon j'aurai documenté pas mal de fonctions...

--
Chryjs