[spip-dev] sql_delete et affected_rows

Hello,

dans certains cas, pour prendre en compte des possibles opérations concourantes, on a besoin de savoir si un appel à sql_delete a eu un effet ou non.

Pour ce faire mysql et postgresql ont une fonction xx_affected_rows() qui permet de connaitre le nombre de ligne modifiées par la dernière requete.
Pour SQLite, cela me parait moins clair, et je n'arrive pas très bien à comprendre comment ça marche dans tous les cas.

Il semble qu'il y ait une fonction sqlite_changes() (qui a la particularité de retourner 0 sur une operation comme
"DELETE FROM xxx" sans WHERE).
Mais dans le cas de l'utilisation de PDO, il ne semble pas y avoir d'equivalent, et la seule solution semble de faire un ->exec() qui retourne le nombre de lignes modifiées au lieu de ->query().

Ma question est donc de savoir si dans l'API sql_ il vaut mieux introduire une fonction sql_affected_rows() ou modifier le retour de sql_delete pour lui faire retourner directement le nombre de lignes affectees (et -1 en cas d'erreur ?), sachant qu'a ce jour le retour de sql_delete n'est jamais utilisé dans le core.

Qu'en pense marcimat qui a le plus mis les mains dans le portage sqlite ?

Cédric

La première solution est à exclure: si un jour on tombe sur un serveur où cette info n'est disponible QUE comme retour du sql_delete, l'existence dans l'interface d'une fonction sql_affected_rows() ferait croire qu'on pourrait donner cette info bien après l'opération dans tous les portages, ce qui ne sera pas le cas. La deuxième solution n'a pas ce problème.

Committo,Ergo:Sum

La première solution est à exclure: si un jour on tombe sur un serveur où
cette info n'est disponible QUE comme retour du sql_delete, l'existence dans
l'interface d'une fonction sql_affected_rows() ferait croire qu'on pourrait
donner cette info bien après l'opération dans tous les portages, ce qui ne
sera pas le cas. La deuxième solution n'a pas ce problème.

je suis d'accord ; et, dans ce cas, faut-il faire pareil pour
sql_update() ? renvoyer false en cas d'erreur, et
mysql_num_affected_rows() en cas de succès ?

-- Fil

Oui d'accord.

Committo,Ergo:Sum

Voici une solution testée pour SQLite (2 et 3) sous SPIP 2.1 dev., tu n'auras qu'à prendre ce qui te plait.

Je me suis construit la fonction sql_affected_rows() pour tester, mais effectivement comme disent Emmanuel et Fil, ça serait mieux en retour des fonctions insert, update et delete. Sauf que false !== 0 affected... ce qui risque encore de perturber quelques plugins. Mais je préfère avoir une meilleure API aussi.

Par ailleurs, sur un autre sujet, je serais partisan, dans la foulée d'un sql_alter_table($table, array($actions)); ce qui faciliterait quelques tests sous sqlite... Si quelqu'un a une objection :slight_smile:

spip.vc.diff (3.12 KB)

Evidemment il faudra faire le :
+// raz de affected_rows
+_sqlite_affected_rows($this->serveur, 0);
En dehors du if(), sinon on va en oublier...