diff --git a/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php b/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php index f5c43271fc..d8f624c7ff 100644 --- a/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php +++ b/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php @@ -131,6 +131,9 @@ class ADODB2_postgres extends ADODB_DataDict { list($lines,$pkey) = $this->_GenFields($flds); $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' '; foreach($lines as $v) { + if (($not_null = preg_match('/NOT NULL/i',$v))) { + $v = preg_replace('/NOT NULL/i','',$v); + } if (preg_match('/^([^ ]+) .*(DEFAULT [^ ]+)/',$v,$matches)) { list(,$colname,$default) = $matches; $sql[] = $alter . str_replace($default,'',$v); @@ -138,6 +141,10 @@ class ADODB2_postgres extends ADODB_DataDict { } else { $sql[] = $alter . $v; } + if ($not_null) { + list($colname) = explode(' ',$v); + $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL'; + } } return $sql; } @@ -194,8 +201,8 @@ class ADODB2_postgres extends ADODB_DataDict { * @internal * @param string $tabname table-name * @param string $dropflds column-names to drop - * @param string $tableflds complete defintion of the new table, eg. for postgres, default '' - * @param array/ $tableoptions options for the new table see CreateTableSQL, default '' + * @param string $tableflds complete defintion of the new table, eg. for postgres + * @param array/string $tableoptions options for the new table see CreateTableSQL, default '' * @return array with SQL strings */ function _recreate_copy_table($tabname,$dropflds,$tableflds,$tableoptions='') @@ -204,7 +211,13 @@ class ADODB2_postgres extends ADODB_DataDict { $copyflds = array(); foreach($this->MetaColumns($tabname) as $fld) { if (!$dropflds || !in_array($fld->name,$dropflds)) { - $copyflds[] = $fld->name; + // we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one + if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) && + in_array($fld->type,array('varchar','char','text','bytea'))) { + $copyflds[] = "to_number($fld->name,'S99D99')"; + } else { + $copyflds[] = $fld->name; + } // identify the sequence name and the fld its on if ($fld->primary_key && $fld->has_default && preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) { @@ -222,6 +235,7 @@ class ADODB2_postgres extends ADODB_DataDict { $aSql = array_merge($aSql,$this->CreateTableSQL($tabname,$tableflds,$tableoptions)); $aSql[] = "INSERT INTO $tabname SELECT $copyflds FROM $tempname"; if ($seq_name && $seq_fld) { // if we have a sequence we need to set it again + $seq_name = $tabname.'_'.$seq_fld.'_seq'; // has to be the name of the new implicit sequence $aSql[] = "SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname"; } $aSql[] = "DROP TABLE $tempname"; diff --git a/phpgwapi/inc/class.schema_proc.inc.php b/phpgwapi/inc/class.schema_proc.inc.php index 7f13b59477..6b8109f18e 100644 --- a/phpgwapi/inc/class.schema_proc.inc.php +++ b/phpgwapi/inc/class.schema_proc.inc.php @@ -27,9 +27,7 @@ class schema_proc { var $m_oTranslator; - var $m_oDeltaProc; var $m_odb; - var $m_aTables; // stores the table-definitions of an application, set by ExecuteScripts var $m_bDeltaOnly; var $debug = 0; // 0=Off, 1=some, eg. primary function calls, 2=lots incl. the SQL used var $max_index_length=array( // if known @@ -43,11 +41,8 @@ * * @param string $dbms type of the database: 'mysql','pgsql','mssql','sapdb' */ - function schema_proc($dbms=False,$aTables=False) + function schema_proc($dbms=False) { - $this->m_aTables = array(); - $this->m_bDeltaOnly = False; // Default to false here in case it's just a CreateTable script - $this->m_odb = is_object($GLOBALS['phpgw']->db) ? $GLOBALS['phpgw']->db : $GLOBALS['phpgw_setup']->db; $this->m_odb->connect(); @@ -84,9 +79,6 @@ { $this->debug_message('schema_proc::CreateTable(%1,%2)',False,$sTableName, $aTableDef); } - $this->m_aTables[$sTableName] = $aTableDef; - if($this->m_bDeltaOnly) return true; - // creating the table $aSql = $this->dict->CreateTableSQL($sTableName,$ado_cols = $this->_egw2adodb_columndef($aTableDef)); if (!($retVal = $this->ExecuteSQLArray($aSql,2,'CreateTableSQL(%1,%2) sql=%3',False,$sTableName,$ado_cols,$aSql))) @@ -170,9 +162,6 @@ if ($this->debug) $bOutputHTML = True; if ($bOutputHTML && !$this->debug) $this->debug = 2; - $this->m_aTables = array(); - if($this->m_bDeltaOnly) return true; - foreach($aTables as $sTableName => $aTableDef) { if($this->DropTable($sTableName)) @@ -198,9 +187,6 @@ */ function DropTable($sTableName) { - unset($this->m_aTables[$sTableName]); - if($this->m_bDeltaOnly) return True; - if ($this->sType == 'pgsql') $this->_PostgresTestDropOldSequence($sTableName); $aSql = $this->dict->DropTableSql($sTableName); @@ -219,10 +205,10 @@ */ function DropColumn($sTableName, $aTableDef, $sColumnName, $bCopyData = true) { - unset($this->m_aTables[$sTableName]['fd'][$sColumnName]); - if($this->m_bDeltaOnly) return True; - - $aSql = $this->dict->DropColumnSql($sTableName,$sColumnName,$ado_table=$this->_egw2adodb_columndef($this->m_aTables[$sTableName])); + $table_def = $this->GetTableDefinition($sTableName); + unset($table_def['fd'][$sColumnName]); + + $aSql = $this->dict->DropColumnSql($sTableName,$sColumnName,$ado_table=$this->_egw2adodb_columndef($table_def)); return $this->ExecuteSQLArray($aSql,2,'DropColumnSQL(%1,%2,%3) sql=%4',False,$sTableName,$sColumnName,$ado_table,$aSql); } @@ -236,10 +222,6 @@ */ function RenameTable($sOldTableName, $sNewTableName) { - $this->m_aTables[$sNewTableName] = $this->m_aTables[$sOldTableName]; - unset($this->m_aTables[$sOldTableName]); - if($this->m_bDeltaOnly) return True; - if ($this->sType == 'pgsql') $this->_PostgresTestDropOldSequence($sTableName); $aSql = $this->dict->RenameTableSQL($sOldTableName, $sNewTableName); @@ -255,13 +237,14 @@ */ function _PostgresTestDropOldSequence($sTableName) { - if (!$this->sType == 'pgsql') return; + if ($this->sType != 'pgsql') return; - $seq = $this->adodb->GetOne("SELECT a.attname FROM pg_attribute a, pg_class c, pg_attrdef d WHERE c.relname='$sTableName' AND c.oid=d.adrelid AND d.adsrc LIKE '%seq_$sTableName%' AND a.attrelid=c.oid AND d.adnum=a.attnum"); + $seq = $this->adodb->GetOne("SELECT d.adsrc FROM pg_attribute a, pg_class c, pg_attrdef d WHERE c.relname='$sTableName' AND c.oid=d.adrelid AND d.adsrc LIKE '%seq_$sTableName%' AND a.attrelid=c.oid AND d.adnum=a.attnum"); - if ($seq) + if ($seq && preg_match('/^nextval\(\'(.*)\'/',$seq,$matches)) { - $this->query("DROP SEQUENCE $seq",__LINE__,__FILE__); + + $this->query('DROP SEQUENCE '.$matches[1],__LINE__,__FILE__); } } @@ -276,13 +259,13 @@ */ function AlterColumn($sTableName, $sColumnName, $aColumnDef, $bCopyData=True) { - $this->m_aTables[$sTableName]['fd'][$sColumnName] = $aColumnDef; - if($this->m_bDeltaOnly) return True; + $table_def = $this->GetTableDefinition($sTableName); + $table_def['fd'][$sColumnName] = $aColumnDef; $aSql = $this->dict->AlterColumnSQL($sTableName,$ado_col = $this->_egw2adodb_columndef(array( 'fd' => array($sColumnName => $aColumnDef), 'pk' => array(), - )),$ado_table=$this->_egw2adodb_columndef($this->m_aTables[$sTableName])); + )),$ado_table=$this->_egw2adodb_columndef($table_def)); return $this->ExecuteSQLArray($aSql,2,'AlterColumnSQL(%1,%2,%3) sql=%4',False,$sTableName,$ado_col,$ado_table,$aSql); } @@ -298,36 +281,12 @@ */ function RenameColumn($sTableName, $sOldColumnName, $sNewColumnName, $bCopyData=True) { - $this->m_aTables[$sTableName]['fd'][$sNewColumnName] = $this->m_aTables[$sTableName]['fd'][$sOldColumnName]; - unset($this->m_aTables[$sTableName]['fd'][$sOldColumnName]); - - // check if column is used in an index and evtl. rename the column in the index-definition - if (($key = array_search($sOldColumnName,$this->m_aTables[$sTableName]['pk'])) !== false) - { - $this->m_aTables[$sTableName]['pk'][$key] = $sNewColumnName; - } - foreach(array('ix','uc') as $kind) - { - foreach($this->m_aTables[$sTableName][$kind] as $key => $index) - { - if (!is_array($index)) - { - if ($index == $sOldColumnName) $this->m_aTables[$sTableName][$kind][$key] = $sNewColumnName; - } - elseif (($sub_key = array_search($sOldColumnName,$index)) !== false) - { - $this->m_aTables[$sTableName][$kind][$key][$sub_key] = $sNewColumnName; - } - } - } - if($this->m_bDeltaOnly) return True; - - // we have to use the new column-name, as m_oDeltaProc has already changed m_aTables + $table_def = $this->GetTableDefinition($sTableName); $col_def = $this->_egw2adodb_columndef(array( - 'fd' => array($sNewColumnName => $this->m_aTables[$sTableName]['fd'][$sNewColumnName]), + 'fd' => array($sNewColumnName => $table_def['fd'][strtolower($sOldColumnName)]), 'pk' => array(), )); - + $aSql = $this->dict->RenameColumnSQL($sTableName,$sOldColumnName,$sNewColumnName,$col_def); return $this->ExecuteSQLArray($aSql,2,'RenameColumnSQL(%1,%2,%3) sql=%4',False,$sTableName,$sOldColumnName, $sNewColumnName,$aSql); @@ -343,9 +302,6 @@ */ function AddColumn($sTableName, $sColumnName, $aColumnDef) { - $this->m_aTables[$sTableName]['fd'][$sColumnName] = $aColumnDef; - if($this->m_bDeltaOnly) return True; - $aSql = $this->dict->AddColumnSQL($sTableName,$ado_cols = $this->_egw2adodb_columndef(array( 'fd' => array($sColumnName => $aColumnDef), 'pk' => array(), @@ -364,20 +320,18 @@ * @param string $sIdxName='' name of the index, if not given (default) its created automaticaly * @return int 2: no error, 1: errors, but continued, 0: errors aborted */ - function CreateIndex($sTableName,$aColumnNames,$type=False,$options='',$sIdxName='') + function CreateIndex($sTableName,$aColumnNames,$bUnique=false,$options='',$sIdxName='') { - $kind = $bUnique ? 'uc' : 'ix'; - $key = !$sIdxName || is_numeric($sIdxName) ? count($this->m_aTables[$sTableName][$kind]) : $sIdxName; - $this->m_aTables[$sTableName][$kind][$key] = $aColumnNames; - if($this->m_bDeltaOnly) return true; - if (!$sIdxName || is_numeric($sIdxName)) { $sIdxName = $this->_index_name($sTableName,$aColumnNames); } - $aSql = $this->dict->CreateIndexSQL($name,$sTableName,$aColumnNames,is_array($options) ? $options : array($options)); + if (!is_array($options)) $options = $options ? array($options) : array(); + if ($bUnique) $options[] = 'UNIQUE'; - return $this->ExecuteSQLArray($aSql,2,'CreateIndexSQL(%1,%2,%3) sql=%4',False,$name,$sTableName,$sColumnName, $aColumnDef,$aSql); + $aSql = $this->dict->CreateIndexSQL($name,$sTableName,$aColumnNames,$options); + + return $this->ExecuteSQLArray($aSql,2,'CreateIndexSQL(%1,%2,%3,%4) sql=%5',False,$name,$sTableName,$aColumnNames,$options,$aSql); } /** @@ -391,20 +345,6 @@ { if (is_array($aColumnNames)) { - foreach(array('ix','uc') as $kind) - { - foreach($this->m_aTables[$sTableName][$kind] as $idx => $columns) - { - if (!is_array($columns)) $columns = array($columns); - unset($columns['options']); - - if (implode(':',$columns) == implode(':',$aColumnNames)) - { - unset($this->m_aTables[$sTableName][$kind][$idx]); - break; - } - } - } $indexes = $this->dict->MetaIndexes($sTableName); if ($indexes === False) { @@ -428,7 +368,7 @@ { $sIdxName = $aColumnNames; } - if($this->m_bDeltaOnly || !$sIdxName) + if(!$sIdxName) { return True; } @@ -455,7 +395,7 @@ $seq_name = $matches[1]; } $sql = "SELECT setval('$seq_name',MAX($sColumnName)) FROM $sTableName"; - if($GLOBALS['DEBUG']) { echo "
Updating sequence '$seq_name using: $sql"; } + if($this->debug) { echo "
Updating sequence '$seq_name using: $sql"; } return $this->query($sql,__LINE__,__FILE__); } return True; @@ -475,11 +415,9 @@ */ function RefreshTable($sTableName, $aTableDef, $aDefaults=False) { - if($GLOBALS['DEBUG']) { echo "

schema_proc::RefreshTable('$sTableName',"._debug_array($aTableDef,False).")

m_aTables[$sTableName]="._debug_array($this->m_aTables[$sTableName],False)."\n"; } - $old_fd = $this->m_aTables[$sTableName]['fd']; - - $this->m_aTables[$sTableName] = $aTableDef; - if($this->m_bDeltaOnly) return true; + if($this->debug) { echo "

schema_proc::RefreshTable('$sTableName',"._debug_array($aTableDef,False).")

$sTableName="._debug_array($old_table_def,False)."\n"; } + + $old_table_def = $this->GetTableDefinition($sTableName); $tmp_name = 'tmp_'.$sTableName; $this->m_odb->transaction_begin(); @@ -492,9 +430,16 @@ { $value = $aDefaults[$name]; } - elseif (isset($old_fd[$name])) // existing column, use its value => column-name in query + elseif (isset($old_table_def['fd'][$name])) // existing column, use its value => column-name in query { $value = $name; + // this is eg. necessary to change a varchar into an int column under postgres + if ($this->sType == 'pgsql' && + in_array($old_table_def['fd'][$name]['type'],array('char','varchar','text','blob')) && + in_array($data['type'],array('int','decimal'))) + { + $value = "to_number($name,'S99D99')"; + } } else // new column => use default value or NULL { @@ -505,11 +450,13 @@ else { $value = $this->m_odb->quote(isset($data['default']) ? $data['default'] : '',$data['type']); - // fix for postgres error "no '<' operator for type 'unknown'" if ($this->sType == 'pgsql') { - $type_translated = $this->m_oTranslator->TranslateType($data['type']); - $value = "CAST($value AS $type_translated)"; + // fix for postgres error "no '<' operator for type 'unknown'" + if(($type_translated = $this->TranslateType($data['type']))) + { + $value = "CAST($value AS $type_translated)"; + } } } } @@ -529,10 +476,10 @@ break; } // because of all the trouble with sequences and indexes in the global namespace, - // we use an additional temp. table for postgres and not rename the existing on, but drop it. + // we use an additional temp. table for postgres and not rename the existing one, but drop it. if ($this->sType == 'pgsql') { - $Ok = $this->m_odb->query("SELECT * INTO TEMPORARY TABLE $tmp_name FROM $sTableName",__LINE__,__FILE__) && + $Ok = $this->m_odb->query("SELEcT * INTO TEMPORARY TABLE $tmp_name FROM $sTableName",__LINE__,__FILE__) && $this->DropTable($sTableName); } else @@ -542,7 +489,7 @@ $Ok = $Ok && $this->CreateTable($sTableName,$aTableDef) && $this->m_odb->query("$extra INSERT INTO $sTableName (". implode(',',array_keys($aTableDef['fd'])). - ") SELECT $distinct $select FROM $tmp_name",__LINE__,__FILE__) && + ") SELEcT $distinct $select FROM $tmp_name",__LINE__,__FILE__) && $this->DropTable($tmp_name); if (!$Ok) @@ -555,7 +502,6 @@ { $this->UpdateSequence($sTableName,$aTableDef['pk'][0]); } - $this->DropTable($tmp_name); $this->m_odb->transaction_commit(); return True; @@ -587,8 +533,6 @@ if ($this->debug) $bOutputHTML = True; if ($bOutputHTML && !$this->debug) $this->debug = 2; - $this->m_aTables = array(); - foreach($aTables as $sTableName => $aTableDef) { if($this->CreateTable($sTableName, $aTableDef)) @@ -620,11 +564,6 @@ */ function f($value,$strip_slashes=False) { - if($this->m_bDeltaOnly) - { - // Don't care, since we are processing deltas only - return False; - } return $this->m_odb->f($value,$strip_slashes); } @@ -635,11 +574,6 @@ */ function num_rows() { - if($this->m_bDeltaOnly) - { - // If not False, we will cause while loops calling us to hang - return False; - } return $this->m_odb->num_rows(); } @@ -650,11 +584,6 @@ */ function next_record() { - if($this->m_bDeltaOnly) - { - // If not False, we will cause while loops calling us to hang - return False; - } return $this->m_odb->next_record(); } @@ -670,11 +599,6 @@ */ function query($sQuery, $line='', $file='') { - if($this->m_bDeltaOnly) - { - // Don't run this query, since we are processing deltas only - return True; - } return $this->m_odb->query($sQuery, $line, $file); } @@ -692,11 +616,6 @@ */ function insert($table,$data,$where,$line,$file,$app) { - if($this->m_bDeltaOnly) - { - // Don't run this query, since we are processing deltas only - return True; - } return $this->m_odb->insert($table,$data,$where,$line,$file,$app); } @@ -934,7 +853,7 @@ } if (!$ado_col) { - $this->error("Ignoring unknown column-type '$col_data[type]($col_data[precision])' !!!"); + $this->error("Ignoring unknown column-type '$col_data[type]($col_data[precision])' !!!
".function_backtrace()); continue; } if (isset($col_data['nullable']) && !$col_data['nullable']) @@ -955,6 +874,21 @@ return implode(",\n",$ado_defs); } + /** + * Translates an eGW type into the DB's native type + * + * @param string $egw_type eGW name of type + * @param string/boolean DB's name of the type or false if the type could not be identified (should not happen) + */ + function TranslateType($egw_type) + { + $ado_col = $this->_egw2adodb_columndef(array( + 'fd' => array('test' => array('type' => $egw_type)), + 'pk' => array(), + )); + return preg_match('/test ([A-Z0-9]+)/i',$ado_col,$matches) ? $this->dict->ActualType($matches[1]) : false; + } + /** * Read the table-definition direct from the database * @@ -1140,7 +1074,7 @@ } /** - * Get actual columnnames as a comma-separated string in$sColumns and set table-definition in class-vars + * Get actual columnnames as a comma-separated string in $sColumns and set indices as class-vars pk,fk,ix,uc * * old translator function, use GetTableDefition() instead * @depricated diff --git a/phpgwapi/inc/class.setup_process.inc.php b/phpgwapi/inc/class.setup_process.inc.php index 7a12738df4..5b1ad0f603 100644 --- a/phpgwapi/inc/class.setup_process.inc.php +++ b/phpgwapi/inc/class.setup_process.inc.php @@ -6,6 +6,8 @@ * This file written by Miles Lott * * Originally written for phpGroupWare. * * (C) 2001-2004 Miles Lott * + * Upgrade process rewritten by to no * + * longer require tables_baseline files and delta-upgrades * * -------------------------------------------- * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the * @@ -43,17 +45,7 @@ */ function init_process() { - $ConfigDomain = get_var('ConfigDomain',array('COOKIE','POST')); - $phpgw_domain = $GLOBALS['phpgw_domain']; - - $GLOBALS['phpgw_setup']->oProc = CreateObject('phpgwapi.schema_proc',$phpgw_domain[$ConfigDomain]['db_type']); - $GLOBALS['phpgw_setup']->oProc->m_odb = $GLOBALS['phpgw_setup']->db; - $GLOBALS['phpgw_setup']->oProc->m_odb->Host = $phpgw_domain[$ConfigDomain]['db_host']; - $GLOBALS['phpgw_setup']->oProc->m_odb->Database = $phpgw_domain[$ConfigDomain]['db_name']; - $GLOBALS['phpgw_setup']->oProc->m_odb->User = $phpgw_domain[$ConfigDomain]['db_user']; - $GLOBALS['phpgw_setup']->oProc->m_odb->Password = $phpgw_domain[$ConfigDomain]['db_pass']; - $GLOBALS['phpgw_setup']->oProc->m_odb->Halt_On_Error = 'report'; - $GLOBALS['phpgw_setup']->oProc->m_odb->connect(); + $GLOBALS['phpgw_setup']->oProc = CreateObject('phpgwapi.schema_proc'); } /*! @@ -64,7 +56,7 @@ @param $DEBUG optional, print debugging info @param $force_en optional, install english language files */ - function pass($setup_info,$method='new',$DEBUG=False,$force_en=False) + function pass($setup_info,$method='new',$DEBUG=False,$force_en=False,$system_charset=false) { if(!$method) { @@ -83,6 +75,7 @@ $passing = array(); $pass_string = implode (':', $pass); $passing_string = implode (':', $passing); + $do_langs = false; while($pass_string != $passing_string) { $passing = array(); @@ -124,14 +117,14 @@ case 'new': /* Create tables and insert new records for each app in this list */ $passing = $this->current($pass,$DEBUG); + $this->save_minimal_config($system_charset); $passing = $this->default_records($passing,$DEBUG); - $passing = $this->add_langs($passing,$DEBUG,array(get_var('ConfigLang',Array('POST','COOKIE')),'en')); - $this->save_minimal_config(); + $do_langs = true; // just do it once at the end of all passes break; case 'upgrade': /* Run upgrade scripts on each app in the list */ $passing = $this->upgrade($pass,$DEBUG); - $passing = $this->upgrade_langs($passing,$DEBUG); + $do_langs = true; // just do it once at the end of all passes //_debug_array($pass);exit; break; default: @@ -179,22 +172,25 @@ $pass_string = implode (':', $pass); $passing_string = implode (':', $passing); } - - /* now return the list */ - @reset($passed); - while(list($key,$value) = @each($passed)) + if ($do_langs) // just do it once at the end of all passes { - $setup_info[$value['name']] = $passed[$value['name']]; + $langs = false; + if ($method == 'new') + { + $langs[] = ($own_lang = get_var('ConfigLang',Array('POST','COOKIE'))); + if ($own_lang != 'en') $langs[] = 'en'; + } + $this->translation->drop_add_all_langs($langs); } - - return ($setup_info); + /* now return the list */ + return $setup_info = array_merge($setup_info,$passed); } /*! @function save_minimal_config @abstract saves a minimal default config, so you get a running install without entering and saveing Step #2 config */ - function save_minimal_config() + function save_minimal_config($system_charset) { $GLOBALS['current_config']['site_title'] = 'eGroupWare'; $GLOBALS['current_config']['hostname'] = $_SERVER['HTTP_HOST']; @@ -225,6 +221,15 @@ // RalfBecker: php.net recommend this for security reasons, it should be our default too $GLOBALS['current_config']['usecookies'] = 'True'; + + if ($system_charset) + { + $GLOBALS['current_config']['system_charset'] = $system_charset; + if (is_object($GLOBALS['phpgw_setup']->translation->sql)) + { + $GLOBALS['phpgw_setup']->translation->sql->system_charset = $system_charset; + } + } foreach($GLOBALS['current_config'] as $setting => $value) { @@ -246,8 +251,6 @@ { $this->init_process(); } - $GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly = False; - /* The following is built so below we won't try to drop a table that isn't there. */ $tablenames = $GLOBALS['phpgw_setup']->db->table_names(); if (!is_array($setup_info) || !is_array($tablenames)) @@ -298,8 +301,6 @@ { $this->init_process(); } - $GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly = False; - @reset($setup_info); while(list($key,$null) = @each($setup_info)) { @@ -380,9 +381,6 @@ { $this->init_process(); } - $GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly = False; -// $oProc = $GLOBALS['phpgw_setup']->oProc; - @reset($setup_info); while(list($key,$null) = @each($setup_info)) { @@ -407,75 +405,6 @@ return ($setup_info); } - /*! - @function add_langs - @abstract process application lang files and uninstall - @param $setup_info array of application info from setup.inc.php files, etc. - */ - function add_langs($setup_info,$DEBUG=False,$force_langs=False) - { - @reset($setup_info); - while(list($key,$null) = @each($setup_info)) - { - $appname = $setup_info[$key]['name']; - $this->translation->add_langs($appname,$DEBUG,$force_langs); - if($DEBUG) - { - echo '
process->add_langs(): Translations added for ' . $appname . "\n"; - } - } - /* Done, return current status */ - return ($setup_info); - } - - /*! - @function drop_langs - @abstract process application lang files and install - @param $setup_info array of application info from setup.inc.php files, etc. - */ - function drop_langs($setup_info,$DEBUG=False) - { - @reset($setup_info); - while(list($key,$null) = @each($setup_info)) - { - $appname = $setup_info[$key]['name']; - $this->translation->drop_langs($appname,$DEBUG); - if($DEBUG) - { - echo '
process->drop_langs(): Translations removed for ' . $appname . "\n"; - } - } - /* Done, return current status */ - return ($setup_info); - } - - /*! - @function upgrade_langs - @abstract process application lang files and reinstall - @param $setup_info array of application info from setup.inc.php files, etc. - */ - function upgrade_langs($setup_info,$DEBUG=False) - { - @reset($setup_info); - while(list($key,$null) = @each($setup_info)) - { - /* Don't upgrade lang files in the middle of an upgrade */ - if($setup_info[$key]['status'] == 'R') - { - continue; - } - $appname = $setup_info[$key]['name']; - $this->translation->drop_langs($appname,$DEBUG); - $this->translation->add_langs($appname,$DEBUG); - if($DEBUG) - { - echo '
process->upgrade_langs(): Translations reinstalled for ' . $appname . "\n"; - } - } - /* Done, return current status */ - return ($setup_info); - } - /*! @function test_data @abstract process test_data.inc.php in each application/setup dir for developer tests @@ -488,9 +417,6 @@ { $this->init_process(); } - $GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly = False; -// $oProc = $GLOBALS['phpgw_setup']->oProc; - @reset($setup_info); while(list($key,$null) = @each($setup_info)) { @@ -569,250 +495,118 @@ { $this->init_process(); } - $GLOBALS['phpgw_setup']->oProc->m_odb->HaltOnError = 'no'; - $GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly = True; + $GLOBALS['phpgw_setup']->oProc->m_odb->HaltOnError = 'yes'; - @reset($setup_info); - while(list($key,$null) = @each($setup_info)) + foreach($setup_info as $key => $appdata) { + $appname = $appdata['name']; /* Don't try to upgrade an app that is not installed */ - if(!$GLOBALS['phpgw_setup']->app_registered($setup_info[$key]['name'])) + if(!$GLOBALS['phpgw_setup']->app_registered($appname)) { if($DEBUG) { - echo '
process->upgrade(): Application not installed: ' . $appname . "\n"; + echo "

process->upgrade(): Application not installed: $appname

\n"; } - unset($setup_info[$key]); + unset($setup_info[$appname]); continue; } /* if upgrade required, or if we are running again after an upgrade or dependency failure */ - if($DEBUG) { echo '
process->upgrade(): Incoming : appname: '.$setup_info[$key]['name'] . ' status: ' . $setup_info[$key]['status']; } - if($setup_info[$key]['status'] == 'U' || - $setup_info[$key]['status'] == 'D' || - $setup_info[$key]['status'] == 'V' || - $setup_info[$key]['status'] == '') // TODO this is not getting set for api upgrade, sometimes ??? + if($DEBUG) + { + echo '
'."process->upgrade(): Incoming : appname: $appname, version: $appdata[currentver], status: $appdata[status]\n"; + } + if($appdata['status'] == 'U' || $appdata['status'] == 'D' ||$appdata['status'] == 'V' || $appdata['status'] == '') // TODO this is not getting set for api upgrade, sometimes ??? { - $appname = $setup_info[$key]['name']; - $apptitle = $setup_info[$key]['title']; - $currentver = $setup_info[$key]['currentver']; - $targetver = $setup_info[$key]['version']; // The version we need to match when done + $currentver = $appdata['currentver']; + $targetver = $appdata['version']; // The version we need to match when done $appdir = PHPGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; - $test = array(); - $GLOBALS['phpgw_setup']->oProc->m_aTables = $phpgw_baseline = array(); -/* - $phpgw_baseline = array(); - - $tmpapp = array(); - $tmpapp[] = $setup_info[$key]; - $this->baseline($tmpapp,$DEBUG); - $GLOBALS['phpgw_setup']->oProc->m_aTables = $phpgw_baseline; - // So far, including the baseline file is not helping. - // Only AlterColumn/RenameColumn seem to be failing silently. - // This is because we are not keeping up with table changes, so a table in baseline - // either does not exist anymore, or the baseline is being lost. - // 10-18-2003 milosch - The baseline file is definitely needed for any app with and update file. -*/ - if($setup_info[$key]['tables'] && file_exists($appdir.'tables_baseline.inc.php')) - { - if($DEBUG) - { - echo '
process->baseline(): Including baseline tables for ' . $appname . "\n"; - } - include ($appdir.'tables_baseline.inc.php'); - $GLOBALS['phpgw_setup']->oProc->m_aTables = $phpgw_baseline; - /* $GLOBALS['phpgw_setup']->oProc->GenerateScripts($phpgw_baseline, $DEBUG); */ - } - else - { - if($DEBUG) - { - echo '
process->baseline(): No baseline tables for ' . $appname . "\n"; - } - /* This should be a break with a status setting, or not at all - break; - */ - } if(file_exists($appdir . 'tables_update.inc.php') && !@$this->updateincluded[$appname]) { include ($appdir . 'tables_update.inc.php'); $this->updateincluded[$appname] = True; - /* $test array comes from update file. It is a list of available upgrade functions */ - @reset($test); - while(list($x,$value) = @each($test)) + while ($currentver && $currentver != $targetver && + function_exists($function = $appname . '_upgrade' . str_replace('.','_',$currentver))) { - $this->currentversion = $currentver = $setup_info[$key]['currentver']; - - /* build upgrade function name */ - $function = $appname . '_upgrade' . str_replace(".", '_', $value); - if($DEBUG) { - echo '
process->upgrade(): appname: ' . $appname; - echo '
process->upgrade(): currentver: ' . $currentver; - echo '
process->upgrade(): targetver: ' . $targetver; - echo '
process->upgrade(): status: ' . $setup_info[$key]['status']; - echo '
process->upgrade(): checking: ' . $value; - echo '
process->upgrade(): function: ' . $function; + echo "
process->upgrade(): $appname($currentver --> $targetver): running $function()\n"; } - - if($value == $targetver) + if (!($currentver = $function())) { - $GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly = False; - /* Done upgrading */ if($DEBUG) { - echo '
process->upgrade(): Upgrade of ' . $appname . ' to ' . $targetver . ' is completed.' . "\n"; - } - $appstatus = 'C'; - $setup_info[$key]['status'] = $appstatus; - $setup_info[$key]['currentver'] = $targetver; - if($GLOBALS['phpgw_setup']->app_registered($appname)) - { - $GLOBALS['phpgw_setup']->update_app($appname); - $GLOBALS['phpgw_setup']->update_hooks($appname); - } - else - { - $GLOBALS['phpgw_setup']->register_app($appname); - $GLOBALS['phpgw_setup']->register_hooks($appname); - } - //break; - } - elseif(($value == $currentver) || !$currentver) - { - /* start upgrading db in addition to baseline */ - $GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly = False; - if($DEBUG) { echo '
process->upgrade(): running ' . $function; } - /* run upgrade function */ - $success = $function(); - if($success != False) - { - $setup_info[$key]['currentver'] = $success; - if($DEBUG) - { - echo '
process->upgrade(): Upgrade of ' . $appname - . ' from ' . $value - . ' to ' . $setup_info[$key]['currentver'] - . ' is completed.' . "\n"; - } - $appstatus = 'R'; - $setup_info[$key]['status'] = $appstatus; - if($GLOBALS['phpgw_setup']->app_registered($appname)) - { - if($DEBUG) - { - echo '
process->upgrade(): Updating registration of ' . $appname . ', new version: ' . $setup_info[$key]['currentver']; - } - $GLOBALS['phpgw_setup']->update_app($appname); - $GLOBALS['phpgw_setup']->update_hooks($appname); - } - else - { - if($DEBUG) - { - echo '
process->upgrade(): Registering ' . $appname . ', version: ' . $setup_info[$key]['currentver']; - } - $GLOBALS['phpgw_setup']->register_app($appname); - $GLOBALS['phpgw_setup']->register_hooks($appname); - } - // is the next update the one we need? - if ($success && $test[$x+1] != $success && - ($num = array_search($success,$test)) !== False) - { - // do we have the needed update somewhere else in the row? - // if yes, position the array-pointer just before that update and continue - reset($test); - while((list($x,$value) = each($test)) && $x < $num-1); - continue; - } - } - else - { - if($DEBUG) - { - echo '
process->upgrade(): Upgrade of ' . $appname - . ' from ' . $currentver - . ' to ' . $value - . ' failed!!!' . "\n"; - } - $appstatus = 'F'; - break; - } - } - elseif ($GLOBALS['phpgw_setup']->alessthanb($value,$currentver)) - { - if($DEBUG) { echo '
process->upgrade(): running baseline delta only: ' . $function . '...'; } - $GLOBALS['phpgw_setup']->oProc->m_bDeltaOnly = True; - $success = $function(); - - // is the next update the one we need? - if ($success && $test[$x+1] != $success && - ($num = array_search($success,$test)) !== False) - { - // do we have the needed update somewhere else in the row? - // if yes, position the array-pointer just before that update and continue - reset($test); - while((list($x,$value) = each($test)) && $x < $num-1); - continue; + echo "failed!!!\n"; } + $appstatus = 'F'; } else { - break; + if($DEBUG) + { + echo "--> $currentver\n"; + } } } + if ($currentver == $targetver) // upgrades succesful + { + if($DEBUG) + { + echo "
process->upgrade(): Upgrade of $appname to $targetver is completed.\n"; + } + $appstatus = 'C'; + } + elseif ($currentver) + { + if($DEBUG) + { + echo "
process->upgrade(): No table upgrade available for appname: $appname, version: $currentver\n"; + } + $setup_info[$key]['currentver'] = $targetver; + $appstatus = 'F'; + } } else { - if($setup_info[$appname]['tables']) + if($DEBUG) { - $appstatus = 'F'; + echo "
process->upgrade(): No table upgrade required/availible for $appname\n"; + } + $appstatus = 'C'; + } + if ($appstatus == 'C') // update successful completed + { + $setup_info[$key]['currentver'] = $targetver; - if($DEBUG) - { - echo '
process->upgrade(): No table upgrade available for ' . $appname . "\n"; - } + if($GLOBALS['phpgw_setup']->app_registered($appname)) + { + $GLOBALS['phpgw_setup']->update_app($appname); + $GLOBALS['phpgw_setup']->update_hooks($appname); } else { - $setup_info[$key]['currentver'] == $targetver; - $appstatus = 'C'; - if($GLOBALS['phpgw_setup']->app_registered($appname)) - { - $GLOBALS['phpgw_setup']->update_app($appname); - $GLOBALS['phpgw_setup']->update_hooks($appname); - } - else - { - $GLOBALS['phpgw_setup']->register_app($appname); - $GLOBALS['phpgw_setup']->register_hooks($appname); - } - - if($DEBUG) - { - echo '
process->upgrade(): No table upgrade required for ' . $appname . "\n"; - } + $GLOBALS['phpgw_setup']->register_app($appname); + $GLOBALS['phpgw_setup']->register_hooks($appname); } } + } else { - $appstatus = 'C'; if($DEBUG) { - echo '
process->upgrade(): No upgrade required for ' . $appname . "\n"; + echo "
process->upgrade(): No upgrade required for $appname\n"; } + $appstatus = 'C'; } - /* Done with this app, update status */ - $setup_info[$key]['status'] = $appstatus; if($DEBUG) { - echo '
process->upgrade(): Outgoing : appname: '.$setup_info[$key]['name'] . ' status: ' . $setup_info[$key]['status']; + echo "
process->upgrade(): Outgoing : appname: $appname, status: $appstatus
\n"; } + $setup_info[$key]['status'] = $appstatus; } /* Done, return current status */ diff --git a/phpgwapi/inc/class.setup_translation.inc.php b/phpgwapi/inc/class.setup_translation.inc.php index 27211e012a..ea7fd4a405 100644 --- a/phpgwapi/inc/class.setup_translation.inc.php +++ b/phpgwapi/inc/class.setup_translation.inc.php @@ -120,5 +120,16 @@ $this->setup_translation_sql(); return $this->sql->add_langs($appname,$DEBUG,$force_langs); } + + function drop_add_all_langs($langs=False) + { + $this->setup_translation_sql(); + + if (!$langs && !count($langs = $this->sql->get_langs())) + { + $langs[] = 'en'; + } + return $this->sql->install_langs($langs,'dumpold'); + } } ?> diff --git a/setup/applications.php b/setup/applications.php index df420ce003..b7a560c06a 100644 --- a/setup/applications.php +++ b/setup/applications.php @@ -123,6 +123,8 @@ $remove = get_var('remove',Array('POST')); $install = get_var('install',Array('POST')); $upgrade = get_var('upgrade',Array('POST')); + + $do_langs = false; if(!empty($remove) && is_array($remove)) { @@ -148,9 +150,7 @@ $GLOBALS['phpgw_setup']->deregister_hooks($setup_info[$appname]['name']); echo '
' . $setup_info[$appname]['title'] . ' ' . lang('hooks deregistered') . '.'; } - - $terror = $GLOBALS['phpgw_setup']->process->drop_langs($terror,$DEBUG); - echo '
' . $setup_info[$appname]['title'] . ' ' . lang('Translations removed') . '.'; + $do_langs = true; if ($historylog->delete($appname)) { @@ -195,13 +195,7 @@ echo '
' . $setup_info[$appname]['title'] . ' ' . lang('hooks registered') . '.'; } } - $force_en = False; - if($appname == 'phpgwapi') - { - $force_en = True; - } - $terror = $GLOBALS['phpgw_setup']->process->add_langs($terror,$DEBUG,$force_en); - echo '
' . $setup_info[$appname]['title'] . ' ' . lang('Translations added') . '.'; + $do_langs = true; } } @@ -222,12 +216,13 @@ { echo '
' . $setup_info[$appname]['title'] . ' ' . lang('upgraded') . '.'; } - - $terror = $GLOBALS['phpgw_setup']->process->upgrade_langs($terror,$DEBUG); - echo '
' . $setup_info[$appname]['title'] . ' ' . lang('Translations upgraded') . '.'; + $do_langs = true; } } - + if ($do_langs) + { + $GLOBALS['phpgw_setup']->process->translation->drop_add_all_langs(); + } //$setup_tpl->set_var('goback', echo '
' . lang('Go back') . ''; //$setup_tpl->pparse('out','submit');