[spip-dev] utilisation de sql_replace()

S'lt

Dans le cadre du traitement d'un formulaire je souhaite :
- soit créer un nouvel enregistrement,
- soit mettre à jour l'enregistrement.

Au début j'avais compris que cela se jouait sur la présence ou non de
la clef primaire dans la clause where. Ce qui n'est pas le cas

Ceci me créé un nouvel enregistrement et ne met pas à jour id_auteur=4
    $id_sql = sql_replace(
        'spip_auteurs',
        array(
            'login' => _request('login'),
            'nom' => _request('nom'),
            'email' => _request('email')
        )
        "id_auteur = 4"
    );

Tandis que ceci semble bien marcher :

    $id_sql = sql_replace(
        'spip_auteurs',
        array(
            'id_auteur' => "4",
            'login' => _request('login'),
            'nom' => _request('nom'),
            'email' => _request('email')
        )
    );

Toutefois j'ai l'impression que les champs non remplit sont mis à Null
au lieu d'etre laissé tranquille. Alors que la doc sur spip.net parle
de mise à jour.

Est ce que j'ai mal compris l'utilité de cette fonction ? Dois je
plutôt faire un sql_insert et sql_updateq en fonction de la présence
ou non de id_auteur ?

De plus que retourne sql_replace ? je pensais récupérer l'id_auteur
dans le cas précèdent, mais cela ne semble pas le cas.

Km

S'lt

On me fait remarquer que j'ai oublié une , c'est une erreur de copier/coller
:blush:

Km

Le 3e argument de sql_replace n'est pas la clause Where, celle-ci est calculée automatiquement.
Il y avait une faute sur ce point dans la doc, je viens de la corriger:
http://www.spip.net/ecrire/?exec=articles&id_article=3683

Committo,Ergo:Sum

S'lt

Ok donc j'avais bien corrigé mon écriture.
Toutefois les champs n'etant pas déclaré dans les valeurs sont mis à
NULL au lieu d'être conservé en l'etat. (SPIP 1.9.3 dev SVN [11689])

Donc cela n'a pas le comportement d'un update.

Code testé ($id_auteur valide) :

    $table = "spip_auteurs";
    $valeurs = array(
        'id_auteur' => $id_auteur,
        'login' => _request('login'),
        'nom' => _request('nom'),
        'email' => _request('email')
    );

    $id_sql = sql_replace(
        $table,
        $valeurs
   );

Par exemple, le champ bio passe à ''

Quelles sont les valeurs possible de $id_sql ? Dans mon cas, la
variable passe à 1, je suppose pour true, opération traitée avec
succés.

Km

En effet, c'est le comportement de Replace tel que défini par MySQL:
http://dev.mysql.com/doc/refman/5.1/en/replace.html

A noter que cette instruction est spécifique à MySQL et n'existe pas en PG.
Pour toutes ces raisons, je déconseille l'utilisation de cette instruction.
SPIP l'utilise d'ailleurs très peu.

Committo,Ergo:Sum

S'lt

Ok merci pour le lien, je commençais à devenir chèvre :slight_smile:

Mais si SPIP n'utilise pas trop cette fonction, si c'est juste pour
faire plaisir à Mysql et qu'en plus cette fonction est trompeuse,
alors quel est l'intérêt de cette fonction.

Dans présentement il vaux mieux faire un test sur $id_auteur et en
fonction soit faire un sql_updateq ou bien un sql_insertq ?

Km

S'lt

Ok merci pour le lien, je commençais à devenir chèvre :slight_smile:

Mais si SPIP n'utilise pas trop cette fonction, si c'est juste pour
faire plaisir à Mysql et qu'en plus cette fonction est trompeuse,
alors quel est l'intérêt de cette fonction.

Au moment de la généralisation de SPIP à n'importe quel serveur SQL,
il était plus rapide de la mettre dans l'interface que de réécrire
la vingtaine d'utilisations qui figurent dans le code de SPIP.
Idéalement je suis pour la supprimer, ou au moins la passer sous silence comme sql_insert,
car en PG elle pose beaucoup de pb (notion de séquence à gérer, limite incompatible donc chère payée).
Mais c'est du boulot.

Dans présentement il vaux mieux faire un test sur $id_auteur et en
fonction soit faire un sql_updateq ou bien un sql_insertq ?

Oui, mais il y a un problème d'accès concurrent, qu'on peut résoudre en profitant du contrôle d'unicité de la clé primaire.
Il y a plusieurs exemples dans le code de SPIP, par exemple les URL propres.

Committo,Ergo:Sum