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

Last change on this file since 5196 was 5196, checked in by plg, 15 years ago

increase copyright year to 2010

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