From 77b79f24b7d599d7397fbd32667c88ad55f81b0e Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Fri, 13 Apr 2018 13:46:49 +0200 Subject: [PATCH] * Setup: updates from old versions (eg. 1.4 or 1.8) no longer require to update to 14.x and 16.1 first --- api/setup/tables_current.inc.php | 1 - api/src/Db/Backup.php | 5 ++-- api/src/Db/Schema.php | 37 +++++++++++++++++++++---- setup/inc/class.setup.inc.php | 47 ++++++++++++++++++++++++-------- 4 files changed, 70 insertions(+), 20 deletions(-) diff --git a/api/setup/tables_current.inc.php b/api/setup/tables_current.inc.php index 3eb42761a1..62788f5757 100644 --- a/api/setup/tables_current.inc.php +++ b/api/setup/tables_current.inc.php @@ -8,7 +8,6 @@ * @package api * @subpackage setup * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ */ $phpgw_baseline = array( diff --git a/api/src/Db/Backup.php b/api/src/Db/Backup.php index fd967dfcad..e84e12484c 100644 --- a/api/src/Db/Backup.php +++ b/api/src/Db/Backup.php @@ -7,8 +7,7 @@ * @package api * @subpackage db * @author Ralf Becker - * @copyright (c) 2003-16 by Ralf Becker - * @version $Id$ + * @copyright (c) 2003-18 by Ralf Becker */ namespace EGroupware\Api\Db; @@ -514,7 +513,7 @@ class Backup if (substr($line,0,9) == 'version: ') { - $api_version = trim(substr($line,9)); + // currenty not used: $api_version = trim(substr($line,9)); continue; } if (substr($line,0,9) == 'charset: ') diff --git a/api/src/Db/Schema.php b/api/src/Db/Schema.php index 1243b4ac20..8d67f133ce 100644 --- a/api/src/Db/Schema.php +++ b/api/src/Db/Schema.php @@ -12,7 +12,6 @@ * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @package api * @subpackage db - * @version $Id$ */ namespace EGroupware\Api\Db; @@ -20,7 +19,7 @@ namespace EGroupware\Api\Db; use EGroupware\Api; /** - * eGW's ADOdb based schema-processor + * EGroupware's ADOdb based schema-processor */ class Schema { @@ -536,7 +535,7 @@ class Schema * Create an (unique) Index over one or more columns * * @param string $sTableName table-name - * @param array $aColumnNames columns for the index + * @param string|array $aColumnNames column(s) for the index * @param boolean $bUnique =false true for a unique index, default false * @param array|string $options ='' db-sepecific options, default '' = none * @param string $sIdxName ='' name of the index, if not given (default) its created automaticaly @@ -556,6 +555,18 @@ class Schema if (!is_array($options)) $options = $options ? array($options) : array(); if ($bUnique) $options[] = 'UNIQUE'; + // if index already exists drop it first + $definition = array(); + $this->GetIndexes($sTableName, $definition); + $type = $bUnique ? 'uc' : 'ix'; + if ($this->_in_index($aColumnNames, $definition[$type], true) || + // sometimes index is listed as unique index too --> ignore that + ($type == 'ix' && $this->_in_index($aColumnNames, $definition['uc'], true))) + { + //error_log(__METHOD__."('$sTableName', ['".implode("','", (array)$aColumnNames)."'], $bUnique, ...) already exists --> droping it first"); + $this->DropIndex($sTableName, (array)$aColumnNames); + } + $aSql = $this->dict->CreateIndexSQL($sIdxName,$sTableName,$aColumnNames,$options); return $this->ExecuteSQLArray($aSql,2,'CreateIndexSQL(%1,%2,%3,%4) sql=%5',False,$sTableName,$aColumnNames,$options,$sIdxName,$aSql); @@ -1100,6 +1111,13 @@ class Schema $ado_col = 'I AUTOINCREMENT NOTNULL'; unset($col_data['nullable']); // else we set it twice break; + case 'binary': // varbinary column for MySQL/MariaDB + if ($this->sType == 'mysql' && $col_data['precision'] <= $this->max_varchar_length) + { + $ado_col = 'C('.$col_data['precision'].') CONSTRAINT "CHARACTER SET binary"'; + break; + } + // fall through to blob case 'blob': $ado_col = 'B'; break; @@ -1413,7 +1431,7 @@ class Schema $s = strtolower($s); }); } - if (count($definition['pk']) && (implode(':',$definition['pk']) == implode(':',$index['columns']) || + if (!empty($definition['pk']) && (implode(':',$definition['pk']) == implode(':',$index['columns']) || $index['unique'] && count(array_intersect($definition['pk'],$index['columns'])) == count($definition['pk']))) { continue; // is already the primary key => ignore it @@ -1430,7 +1448,9 @@ class Schema /** * Check if all indexes exist and create them if not * - * Does not check index-type of length! + * Used eg. after restoring a backup to make sure all indexes are in place. + * + * Does not check index-type or length! */ function CheckCreateIndexes() { @@ -1440,6 +1460,7 @@ class Schema $definition = array(); $this->GetIndexes($table, $definition); + $current = $this->m_odb->metadata($table, true); // iterate though indexes we should have according to tables_current foreach(array('uc', 'ix') as $type) @@ -1449,6 +1470,12 @@ class Schema // sometimes primary key is listed as (unique) index too --> ignore it if ($this->_in_index($columns, array($table_def['pk']), true)) continue; + // current table does NOT contain all columns, eg. not yet updated --> ignore index + if (array_diff((array)$columns, array_keys($current['meta']))) + { + //error_log(__METHOD__."() Can't create index over ", implode(',')." on table $table, as not all columns exist (yet)!"); + continue; + } // check if they exist in real table and create them if not if (!$this->_in_index($columns, $definition[$type]) && // sometimes index is listed as unique index too --> ignore that diff --git a/setup/inc/class.setup.inc.php b/setup/inc/class.setup.inc.php index 01d8353e1a..3ef7d460e4 100644 --- a/setup/inc/class.setup.inc.php +++ b/setup/inc/class.setup.inc.php @@ -10,7 +10,6 @@ * @author Miles Lott * @author Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ */ use EGroupware\Api; @@ -515,17 +514,31 @@ class setup 'config_value' => $setup_info[$appname]['tables_prefix'], ),False,__LINE__,__FILE__); } - $this->db->insert($this->applications_table,array( - 'app_name' => $appname, - 'app_enabled' => $enable, - 'app_order' => $setup_info[$appname]['app_order'], - 'app_tables' => (string)$tables, // app_tables is NOT NULL - 'app_version' => $setup_info[$appname]['version'], - 'app_index' => $setup_info[$appname]['index'], - 'app_icon' => $setup_info[$appname]['icon'], - 'app_icon_app' => $setup_info[$appname]['icon_app'], - ),False,__LINE__,__FILE__); + try { + $this->db->insert($this->applications_table,array( + 'app_name' => $appname, + 'app_enabled' => $enable, + 'app_order' => $setup_info[$appname]['app_order'], + 'app_tables' => (string)$tables, // app_tables is NOT NULL + 'app_version' => $setup_info[$appname]['version'], + 'app_index' => $setup_info[$appname]['index'], + 'app_icon' => $setup_info[$appname]['icon'], + 'app_icon_app' => $setup_info[$appname]['icon_app'], + ),False,__LINE__,__FILE__); + } + catch (Api\Db\Exception\InvalidSql $e) + { + // ease update from pre 1.6 eg. 1.4 not having app_index, app_icon, app_icon_app columns + _egw_log_exception($e); + $this->db->insert($this->applications_table,array( + 'app_name' => $appname, + 'app_enabled' => $enable, + 'app_order' => $setup_info[$appname]['app_order'], + 'app_tables' => (string)$tables, // app_tables is NOT NULL + 'app_version' => $setup_info[$appname]['version'], + ),False,__LINE__,__FILE__); + } Api\Egw\Applications::invalidate(); } } @@ -1024,6 +1037,18 @@ class setup 'account_email' => $email, 'account_members' => array() ); + + // check if egw_accounts.account_description already exists, as the update otherwise fails + $meta = $GLOBALS['egw_setup']->db->metadata('egw_accounts', true); + if (!isset($meta['meta']['account_description'])) + { + $GLOBALS['egw_setup']->oProc->AddColumn('egw_accounts','account_description',array( + 'type' => 'varchar', + 'precision' => '255', + 'comment' => 'group description' + )); + } + if (!($accountid = $this->accounts->save($account))) { error_log("setup::add_account('$username','$first','$last',\$passwd,'$primary_group',$changepw,'$email') failed! accountid=$accountid");