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

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

Fix bug 1717 : SQLite: access failure on Admin > Tools > History
hour function doesn't exists

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