3 * FusionForge Database Installer Class
5 * Copyright (C) 2010-2011 Alain Peyrat
7 * This file is part of FusionForge. FusionForge is free software;
8 * you can redistribute it and/or modify it under the terms of the
9 * GNU General Public License as published by the Free Software
10 * Foundation; either version 2 of the Licence, or (at your option)
13 * FusionForge is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 class DatabaseInstaller extends FFError {
26 * __construct - DatabaseInstaller constructor
28 * @param string $name If set, name of plugin.
29 * @param string $path If set, path of upgrade scripts.
31 function __construct($name = '', $path = '') {
37 * install - Run database install scripts (for plugins)
39 * @return bool|string Output
45 $init = "$path/$name-init.sql";
47 $ret = $this->_runScript($init);
51 return $this->upgrade($name, $path);
53 return $this->setError(_('No database installation scripts found.'));
57 * upgrade - Upgrade database with upgrade scripts (usually in src/sql)
59 * @return bool|string Output
70 $date = $this->getDatabaseDate();
73 $scripts = $this->_getScripts($path);
75 foreach ($scripts as $script) {
76 if ((int)$script['date'] > $date) {
77 $res = db_query_params('SELECT * FROM database_changes WHERE filename=$1',
78 array($prefix.$script['filename']));
80 return $this->setError("ERROR-2: ".db_error());
81 } elseif (db_numrows($res) == 0) {
82 $output .= "Running script: {$script['filename']}\n";
83 $result = $this->_runScript($path.'/'.$script['filename']);
85 $res = db_query_params('INSERT INTO database_changes (filename) VALUES ($1)',
86 array($prefix.$script['filename']));
88 return $this->setError("ERROR-3: ".db_error());
100 * getDatabaseDate - Get status (date format) of the database.
102 * @return bool|int date if success, false otherwise.
104 private function getDatabaseDate() {
105 // Check if table 'database_startpoint' has proper values
106 $res = db_query_params('SELECT * FROM database_startpoint', array());
107 if (!$res) { // db error
108 return $this->setError("DB-ERROR-3: ".db_error()."\n");
109 } elseif (db_numrows($res) == 0) { // table 'database_startpoint' is empty
110 return $this->setError("Table 'database_startpoint' is empty, run startpoint.php first.");
112 return (int)db_result($res, 0, 'db_start_date');
116 * _runScript - Execute migration script given as argument (file)
118 * @param string $file Filename
119 * @return bool True if success
121 private function _runScript($file) {
122 // If a condition statement if found, then run the script only if true.
123 $content = file($file);
124 if (preg_match('/^-- TRUE\? (.+)/', $content[0], $match)) {
125 $res = db_query_params($match[1], array());
126 if (db_result($res, 0, 0) == 'f') {
130 $res = db_query_from_file($file);
133 db_free_result($res);
134 $res = db_next_result();
137 return $this->setError(_('Database initialisation error:').' '.db_error());
143 * _getScripts - Return a sorted array of available database upgrade scripts.
149 private static function _getScripts($dir) {
152 if ($dh = opendir($dir)) {
153 while (($file = readdir($dh)) !== false) {
154 $pos = strrpos($file, '.');
155 if ($pos !== false && $pos > 0) {
156 $name = substr($file, 0, $pos);
157 if (strlen($name) >= 8) {
158 $date_aux = substr($name, 0, 8);
159 $type_aux = substr($file, $pos + 1);
160 if ((int)$date_aux > 20000000 && ($type_aux == 'sql' || $type_aux == 'php')
161 && strpos($file, 'debian') === false
163 $data[] = array('date'=> $date_aux, 'filename'=> $file, 'ext'=> $type_aux);
170 usort($data, array('DatabaseInstaller', '_compare_scripts'));
177 * _compare_scripts - compare script for sorting (using filename)
184 private static function _compare_scripts($a, $b) {
185 return strcmp($a['filename'], $b['filename']);