Carnet Wiki

API sql_ et préfixes des tables

Dans l’API sql_ de SPIP, il faut toujours écrire les nom des tables SQL avec le préfixe ’spip_’, même si ce n’est pas le préfixe de la BDD, car SPIP va remplacer automatiquement par le bon préfixe. Ca permet de faire du code portable, quel que soit le préfixe sur une installation.

Il y a toutefois 2 limites à ce mécanismes de remplacement :
-  les préfixes des noms de tables entourées par des backquotes ne sont pas remplacés.
-  après une parenthèse, le remplacement n’est pas fait.

Le source dans ecrire/req/mysql.php et l’expression régulière _SQL_PREFIXE_TABLE indiquent qu’il faut un espace avant le nom de table ’spip_...’ pour que le remplacement soit fait correctement.

Pour le premier point, il suffit d’utiliser de ne pas utiliser de quotes.

Pour le 2e point, lorsque les parenthèses sont indispensables, on peut définir des alias des tables avant les parenthèses, ce qui lève le problème.

La requête suivante ne va pas à cause du point 2 :

$rowset = sql_select(
        array( "spip_articles.id_article AS id", "spip_articles.titre AS titre", "spip_articles.date AS date",
            "spip_gmap_points.latitude AS coord_lat", "spip_gmap_points.longitude AS coord_long",
            "spip_gmap_points.zoom AS zoom", "spip_gmap_types.nom AS type",
            "ABS(DATEDIFF('" . $row['date'] . "', spip_articles.date)) AS distdate"),
        "spip_articles
            JOIN spip_gmap_points_liens ON (spip_articles.id_article = spip_gmap_points_liens.id_objet AND spip_gmap_points_liens.objet = 'article')
            JOIN spip_gmap_points ON spip_gmap_points.id_point = spip_gmap_points_liens.id_point
            JOIN spip_gmap_types ON spip_gmap_points.id_type_point = spip_gmap_types.id_type_point",
        $where,
        "", "distdate ASC", $limit);

On la corrige en définissant un alias avant la parenthèse :

$rowset = sql_select(
        array( "articles.id_article AS id", "articles.titre AS titre", "articles.date AS date",
            "points.latitude AS coord_lat", "points.longitude AS coord_long", "points.zoom AS zoom",
            "types.nom AS type",
            "ABS(DATEDIFF('" . $row['date'] . "', articles.date)) AS distdate"),
        "spip_articles AS articles".
            " JOIN spip_gmap_points_liens AS liens ON (articles.id_article = liens.id_objet AND liens.objet = 'article')".
            " JOIN spip_gmap_points AS points ON points.id_point = liens.id_point".
            " JOIN spip_gmap_types AS types ON points.id_type_point = types.id_type_point",
        $where,
        "", "distdate ASC", $limit);

cf http://zone.spip.org/trac/spip-zone/changeset/53708

JLuc - Mise à jour :24 octobre 2011 à 20h48min