[SPIP] ~v3.0.20-->v3.0.25
[lhc/web/clavette_www.git] / www / ecrire / base / abstract_sql.php
1 <?php
2
3 /* *************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2016 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 /**
14 * Definition de l'API SQL
15 *
16 * Ce fichier definit la couche d'abstraction entre SPIP et ses serveurs SQL.
17 * Cette version 1 est un ensemble de fonctions ecrites rapidement
18 * pour generaliser le code strictement MySQL de SPIP <= 1.9.2
19 * Des retouches sont a prevoir apres l'experience des premiers portages.
20 * Les symboles sql_* (constantes et nom de fonctions) sont reserves
21 * a cette interface, sans quoi le gestionnaire de version dysfonctionnera.
22 *
23 * @package SPIP\SQL\API
24 * @version 1
25 */
26
27 if (!defined('_ECRIRE_INC_VERSION')) return;
28
29 /** Version de l'API SQL */
30 define('sql_ABSTRACT_VERSION', 1);
31 include_spip('base/connect_sql');
32
33
34
35 /**
36 * Charge le serveur de base de donnees
37 *
38 * Fonction principale. Elle charge l'interface au serveur de base de donnees
39 * via la fonction spip_connect_version qui etablira la connexion au besoin.
40 * Elle retourne la fonction produisant la requete SQL demandee
41 * Erreur fatale si la fonctionnalite est absente sauf si le 3e arg <> false
42 *
43 * @internal Cette fonction de base est appelee par les autres fonctions sql_*
44 * @param string $ins_sql
45 * Instruction de l'API SQL demandee (insertq, update, select...)
46 * @param string $serveur
47 * Nom du connecteur ('' pour celui par defaut a l'installation de SPIP)
48 * @param bool $continue
49 * true pour ne pas generer d'erreur si le serveur SQL ne dispose pas de la fonction demandee
50 * @return string|array
51 * Nom de la fonction a appeler pour l'instruction demandee pour le type de serveur SQL correspondant au fichier de connexion.
52 * Si l'instruction demandee n'existe pas, retourne la liste de toutes les instructions du serveur SQL avec $continue a true.
53 *
54 **/
55 function sql_serveur($ins_sql='', $serveur='', $continue=false) {
56 static $sql_serveur = array();
57 if (!isset($sql_serveur[$serveur][$ins_sql])){
58 $f = spip_connect_sql(sql_ABSTRACT_VERSION, $ins_sql, $serveur, $continue);
59 if (!is_string($f) OR !$f) return $f;
60 $sql_serveur[$serveur][$ins_sql] = $f;
61 }
62 return $sql_serveur[$serveur][$ins_sql];
63 }
64
65 /**
66 * Demande si un charset est disponible
67 *
68 * Demande si un charset (tel que utf-8) est disponible
69 * sur le gestionnaire de base de donnees de la connexion utilisee
70 *
71 * @api
72 * @see sql_set_charset() pour utiliser un charset
73 *
74 * @param string $charset
75 * Le charset souhaite
76 * @param string $serveur
77 * Le nom du connecteur
78 * @param bool $option
79 * Inutilise
80 * @return string|bool
81 * Retourne le nom du charset si effectivement trouve, sinon false.
82 **/
83 function sql_get_charset($charset, $serveur='', $option=true){
84 // le nom http du charset differe parfois du nom SQL utf-8 ==> utf8 etc.
85 $desc = sql_serveur('', $serveur, true,true);
86 $desc = $desc[sql_ABSTRACT_VERSION];
87 $c = $desc['charsets'][$charset];
88 if ($c) {
89 if (function_exists($f=@$desc['get_charset']))
90 if ($f($c, $serveur, $option!==false)) return $c;
91 }
92 spip_log( "SPIP ne connait pas les Charsets disponibles sur le serveur $serveur. Le serveur choisira seul.", _LOG_AVERTISSEMENT);
93 return false;
94 }
95
96
97 /**
98 * Regler le codage de connexion
99 *
100 * Affecte un charset (tel que utf-8) sur la connexion utilisee
101 * avec le gestionnaire de base de donnees
102 *
103 * @api
104 * @see sql_get_charset() pour tester l'utilisation d'un charset
105 *
106 * @param string $charset
107 * Le charset souhaite
108 * @param string $serveur
109 * Le nom du connecteur
110 * @param bool|string $option
111 * Peut avoir 2 valeurs :
112 * - true pour executer la requete.
113 * - continue pour ne pas echouer en cas de serveur sql indisponible.
114 *
115 * @return bool
116 * Retourne true si elle reussie.
117 **/
118 function sql_set_charset($charset,$serveur='', $option=true){
119 $f = sql_serveur('set_charset', $serveur, $option==='continue' OR $option===false);
120 if (!is_string($f) OR !$f) return false;
121 return $f($charset, $serveur, $option!==false);
122 }
123
124
125
126 /**
127 * Effectue une requete de selection
128 *
129 * Fonction de selection (SELECT), retournant la ressource interrogeable par sql_fetch.
130 *
131 * @api
132 * @see sql_fetch() Pour boucler sur les resultats de cette fonction
133 *
134 * @param array|string $select
135 * Liste des champs a recuperer (Select)
136 * @param array|string $from
137 * Tables a consulter (From)
138 * @param array|string $where
139 * Conditions a remplir (Where)
140 * @param array|string $groupby
141 * Critere de regroupement (Group by)
142 * @param array|string $orderby
143 * Tableau de classement (Order By)
144 * @param string $limit
145 * Critere de limite (Limit)
146 * @param array $having
147 * Tableau des des post-conditions a remplir (Having)
148 * @param string $serveur
149 * Le serveur sollicite (pour retrouver la connexion)
150 * @param bool|string $option
151 * Peut avoir 3 valeurs :
152 * - false -> ne pas l'executer mais la retourner,
153 * - continue -> ne pas echouer en cas de serveur sql indisponible,
154 * - true|array -> executer la requete.
155 * Le cas array est, pour une requete produite par le compilateur,
156 * un tableau donnnant le contexte afin d'indiquer le lieu de l'erreur au besoin
157 *
158 *
159 * @return mixed
160 * Ressource SQL
161 * - Ressource SQL pour sql_fetch, si la requete est correcte
162 * - false en cas d'erreur
163 * - Chaine contenant la requete avec $option=false
164 *
165 * Retourne false en cas d'erreur, apres l'avoir denoncee.
166 * Les portages doivent retourner la requete elle-meme en cas d'erreur,
167 * afin de disposer du texte brut.
168 *
169 **/
170 function sql_select ($select = array(), $from = array(), $where = array(),
171 $groupby = array(), $orderby = array(), $limit = '', $having = array(),
172 $serveur='', $option=true) {
173 $f = sql_serveur('select', $serveur, $option==='continue' OR $option===false);
174 if (!is_string($f) OR !$f) return false;
175
176 $debug = (defined('_VAR_MODE') AND _VAR_MODE == 'debug');
177 if (($option !== false) AND !$debug) {
178 $res = $f($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, is_array($option) ? true : $option);
179 } else {
180 $query = $f($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, false);
181 if (!$option) return $query;
182 // le debug, c'est pour ce qui a ete produit par le compilateur
183 if (isset($GLOBALS['debug']['aucasou'])) {
184 list($table, $id,) = $GLOBALS['debug']['aucasou'];
185 $nom = $GLOBALS['debug_objets']['courant'] . $id;
186 $GLOBALS['debug_objets']['requete'][$nom] = $query;
187 }
188 $res = $f($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, true);
189 }
190
191 // en cas d'erreur
192 if (!is_string($res)) return $res;
193 // denoncer l'erreur SQL dans sa version brute
194 spip_sql_erreur($serveur);
195 // idem dans sa version squelette (prefixe des tables non substitue)
196 erreur_squelette(array(sql_errno($serveur), sql_error($serveur), $res), $option);
197 return false;
198 }
199
200
201 /**
202 * Recupere la syntaxe de la requete select sans l'executer
203 *
204 * Passe simplement $option a false au lieu de true
205 * sans obliger a renseigner tous les arguments de sql_select.
206 * Les autres parametres sont identiques.
207 *
208 * @api
209 * @uses sql_select()
210 *
211 * @param array|string $select
212 * Liste des champs a recuperer (Select)
213 * @param array|string $from
214 * Tables a consulter (From)
215 * @param array|string $where
216 * Conditions a remplir (Where)
217 * @param array|string $groupby
218 * Critere de regroupement (Group by)
219 * @param array|string $orderby
220 * Tableau de classement (Order By)
221 * @param string $limit
222 * Critere de limite (Limit)
223 * @param array $having
224 * Tableau des des post-conditions a remplir (Having)
225 * @param string $serveur
226 * Le serveur sollicite (pour retrouver la connexion)
227 *
228 * @return mixed
229 * Chaine contenant la requete
230 * ou false en cas d'erreur
231 *
232 **/
233 function sql_get_select($select = array(), $from = array(), $where = array(),
234 $groupby = array(), $orderby = array(), $limit = '', $having = array(),
235 $serveur='') {
236 return sql_select ($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, false);
237 }
238
239
240 /**
241 * Retourne le nombre de lignes d'une selection
242 *
243 * Ramene seulement et tout de suite le nombre de lignes
244 * Pas de colonne ni de tri a donner donc.
245 *
246 * @api
247 *
248 * @param array|string $from
249 * Tables a consulter (From)
250 * @param array|string $where
251 * Conditions a remplir (Where)
252 * @param array|string $groupby
253 * Critere de regroupement (Group by)
254 * @param array $having
255 * Tableau des des post-conditions a remplir (Having)
256 * @param string $serveur
257 * Le serveur sollicite (pour retrouver la connexion)
258 * @param bool|string $option
259 * Peut avoir 3 valeurs :
260 * - false -> ne pas l'executer mais la retourner,
261 * - continue -> ne pas echouer en cas de serveur sql indisponible,
262 * - true -> executer la requete.
263 *
264 * @return int|bool
265 * Nombre de lignes de resultat
266 * ou false en cas d'erreur
267 *
268 **/
269 function sql_countsel($from = array(), $where = array(),
270 $groupby = array(), $having = array(),
271 $serveur='', $option=true) {
272 $f = sql_serveur('countsel', $serveur, $option==='continue' OR $option===false);
273 if (!is_string($f) OR !$f) return false;
274 $r = $f($from, $where, $groupby, $having, $serveur, $option!==false);
275 if ($r===false) spip_sql_erreur($serveur);
276 return $r;
277 }
278
279 /**
280 * Modifie la structure de la base de donnees
281 *
282 * Effectue une operation ALTER.
283 *
284 * @example
285 * <code>sql_alter('DROP COLUMN supprimer');</code>
286 *
287 * @api
288 * @param string $q
289 * La requete a executer (sans la preceder de 'ALTER ')
290 * @param string $serveur
291 * Le serveur sollicite (pour retrouver la connexion)
292 * @param bool|string $option
293 * Peut avoir 2 valeurs :
294 * - true -> executer la requete
295 * - continue -> ne pas echouer en cas de serveur sql indisponible
296 * @return mixed
297 * 2 possibilites :
298 * - Incertain en cas d'execution correcte de la requete
299 * - false en cas de serveur indiponible ou d'erreur
300 * Ce retour n'est pas pertinent pour savoir si l'operation est correctement realisee.
301 **/
302 function sql_alter($q, $serveur='', $option=true) {
303 $f = sql_serveur('alter', $serveur, $option==='continue' OR $option===false);
304 if (!is_string($f) OR !$f) return false;
305 $r = $f($q, $serveur, $option!==false);
306 if ($r===false) spip_sql_erreur($serveur);
307 return $r;
308 }
309
310 /**
311 * Retourne un enregistrement d'une selection
312 *
313 * Retourne un resultat d'une ressource obtenue avec sql_select()
314 *
315 * @api
316 * @param mixed
317 * Ressource retournee par sql_select()
318 * @param string $serveur
319 * Le nom du connecteur
320 * @param bool|string $option
321 * Peut avoir 2 valeurs :
322 * - true -> executer la requete
323 * - continue -> ne pas echouer en cas de serveur sql indisponible
324 *
325 * @return array
326 * Tableau de cles (colonnes SQL ou alias) / valeurs (valeurs dans la colonne de la table ou calculee)
327 * presentant une ligne de resultat d'une selection
328 */
329 function sql_fetch($res, $serveur='', $option=true) {
330 $f = sql_serveur('fetch', $serveur, $option==='continue' OR $option===false);
331 if (!is_string($f) OR !$f) return false;
332 return $f($res, NULL, $serveur, $option!==false);
333 }
334
335
336 /**
337 * Retourne tous les enregistrements d'une selection
338 *
339 * Retourne tous les resultats d'une ressource obtenue avec sql_select()
340 * dans un tableau
341 *
342 * @api
343 * @param mixed
344 * Ressource retournee par sql_select()
345 * @param string $serveur
346 * Le nom du connecteur
347 * @param bool|string $option
348 * Peut avoir 2 valeurs :
349 * - true -> executer la requete
350 * - continue -> ne pas echouer en cas de serveur sql indisponible
351 *
352 * @return array
353 * Tableau contenant les enregistrements.
354 * Chaque entree du tableau est un autre tableau
355 * de cles (colonnes SQL ou alias) / valeurs (valeurs dans la colonne de la table ou calculee)
356 * presentant une ligne de resultat d'une selection
357 */
358 function sql_fetch_all($res, $serveur='', $option=true){
359 $rows = array();
360 if (!$res) return $rows;
361 $f = sql_serveur('fetch', $serveur, $option==='continue' OR $option===false);
362 if (!is_string($f) OR !$f) return array();
363 while ($r = $f($res, NULL, $serveur, $option!==false))
364 $rows[] = $r;
365 sql_free($res, $serveur);
366 return $rows;
367 }
368
369 /**
370 * Deplace le pointeur d'une ressource de selection
371 *
372 * Deplace le pointeur sur un numero de ligne precise
373 * sur une ressource issue de sql_select, afin que
374 * le prochain sql_fetch recupere cette ligne.
375 *
376 * @api
377 * @see sql_skip() Pour sauter des enregistrements
378 *
379 * @param mixed $res
380 * Ressource issue de sql_select
381 * @param int $row_number
382 * Numero de ligne sur laquelle placer le pointeur
383 * @param string $serveur
384 * Le nom du connecteur
385 * @param bool|string $option
386 * Peut avoir 2 valeurs :
387 * - true -> executer la requete
388 * - continue -> ne pas echouer en cas de serveur sql indisponible
389 *
390 * @return bool
391 * Operation effectuee (true), sinon false.
392 **/
393 function sql_seek($res, $row_number, $serveur='', $option=true) {
394 $f = sql_serveur('seek', $serveur, $option==='continue' OR $option===false);
395 if (!is_string($f) OR !$f) return false;
396 $r = $f($res, $row_number, $serveur, $option!==false);
397 if ($r===false) spip_sql_erreur($serveur);
398 return $r;
399 }
400
401
402 /**
403 * Liste des bases de donnees accessibles
404 *
405 * Retourne un tableau du nom de toutes les bases de donnees
406 * accessibles avec les permissions de l'utilisateur SQL
407 * de cette connexion.
408 * Attention on n'a pas toujours les droits !
409 *
410 * @api
411 * @param string $serveur
412 * Nom du connecteur
413 * @param bool|string $option
414 * Peut avoir 2 valeurs :
415 * - true -> executer la requete
416 * - continue -> ne pas echouer en cas de serveur sql indisponible
417 *
418 * @return array|bool
419 * Tableau contenant chaque nom de base de donnees.
420 * False en cas d'erreur.
421 **/
422 function sql_listdbs($serveur='', $option=true) {
423 $f = sql_serveur('listdbs', $serveur, $option==='continue' OR $option===false);
424 if (!is_string($f) OR !$f) return false;
425 $r = $f($serveur);
426 if ($r===false) spip_sql_erreur($serveur);
427 return $r;
428 }
429
430
431 /**
432 * Demande d'utiliser d'une base de donnees
433 *
434 * @api
435 * @param string $nom
436 * Nom de la base a utiliser
437 * @param string $serveur
438 * Nom du connecteur
439 * @param bool|string $option
440 * Peut avoir 2 valeurs :
441 * - true -> executer la requete
442 * - continue -> ne pas echouer en cas de serveur sql indisponible
443 *
444 * @return bool|string
445 * True ou nom de la base en cas de success.
446 * False en cas d'erreur.
447 **/
448 function sql_selectdb($nom, $serveur='', $option=true)
449 {
450 $f = sql_serveur('selectdb', $serveur, $option==='continue' OR $option===false);
451 if (!is_string($f) OR !$f) return false;
452 $r = $f($nom, $serveur, $option!==false);
453 if ($r===false) spip_sql_erreur($serveur);
454 return $r;
455 }
456
457 // http://doc.spip.org/@sql_count
458 function sql_count($res, $serveur='', $option=true)
459 {
460 $f = sql_serveur('count', $serveur, $option==='continue' OR $option===false);
461 if (!is_string($f) OR !$f) return false;
462 $r = $f($res, $serveur, $option!==false);
463 if ($r===false) spip_sql_erreur($serveur);
464 return $r;
465 }
466
467 // http://doc.spip.org/@sql_free
468 function sql_free($res, $serveur='', $option=true)
469 {
470 $f = sql_serveur('free', $serveur, $option==='continue' OR $option===false);
471 if (!is_string($f) OR !$f) return false;
472 return $f($res);
473 }
474
475 // Cette fonction ne garantit pas une portabilite totale
476 // ===> lui preferer la suivante.
477 // Elle est fournie pour permettre l'actualisation de vieux codes
478 // par un Sed brutal qui peut donner des resultats provisoirement acceptables
479 // http://doc.spip.org/@sql_insert
480 function sql_insert($table, $noms, $valeurs, $desc=array(), $serveur='', $option=true)
481 {
482 $f = sql_serveur('insert', $serveur, $option==='continue' OR $option===false);
483 if (!is_string($f) OR !$f) return false;
484 $r = $f($table, $noms, $valeurs, $desc, $serveur, $option!==false);
485 if ($r === false) spip_sql_erreur($serveur);
486 return $r;
487 }
488
489 // http://doc.spip.org/@sql_insertq
490 function sql_insertq($table, $couples=array(), $desc=array(), $serveur='', $option=true)
491 {
492 $f = sql_serveur('insertq', $serveur, $option==='continue' OR $option===false);
493 if (!is_string($f) OR !$f) return false;
494 $r = $f($table, $couples, $desc, $serveur, $option!==false);
495 if ($r === false) spip_sql_erreur($serveur);
496 return $r;
497 }
498
499 // http://doc.spip.org/@sql_insertq_multi
500 function sql_insertq_multi($table, $couples=array(), $desc=array(), $serveur='', $option=true)
501 {
502 $f = sql_serveur('insertq_multi', $serveur, $option==='continue' OR $option===false);
503 if (!is_string($f) OR !$f) return false;
504 $r = $f($table, $couples, $desc, $serveur, $option!==false);
505 if ($r === false) spip_sql_erreur($serveur);
506 return $r;
507 }
508
509 // http://doc.spip.org/@sql_update
510 function sql_update($table, $exp, $where='', $desc=array(), $serveur='', $option=true)
511 {
512 $f = sql_serveur('update', $serveur, $option==='continue' OR $option===false);
513 if (!is_string($f) OR !$f) return false;
514 $r = $f($table, $exp, $where, $desc, $serveur, $option!==false);
515 if ($r === false) spip_sql_erreur($serveur);
516 return $r;
517 }
518
519 // Update est presque toujours appelee sur des constantes ou des dates
520 // Cette fonction est donc plus utile que la precedente,d'autant qu'elle
521 // permet de gerer les differences de representation des constantes.
522 // http://doc.spip.org/@sql_updateq
523 function sql_updateq($table, $exp, $where='', $desc=array(), $serveur='', $option=true)
524 {
525 $f = sql_serveur('updateq', $serveur, $option==='continue' OR $option===false);
526 if (!is_string($f) OR !$f) return false;
527 $r = $f($table, $exp, $where, $desc, $serveur, $option!==false);
528 if ($r === false) spip_sql_erreur($serveur);
529 return $r;
530 }
531
532 // http://doc.spip.org/@sql_delete
533 function sql_delete($table, $where='', $serveur='', $option=true)
534 {
535 $f = sql_serveur('delete', $serveur, $option==='continue' OR $option===false);
536 if (!is_string($f) OR !$f) return false;
537 $r = $f($table, $where, $serveur, $option!==false);
538 if ($r === false) spip_sql_erreur($serveur);
539 return $r;
540 }
541
542 // http://doc.spip.org/@sql_replace
543 function sql_replace($table, $couples, $desc=array(), $serveur='', $option=true)
544 {
545 $f = sql_serveur('replace', $serveur, $option==='continue' OR $option===false);
546 if (!is_string($f) OR !$f) return false;
547 $r = $f($table, $couples, $desc, $serveur, $option!==false);
548 if ($r === false) spip_sql_erreur($serveur);
549 return $r;
550 }
551
552
553 // http://doc.spip.org/@sql_replace_multi
554 function sql_replace_multi($table, $tab_couples, $desc=array(), $serveur='', $option=true)
555 {
556 $f = sql_serveur('replace_multi', $serveur, $option==='continue' OR $option===false);
557 if (!is_string($f) OR !$f) return false;
558 $r = $f($table, $tab_couples, $desc, $serveur, $option!==false);
559 if ($r === false) spip_sql_erreur($serveur);
560 return $r;
561 }
562
563 // http://doc.spip.org/@sql_drop_table
564 function sql_drop_table($table, $exist='', $serveur='', $option=true)
565 {
566 $f = sql_serveur('drop_table', $serveur, $option==='continue' OR $option===false);
567 if (!is_string($f) OR !$f) return false;
568 $r = $f($table, $exist, $serveur, $option!==false);
569 if ($r === false) spip_sql_erreur($serveur);
570 return $r;
571 }
572
573 // supprimer une vue sql
574 // http://doc.spip.org/@sql_drop_view
575 function sql_drop_view($table, $exist='', $serveur='', $option=true)
576 {
577 $f = sql_serveur('drop_view', $serveur, $option==='continue' OR $option===false);
578 if (!is_string($f) OR !$f) return false;
579 $r = $f($table, $exist, $serveur, $option!==false);
580 if ($r === false) spip_sql_erreur($serveur);
581 return $r;
582 }
583
584 /**
585 * Retourne une ressource de la liste des tables de la base de données
586 *
587 * @api
588 * @param string $spip
589 * Filtre sur tables retournées
590 * - NULL : retourne les tables SPIP uniquement (tables préfixées avec le préfixe de la connexion)
591 * - '%' : retourne toutes les tables de la base
592 * @param string $serveur
593 * Le nom du connecteur
594 * @param bool|string $option
595 * Peut avoir 3 valeurs :
596 * - false -> ne pas l'executer mais la retourner,
597 * - continue -> ne pas echouer en cas de serveur sql indisponible,
598 * - true -> executer la requete.
599 * @return ressource
600 * Ressource à utiliser avec sql_fetch()
601 **/
602 function sql_showbase($spip=NULL, $serveur='', $option=true)
603 {
604 $f = sql_serveur('showbase', $serveur, $option==='continue' OR $option===false);
605 if (!is_string($f) OR !$f) return false;
606
607 // la globale n'est remplie qu'apres l'appel de sql_serveur.
608 if ($spip == NULL){
609 $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
610 $spip = $connexion['prefixe'] . '\_%';
611 }
612
613 return $f($spip, $serveur, $option!==false);
614 }
615
616 /**
617 * Retourne la liste des tables SQL
618 *
619 * @api
620 * @uses sql_showbase()
621 * @param string $spip
622 * Filtre sur tables retournées
623 * - NULL : retourne les tables SPIP uniquement (tables préfixées avec le préfixe de la connexion)
624 * - '%' : retourne toutes les tables de la base
625 * @param string $serveur
626 * Le nom du connecteur
627 * @param bool|string $option
628 * Peut avoir 3 valeurs :
629 * - false -> ne pas l'executer mais la retourner,
630 * - continue -> ne pas echouer en cas de serveur sql indisponible,
631 * - true -> executer la requete.
632 * @return array
633 * Liste des tables SQL
634 **/
635 function sql_alltable($spip=NULL, $serveur='', $option=true)
636 {
637 $q = sql_showbase($spip, $serveur, $option);
638 $r = array();
639 if ($q) while ($t = sql_fetch($q, $serveur)) { $r[] = array_shift($t);}
640 return $r;
641 }
642
643 // http://doc.spip.org/@sql_showtable
644 function sql_showtable($table, $table_spip = false, $serveur='', $option=true)
645 {
646 $f = sql_serveur('showtable', $serveur, $option==='continue' OR $option===false);
647 if (!is_string($f) OR !$f) return false;
648
649 // la globale n'est remplie qu'apres l'appel de sql_serveur.
650 if ($table_spip){
651 $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
652 $prefixe = $connexion['prefixe'];
653 $vraie_table = preg_replace('/^spip/', $prefixe, $table);
654 } else $vraie_table = $table;
655
656 $f = $f($vraie_table, $serveur, $option!==false);
657 if (!$f) return array();
658 if (isset($GLOBALS['tables_principales'][$table]['join']))
659 $f['join'] = $GLOBALS['tables_principales'][$table]['join'];
660 elseif (isset($GLOBALS['tables_auxiliaires'][$table]['join']))
661 $f['join'] = $GLOBALS['tables_auxiliaires'][$table]['join'];
662 return $f;
663 }
664
665 // http://doc.spip.org/@sql_create
666 function sql_create($nom, $champs, $cles=array(), $autoinc=false, $temporary=false, $serveur='', $option=true) {
667 $f = sql_serveur('create', $serveur, $option==='continue' OR $option===false);
668 if (!is_string($f) OR !$f) return false;
669 $r = $f($nom, $champs, $cles, $autoinc, $temporary, $serveur, $option!==false);
670 if ($r === false) spip_sql_erreur($serveur);
671 return $r;
672 }
673
674 function sql_create_base($nom, $serveur='', $option=true)
675 {
676 $f = sql_serveur('create_base', $serveur, $option==='continue' OR $option===false);
677 if (!is_string($f) OR !$f) return false;
678 $r = $f($nom, $serveur, $option!==false);
679 if ($r === false) spip_sql_erreur($serveur);
680 return $r;
681 }
682
683 // Fonction pour creer une vue
684 // nom : nom de la vue,
685 // select_query : une requete select, idealement cree avec $req = sql_select()
686 // (en mettant $option du sql_select a false pour recuperer la requete)
687 // http://doc.spip.org/@sql_create_view
688 function sql_create_view($nom, $select_query, $serveur='', $option=true) {
689 $f = sql_serveur('create_view', $serveur, $option==='continue' OR $option===false);
690 if (!is_string($f) OR !$f) return false;
691 $r = $f($nom, $select_query, $serveur, $option!==false);
692 if ($r === false) spip_sql_erreur($serveur);
693 return $r;
694 }
695
696 // http://doc.spip.org/@sql_multi
697 function sql_multi($sel, $lang, $serveur='', $option=true)
698 {
699 $f = sql_serveur('multi', $serveur, $option==='continue' OR $option===false);
700 if (!is_string($f) OR !$f) return false;
701 return $f($sel, $lang);
702 }
703
704
705 /**
706 * Retourne la dernière erreur connue
707 *
708 * @api
709 * @param string $serveur
710 * Nom du connecteur
711 * @return bool|string
712 * Description de l'erreur
713 * False si le serveur est indisponible
714 */
715 function sql_error($serveur='') {
716 $f = sql_serveur('error', $serveur, 'continue');
717 if (!is_string($f) OR !$f) return false;
718 return $f('query inconnue', $serveur);
719 }
720
721 /**
722 * Retourne le numéro de la derniere erreur connue
723 *
724 * @api
725 * @param string $serveur
726 * Nom du connecteur
727 * @return bool|int
728 * Numéro de l'erreur
729 * False si le serveur est indisponible
730 */
731 function sql_errno($serveur='') {
732 $f = sql_serveur('errno', $serveur, 'continue');
733 if (!is_string($f) OR !$f) return false;
734 return $f($serveur);
735 }
736
737 // http://doc.spip.org/@sql_explain
738 function sql_explain($q, $serveur='', $option=true) {
739 $f = sql_serveur('explain', $serveur, 'continue');
740 if (!is_string($f) OR !$f) return false;
741 $r = $f($q, $serveur, $option!==false);
742 if ($r === false) spip_sql_erreur($serveur);
743 return $r;
744 }
745
746 // http://doc.spip.org/@sql_optimize
747 function sql_optimize($table, $serveur='', $option=true) {
748 $f = sql_serveur('optimize', $serveur, $option==='continue' OR $option===false);
749 if (!is_string($f) OR !$f) return false;
750 $r = $f($table, $serveur, $option!==false);
751 if ($r === false) spip_sql_erreur($serveur);
752 return $r;
753 }
754
755 // http://doc.spip.org/@sql_repair
756 function sql_repair($table, $serveur='', $option=true) {
757 $f = sql_serveur('repair', $serveur, $option==='continue' OR $option===false);
758 if (!is_string($f) OR !$f) return false;
759 $r = $f($table, $serveur, $option!==false);
760 if ($r === false) spip_sql_erreur($serveur);
761 return $r;
762 }
763
764 // Fonction la plus generale ... et la moins portable
765 // A n'utiliser qu'en derniere extremite
766
767 // http://doc.spip.org/@sql_query
768 function sql_query($ins, $serveur='', $option=true) {
769 $f = sql_serveur('query', $serveur, $option==='continue' OR $option===false);
770 if (!is_string($f) OR !$f) return false;
771 $r = $f($ins, $serveur, $option!==false);
772 if ($r === false) spip_sql_erreur($serveur);
773 return $r;
774 }
775
776 /**
777 * Retourne la premiere ligne d'une selection
778 *
779 * Retourne la premiere ligne de resultat d'une selection
780 * comme si l'on appelait successivement sql_select() puis sql_fetch()
781 *
782 * @example
783 * <code>
784 * $art = sql_fetsel(array('id_rubrique','id_secteur'), 'spip_articles', 'id_article='.sql_quote($id_article));
785 * $id_rubrique = $art['id_rubrique'];
786 * </code>
787 *
788 * @api
789 * @uses sql_select()
790 * @uses sql_fetch()
791 *
792 * @param array|string $select
793 * Liste des champs a recuperer (Select)
794 * @param array|string $from
795 * Tables a consulter (From)
796 * @param array|string $where
797 * Conditions a remplir (Where)
798 * @param array|string $groupby
799 * Critere de regroupement (Group by)
800 * @param array|string $orderby
801 * Tableau de classement (Order By)
802 * @param string $limit
803 * Critere de limite (Limit)
804 * @param array $having
805 * Tableau des des post-conditions a remplir (Having)
806 * @param string $serveur
807 * Le serveur sollicite (pour retrouver la connexion)
808 * @param bool|string $option
809 * Peut avoir 3 valeurs :
810 * - true -> executer la requete.
811 * - continue -> ne pas echouer en cas de serveur sql indisponible.
812 * - false -> ne pas l'executer mais la retourner.
813 *
814 * @return array
815 * Tableau de la premiere ligne de resultat de la selection
816 * {@example
817 * <code>array('id_rubrique' => 1, 'id_secteur' => 2)</code>
818 * }
819 *
820 **/
821 function sql_fetsel($select = array(), $from = array(), $where = array(),
822 $groupby = array(), $orderby = array(), $limit = '',
823 $having = array(), $serveur='', $option=true) {
824 $q = sql_select($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, $option);
825 if ($option===false) return $q;
826 if (!$q) return array();
827 $r = sql_fetch($q, $serveur, $option);
828 sql_free($q, $serveur, $option);
829 return $r;
830 }
831
832
833 /**
834 * Retourne le tableau de toutes les lignes d'une selection
835 *
836 * Retourne toutes les lignes de resultat d'une selection
837 * comme si l'on appelait successivement sql_select() puis while(sql_fetch())
838 *
839 * @example
840 * <code>
841 * $rubs = sql_allfetsel('id_rubrique', 'spip_articles', 'id_secteur='.sql_quote($id_secteur));
842 * // $rubs = array(array('id_rubrique'=>1), array('id_rubrique'=>3, ...)
843 * </code>
844 *
845 * @api
846 * @uses sql_select()
847 * @uses sql_fetch()
848 *
849 * @param array|string $select
850 * Liste des champs a recuperer (Select)
851 * @param array|string $from
852 * Tables a consulter (From)
853 * @param array|string $where
854 * Conditions a remplir (Where)
855 * @param array|string $groupby
856 * Critere de regroupement (Group by)
857 * @param array|string $orderby
858 * Tableau de classement (Order By)
859 * @param string $limit
860 * Critere de limite (Limit)
861 * @param array $having
862 * Tableau des des post-conditions a remplir (Having)
863 * @param string $serveur
864 * Le serveur sollicite (pour retrouver la connexion)
865 * @param bool|string $option
866 * Peut avoir 3 valeurs :
867 * - true -> executer la requete.
868 * - continue -> ne pas echouer en cas de serveur sql indisponible.
869 * - false -> ne pas l'executer mais la retourner.
870 *
871 * @return array
872 * Tableau de toutes les lignes de resultat de la selection
873 * Chaque entree contient un tableau des elements demandees dans le SELECT.
874 * {@example
875 * <code>
876 * array(
877 * array('id_rubrique' => 1, 'id_secteur' => 2)
878 * array('id_rubrique' => 4, 'id_secteur' => 2)
879 * ...
880 * )
881 * </code>
882 * }
883 *
884 **/
885 function sql_allfetsel($select = array(), $from = array(), $where = array(),
886 $groupby = array(), $orderby = array(), $limit = '',
887 $having = array(), $serveur='', $option=true) {
888 $q = sql_select($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, $option);
889 if ($option===false) return $q;
890 return sql_fetch_all($q, $serveur, $option);
891 }
892
893
894 /**
895 * Retourne un unique champ d'une selection
896 *
897 * Retourne dans la premiere ligne de resultat d'une selection
898 * un unique champ demande
899 *
900 * @example
901 * <code>
902 * $id_rubrique = sql_getfetsel('id_rubrique', 'spip_articles', 'id_article='.sql_quote($id_article));
903 * </code>
904 *
905 * @api
906 * @uses sql_fetsel()
907 *
908 * @param array|string $select
909 * Liste des champs a recuperer (Select)
910 * @param array|string $from
911 * Tables a consulter (From)
912 * @param array|string $where
913 * Conditions a remplir (Where)
914 * @param array|string $groupby
915 * Critere de regroupement (Group by)
916 * @param array|string $orderby
917 * Tableau de classement (Order By)
918 * @param string $limit
919 * Critere de limite (Limit)
920 * @param array $having
921 * Tableau des des post-conditions a remplir (Having)
922 * @param string $serveur
923 * Le serveur sollicite (pour retrouver la connexion)
924 * @param bool|string $option
925 * Peut avoir 3 valeurs :
926 * - true -> executer la requete.
927 * - continue -> ne pas echouer en cas de serveur sql indisponible.
928 * - false -> ne pas l'executer mais la retourner.
929 *
930 * @return mixed
931 * Contenu de l'unique valeur demandee du premier enregistrement retourne
932 *
933 **/
934 function sql_getfetsel($select, $from = array(), $where = array(), $groupby = array(),
935 $orderby = array(), $limit = '', $having = array(), $serveur='', $option=true) {
936 if (preg_match('/\s+as\s+(\w+)$/i', $select, $c)) $id = $c[1];
937 elseif (!preg_match('/\W/', $select)) $id = $select;
938 else {$id = 'n'; $select .= ' AS n';}
939 $r = sql_fetsel($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, $option);
940 if ($option===false) return $r;
941 if (!$r) return NULL;
942 return $r[$id];
943 }
944
945 /**
946 * Retourne le numero de version du serveur SQL
947 *
948 * @api
949 * @param string $serveur
950 * Nom du connecteur
951 * @param bool|string $option
952 * Peut avoir 2 valeurs :
953 * - true pour executer la requete.
954 * - continue pour ne pas echouer en cas de serveur sql indisponible.
955 *
956 * @return string
957 * Numero de version du serveur SQL
958 **/
959 function sql_version($serveur='', $option=true) {
960 $row = sql_fetsel("version() AS n", '','','','','','',$serveur);
961 return ($row['n']);
962 }
963
964 /**
965 * Informe si le moteur SQL prefere utiliser des transactions
966 *
967 * Cette fonction experimentale est pour l'instant presente pour accelerer certaines
968 * insertions multiples en SQLite, en les encadrant d'une transaction.
969 * SQLite ne cree alors qu'un verrou pour l'ensemble des insertions
970 * et non un pour chaque, ce qui accelere grandement le processus.
971 * Evidemment, si une des insertions echoue, rien ne sera enregistre.
972 * Pour ne pas perturber les autres moteurs, cette fonction permet
973 * de verifier que le moteur prefere utiliser des transactions dans ce cas.
974 *
975 * @example
976 * <code>
977 * if (sql_preferer_transaction()) {
978 * sql_demarrer_transaction();
979 * }
980 * </code>
981 *
982 * @api
983 * @see sql_demarrer_transaction()
984 * @see sql_terminer_transaction()
985 *
986 * @param string $serveur
987 * Nom du connecteur
988 * @param bool|string $option
989 * Peut avoir 2 valeurs :
990 * - true pour executer la requete.
991 * - continue pour ne pas echouer en cas de serveur sql indisponible.
992 *
993 * @return bool
994 * Le serveur SQL prefere t'il des transactions pour les insertions multiples ?
995 **/
996 function sql_preferer_transaction($serveur='', $option=true) {
997 $f = sql_serveur('preferer_transaction', $serveur, 'continue');
998 if (!is_string($f) OR !$f) return false;
999 $r = $f($serveur, $option!==false);
1000 if ($r === false) spip_sql_erreur($serveur);
1001 return $r;
1002 };
1003
1004 /**
1005 * Demarre une transaction
1006 *
1007 * @api
1008 * @see sql_terminer_transaction() Pour cloturer la transaction
1009 *
1010 * @param string $serveur
1011 * Nom du connecteur
1012 * @param bool|string $option
1013 * Peut avoir 3 valeurs :
1014 * - true pour executer la requete.
1015 * - continue pour ne pas echouer en cas de serveur sql indisponible.
1016 * - false pour obtenir le code de la requete
1017 *
1018 * @return bool
1019 * true si la transaction est demarree
1020 * false en cas d'erreur
1021 **/
1022 function sql_demarrer_transaction($serveur='', $option=true) {
1023 $f = sql_serveur('demarrer_transaction', $serveur, 'continue');
1024 if (!is_string($f) OR !$f) return false;
1025 $r = $f($serveur, $option!==false);
1026 if ($r === false) spip_sql_erreur($serveur);
1027 return $r;
1028 };
1029
1030 /**
1031 * Termine une transaction
1032 *
1033 * @api
1034 * @see sql_demarrer_transaction() Pour demarrer une transaction
1035 *
1036 * @param string $serveur
1037 * Nom du connecteur
1038 * @param bool|string $option
1039 * Peut avoir 3 valeurs :
1040 * - true pour executer la requete.
1041 * - continue pour ne pas echouer en cas de serveur sql indisponible.
1042 * - false pour obtenir le code de la requete
1043 *
1044 * @return bool
1045 * true si la transaction est demarree
1046 * false en cas d'erreur
1047 **/
1048 function sql_terminer_transaction($serveur='', $option=true) {
1049 $f = sql_serveur('terminer_transaction', $serveur, 'continue');
1050 if (!is_string($f) OR !$f) return false;
1051 $r = $f($serveur, $option!==false);
1052 if ($r === false) spip_sql_erreur($serveur);
1053 return $r;
1054 };
1055
1056
1057 /**
1058 * Prepare une chaine hexadecimale
1059 *
1060 * Prend une chaine sur l'aphabet hexa
1061 * et retourne sa representation numerique attendue par le serveur SQL.
1062 * Par exemple : FF ==> 0xFF en MySQL mais x'FF' en PG
1063 *
1064 * @api
1065 * @param string $val
1066 * Chaine hexadecimale
1067 * @param string $serveur
1068 * Nom du connecteur
1069 * @param bool|string $option
1070 * Peut avoir 2 valeurs :
1071 * - true pour executer la demande.
1072 * - continue pour ne pas echouer en cas de serveur sql indisponible.
1073 * @return string
1074 * Retourne la valeur hexadecimale attendue par le serveur SQL
1075 **/
1076 function sql_hex($val, $serveur='', $option=true)
1077 {
1078 $f = sql_serveur('hex', $serveur, $option==='continue' OR $option===false);
1079 if (!is_string($f) OR !$f) return false;
1080 return $f($val);
1081 }
1082
1083 /**
1084 * Echapper du contenu
1085 *
1086 * Echappe du contenu selon ce qu'attend le type de serveur SQL
1087 * et en fonction du type de contenu.
1088 *
1089 * Cette fonction est automatiquement appelee par les fonctions sql_*q
1090 * tel que sql_instertq ou sql_updateq
1091 *
1092 * @api
1093 * @param string $val
1094 * Chaine a echapper
1095 * @param string $serveur
1096 * Nom du connecteur
1097 * @param string $type
1098 * Peut contenir une declaration de type de champ SQL
1099 * {@example <code>int NOT NULL</code>} qui sert alors aussi a calculer le type d'echappement
1100 * @return string
1101 * La chaine echappee
1102 **/
1103 function sql_quote($val, $serveur='', $type='')
1104 {
1105 $f = sql_serveur('quote', $serveur, true);
1106 if (!is_string($f) OR !$f) $f = '_q';
1107 return $f($val, $type);
1108 }
1109
1110 function sql_date_proche($champ, $interval, $unite, $serveur='', $option=true)
1111 {
1112 $f = sql_serveur('date_proche', $serveur, true);
1113 if (!is_string($f) OR !$f) return false;
1114 return $f($champ, $interval, $unite);
1115 }
1116
1117 /**
1118 * Retourne une expression IN pour le gestionnaire de base de données
1119 *
1120 * Retourne un code à insérer dans une requête SQL pour récupérer
1121 * les éléments d'une colonne qui appartiennent à une liste donnée
1122 *
1123 * @example
1124 * sql_in('id_rubrique', array(3,4,5))
1125 * retourne approximativement «id_rubrique IN (3,4,5)» selon ce qu'attend
1126 * le gestionnaire de base de donnée du connecteur en cours.
1127 *
1128 * @api
1129 * @param string $val
1130 * Colonne SQL sur laquelle appliquer le test
1131 * @param string|array $valeurs
1132 * Liste des valeurs possibles (séparés par des virgules si string)
1133 * @param string $not
1134 * - '' sélectionne les éléments correspondant aux valeurs
1135 * - 'NOT' inverse en sélectionnant les éléments ne correspondant pas aux valeurs
1136 * @param string $serveur
1137 * Nom du connecteur
1138 * @param bool|string $option
1139 * Peut avoir 2 valeurs :
1140 * - continue -> ne pas echouer en cas de serveur sql indisponible
1141 * - true ou false -> retourne l'expression
1142 * @return string
1143 * Expression de requête SQL
1144 **/
1145 function sql_in($val, $valeurs, $not='', $serveur='', $option=true) {
1146 if (is_array($valeurs)) {
1147 $f = sql_serveur('quote', $serveur, true);
1148 if (!is_string($f) OR !$f) return false;
1149 $valeurs = join(',', array_map($f, array_unique($valeurs)));
1150 } elseif (isset($valeurs[0]) AND $valeurs[0]===',') $valeurs = substr($valeurs,1);
1151 if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1');
1152
1153 $f = sql_serveur('in', $serveur, $option==='continue' OR $option===false);
1154 if (!is_string($f) OR !$f) return false;
1155 return $f($val, $valeurs, $not, $serveur, $option!==false);
1156 }
1157
1158 // Penser a dire dans la description du serveur
1159 // s'il accepte les requetes imbriquees afin d'optimiser ca
1160
1161 // http://doc.spip.org/@sql_in_select
1162 function sql_in_select($in, $select, $from = array(), $where = array(),
1163 $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur='')
1164 {
1165 $liste = array();
1166 $res = sql_select($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur);
1167 while ($r = sql_fetch($res)) {$liste[] = array_shift($r);}
1168 sql_free($res);
1169 return sql_in($in, $liste);
1170 }
1171
1172 /**
1173 * Implementation securisee du saut en avant,
1174 * qui ne depend pas de la disponibilite de la fonction sql_seek
1175 * ne fait rien pour une valeur negative ou nulle de $saut
1176 * retourne la position apres le saut
1177 *
1178 * @see sql_seek()
1179 *
1180 * @param resource $res
1181 * Ressource issue d'une selection sql_select
1182 * @param int $pos
1183 * position courante
1184 * @param int $saut
1185 * saut demande
1186 * @param int $count
1187 * position maximale
1188 * (nombre de resultat de la requete OU position qu'on ne veut pas depasser)
1189 * @param string $serveur
1190 * Nom du connecteur
1191 * @param bool|string $option
1192 * Peut avoir 2 valeurs :
1193 * - true -> executer la requete
1194 * - continue -> ne pas echouer en cas de serveur sql indisponible
1195 *
1196 * @return int
1197 * Position apres le saut.
1198 */
1199 function sql_skip($res, $pos, $saut, $count, $serveur='', $option=true){
1200 // pas de saut en arriere qu'on ne sait pas faire sans sql_seek
1201 if (($saut=intval($saut))<=0) return $pos;
1202
1203 $seek = $pos + $saut;
1204 // si le saut fait depasser le maxi, on libere la resource
1205 // et on sort
1206 if ($seek>=$count) {sql_free($res, $serveur, $option); return $count;}
1207
1208 if (sql_seek($res, $seek))
1209 $pos = $seek;
1210 else
1211 while ($pos<$seek AND sql_fetch($res, $serveur, $option))
1212 $pos++;
1213 return $pos;
1214 }
1215
1216 // http://doc.spip.org/@sql_test_int
1217 function sql_test_int($type, $serveur='', $option=true)
1218 {
1219 return preg_match('/^(TINYINT|SMALLINT|MEDIUMINT|INT|INTEGER|BIGINT)/i',trim($type));
1220 }
1221
1222 // http://doc.spip.org/@sql_test_date
1223 function sql_test_date($type, $serveur='', $option=true)
1224 {
1225 return preg_match('/^(DATE|DATETIME|TIMESTAMP|TIME)/i',trim($type));
1226 }
1227
1228 /**
1229 * Formate une date
1230 *
1231 * Formater une date Y-m-d H:i:s sans passer par mktime
1232 * qui ne sait pas gerer les dates < 1970
1233 *
1234 * http://doc.spip.org/@format_mysql_date
1235 *
1236 * @param int $annee Annee
1237 * @param int $mois Numero du mois
1238 * @param int $jour Numero du jour dans le mois
1239 * @param int $h Heures
1240 * @param int $m Minutes
1241 * @param int $s Secondes
1242 * @param string $serveur
1243 * Le serveur sollicite (pour retrouver la connexion)
1244 * @return string
1245 * La date formatee
1246 */
1247 function sql_format_date($annee=0, $mois=0, $jour=0, $h=0, $m=0, $s=0, $serveur=''){
1248 $annee = sprintf("%04s",$annee);
1249 $mois = sprintf("%02s",$mois);
1250
1251 if ($annee == "0000") $mois = 0;
1252 if ($mois == "00") $jour = 0;
1253
1254 return sprintf("%04u",$annee) . '-' . sprintf("%02u",$mois) . '-'
1255 . sprintf("%02u",$jour) . ' ' . sprintf("%02u",$h) . ':'
1256 . sprintf("%02u",$m) . ':' . sprintf("%02u",$s);
1257 }
1258
1259
1260
1261 /**
1262 * Retourne la description de la table SQL
1263 *
1264 * Retrouve la description de la table SQL en privilegiant
1265 * la structure reelle de la base de donnees.
1266 * En absence, ce qui arrive lors de l'installation, la fonction
1267 * s'appuie sur la declaration des tables SQL principales ou auxiliaires.
1268 *
1269 * @internal Cette fonction devrait disparaître
1270 *
1271 * @param string $nom
1272 * Nom de la table dont on souhait la description
1273 * @param string $serveur
1274 * Nom du connecteur
1275 * @return array|bool
1276 * Description de la table ou false si elle n'est pas trouvee ou declaree.
1277 **/
1278 function description_table($nom, $serveur=''){
1279
1280 global $tables_principales, $tables_auxiliaires;
1281 static $trouver_table;
1282
1283 /* toujours utiliser trouver_table
1284 qui renverra la description theorique
1285 car sinon on va se comporter differement selon que la table est declaree
1286 ou non
1287 */
1288 if (!$trouver_table) $trouver_table = charger_fonction('trouver_table', 'base');
1289 if ($desc = $trouver_table($nom, $serveur))
1290 return $desc;
1291
1292 // sauf a l'installation :
1293 include_spip('base/serial');
1294 if (isset($tables_principales[$nom]))
1295 return $tables_principales[$nom];
1296
1297 include_spip('base/auxiliaires');
1298 if (isset($tables_auxiliaires[$nom]))
1299 return $tables_auxiliaires[$nom];
1300
1301 return false;
1302 }
1303
1304
1305 ?>