source: spip-zone/_plugins_/extension_mysqli/req/mysqli.php @ 35787

Last change on this file since 35787 was 35787, checked in by gilles.vincent@…, 11 years ago

le plugin dans sa forme finale.. On approche de la surcharge de MySQL
(L'idée est de ne pas faire de nouveau connecteur, mais bien de se substituer à la connexion existante)

L'avantage de cette méthode est qu'il n'y a aucune manipulation à faire dans les fichiers XXX_connect.php.

File size: 24.5 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2010                                                *
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
13if (!defined("_ECRIRE_INC_VERSION")) return;
14
15// fonction pour changer la connexion aux serveurs MySQL en gardant les paramètres existant
16
17function req_mysql_dist() {
18        charger_php_extension('mysqli');
19        if ($port > 0) $host = "$host:$port";
20        $link = new mysqli($host, $login, $pass, $db);
21        if (!$link) return false;
22        $last = '';
23        if (!$db) {
24                $db = 'spip';
25        }
26
27        return array(
28                'db' => $db,
29                'last' => $last,
30                'prefixe' => $prefixe ? $prefixe : $db,
31                'link' => $link
32        );
33
34}
35
36// On redirige toutes les fonctions mysql vers la version mysqli
37$GLOBALS['spip_mysql_functions_1'] = array(
38        'alter' => 'spip_mysqli_alter',
39        'count' => 'spip_mysqli_count',
40        'countsel' => 'spip_mysqli_countsel',
41        'create' => 'spip_mysqli_create',
42        'create_base' => 'spip_mysqli_create_base',
43        'create_view' => 'spip_mysqli_create_view',
44        'date_proche' => 'spip_mysqli_date_proche',
45        'delete' => 'spip_mysqli_delete',
46        'drop_table' => 'spip_mysqli_drop_table',
47        'drop_view' => 'spip_mysqli_drop_view',
48        'errno' => 'spip_mysqli_errno',
49        'error' => 'spip_mysqli_error',
50        'explain' => 'spip_mysqli_explain',
51        'fetch' => 'spip_mysqli_fetch',
52        'seek' => 'spip_mysqli_seek',
53        'free' => 'spip_mysqli_free',
54        'hex' => 'spip_mysqli_hex',
55        'in' => 'spip_mysqli_in', 
56        'insert' => 'spip_mysqli_insert',
57        'insertq' => 'spip_mysqli_insertq',
58        'insertq_multi' => 'spip_mysqli_insertq_multi',
59        'listdbs' => 'spip_mysqli_listdbs',
60        'multi' => 'spip_mysqli_multi',
61        'optimize' => 'spip_mysqli_optimize',
62        'query' => 'spip_mysqli_query',
63        'quote' => 'spip_mysqli_quote',
64        'replace' => 'spip_mysqli_replace',
65        'replace_multi' => 'spip_mysqli_replace_multi',
66        'repair' => 'spip_mysqli_repair',
67        'select' => 'spip_mysqli_select',
68        'selectdb' => 'spip_mysqli_selectdb',
69        'set_charset' => 'spip_mysqli_set_charset',
70        'get_charset' => 'spip_mysqli_get_charset',
71        'showbase' => 'spip_mysqli_showbase',
72        'showtable' => 'spip_mysqli_showtable',
73        'update' => 'spip_mysqli_update',
74        'updateq' => 'spip_mysqli_updateq',
75        //// association de chaque nom http d'un charset aux couples MySQL
76        'charsets' => array(
77                'cp1250'=>array('charset'=>'cp1250','collation'=>'cp1250_general_ci'),
78                'cp1251'=>array('charset'=>'cp1251','collation'=>'cp1251_general_ci'),
79                'cp1256'=>array('charset'=>'cp1256','collation'=>'cp1256_general_ci'),
80                'iso-8859-1'=>array('charset'=>'latin1','collation'=>'latin1_swedish_ci'),
81                //'iso-8859-6'=>array('charset'=>'latin1','collation'=>'latin1_swedish_ci'),
82                'iso-8859-9'=>array('charset'=>'latin5','collation'=>'latin5_turkish_ci'),
83                //'iso-8859-15'=>array('charset'=>'latin1','collation'=>'latin1_swedish_ci'),
84                'utf-8'=>array('charset'=>'utf8','collation'=>'utf8_general_ci')
85                )
86        );
87
88// Reconnecte SPIP sur MySQL via un connecteur MySQLi
89function spip_mysqli_connect_db($host, $port, $login, $pass, $db='') {
90        if ($port > 0) $host = "$host:$port";
91        $link = new mysqli($host, $login, $pass, $db);
92        return $link;
93}
94
95// portage de http://doc.spip.org/@spip_mysql_set_charset
96function spip_mysqli_set_charset($charset, $serveur='',$requeter=true,$requeter=true){
97        $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0];
98        #spip_log("changement de charset sql : "."SET NAMES "._q($charset));
99        return mysqli_set_charset($connexion,_q($charset));
100}
101
102// portage de http://doc.spip.org/@spip_mysql_get_charset
103function spip_mysqli_get_charset($charset=array(), $serveur='',$requeter=true){
104        $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0];
105        $connexion['last'] = $c = "SHOW CHARACTER SET"
106        . (!$charset ? '' : (" LIKE "._q($charset['charset'])));
107        return mysqli_get_charset($connexion);
108}
109
110// Fonction de requete generale, munie d'une trace a la demande
111
112// portage de http://doc.spip.org/@spip_mysql_query
113function spip_mysqli_query($query, $serveur='',$requeter=true) {
114
115        $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0];
116        $prefixe = $connexion['prefixe'];
117        $link = $connexion['link'];
118        $db = $connexion['db'];
119
120        $query = traite_mysqli_query($query, $db, $prefixe);
121
122        // renvoyer la requete inerte si demandee
123        if (!$requeter) return $query;
124
125        if (isset($_GET['var_profile'])) {
126                include_spip('public/tracer');
127                $t = trace_query_start();
128        } else $t = 0 ;
129 
130        $connexion['last'] = $query;
131        $r = $link->query($query);
132
133        return $t ? trace_query_end($query, $t, $r, $serveur) : $r;
134}
135
136// portage de http://doc.spip.org/@spip_mysql_alter
137function spip_mysqli_alter($query, $serveur='',$requeter=true){
138        return spip_mysqli_query("ALTER ".$query, $serveur, $requeter); # i.e. que PG se debrouille
139}
140
141// portage de http://doc.spip.org/@spip_mysql_optimize
142function spip_mysqli_optimize($table, $serveur='',$requeter=true){
143        spip_mysqli_query("OPTIMIZE TABLE ". $table);
144        return true;
145}
146
147// portage de http://doc.spip.org/@spip_mysql_explain
148function spip_mysqli_explain($query, $serveur='',$requeter=true){
149        if (strpos(ltrim($query), 'SELECT') !== 0) return array();
150        $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0];
151        $prefixe = $connexion['prefixe'];
152        $link = $connexion['link'];
153        $db = $connexion['db'];
154
155        $query = 'EXPLAIN ' . traite_mysqli_query($query, $db, $prefixe);
156        $r = $link->query($query);
157        return spip_mysqli_fetch($r, NULL, $serveur);
158}
159// fonction  instance de sql_select, voir ses specs dans abstract.php
160// traite_mysqli_query pourrait y etre fait d'avance ce serait moins cher
161// Les \n et \t sont utiles au debusqueur.
162
163
164// portage de http://doc.spip.org/@spip_mysql_select
165function spip_mysqli_select($select, $from, $where='',
166                           $groupby='', $orderby='', $limit='', $having='',
167                           $serveur='',$requeter=true) {
168
169
170        $from = (!is_array($from) ? $from : spip_mysqli_select_as($from));
171        $query = 
172                  calculer_mysqli_expression('SELECT', $select, ', ')
173                . calculer_mysqli_expression('FROM', $from, ', ')
174                . calculer_mysqli_expression('WHERE', $where)
175                . calculer_mysqli_expression('GROUP BY', $groupby, ',')
176                . calculer_mysqli_expression('HAVING', $having)
177                . ($orderby ? ("\nORDER BY " . spip_mysqli_order($orderby)) :'')
178                . ($limit ? "\nLIMIT $limit" : '');
179
180        // renvoyer la requete inerte si demandee
181        if ($requeter === false) return $query;
182        $r = spip_mysqli_query($query, $serveur, $requeter);
183        return $r ? $r : $query;
184}
185
186// 0+x avec un champ x commencant par des chiffres est converti par MySQL
187// en le nombre qui commence x.
188// Pas portable malheureusement, on laisse pour le moment.
189
190// portage de http://doc.spip.org/@spip_mysql_order
191function spip_mysqli_order($orderby)
192{
193        return (is_array($orderby)) ? join(", ", $orderby) :  $orderby;
194}
195
196
197// portage de http://doc.spip.org/@calculer_mysqli_where
198function calculer_mysqli_where($v)
199{
200        if (!is_array($v))
201          return $v ;
202
203        $op = array_shift($v);
204        if (!($n=count($v)))
205                return $op;
206        else {
207                $arg = calculer_mysqli_where(array_shift($v));
208                if ($n==1) {
209                          return "$op($arg)";
210                } else {
211                        $arg2 = calculer_mysqli_where(array_shift($v));
212                        if ($n==2) {
213                                return "($arg $op $arg2)";
214                        } else return "($arg $op ($arg2) : $v[0])";
215                }
216        }
217}
218
219// portage de http://doc.spip.org/@calculer_mysql_expression
220function calculer_mysqli_expression($expression, $v, $join = 'AND'){
221        if (empty($v))
222                return '';
223       
224        $exp = "\n$expression ";
225       
226        if (!is_array($v)) {
227                return $exp . $v;
228        } else {
229                if (strtoupper($join) === 'AND')
230                        return $exp . join("\n\t$join ", array_map('calculer_mysqli_where', $v));
231                else
232                        return $exp . join($join, $v);
233        }
234}
235
236// portage de http://doc.spip.org/@spip_mysql_select_as
237function spip_mysqli_select_as($args)
238{
239        $res = '';
240        foreach($args as $k => $v) {
241                if (substr($k,-1)=='@') {
242                        // c'est une jointure qui se refere au from precedent
243                        // pas de virgule
244                  $res .= '  ' . $v ;
245                }
246                else {
247                  if (!is_numeric($k)) {
248                        $p = strpos($v, " ");
249                        if ($p)
250                          $v = substr($v,0,$p) . " AS `$k`" . substr($v,$p);
251                        else $v .= " AS `$k`";
252                  }
253                     
254                  $res .= ', ' . $v ;
255                }
256        }
257        return substr($res,2);
258}
259
260//
261// Changer les noms des tables ($table_prefix)
262// Quand tous les appels SQL seront abstraits on pourra l'ameliorer
263
264define('_SQL_PREFIXE_TABLE', '/([,\s])spip_/S');
265
266// portage de http://doc.spip.org/@traite_mysql_query
267function traite_mysqli_query($query, $db='', $prefixe='') {
268
269        if ($GLOBALS['mysqli_rappel_nom_base'] AND $db)
270                $pref = '`'. $db.'`.';
271        else $pref = '';
272
273        if ($prefixe)
274                $pref .= $prefixe . "_";
275
276        if (!preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/i', $query, $regs)) {
277                $suite ='';
278        } else {
279                $suite = strstr($query, $regs[0]);
280                $query = substr($query, 0, -strlen($suite));
281                if (preg_match('/^(.*?)([(]\s*SELECT\b.*)$/si', $suite, $r)) {
282                  $suite = $r[1] . traite_mysqli_query($r[2], $db, $prefixe);
283                }
284        }
285        $r = preg_replace(_SQL_PREFIXE_TABLE, '\1'.$pref, $query) . $suite;
286        # spip_log("traite_mysqli_query: " . substr($r,0, 50) . ".... $db, $prefixe");
287        return $r;
288}
289
290// portage de http://doc.spip.org/@spip_mysql_selectdb
291function spip_mysqli_selectdb($db) {
292        return mysqli_select_db($db);
293}
294
295
296// Retourne les bases accessibles
297// Attention on n'a pas toujours les droits
298
299// portage de http://doc.spip.org/@spip_mysql_listdbs
300function spip_mysqli_listdbs($serveur='',$requeter=true) {
301        return spip_mysqli_query("show databases",$serveur,$requeter);
302}
303
304// Fonction de creation d'une table SQL nommee $nom
305// a partir de 2 tableaux PHP :
306// champs: champ => type
307// cles: type-de-cle => champ(s)
308// si $autoinc, c'est une auto-increment (i.e. serial) sur la Primary Key
309// Le nom des caches doit etre inferieur a 64 caracteres
310
311// portage de http://doc.spip.org/@spip_mysql_create
312function spip_mysqli_create($nom, $champs, $cles, $autoinc=false, $temporary=false, $serveur='',$requeter=true) {
313
314        $query = ''; $keys = ''; $s = ''; $p='';
315
316        // certains plugins declarent les tables  (permet leur inclusion dans le dump)
317        // sans les renseigner (laisse le compilo recuperer la description)
318        if (!is_array($champs) || !is_array($cles)) 
319                return;
320
321        foreach($cles as $k => $v) {
322                $keys .= "$s\n\t\t$k ($v)";
323                if ($k == "PRIMARY KEY")
324                        $p = $v;
325                $s = ",";
326        }
327        $s = '';
328       
329        $character_set = "";
330        if (@$GLOBALS['meta']['charset_sql_base'])
331                $character_set .= " CHARACTER SET ".$GLOBALS['meta']['charset_sql_base'];
332        if (@$GLOBALS['meta']['charset_collation_sql_base'])
333                $character_set .= " COLLATE ".$GLOBALS['meta']['charset_collation_sql_base'];
334
335        foreach($champs as $k => $v) {
336                if (preg_match(',([a-z]*\s*(\(\s*[0-9]*\s*\))?(\s*binary)?),i',$v,$defs)){
337                        if (preg_match(',(char|text),i',$defs[1]) AND !preg_match(',binary,i',$defs[1]) ){
338                                $v = $defs[1] . $character_set . ' ' . substr($v,strlen($defs[1]));
339                        }
340                }
341
342                $query .= "$s\n\t\t$k $v"
343                        . (($autoinc && ($p == $k) && preg_match(',\b(big|small|medium)?int\b,i', $v))
344                                ? " auto_increment"
345                                : ''
346                        );
347                $s = ",";
348        }
349        $temporary = $temporary ? 'TEMPORARY':'';
350        $q = "CREATE $temporary TABLE IF NOT EXISTS $nom ($query" . ($keys ? ",$keys" : '') . ")".
351        ($character_set?" DEFAULT $character_set":"")
352        ."\n";
353        return spip_mysqli_query($q, $serveur);
354}
355
356function spip_mysqli_create_base($nom, $serveur='',$requeter=true) {
357  return spip_mysqli_query("CREATE DATABASE `$nom`", $serveur, $requeter);
358}
359
360// Fonction de creation d'une vue SQL nommee $nom
361// portage de http://doc.spip.org/@spip_mysql_create_view
362function spip_mysqli_create_view($nom, $query_select, $serveur='',$requeter=true) {
363        if (!$query_select) return false;
364        // vue deja presente
365        if (sql_showtable($nom, false, $serveur)) {
366                spip_log("Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)");
367                return false;
368        }
369       
370        $query = "CREATE VIEW $nom AS ". $query_select;
371        return spip_mysqli_query($query, $serveur, $requeter);
372}
373
374
375// portage de http://doc.spip.org/@spip_mysql_drop_table
376function spip_mysqli_drop_table($table, $exist='', $serveur='',$requeter=true)
377{
378        if ($exist) $exist =" IF EXISTS";
379        return spip_mysqli_query("DROP TABLE$exist $table", $serveur, $requeter);
380}
381
382// supprime une vue
383// portage de http://doc.spip.org/@spip_mysql_drop_view
384function spip_mysqli_drop_view($view, $exist='', $serveur='',$requeter=true) {
385        if ($exist) $exist =" IF EXISTS";
386        return spip_mysqli_query("DROP VIEW$exist $view", $serveur, $requeter);
387}
388
389// portage de http://doc.spip.org/@spip_mysql_showbase
390function spip_mysqli_showbase($match, $serveur='',$requeter=true)
391{
392        return spip_mysqli_query("SHOW TABLES LIKE '$match'", $serveur, $requeter);
393}
394
395// portage de http://doc.spip.org/@spip_mysql_repair
396function spip_mysqli_repair($table, $serveur='',$requeter=true)
397{
398        return spip_mysqli_query("REPAIR TABLE $table", $serveur, $requeter);
399}
400
401// Recupere la definition d'une table ou d'une vue MySQL
402// colonnes, indexes, etc.
403// au meme format que la definition des tables de SPIP
404// portage de http://doc.spip.org/@spip_mysql_showtable
405function spip_mysqli_showtable($nom_table, $serveur='',$requeter=true)
406{
407        $s = spip_mysqli_query("SHOW CREATE TABLE `$nom_table`", $serveur, $requeter);
408        if (!$s) return '';
409        if (!$requeter) return $s;
410
411        list(,$a) = mysqli_fetch_array($s ,MYSQLI_NUM);
412        if (preg_match("/^[^(),]*\((([^()]*\([^()]*\)[^()]*)*)\)[^()]*$/", $a, $r)){
413                $dec = $r[1];
414                if (preg_match("/^(.*?),([^,]*KEY.*)$/s", $dec, $r)) {
415                  $namedkeys = $r[2];
416                  $dec = $r[1];
417                }
418                else 
419                  $namedkeys = "";
420
421                $fields = array();
422                foreach(preg_split("/,\s*`/",$dec) as $v) {
423                  preg_match("/^\s*`?([^`]*)`\s*(.*)/",$v,$r);
424                  $fields[strtolower($r[1])] = $r[2];
425                }
426                $keys = array();
427
428                foreach(preg_split('/\)\s*,?/',$namedkeys) as $v) {
429                  if (preg_match("/^\s*([^(]*)\((.*)$/",$v,$r)) {
430                        $k = str_replace("`", '', trim($r[1]));
431                        $t = strtolower(str_replace("`", '', $r[2]));
432                        if ($k && !isset($keys[$k])) $keys[$k] = $t; else $keys[] = $t;
433                  }
434                }
435                spip_mysqli_free($s);
436                return array('field' => $fields, 'key' => $keys);
437        }
438
439        $res = spip_mysqli_query("SHOW COLUMNS FROM `$nom_table`", $serveur);
440        if($res) {
441          $nfields = array();
442          $nkeys = array();
443          while($val = spip_mysqli_fetch($res)) {
444                $nfields[$val["Field"]] = $val['Type'];
445                if($val['Null']=='NO') {
446                  $nfields[$val["Field"]] .= ' NOT NULL'; 
447                }
448                if($val['Default'] === '0' || $val['Default']) {
449                  if(preg_match('/[A-Z_]/',$val['Default'])) {
450                        $nfields[$val["Field"]] .= ' DEFAULT '.$val['Default'];           
451                  } else {
452                        $nfields[$val["Field"]] .= " DEFAULT '".$val['Default']."'";             
453                  }
454                }
455                if($val['Extra'])
456                  $nfields[$val["Field"]] .= ' '.$val['Extra'];
457                if($val['Key'] == 'PRI') {
458                  $nkeys['PRIMARY KEY'] = $val["Field"];
459                } else if($val['Key'] == 'MUL') {
460                  $nkeys['KEY '.$val["Field"]] = $val["Field"];
461                } else if($val['Key'] == 'UNI') {
462                  $nkeys['UNIQUE KEY '.$val["Field"]] = $val["Field"];
463                }
464          }
465          spip_mysqli_free($res);
466          return array('field' => $nfields, 'key' => $nkeys);
467        }
468        return "";
469}
470
471//
472// Recuperation des resultats
473//
474
475// portage de http://doc.spip.org/@spip_mysql_fetch
476function spip_mysqli_fetch($r, $t='', $serveur='',$requeter=true) {
477        if (!$t) $t = MYSQLI_ASSOC;
478        if ($r) return mysqli_fetch_array($r, $t);
479}
480
481function spip_mysqli_seek($r, $row_number, $serveur='',$requeter=true) {
482        if ($r) return mysqli_data_seek($r,$row_number);
483}
484
485
486// portage de http://doc.spip.org/@spip_mysql_countsel
487function spip_mysqli_countsel($from = array(), $where = array(),
488                             $groupby = '', $having = array(), $serveur='',$requeter=true)
489{
490        $c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
491
492        $r = spip_mysqli_select("COUNT($c)", $from, $where,'', '', '', $having, $serveur, $requeter);
493
494        if (!$requeter) return $r;
495        if (!is_resource($r)) return 0;
496        list($c) = mysqli_fetch_array($r, MYSQLI_NUM);
497        mysqli_free_result($r);
498        return $c;
499}
500
501// portage de http://doc.spip.org/@spip_mysql_error
502function spip_mysqli_error($serveur='') {
503        $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0];
504        $link = $connexion['link'];
505        return ($link ? mysqli_error($link) : mysqli_error()) . $connexion['last'];
506}
507
508// A transposer dans les portages
509// portage de http://doc.spip.org/@spip_mysql_errno
510function spip_mysqli_errno($serveur='') {
511        $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0];
512        $link = $connexion['link'];
513        $s = $link ? mysqli_errno($link) : mysqli_errno();
514        // 2006 MySQL server has gone away
515        // 2013 Lost connection to MySQL server during query
516        if (in_array($s, array(2006,2013)))
517                define('spip_interdire_cache', true);
518        return $s;
519}
520
521// Interface de abstract_sql
522// portage de http://doc.spip.org/@spip_mysql_count
523function spip_mysqli_count($r, $serveur='',$requeter=true) {
524        if ($r) return mysqli_num_rows($r);
525}
526
527
528// portage de http://doc.spip.org/@spip_mysql_free
529function spip_mysqli_free($r, $serveur='',$requeter=true) {
530        return mysqli_free_result($r);
531}
532
533// portage de http://doc.spip.org/@spip_mysql_insert
534function spip_mysqli_insert($table, $champs, $valeurs, $desc='', $serveur='',$requeter=true) {
535
536        $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0];
537        $prefixe = $connexion['prefixe'];
538        $link = $connexion['link'];
539        $db = $connexion['db'];
540
541        if ($prefixe) $table = preg_replace('/^spip/', $prefixe, $table);
542
543        if (isset($_GET['var_profile'])) {
544                include_spip('public/tracer');
545                $t = trace_query_start();
546        } else $t = 0 ;
547 
548        $connexion['last'] = $query ="INSERT INTO $table $champs VALUES $valeurs";
549#       spip_log($query);
550        if ($link->query($query))
551                $r = mysqli_insert_id($link);
552        else $r = false;
553
554        return $t ? trace_query_end($query, $t, $r, $serveur) : $r;
555
556        // return $r ? $r : (($r===0) ? -1 : 0); pb avec le multi-base.
557}
558
559// portage de http://doc.spip.org/@spip_mysql_insertq
560function spip_mysqli_insertq($table, $couples=array(), $desc=array(), $serveur='',$requeter=true) {
561
562        if (!$desc) $desc = description_table($table);
563        if (!$desc) $couples = array();
564        $fields =  isset($desc['field'])?$desc['field']:array();
565
566        foreach ($couples as $champ => $val) {
567                $couples[$champ]= spip_mysqli_cite($val, $fields[$champ]);
568        }
569
570        return spip_mysqli_insert($table, "(".join(',',array_keys($couples)).")", "(".join(',', $couples).")", $desc, $serveur, $requeter);
571}
572
573
574// portage de http://doc.spip.org/@spip_mysql_insertq_multi
575function spip_mysqli_insertq_multi($table, $tab_couples=array(), $desc=array(), $serveur='',$requeter=true) {
576
577        if (!$desc) $desc = description_table($table);
578        if (!$desc) $tab_couples = array();
579        $fields =  isset($desc['field'])?$desc['field']:array();
580       
581        $cles = "(" . join(',',array_keys($tab_couples[0])) . ')';
582        $valeurs = array();
583        foreach ($tab_couples as $couples) {
584                foreach ($couples as $champ => $val){
585                        $couples[$champ]= spip_mysqli_cite($val, $fields[$champ]);
586                }
587                $valeurs[] = '(' .join(',', $couples) . ')';
588        }
589
590        // Inserer par groupes de 100 max pour eviter un debordement de pile
591        $r = false;
592        do {
593                $ins = array_slice($valeurs,0,100);
594                $valeurs = array_slice($valeurs,100);
595                $r = spip_mysqli_insert($table, $cles, join(', ', $ins), $desc, $serveur, $requeter);
596        }  while (count($valeurs));
597
598        return $r; // dans le cas d'une table auto_increment, le dernier insert_id
599}
600
601// portage de http://doc.spip.org/@spip_mysql_update
602function spip_mysqli_update($table, $champs, $where='', $desc='', $serveur='',$requeter=true) {
603        $set = array();
604        foreach ($champs as $champ => $val)
605                $set[] = $champ . "=$val";
606        if (!empty($set))
607                return spip_mysqli_query(
608                          calculer_mysqli_expression('UPDATE', $table, ',')
609                        . calculer_mysqli_expression('SET', $set, ',')
610                        . calculer_mysqli_expression('WHERE', $where), 
611                        $serveur, $requeter);
612}
613
614// idem, mais les valeurs sont des constantes a mettre entre apostrophes
615// sauf les expressions de date lorsqu'il s'agit de fonctions SQL (NOW etc)
616// portage de http://doc.spip.org/@spip_mysql_updateq
617function spip_mysqli_updateq($table, $champs, $where='', $desc=array(), $serveur='',$requeter=true) {
618
619        if (!$champs) return;
620        if (!$desc) $desc = description_table($table);
621        if (!$desc) $champs = array(); else $fields =  $desc['field'];
622        $set = array();
623        foreach ($champs as $champ => $val) {
624                $set[] = $champ . '=' . spip_mysqli_cite($val, $fields[$champ]);
625        }
626        return spip_mysqli_query(
627                          calculer_mysqli_expression('UPDATE', $table, ',')
628                        . calculer_mysqli_expression('SET', $set, ',')
629                        . calculer_mysqli_expression('WHERE', $where),
630                        $serveur, $requeter);
631}
632
633// portage de http://doc.spip.org/@spip_mysql_delete
634function spip_mysqli_delete($table, $where='', $serveur='',$requeter=true) {
635        $res = spip_mysqli_query(
636                          calculer_mysqli_expression('DELETE FROM', $table, ',')
637                        . calculer_mysqli_expression('WHERE', $where),
638                        $serveur, $requeter);
639        if ($res){
640                $link = $GLOBALS['connexions'][$serveur ? $serveur : 0]['link'];
641                return $link ? mysqli_affected_rows($link) : mysqli_affected_rows();
642        }
643        else
644                return false;
645}
646
647// portage de http://doc.spip.org/@spip_mysql_replace
648function spip_mysqli_replace($table, $couples, $desc=array(), $serveur='',$requeter=true) {
649        return spip_mysqli_query("REPLACE $table (" . join(',',array_keys($couples)) . ') VALUES (' .join(',',array_map('_q', $couples)) . ')', $serveur, $requeter);
650}
651
652
653// portage de http://doc.spip.org/@spip_mysql_replace_multi
654function spip_mysqli_replace_multi($table, $tab_couples, $desc=array(), $serveur='',$requeter=true) {
655        $cles = "(" . join(',',array_keys($tab_couples[0])). ')';
656        $valeurs = array();
657        foreach ($tab_couples as $couples) {
658                $valeurs[] = '(' .join(',',array_map('_q', $couples)) . ')';
659        }
660        $valeurs = implode(', ',$valeurs);
661        return spip_mysqli_query("REPLACE $table $cles VALUES $valeurs", $serveur, $requeter);
662}
663
664
665// portage de http://doc.spip.org/@spip_mysql_multi
666function spip_mysqli_multi ($objet, $lang) {
667        $lengthlang = strlen("[$lang]");
668        $posmulti = "INSTR(".$objet.", '<multi>')";
669        $posfinmulti = "INSTR(".$objet.", '</multi>')";
670        $debutchaine = "LEFT(".$objet.", $posmulti-1)";
671        $finchaine = "RIGHT(".$objet.", CHAR_LENGTH(".$objet.") -(7+$posfinmulti))";
672        $chainemulti = "TRIM(SUBSTRING(".$objet.", $posmulti+7, $posfinmulti -(7+$posmulti)))";
673        $poslang = "INSTR($chainemulti,'[".$lang."]')";
674        $poslang = "IF($poslang=0,INSTR($chainemulti,']')+1,$poslang+$lengthlang)";
675        $chainelang = "TRIM(SUBSTRING(".$objet.", $posmulti+7+$poslang-1,$posfinmulti -($posmulti+7+$poslang-1) ))";
676        $posfinlang = "INSTR(".$chainelang.", '[')";
677        $chainelang = "IF($posfinlang>0,LEFT($chainelang,$posfinlang-1),$chainelang)";
678        //$chainelang = "LEFT($chainelang,$posfinlang-1)";
679        $retour = "(TRIM(IF($posmulti = 0 , ".
680                "     TRIM(".$objet."), ".
681                "     CONCAT( ".
682                "          $debutchaine, ".
683                "          IF( ".
684                "               $poslang = 0, ".
685                "                     $chainemulti, ".
686                "               $chainelang".
687                "          ), ". 
688                "          $finchaine".
689                "     ) ".
690                "))) AS multi";
691
692        return $retour;
693}
694
695// portage de http://doc.spip.org/@spip_mysql_hex
696function spip_mysqli_hex($v)
697{
698        return "0x" . $v;
699}
700
701function spip_mysqli_quote($v, $type='')
702{
703        return ($type === 'int' AND !$v) ? '0' :  _q($v);
704}
705
706function spip_mysqli_date_proche($champ, $interval, $unite)
707{
708        return '('
709        . $champ
710        . (($interval <= 0) ? '>' : '<')
711        . (($interval <= 0) ? 'DATE_SUB' : 'DATE_ADD')
712        . '('
713        . sql_quote(date('Y-m-d H:i:s'))
714        . ', INTERVAL '
715        . (($interval > 0) ? $interval : (0-$interval))
716        . ' '
717        . $unite
718        . '))';
719}
720
721//
722// IN (...) est limite a 255 elements, d'ou cette fonction assistante
723//
724// portage de http://doc.spip.org/@spip_mysql_in
725function spip_mysqli_in($val, $valeurs, $not='', $serveur='',$requeter=true) {
726        $n = $i = 0;
727        $in_sql ="";
728        while ($n = strpos($valeurs, ',', $n+1)) {
729          if ((++$i) >= 255) {
730                        $in_sql .= "($val $not IN (" .
731                          substr($valeurs, 0, $n) .
732                          "))\n" .
733                          ($not ? "AND\t" : "OR\t");
734                        $valeurs = substr($valeurs, $n+1);
735                        $i = $n = 0;
736                }
737        }
738        $in_sql .= "($val $not IN ($valeurs))";
739
740        return "($in_sql)";
741}
742
743// pour compatibilite. Ne plus utiliser.
744// portage de http://doc.spip.org/@calcul_mysql_in
745function calcul_mysqli_in($val, $valeurs, $not='') {
746        if (is_array($valeurs))
747                $valeurs = join(',', array_map('_q', $valeurs));
748        elseif ($valeurs[0]===',') $valeurs = substr($valeurs,1);
749        if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1');
750        return spip_mysqli_in($val, $valeurs, $not);
751}
752
753// portage de http://doc.spip.org/@spip_mysql_cite
754function spip_mysqli_cite($v, $type) {
755        if (sql_test_date($type) AND preg_match('/^\w+\(/', $v)
756        OR (sql_test_int($type)
757                 AND (is_numeric($v)
758                      OR (ctype_xdigit(substr($v,2))
759                          AND $v[0]=='0' AND $v[1]=='x'))))
760                return $v;
761        else return  ("'" . addslashes($v) . "'");
762}
763
764
765?>
Note: See TracBrowser for help on using the repository browser.