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

Last change on this file since 12802 was 12802, checked in by rvelices, 12 years ago

fetaure 2542 replace $conflocal_data_dir with $confdata_location and move combined files and image derivatives from local to _data

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