diff options
author | Andy Wermke <andy@dev.next-step-software.com> | 2013-04-04 16:10:23 +0200 |
---|---|---|
committer | Andy Wermke <andy@dev.next-step-software.com> | 2013-04-04 16:10:23 +0200 |
commit | 92cd7f34b07e86062f2c024039e3309768b48ce6 (patch) | |
tree | 63b9f39280ebcab80742d9f2b4db6a139c1791e1 /bin/updatedb.sh | |
parent | 029d18f13bcf01aa2f1f08dbdfc6400c081bf7cb (diff) | |
parent | 443b92a7ee19e321b350750240e0fc54ec5be357 (diff) |
Merge branch 'master' of https://github.com/roundcube/roundcubemail
Diffstat (limited to 'bin/updatedb.sh')
-rwxr-xr-x | bin/updatedb.sh | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/bin/updatedb.sh b/bin/updatedb.sh new file mode 100755 index 000000000..7fa8cceb9 --- /dev/null +++ b/bin/updatedb.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env php +<?php +/* + +-----------------------------------------------------------------------+ + | bin/updatedb.sh | + | | + | This file is part of the Roundcube Webmail client | + | Copyright (C) 2010-2012, The Roundcube Dev Team | + | Copyright (C) 2010-2012, Kolab Systems AG | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + | PURPOSE: | + | Update database schema | + +-----------------------------------------------------------------------+ + | Author: Aleksander Machniak <alec@alec.pl> | + +-----------------------------------------------------------------------+ +*/ + +define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' ); + +require_once INSTALL_PATH . 'program/include/clisetup.php'; + +// get arguments +$opts = rcube_utils::get_opt(array( + 'v' => 'version', + 'd' => 'dir', + 'p' => 'package', +)); + +if (empty($opts['dir'])) { + echo "ERROR: Database schema directory not specified (--dir).\n"; + exit(1); +} +if (empty($opts['package'])) { + echo "ERROR: Database schema package name not specified (--package).\n"; + exit(1); +} + +// Check if directory exists +if (!file_exists($opts['dir'])) { + echo "ERROR: Specified database schema directory doesn't exist.\n"; + exit(1); +} + +$RC = rcube::get_instance(); +$DB = rcube_db::factory($RC->config->get('db_dsnw')); + +// Connect to database +$DB->db_connect('w'); +if (!$DB->is_connected()) { + echo "Error connecting to database: " . $DB->is_error() . ".\n"; + exit(1); +} + +// Read DB schema version from database (if 'system' table exists) +if (in_array($DB->table_name('system'), (array)$DB->list_tables())) { + $DB->query("SELECT " . $DB->quote_identifier('value') + ." FROM " . $DB->quote_identifier($DB->table_name('system')) + ." WHERE " . $DB->quote_identifier('name') ." = ?", + $opts['package'] . '-version'); + + $row = $DB->fetch_array(); + $version = preg_replace('/[^0-9]/', '', $row[0]); +} + +// DB version not found, but release version is specified +if (!$version && $opts['version']) { + // Map old release version string to DB schema version + // Note: This is for backward compat. only, do not need to be updated + $map = array( + '0.1-stable' => 1, + '0.1.1' => 2008030300, + '0.2-alpha' => 2008040500, + '0.2-beta' => 2008060900, + '0.2-stable' => 2008092100, + '0.3-stable' => 2008092100, + '0.3.1' => 2009090400, + '0.4-beta' => 2009103100, + '0.4.2' => 2010042300, + '0.5-beta' => 2010100600, + '0.5' => 2010100600, + '0.5.1' => 2010100600, + '0.6-beta' => 2011011200, + '0.6' => 2011011200, + '0.7-beta' => 2011092800, + '0.7' => 2011111600, + '0.7.1' => 2011111600, + '0.7.2' => 2011111600, + '0.7.3' => 2011111600, + '0.7.4' => 2011111600, + '0.8-beta' => 2011121400, + '0.8-rc' => 2011121400, + '0.8.0' => 2011121400, + '0.8.1' => 2011121400, + '0.8.2' => 2011121400, + '0.8.3' => 2011121400, + '0.8.4' => 2011121400, + '0.8.5' => 2011121400, + '0.8.6' => 2011121400, + '0.9-beta' => 2012080700, + ); + + $version = $map[$opts['version']]; +} + +// Assume last version before the 'system' table was added +if (empty($version)) { + $version = 2012080700; +} + +$dir = $opts['dir'] . DIRECTORY_SEPARATOR . $DB->db_provider; +if (!file_exists($dir)) { + echo "DDL Upgrade files for " . $DB->db_provider . " driver not found.\n"; + exit(1); +} + +$dh = opendir($dir); +$result = array(); + +while ($file = readdir($dh)) { + if (preg_match('/^([0-9]+)\.sql$/', $file, $m) && $m[1] > $version) { + $result[] = $m[1]; + } +} +sort($result, SORT_NUMERIC); + +foreach ($result as $v) { + echo "Updating database schema ($v)... "; + $error = update_db_schema($opts['package'], $v, $dir . DIRECTORY_SEPARATOR . "$v.sql"); + + if ($error) { + echo "\nError in DDL upgrade $v: $error\n"; + exit(1); + } + echo "[OK]\n"; +} + +exit(0); + +function update_db_schema($package, $version, $file) +{ + global $DB; + + // read DDL file + if ($lines = file($file)) { + $sql = ''; + foreach ($lines as $line) { + if (preg_match('/^--/', $line) || trim($line) == '') + continue; + + $sql .= $line . "\n"; + if (preg_match('/(;|^GO)$/', trim($line))) { + @$DB->query(fix_table_names($sql)); + $sql = ''; + if ($error = $DB->is_error()) { + return $error; + } + } + } + } + + // escape if 'system' table does not exist + if ($version < 2013011000) { + return; + } + + $system_table = $DB->quote_identifier($DB->table_name('system')); + + $DB->query("UPDATE " . $system_table + ." SET " . $DB->quote_identifier('value') . " = ?" + ." WHERE " . $DB->quote_identifier('name') . " = ?", + $version, $package . '-version'); + + if (!$DB->is_error() && !$DB->affected_rows()) { + $DB->query("INSERT INTO " . $system_table + ." (" . $DB->quote_identifier('name') . ", " . $DB->quote_identifier('value') . ")" + ." VALUES (?, ?)", + $package . '-version', $version); + } + + return $DB->is_error(); +} + +function fix_table_names($sql) +{ + global $DB; + + foreach (array('users','identities','contacts','contactgroups','contactgroupmembers','session','cache','cache_index','cache_index','cache_messages','dictionary','searches','system') as $table) { + $real_table = $DB->table_name($table); + if ($real_table != $table) { + $sql = preg_replace("/([^a-z0-9_])$table([^a-z0-9_])/i", "\\1$real_table\\2", $sql); + } + } + + return $sql; +} + +?> |