source: trunk/include/dblayer/functions_pdo-sqlite.inc.php @ 12922

Last change on this file since 12922 was 12922, checked in by mistic100, 12 years ago

update Piwigo headers to 2012, last change before the expected (or not) apocalypse

File size: 15.2 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
23
24define('REQUIRED_PDO_SQLITE_VERSION', '3.0.0');
25define('DB_ENGINE', 'SQLite');
26
27define('DB_REGEX_OPERATOR', 'REGEXP');
28define('DB_RANDOM_FUNCTION', 'RANDOM');
29
30/**
31 *
32 * simple functions
33 *
34 */
35
36function pwg_db_connect($host, $user, $password, $database)
37{
38  global $conf;
39
40  $db_file = sprintf('sqlite:%s/%s.db', PHPWG_ROOT_PATH.$conf['data_location'], $database);
41
42  $link = new PDO($db_file);
43  if (!$link)
44  {
45    throw new  Exception('Connection to server succeed, but it was impossible to connect to database');
46  }
47
48  $link->sqliteCreateFunction('now', 'pwg_now', 0);
49  $link->sqliteCreateFunction('unix_timestamp', 'pwg_unix_timestamp', 0);
50  $link->sqliteCreateFunction('md5', 'md5', 1);
51  $link->sqliteCreateFunction('if', 'pwg_if', 3);
52
53  $link->sqliteCreateFunction('regexp', 'pwg_regexp', 2);
54
55  return $link;
56}
57
58function pwg_db_check_version()
59{
60  $current_version = pwg_get_db_version();
61  if (version_compare($current_version, REQUIRED_PDO_SQLITE_VERSION, '<'))
62  {
63    fatal_error(
64      sprintf(
65        'your database version is too old, you have "%s" and you need at least "%s"',
66        $current_version,
67        REQUIRED_PDO_SQLITE_VERSION
68        )
69      );
70  }
71}
72
73function pwg_db_check_charset() 
74{
75  return true;
76}
77
78function pwg_get_db_version() 
79{
80  global $pwg_db_link;
81
82  return $pwg_db_link->getAttribute(PDO::ATTR_SERVER_VERSION);
83}
84
85function pwg_query($query)
86{
87  global $conf,$page,$debug,$t2,$pwg_db_link;
88
89  $start = get_moment();
90
91  $truncate_pattern = '`truncate(.*)`i';
92  $insert_pattern = '`(INSERT INTO [^)]*\)\s*VALUES)(\([^)]*\))\s*,\s*(.*)`mi'; 
93
94  if (preg_match($truncate_pattern, $query, $matches))
95  {
96    $query = str_replace('TRUNCATE TABLE', 'DELETE FROM', $query);
97    $truncate_query = true;
98    ($result = $pwg_db_link->exec($query)) or die($query."\n<br>".$pwg_db_link->errorInfo());
99  }
100  elseif (preg_match($insert_pattern, $query, $matches))
101  {
102    $base_query = substr($query, 0, strlen($matches[1])+1);
103    $values_pattern = '`\)\s*,\s*\(`';
104    $values = preg_split($values_pattern, substr($query, strlen($matches[1])+1));
105    $values[0] = substr($values[0], 1);
106    $values[count($values)-1] = substr($values[count($values)-1], 
107                                     0, 
108                                     strlen($values[count($values)-1])-1
109                                     );
110    for ($n=0;$n<count($values);$n++)
111    {
112      $query = $base_query . '('. $values[$n] . ")\n;";
113      ($result = $pwg_db_link->query($query)) 
114        or die($query."\n<br>".$pwg_db_link->lastErrorMsg());
115    }
116  }
117  else 
118  {
119    ($result = $pwg_db_link->query($query)) 
120      or die($query."\n<br>".$pwg_db_link->errorInfo());
121  }
122
123  $time = get_moment() - $start;
124
125  if (!isset($page['count_queries']))
126  {
127    $page['count_queries'] = 0;
128    $page['queries_time'] = 0;
129  }
130
131  $page['count_queries']++;
132  $page['queries_time']+= $time;
133
134  if ($conf['show_queries'])
135  {
136    $output = '';
137    $output.= '<pre>['.$page['count_queries'].'] ';
138    $output.= "\n".$query;
139    $output.= "\n".'(this query time : ';
140    $output.= '<b>'.number_format($time, 3, '.', ' ').' s)</b>';
141    $output.= "\n".'(total SQL time  : ';
142    $output.= number_format($page['queries_time'], 3, '.', ' ').' s)';
143    $output.= "\n".'(total time      : ';
144    $output.= number_format( ($time+$start-$t2), 3, '.', ' ').' s)';
145    if ( $result!=null and preg_match('/\s*SELECT\s+/i',$query) )
146    {
147      $output.= "\n".'(num rows        : ';
148      $output.= pwg_db_num_rows($result).' )';
149    }
150    elseif ( $result!=null
151      and preg_match('/\s*INSERT|UPDATE|REPLACE|DELETE\s+/i',$query) 
152      and !isset($truncate_query))
153    {
154      $output.= "\n".'(affected rows   : ';
155      $output.= pwg_db_changes($result).' )';
156    }
157    $output.= "</pre>\n";
158
159    $debug .= $output;
160  }
161
162  return $result;
163}
164
165function pwg_db_nextval($column, $table)
166{
167  $query = '
168SELECT MAX('.$column.')+1
169  FROM '.$table;
170  list($next) = pwg_db_fetch_row(pwg_query($query));
171  if (is_null($next))
172  {
173    $next = 1;
174  }
175  return $next;
176}
177
178/**
179 *
180 * complex functions
181 *
182 */
183
184function pwg_db_changes(PDOStatement $result=null) 
185{
186  return $result->rowCount();
187}
188
189function pwg_db_num_rows(PDOStatement $result) 
190{ 
191  return $result->rowCount();
192}
193
194function pwg_db_fetch_assoc($result)
195{
196  return $result->fetch(PDO::FETCH_ASSOC);
197}
198
199function pwg_db_fetch_row($result)
200{
201  return $result->fetch(PDO::FETCH_NUM);
202}
203
204function pwg_db_fetch_object($result)
205{
206  return $result;
207}
208
209function pwg_db_free_result($result) 
210{
211}
212
213function pwg_db_real_escape_string($s)
214{
215  global $pwg_db_link;
216
217  return trim($pwg_db_link->quote($s), "'");
218}
219
220function pwg_db_insert_id($table=null, $column='id')
221{
222  global $pwg_db_link;
223
224  return $pwg_db_link->lastInsertRowID();
225}
226
227/**
228 *
229 * complex functions
230 *
231 */
232
233/**
234 * creates an array based on a query, this function is a very common pattern
235 * used here
236 *
237 * @param string $query
238 * @param string $fieldname
239 * @return array
240 */
241function array_from_query($query, $fieldname)
242{
243  $array = array();
244
245  $result = pwg_query($query);
246  while ($row = pwg_db_fetch_assoc($result))
247  {
248    array_push($array, $row[$fieldname]);
249  }
250
251  return $array;
252}
253
254define('MASS_UPDATES_SKIP_EMPTY', 1);
255/**
256 * updates multiple lines in a table
257 *
258 * @param string table_name
259 * @param array dbfields
260 * @param array datas
261 * @param int flags - if MASS_UPDATES_SKIP_EMPTY - empty values do not overwrite existing ones
262 * @return void
263 */
264function mass_updates($tablename, $dbfields, $datas, $flags=0)
265{
266  if (count($datas) == 0)
267    return;
268
269  foreach ($datas as $data)
270  {
271    $query = '
272UPDATE '.$tablename.'
273  SET ';
274    $is_first = true;
275    foreach ($dbfields['update'] as $key)
276    {
277      $separator = $is_first ? '' : ",\n    ";
278     
279      if (isset($data[$key]) and $data[$key] != '')
280      {
281        $query.= $separator.$key.' = \''.$data[$key].'\'';
282      }
283      else
284      {
285        if ( $flags & MASS_UPDATES_SKIP_EMPTY )
286          continue; // next field
287        $query.= "$separator$key = NULL";
288      }
289      $is_first = false;
290    }
291    if (!$is_first)
292    {// only if one field at least updated
293      $query.= '
294  WHERE ';
295      $is_first = true;
296      foreach ($dbfields['primary'] as $key)
297      {
298        if (!$is_first)
299        {
300          $query.= ' AND ';
301        }
302        if ( isset($data[$key]) )
303        {
304          $query.= $key.' = \''.$data[$key].'\'';
305        }
306        else
307        {
308          $query.= $key.' IS NULL';
309        }
310        $is_first = false;
311      }
312      pwg_query($query);
313    }
314  }
315}
316
317/**
318 * updates one line in a table
319 *
320 * @param string table_name
321 * @param array set_fields
322 * @param array where_fields
323 * @param int flags - if MASS_UPDATES_SKIP_EMPTY - empty values do not overwrite existing ones
324 * @return void
325 */
326function single_update($tablename, $set_fields, $where_fields, $flags=0)
327{
328  if (count($set_fields) == 0)
329  {
330    return;
331  }
332
333  $query = '
334UPDATE '.$tablename.'
335  SET ';
336  $is_first = true;
337  foreach ($set_fields as $key => $value)
338  {
339    $separator = $is_first ? '' : ",\n    ";
340
341    if (isset($value) and $value != '')
342    {
343      $query.= $separator.$key.' = \''.$value.'\'';
344    }
345    else
346    {
347      if ( $flags & MASS_UPDATES_SKIP_EMPTY )
348        continue; // next field
349      $query.= "$separator$key = NULL";
350    }
351    $is_first = false;
352  }
353  if (!$is_first)
354  {// only if one field at least updated
355    $query.= '
356  WHERE ';
357    $is_first = true;
358    foreach ($where_fields as $key => $value)
359    {
360      if (!$is_first)
361      {
362        $query.= ' AND ';
363      }
364      if ( isset($value) )
365      {
366        $query.= $key.' = \''.$value.'\'';
367      }
368      else
369      {
370        $query.= $key.' IS NULL';
371      }
372      $is_first = false;
373    }
374    pwg_query($query);
375  }
376}
377
378/**
379 * inserts multiple lines in a table
380 *
381 * @param string table_name
382 * @param array dbfields
383 * @param array inserts
384 * @return void
385 */
386function mass_inserts($table_name, $dbfields, $datas)
387{
388  if (count($datas) != 0)
389  {
390    $first = true;
391
392    $packet_size = 16777216;
393    $packet_size = $packet_size - 2000; // The last list of values MUST not exceed 2000 character*/
394    $query = '';
395
396    foreach ($datas as $insert)
397    {
398      if (strlen($query) >= $packet_size)
399      {
400        pwg_query($query);
401        $first = true;
402      }
403
404      if ($first)
405      {
406        $query = '
407INSERT INTO '.$table_name.'
408  ('.implode(',', $dbfields).')
409  VALUES';
410        $first = false;
411      }
412      else
413      {
414        $query .= '
415  , ';
416      }
417
418      $query .= '(';
419      foreach ($dbfields as $field_id => $dbfield)
420      {
421        if ($field_id > 0)
422        {
423          $query .= ',';
424        }
425
426        if (!isset($insert[$dbfield]) or $insert[$dbfield] === '')
427        {
428          $query .= 'NULL';
429        }
430        else
431        {
432          $query .= "'".$insert[$dbfield]."'";
433        }
434      }
435      $query .= ')';
436    }
437    pwg_query($query);
438  }
439}
440
441/**
442 * inserts one line in a table
443 *
444 * @param string table_name
445 * @param array dbfields
446 * @param array insert
447 * @return void
448 */
449function single_insert($table_name, $data)
450{
451  if (count($data) != 0)
452  {
453    $query = '
454INSERT INTO '.$table_name.'
455  ('.implode(',', array_keys($data)).')
456  VALUES';
457
458    $query .= '(';
459    $is_first = true;
460    foreach ($data as $key => $value)
461    {
462      if (!$is_first)
463      {
464        $query .= ',';
465      }
466      else
467      {
468        $is_first = false;
469      }
470     
471      if ($value === '')
472      {
473        $query .= 'NULL';
474      }
475      else
476      {
477        $query .= "'".$value."'";
478      }
479    }
480    $query .= ')';
481   
482    pwg_query($query);
483  }
484}
485
486/**
487 * Do maintenance on all PWG tables
488 *
489 * @return none
490 */
491function do_maintenance_all_tables()
492{
493  global $prefixeTable, $page;
494
495  $all_tables = array();
496
497  // List all tables
498  $query = 'SELECT name FROM SQLITE_MASTER
499WHERE name LIKE \''.$prefixeTable.'%\'';
500
501  $all_tables = array_from_query($query, 'name');
502  foreach ($all_tables as $table_name)
503  {
504    $query = 'VACUUM '.$table_name.';';
505    $result = pwg_query($query);
506  }
507 
508  array_push($page['infos'],
509             l10n('All optimizations have been successfully completed.')
510             );
511}
512
513function pwg_db_concat($array)
514{
515  return implode($array, ' || ');
516}
517
518function pwg_db_concat_ws($array, $separator)
519{
520  return implode($array, ' || \''.$separator.'\' || ');
521}
522
523function pwg_db_cast_to_text($string)
524{
525  return $string;
526}
527
528/**
529 * returns an array containing the possible values of an enum field
530 *
531 * @param string tablename
532 * @param string fieldname
533 */
534function get_enums($table, $field)
535{
536  $Enums['categories']['status'] = array('public', 'private');
537  $Enums['history']['section'] = array('categories','tags','search','list','favorites','most_visited','best_rated','recent_pics','recent_cats');
538  $Enums['user_infos']['status'] = array('webmaster','admin','normal','generic','guest');
539  $Enums['image']['type'] = array('picture','high','other');
540  $Enums['plugins']['state'] = array('active', 'inactive');
541  $Enums['user_cache_image']['access_type'] = array('NOT IN','IN');
542
543  $table = str_replace($GLOBALS['prefixeTable'], '', $table);
544  if (isset($Enums[$table][$field])) {
545    return $Enums[$table][$field];
546  } else {
547    return array();
548  }
549}
550
551// get_boolean transforms a string to a boolean value. If the string is
552// "false" (case insensitive), then the boolean value false is returned. In
553// any other case, true is returned.
554function get_boolean( $string )
555{
556  $boolean = true;
557  if ('f' === $string || 'false' === $string)
558  {
559    $boolean = false;
560  }
561  return $boolean;
562}
563
564/**
565 * returns boolean string 'true' or 'false' if the given var is boolean
566 *
567 * @param mixed $var
568 * @return mixed
569 */
570function boolean_to_string($var)
571{
572  if (is_bool($var))
573  {
574    return $var ? 'true' : 'false';
575  }
576  else
577  {
578    return $var;
579  }
580}
581
582/**
583 *
584 * interval and date functions
585 *
586 */
587
588function pwg_db_get_recent_period_expression($period, $date='CURRENT_DATE')
589{
590  if ($date!='CURRENT_DATE')
591  {
592    $date = '\''.$date.'\'';
593  }
594
595  return 'date('.$date.',\''.-$period.' DAY\')';
596}
597
598function pwg_db_get_recent_period($period, $date='CURRENT_DATE')
599{
600  $query = 'select '.pwg_db_get_recent_period_expression($period, $date);
601  list($d) = pwg_db_fetch_row(pwg_query($query));
602
603  return $d;
604}
605
606function pwg_db_get_flood_period_expression($seconds)
607{
608  return 'datetime(\'now\', \'localtime\', \''.-$seconds.' seconds\')';
609}
610
611function pwg_db_get_hour($date)
612{
613  return 'strftime(\'%H\', '.$date.')';
614}
615
616
617function pwg_db_get_date_YYYYMM($date)
618{
619  return 'strftime(\'%Y%m\','.$date.')';
620}
621
622function pwg_db_get_date_MMDD($date)
623{
624  return 'strftime(\'%m%d\','.$date.')';
625}
626
627function pwg_db_get_year($date)
628{
629  return 'strftime(\'%Y\','.$date.')';
630}
631
632function pwg_db_get_month($date)
633{
634  return 'strftime(\'%m\','.$date.')';
635}
636
637function pwg_db_get_week($date, $mode=null)
638{
639  return 'strftime(\'%W\','.$date.')';
640}
641
642function pwg_db_get_dayofmonth($date)
643{
644  return 'strftime(\'%d\','.$date.')';
645}
646
647function pwg_db_get_dayofweek($date)
648{
649  return 'strftime(\'%w\','.$date.')';
650}
651
652function pwg_db_get_weekday($date)
653{
654  return 'strftime(\'%w\',date('.$date.',\'-1 DAY\'))';
655}
656
657function pwg_db_date_to_ts($date) 
658{
659  return 'UNIX_TIMESTAMP('.$date.')';
660}
661
662// my_error returns (or send to standard output) the message concerning the
663// error occured for the last mysql query.
664function my_error($header, $die)
665{
666  global $pwg_db_link;
667
668  $error = '';
669  if (isset($pwg_db_link)) 
670  {
671    $error .= '[sqlite error]'.$pwg_db_link->errorInfo()."\n";
672  }
673
674  $error .= $header;
675
676  if ($die)
677  {
678    fatal_error($error);
679  }
680  echo("<pre>");
681  trigger_error($error, E_USER_WARNING);
682  echo("</pre>");
683}
684
685// sqlite create functions
686function pwg_now()
687{
688  return date('Y-m-d H:i:s');
689}
690
691function pwg_unix_timestamp()
692{
693  return time();
694}
695
696function pwg_if($expression, $value1, $value2) 
697{
698  if ($expression)
699  {
700    return $value1;
701  }
702  else
703  {
704    return $value2;
705  }
706} 
707
708function pwg_regexp($pattern, $string)
709{
710  $pattern = sprintf('`%s`', $pattern);
711  return preg_match($pattern, $string);
712}
713?>
Note: See TracBrowser for help on using the repository browser.