. * * For more information, contact Colosa Inc, 2566 Le Jeune Rd., * Coral Gables, FL, 33134, USA, or email info@colosa.com. */ global $DB_ADAPTER; global $DB_HOST; global $DB_USER; global $DB_PASS; global $DB_NAME; set_time_limit( 0 ); $id = ''; if (isset( $_POST['id'] )) $id = $_POST['id']; G::LoadClass( 'languages' ); G::LoadSystem( 'database_mysql' ); G::LoadSystem('inputfilter'); $aUpgradeData = unserialize( file_get_contents( PATH_DATA . 'log' . PATH_SEP . "upgrade.data.bin" ) ); $aWorkspaces = $aUpgradeData['workspaces']; if (is_array( $aWorkspaces ) && count( $aWorkspaces ) > 0) { $workspace = array_shift( $aUpgradeData['workspaces'] ); eval( getDatabaseCredentials( PATH_DB . $workspace . PATH_SEP . 'db.php' ) ); $oDataBase = new database( $DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME ); $oDataBase->iFetchType = MYSQL_NUM; //processing .po file if ($aUpgradeData['sPoFile'] != '') { $oLanguages = new languages(); $oLanguages->importLanguage( $aUpgradeData['sPoFile'], $aUpgradeData['bForceXmlPoFile'] ); $aUpgradeData['bForceXmlPoFile'] = false; } if ($aUpgradeData['sSchemaFile'] != '') processMasterSchemaFile( $aUpgradeData['sSchemaFile'] ); //draw a gauge control indicating the progress in workspaces $gauge = intval( (($aUpgradeData['wsQuantity'] - count( $aWorkspaces ) + 1) / $aUpgradeData['wsQuantity']) * 301 ); print "
"; print "
"; print "
"; print "
Upgrading the workspace ".$filter->xssFilterHard($workspace)."| ".$filter->xssFilterHard($id)." Remaining
"; file_put_contents( PATH_DATA . 'log' . PATH_SEP . "upgrade.data.bin", serialize( $aUpgradeData ) ); } else { print "
    "; print "
"; print "
"; print "
Finished! All workspaces were upgraded successfully.
"; } die(); function getDatabaseCredentials ($dbFile) { $sContent = file_get_contents( $dbFile ); $sContent = str_replace( '', '', $sContent ); $sContent = str_replace( 'define', '', $sContent ); $sContent = str_replace( "('", '$', $sContent ); $sContent = str_replace( "',", '=', $sContent ); $sContent = str_replace( ");", ';', $sContent ); return $sContent; } function processMasterSchemaFile ($sSchemaFile) { global $DB_ADAPTER; global $DB_HOST; global $DB_USER; global $DB_PASS; global $DB_NAME; global $aUpgradeData; //convert newSchema to array if (isset( $aUpgradeData['aNewSchema'] )) { $aNewSchema = $aUpgradeData['aNewSchema']; } else { $aNewSchema = schemaToArray( $sSchemaFile ); $aUpgradeData['aNewSchema'] = $aNewSchema; } $aOldSchema = processSchemaFile(); if (is_null( $aOldSchema )) { return; } $aChanges = obtainChanges( $aOldSchema, $aNewSchema ); $oDataBase = new database( $DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME ); if (! $oDataBase->isConnected()) { return; } $oDataBase->iFetchType = MYSQL_NUM; $oDataBase->logQuery( count( $aChanges ) ); foreach ($aChanges['tablesToAdd'] as $sTable => $aColumns) { $oDataBase->executeQuery( $oDataBase->generateCreateTableSQL( $sTable, $aColumns ) ); if (isset( $aChanges['tablesToAdd'][$sTable]['INDEXES'] )) { foreach ($aChanges['tablesToAdd'][$sTable]['INDEXES'] as $indexName => $aIndex) { $oDataBase->executeQuery( $oDataBase->generateAddKeysSQL( $sTable, $indexName, $aIndex ) ); } } } foreach ($aChanges['tablesToAlter'] as $sTable => $aActions) { foreach ($aActions as $sAction => $aAction) { foreach ($aAction as $sColumn => $vData) { switch ($sAction) { case 'DROP': $oDataBase->executeQuery( $oDataBase->generateDropColumnSQL( $sTable, $vData ) ); break; case 'ADD': $oDataBase->executeQuery( $oDataBase->generateAddColumnSQL( $sTable, $sColumn, $vData ) ); break; case 'CHANGE': $oDataBase->executeQuery( $oDataBase->generateChangeColumnSQL( $sTable, $sColumn, $vData ) ); break; } } } } foreach ($aChanges['tablesWithNewIndex'] as $sTable => $aIndexes) { foreach ($aIndexes as $sIndexName => $aIndexFields) { $oDataBase->executeQuery( $oDataBase->generateAddKeysSQL( $sTable, $sIndexName, $aIndexFields ) ); } } foreach ($aChanges['tablesToAlterIndex'] as $sTable => $aIndexes) { foreach ($aIndexes as $sIndexName => $aIndexFields) { $oDataBase->executeQuery( $oDataBase->generateDropKeySQL( $sTable, $sIndexName ) ); $oDataBase->executeQuery( $oDataBase->generateAddKeysSQL( $sTable, $sIndexName, $aIndexFields ) ); } } $oDataBase->close(); } function processSchemaFile () { global $DB_ADAPTER; global $DB_HOST; global $DB_USER; global $DB_PASS; global $DB_NAME; try { G::LoadSystem( 'database_' . strtolower( $DB_ADAPTER ) ); $aOldSchema = array (); $oDataBase = new database( $DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME ); if (! $oDataBase->isConnected()) { $oDataBase->logQuery( G::LoadTranslation('ID_DOES_NOT_EXIST_AVAILABLE_CONNECTION') ); return null; } $oDataBase->iFetchType = MYSQL_NUM; $oDataset1 = $oDataBase->executeQuery( $oDataBase->generateShowTablesSQL() ); } catch (Exception $e) { $oDataBase->logQuery( $e->getmessage() ); return null; } //going thru all tables in current WF_ database while ($aRow1 = $oDataBase->getRegistry( $oDataset1 )) { $aPrimaryKeys = array (); $sTable = strtoupper( $aRow1[0] ); //get description of each table, ( column and primary keys ) //$oDataset2 = $oDataBase->executeQuery( $oDataBase->generateDescTableSQL($aRow1[0]) ); $oDataset2 = $oDataBase->executeQuery( $oDataBase->generateDescTableSQL( $sTable ) ); $aOldSchema[$sTable] = array (); $oDataBase->iFetchType = MYSQL_ASSOC; while ($aRow2 = $oDataBase->getRegistry( $oDataset2 )) { $aOldSchema[$sTable][$aRow2['Field']]['Field'] = $aRow2['Field']; $aOldSchema[$sTable][$aRow2['Field']]['Type'] = $aRow2['Type']; $aOldSchema[$sTable][$aRow2['Field']]['Null'] = $aRow2['Null']; $aOldSchema[$sTable][$aRow2['Field']]['Default'] = $aRow2['Default']; } //get indexes of each table SHOW INDEX FROM `ADDITIONAL_TABLES`; -- WHERE Key_name <> 'PRIMARY' $oDataset2 = $oDataBase->executeQuery( $oDataBase->generateTableIndexSQL( $aRow1[0] ) ); $oDataBase->iFetchType = MYSQL_ASSOC; while ($aRow2 = $oDataBase->getRegistry( $oDataset2 )) { if (! isset( $aOldSchema[$sTable]['INDEXES'] )) { $aOldSchema[$sTable]['INDEXES'] = array (); } if (! isset( $aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']] )) { $aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']] = array (); } $aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']][] = $aRow2['Column_name']; } $oDataBase->iFetchType = MYSQL_NUM; //this line is neccesary because the next fetch needs to be with MYSQL_NUM } //finally return the array with old schema obtained from the Database if (count( $aOldSchema ) == 0) $aOldSchema = null; return $aOldSchema; } //process the schema file in the patch file, and obtain an array function schemaToArray ($sSchemaFile) { try { $aSchema = array (); $oXml = new DomDocument(); $oXml->load( $sSchemaFile ); $aTables = $oXml->getElementsByTagName( 'table' ); foreach ($aTables as $oTable) { $aPrimaryKeys = array (); $sTableName = $oTable->getAttribute( 'name' ); $aSchema[$sTableName] = array (); $aColumns = $oTable->getElementsByTagName( 'column' ); foreach ($aColumns as $oColumn) { $sColumName = $oColumn->getAttribute( 'name' ); $aSchema[$sTableName][$sColumName] = array (); $aVendors = $oColumn->getElementsByTagName( 'vendor' ); foreach ($aVendors as $oVendor) { if ($oVendor->getAttribute( 'type' ) == DB_ADAPTER) { break; } } $aParameters = $oColumn->getElementsByTagName( 'parameter' ); foreach ($aParameters as $oParameter) { $parameterName = ucwords( $oParameter->getAttribute( 'name' ) ); if ($parameterName == 'Key' && strtoupper( $oParameter->getAttribute( 'value' ) ) == 'PRI') { $aPrimaryKeys[] = $oColumn->getAttribute( 'name' ); } if (in_array( $parameterName, array ('Field','Type','Null','Default' ) )) { $aSchema[$sTableName][$sColumName][$parameterName] = $oParameter->getAttribute( 'value' ); } } } if (is_array( $aPrimaryKeys ) && count( $aPrimaryKeys ) > 0) { $aSchema[$sTableName]['INDEXES']['PRIMARY'] = $aPrimaryKeys; } $aIndexes = $oTable->getElementsByTagName( 'index' ); foreach ($aIndexes as $oIndex) { $aIndex = array (); $aIndexesColumns = $oIndex->getElementsByTagName( 'index-column' ); foreach ($aIndexesColumns as $oIndexColumn) { $aIndex[] = $oIndexColumn->getAttribute( 'name' ); } $aSchema[$sTableName]['INDEXES'][$oIndex->getAttribute( 'name' )] = $aIndex; } } return $aSchema; } catch (Exception $oError) { throw $oError; } } function obtainChanges ($aOldSchema, $aNewSchema) { //$aChanges = array('tablesToDelete' => array(), 'tablesToAdd' => array(), 'tablesToAlter' => array()); //Tables to delete, but this is disabled //foreach ($aOldSchema as $sTableName => $aColumns) { // if ( !isset($aNewSchema[$sTableName])) { // if (!in_array($sTableName, array('KT_APPLICATION', 'KT_DOCUMENT', 'KT_PROCESS'))) { // $aChanges['tablesToDelete'][] = $sTableName; // } // } //} $aChanges = array ('tablesToAdd' => array (),'tablesToAlter' => array (),'tablesWithNewIndex' => array (),'tablesToAlterIndex' => array () ); //new tables to create and alter foreach ($aNewSchema as $sTableName => $aColumns) { if (! isset( $aOldSchema[$sTableName] )) { $aChanges['tablesToAdd'][$sTableName] = $aColumns; } else { //drop old columns foreach ($aOldSchema[$sTableName] as $sColumName => $aParameters) { if (! isset( $aNewSchema[$sTableName][$sColumName] )) { if (! isset( $aChanges['tablesToAlter'][$sTableName] )) { $aChanges['tablesToAlter'][$sTableName] = array ('DROP' => array (),'ADD' => array (),'CHANGE' => array () ); } $aChanges['tablesToAlter'][$sTableName]['DROP'][$sColumName] = $sColumName; } } //create new columns //foreach ($aNewSchema[$sTableName] as $sColumName => $aParameters) { foreach ($aColumns as $sColumName => $aParameters) { if ($sColumName != 'INDEXES') { if (! isset( $aOldSchema[$sTableName][$sColumName] )) { //this column doesnt exist in oldschema if (! isset( $aChanges['tablesToAlter'][$sTableName] )) { $aChanges['tablesToAlter'][$sTableName] = array ('DROP' => array (),'ADD' => array (),'CHANGE' => array () ); } $aChanges['tablesToAlter'][$sTableName]['ADD'][$sColumName] = $aParameters; } else { //the column exists $newField = $aNewSchema[$sTableName][$sColumName]; $oldField = $aOldSchema[$sTableName][$sColumName]; //both are null, no change is required if (! isset( $newField['Default'] ) && ! isset( $oldField['Default'] )) $changeDefaultAttr = false; //one of them is null, change IS required if (! isset( $newField['Default'] ) && isset( $oldField['Default'] ) && $oldField['Default'] != '') $changeDefaultAttr = true; if (isset( $newField['Default'] ) && ! isset( $oldField['Default'] )) $changeDefaultAttr = true; //both are defined and they are different. if (isset( $newField['Default'] ) && isset( $oldField['Default'] )) { if ($newField['Default'] != $oldField['Default']) $changeDefaultAttr = true; else $changeDefaultAttr = false; } //special cases // BLOB and TEXT columns cannot have DEFAULT values. http://dev.mysql.com/doc/refman/5.0/en/blob.html if (in_array( strtolower( $newField['Type'] ), array ('text','mediumtext' ) )) $changeDefaultAttr = false; //#1067 - Invalid default value for datetime field if (in_array( $newField['Type'], array ('datetime' ) ) && isset( $newField['Default'] ) && $newField['Default'] == '') $changeDefaultAttr = false; //#1067 - Invalid default value for int field if (substr( $newField['Type'], 0, 3 ) && isset( $newField['Default'] ) && $newField['Default'] == '') $changeDefaultAttr = false; //if any difference exists, then insert the difference in aChanges if ($newField['Field'] != $oldField['Field'] || $newField['Type'] != $oldField['Type'] || $newField['Null'] != $oldField['Null'] || $changeDefaultAttr) { if (! isset( $aChanges['tablesToAlter'][$sTableName] )) { $aChanges['tablesToAlter'][$sTableName] = array ('DROP' => array (),'ADD' => array (),'CHANGE' => array () ); } $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Field'] = $newField['Field']; $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Type'] = $newField['Type']; $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Null'] = $newField['Null']; if (isset( $newField['Default'] )) $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = $newField['Default']; else $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = null; } } } //only columns, no the indexes column } //foreach $aColumns //now check the indexes of table if (isset( $aNewSchema[$sTableName]['INDEXES'] )) { foreach ($aNewSchema[$sTableName]['INDEXES'] as $indexName => $indexFields) { if (! isset( $aOldSchema[$sTableName]['INDEXES'][$indexName] )) { if (! isset( $aChanges['tablesWithNewIndex'][$sTableName] )) { $aChanges['tablesWithNewIndex'][$sTableName] = array (); } $aChanges['tablesWithNewIndex'][$sTableName][$indexName] = $indexFields; } else { if ($aOldSchema[$sTableName]['INDEXES'][$indexName] != $indexFields) { if (! isset( $aChanges['tablesToAlterIndex'][$sTableName] )) { $aChanges['tablesToAlterIndex'][$sTableName] = array (); } $aChanges['tablesToAlterIndex'][$sTableName][$indexName] = $indexFields; } } } } } //for-else table exists } //for new schema return $aChanges; }