source: trunk/include/dblayer/functions_sqlite.inc.php @ 5236

Last change on this file since 5236 was 5236, checked in by nikrou, 14 years ago

Feature 1255 :
only one function
use exceptions to deal with differents possible errors

File size: 12.7 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based picture gallery                                  |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2010 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_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('%s/%s.db', $conf['local_data_dir'], $database);
41
42  if (script_basename()=='install') 
43  {
44    $sqlite_open_mode = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE;
45  }
46  else 
47  {
48    $sqlite_open_mode = SQLITE3_OPEN_READWRITE;
49  }
50 
51  $link = new SQLite3($db_file, $sqlite_open_mode);
52  if (!$link)
53  {
54    throw new  Exception('Connection to server succeed, but it was impossible to connect to database');
55  }
56
57  $link->createFunction('now', 'pwg_now', 0);
58  $link->createFunction('unix_timestamp', 'pwg_unix_timestamp', 0);
59  $link->createFunction('md5', 'md5', 1);
60  $link->createFunction('if', 'pwg_if', 3);
61
62  $link->createAggregate('std', 'pwg_std_step', 'pwg_std_finalize');
63  $link->createFunction('regexp', 'pwg_regexp', 2);
64
65  return $link;
66}
67
68function pwg_db_check_charset() 
69{
70  return true;
71}
72
73function pwg_get_db_version() 
74{
75  global $pwg_db_link;
76
77  $versionInfos = $pwg_db_link->version();
78  return $versionInfos['versionString'];
79}
80
81function pwg_query($query)
82{
83  global $conf,$page,$debug,$t2,$pwg_db_link;
84
85  $start = get_moment();
86
87  $truncate_pattern = '`truncate(.*)`i';
88  $insert_pattern = '`(INSERT INTO [^)]*\)\s*VALUES)(\([^)]*\))\s*,\s*(.*)`mi'; 
89
90  if (preg_match($truncate_pattern, $query, $matches))
91  {
92    $query = str_replace('TRUNCATE TABLE', 'DELETE FROM', $query);
93    $truncate_query = true;
94    ($result = $pwg_db_link->exec($query)) or die($query."\n<br>".$pwg_db_link->lastErrorMsg());
95  }
96  elseif (preg_match($insert_pattern, $query, $matches))
97  {
98    $base_query = substr($query, 0, strlen($matches[1])+1);
99    $values_pattern = '`\)\s*,\s*\(`';
100    $values = preg_split($values_pattern, substr($query, strlen($matches[1])+1));
101    $values[0] = substr($values[0], 1);
102    $values[count($values)-1] = substr($values[count($values)-1], 
103                                     0, 
104                                     strlen($values[count($values)-1])-1
105                                     );
106    for ($n=0;$n<count($values);$n++)
107    {
108      $query = $base_query . '('. $values[$n] . ")\n;";
109      ($result = $pwg_db_link->query($query)) 
110        or die($query."\n<br>".$pwg_db_link->lastErrorMsg());
111    }
112  }
113  else 
114  {
115    ($result = $pwg_db_link->query($query)) 
116      or die($query."\n<br>".$pwg_db_link->lastErrorMsg());
117  }
118
119  $time = get_moment() - $start;
120
121  if (!isset($page['count_queries']))
122  {
123    $page['count_queries'] = 0;
124    $page['queries_time'] = 0;
125  }
126
127  $page['count_queries']++;
128  $page['queries_time']+= $time;
129
130  if ($conf['show_queries'])
131  {
132    $output = '';
133    $output.= '<pre>['.$page['count_queries'].'] ';
134    $output.= "\n".$query;
135    $output.= "\n".'(this query time : ';
136    $output.= '<b>'.number_format($time, 3, '.', ' ').' s)</b>';
137    $output.= "\n".'(total SQL time  : ';
138    $output.= number_format($page['queries_time'], 3, '.', ' ').' s)';
139    $output.= "\n".'(total time      : ';
140    $output.= number_format( ($time+$start-$t2), 3, '.', ' ').' s)';
141    if ( $result!=null and preg_match('/\s*SELECT\s+/i',$query) )
142    {
143      $output.= "\n".'(num rows        : ';
144      $output.= pwg_db_num_rows($result).' )';
145    }
146    elseif ( $result!=null
147      and preg_match('/\s*INSERT|UPDATE|REPLACE|DELETE\s+/i',$query) 
148      and !isset($truncate_query))
149    {
150      $output.= "\n".'(affected rows   : ';
151      $output.= pwg_db_changes($result).' )';
152    }
153    $output.= "</pre>\n";
154
155    $debug .= $output;
156  }
157
158  return $result;
159}
160
161function pwg_db_nextval($column, $table)
162{
163  $query = '
164SELECT MAX('.$column.')+1
165  FROM '.$table;
166  list($next) = pwg_db_fetch_row(pwg_query($query));
167  if (is_null($next))
168  {
169    $next = 1;
170  }
171  return $next;
172}
173
174/**
175 *
176 * complex functions
177 *
178 */
179
180function pwg_db_changes(SQLite3Result $result=null) 
181{
182  global $pwg_db_link;
183
184  return $pwg_db_link->changes();
185}
186
187function pwg_db_num_rows($result) 
188{ 
189  return $result->numColumns();
190}
191
192function pwg_db_fetch_assoc($result)
193{
194  return $result->fetchArray(SQLITE3_ASSOC);
195}
196
197function pwg_db_fetch_row($result)
198{
199  return $result->fetchArray(SQLITE3_NUM);
200}
201
202function pwg_db_fetch_object($result)
203{
204  return $result;
205}
206
207function pwg_db_free_result($result) 
208{
209}
210
211function pwg_db_real_escape_string($s)
212{
213  global $pwg_db_link;
214
215  return $pwg_db_link->escapeString($s);
216}
217
218function pwg_db_insert_id($table=null, $column='id')
219{
220  global $pwg_db_link;
221
222  return $pwg_db_link->lastInsertRowID();
223}
224
225/**
226 *
227 * complex functions
228 *
229 */
230
231/**
232 * creates an array based on a query, this function is a very common pattern
233 * used here
234 *
235 * @param string $query
236 * @param string $fieldname
237 * @return array
238 */
239function array_from_query($query, $fieldname)
240{
241  $array = array();
242
243  $result = pwg_query($query);
244  while ($row = pwg_db_fetch_assoc($result))
245  {
246    array_push($array, $row[$fieldname]);
247  }
248
249  return $array;
250}
251
252define('MASS_UPDATES_SKIP_EMPTY', 1);
253/**
254 * updates multiple lines in a table
255 *
256 * @param string table_name
257 * @param array dbfields
258 * @param array datas
259 * @param int flags - if MASS_UPDATES_SKIP_EMPTY - empty values do not overwrite existing ones
260 * @return void
261 */
262function mass_updates($tablename, $dbfields, $datas, $flags=0)
263{
264  if (count($datas) == 0)
265    return;
266
267  foreach ($datas as $data)
268  {
269    $query = '
270UPDATE '.$tablename.'
271  SET ';
272    $is_first = true;
273    foreach ($dbfields['update'] as $key)
274    {
275      $separator = $is_first ? '' : ",\n    ";
276     
277      if (isset($data[$key]) and $data[$key] != '')
278      {
279        $query.= $separator.$key.' = \''.$data[$key].'\'';
280      }
281      else
282      {
283        if ($flags & MASS_UPDATES_SKIP_EMPTY )
284          continue; // next field
285        $query.= "$separator$key = NULL";
286      }
287      $is_first = false;
288    }
289    if (!$is_first)
290    {// only if one field at least updated
291      $query.= '
292  WHERE ';
293      $is_first = true;
294      foreach ($dbfields['primary'] as $key)
295      {
296        if (!$is_first)
297        {
298          $query.= ' AND ';
299        }
300        if ( isset($data[$key]) )
301        {
302          $query.= $key.' = \''.$data[$key].'\'';
303        }
304        else
305        {
306          $query.= $key.' IS NULL';
307        }
308        $is_first = false;
309      }
310      pwg_query($query);
311    }
312  }
313}
314
315
316/**
317 * inserts multiple lines in a table
318 *
319 * @param string table_name
320 * @param array dbfields
321 * @param array inserts
322 * @return void
323 */
324
325function mass_inserts($table_name, $dbfields, $datas)
326{
327  if (count($datas) != 0)
328  {
329    $first = true;
330
331    $packet_size = 16777216;
332    $packet_size = $packet_size - 2000; // The last list of values MUST not exceed 2000 character*/
333    $query = '';
334
335    foreach ($datas as $insert)
336    {
337      if (strlen($query) >= $packet_size)
338      {
339        pwg_query($query);
340        $first = true;
341      }
342
343      if ($first)
344      {
345        $query = '
346INSERT INTO '.$table_name.'
347  ('.implode(',', $dbfields).')
348  VALUES';
349        $first = false;
350      }
351      else
352      {
353        $query .= '
354  , ';
355      }
356
357      $query .= '(';
358      foreach ($dbfields as $field_id => $dbfield)
359      {
360        if ($field_id > 0)
361        {
362          $query .= ',';
363        }
364
365        if (!isset($insert[$dbfield]) or $insert[$dbfield] === '')
366        {
367          $query .= 'NULL';
368        }
369        else
370        {
371          $query .= "'".$insert[$dbfield]."'";
372        }
373      }
374      $query .= ')';
375    }
376    pwg_query($query);
377  }
378}
379
380/**
381 * Do maintenance on all PWG tables
382 *
383 * @return none
384 */
385function do_maintenance_all_tables()
386{
387  global $prefixeTable, $page;
388
389  $all_tables = array();
390
391  // List all tables
392  $query = 'SELECT name FROM SQLITE_MASTER
393WHERE name LIKE \''.$prefixeTable.'%\'';
394
395  $all_tables = array_from_query($query, 'name');
396  foreach ($all_tables as $table_name)
397  {
398    $query = 'VACUUM '.$table_name.';';
399    $result = pwg_query($query);
400  }
401 
402  array_push($page['infos'],
403             l10n('All optimizations have been successfully completed.')
404             );
405}
406
407function pwg_db_concat($array)
408{
409  return implode($array, ' || ');
410}
411
412function pwg_db_concat_ws($array, $separator)
413{
414  $glue = sprintf(' || \'%s\' || ', $separator);
415
416  return implode($array, $glue);
417}
418
419function pwg_db_cast_to_text($string)
420{
421  return $string;
422}
423
424/**
425 * returns an array containing the possible values of an enum field
426 *
427 * @param string tablename
428 * @param string fieldname
429 */
430function get_enums($table, $field)
431{
432  return array();
433}
434
435// get_boolean transforms a string to a boolean value. If the string is
436// "false" (case insensitive), then the boolean value false is returned. In
437// any other case, true is returned.
438function get_boolean( $string )
439{
440  $boolean = true;
441  if ('f' === $string || 'false' === $string)
442  {
443    $boolean = false;
444  }
445  return $boolean;
446}
447
448/**
449 * returns boolean string 'true' or 'false' if the given var is boolean
450 *
451 * @param mixed $var
452 * @return mixed
453 */
454function boolean_to_string($var)
455{
456  if (!empty($var) && ($var == 'true'))
457  {
458    return 'true';
459  }
460  else
461  {
462    return 'false';
463  }
464}
465
466/**
467 *
468 * interval and date functions
469 *
470 */
471
472function pwg_db_get_recent_period_expression($period, $date='CURRENT_DATE')
473{
474  if ($date!='CURRENT_DATE')
475  {
476    $date = '\''.$date.'\'';
477  }
478
479  return 'date('.$date.',\''.-$period.' DAY\')';
480}
481
482function pwg_db_get_recent_period($period, $date='CURRENT_DATE')
483{
484  $query = 'select '.pwg_db_get_recent_period_expression($period, $date);
485  list($d) = pwg_db_fetch_row(pwg_query($query));
486
487  return $d;
488}
489
490function pwg_db_get_date_YYYYMM($date)
491{
492  return 'strftime(\'%Y%m\','.$date.')';
493}
494
495function pwg_db_get_date_MMDD($date)
496{
497  return 'strftime(\'%m%d\','.$date.')';
498}
499
500function pwg_db_get_year($date)
501{
502  return 'strftime(\'%Y\','.$date.')';
503}
504
505function pwg_db_get_month($date)
506{
507  return 'strftime(\'%m\','.$date.')';
508}
509
510function pwg_db_get_week($date, $mode=null)
511{
512  return 'strftime(\'%W\','.$date.')';
513}
514
515function pwg_db_get_dayofmonth($date)
516{
517  return 'strftime(\'%d\','.$date.')';
518}
519
520function pwg_db_get_dayofweek($date)
521{
522  return 'strftime(\'%w\','.$date.')';
523}
524
525function pwg_db_get_weekday($date)
526{
527  return 'strftime(\'%w\',date('.$date.',\'-1 DAY\'))';
528}
529
530// my_error returns (or send to standard output) the message concerning the
531// error occured for the last mysql query.
532function my_error($header, $die)
533{
534  global $pwg_db_link;
535
536  $error = '';
537  if (isset($pwg_db_link)) 
538  {
539    $error .= '[sqlite error]'.$pwg_db_link->lastErrorMsg()."\n";
540  }
541
542  $error .= $header;
543
544  if ($die)
545  {
546    fatal_error($error);
547  }
548  echo("<pre>");
549  trigger_error($error, E_USER_WARNING);
550  echo("</pre>");
551}
552
553// sqlite create functions
554function pwg_now()
555{
556  return date('Y-m-d H:i:s');
557}
558
559function pwg_unix_timestamp()
560{
561  return time();
562}
563
564function pwg_if($expression, $value1, $value2) 
565{
566  if ($expression)
567  {
568    return $value1;
569  }
570  else
571  {
572    return $value2;
573  }
574} 
575
576function pwg_regexp($pattern, $string)
577{
578  $pattern = sprintf('`%s`', $pattern);
579  return preg_match($pattern, $string);
580}
581
582function pwg_std_step(&$values, $rownumber, $value) 
583{
584  $values[] = $value;
585
586  return $values;
587}
588
589function pwg_std_finalize(&$values, $rownumber) 
590{
591  if (count($values)<=1)
592  {
593    return 0;
594  }
595
596  $total = 0;
597  $total_square = 0;
598  foreach ($values as $value)
599  {
600    $total += $value;
601    $total_square += pow($value, 2);
602  }
603
604  $mean = $total/count($values);
605  $var = $total_square/count($values) - pow($mean, 2);
606 
607  return sqrt($var);
608}
609?>
Note: See TracBrowser for help on using the repository browser.