[Cs-webdbupgrade-commits] SF.net SVN: cs-webdbupgrade:[40] trunk/0.2/cs_webdbupgrade.class.php
Status: Inactive
Brought to you by:
crazedsanity
From: <cra...@us...> - 2009-08-13 15:09:32
|
Revision: 40 http://cs-webdbupgrade.svn.sourceforge.net/cs-webdbupgrade/?rev=40&view=rev Author: crazedsanity Date: 2009-08-13 15:09:23 +0000 (Thu, 13 Aug 2009) Log Message: ----------- Re-apply changes from the trunk/0.1 folder that were for the trunk/0.2 folder. Modified Paths: -------------- trunk/0.2/cs_webdbupgrade.class.php Modified: trunk/0.2/cs_webdbupgrade.class.php =================================================================== --- trunk/0.2/cs_webdbupgrade.class.php 2009-08-13 15:04:14 UTC (rev 39) +++ trunk/0.2/cs_webdbupgrade.class.php 2009-08-13 15:09:23 UTC (rev 40) @@ -13,6 +13,7 @@ */ require_once(constant('LIBDIR') .'/cs-versionparse/cs_version.abstract.class.php'); +require_once(constant('LIBDIR') .'/cs_debug.php'); class cs_webdbupgrade extends cs_versionAbstract { @@ -46,9 +47,16 @@ /** Name (absolute location) of *.lock file that indicates an upgrade is running. */ private $lockfile; + /** Determines if an internal upgrade is happening (avoids some infinite loops) */ + private $internalUpgradeInProgress = false; + /** */ private $allowNoDBVersion=true; + /** Log messages to store during an internal upgrade (to avoid problems) */ + private $storedLogs = array(); + private $debugLogs=array(); + /** List of acceptable suffixes; example "1.0.0-BETA3" -- NOTE: these MUST be in * an order that reflects newest -> oldest; "ALPHA happens before BETA, etc. */ private $suffixList = array( @@ -58,34 +66,17 @@ ); //========================================================================= - public function __construct($versionFileLocation, array $config) { + public function __construct($versionFileLocation, $upgradeConfigFile, $lockFile='upgrade.lock') { - //Handle the config array (cope with XML-ish array) - if(is_array($config)) { - //check if it is in the complex XML array style... - $keys = array_keys($config); - if(isset($config[$keys[0]]['type'])) { - $this->fix_xml_config($config); - $this->config = $this->tempXmlConfig; - } - else { - $this->config = $config; - } - } - else { - throw new exception(__METHOD__ .": no configuration available"); - } - - //cope with problems in CS-Content v1.0-ALPHA9 (or before)--see http://project.crazedsanity.com/extern/helpdesk/view?ID=281 - if(isset($this->config['DBPARMLINKER'])) { - $this->config['DBPARAMS'] = array(); - foreach($this->config['DBPARMLINKER'] as $i=>$loc) { - $this->config['DBPARAMS'][strtolower($i)] = $this->config[$loc]; - unset($this->config[$loc]); - } - unset($this->config['DBPARMLINKER']); - } - + //setup configuration parameters for database connectivity. + $dbParams = array( + 'host' => constant(__CLASS__ .'-DB_CONNECT_HOST'), + 'port' => constant(__CLASS__ .'-DB_CONNECT_PORT'), + 'dbname' => constant(__CLASS__ .'-DB_CONNECT_DBNAME'), + 'user' => constant(__CLASS__ .'-DB_CONNECT_USER'), + 'password' => constant(__CLASS__ .'-DB_CONNECT_PASSWORD') + ); + $this->config['DBPARAMS'] = $dbParams; //Check for some required constants. $requisiteConstants = array('LIBDIR'); if(!defined('LIBDIR')) { @@ -103,32 +94,46 @@ require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlCreator.class.php'); require_once(constant('LIBDIR') .'/cs-phpxml/cs_arrayToPath.class.php'); - $this->versionFileLocation = $versionFileLocation; - $this->fsObj = new cs_fileSystem(constant('SITE_ROOT')); $this->gfObj = new cs_globalFunctions; if(defined('DEBUGPRINTOPT')) { $this->gfObj->debugPrintOpt = constant('DEBUGPRINTOPT'); } - if(!isset($this->config['DB_PRIMARYKEY']) || !isset($this->config['DB_TABLE'])) { + if(!defined(__CLASS__ .'-DB_PRIMARYKEY') || !defined(__CLASS__ .'-DB_TABLE')) { throw new exception(__METHOD__ .": no setting for DB_TABLE or DB_PRIMARYKEY, cannot continue"); } + else { + $this->config['DB_TABLE'] = constant(__CLASS__ .'-DB_TABLE'); + $this->config['DB_PRIMARYKEY'] = constant(__CLASS__ .'-DB_PRIMARYKEY'); + } $this->sequenceName = $this->config['DB_TABLE'] .'_'. $this->config['DB_PRIMARYKEY'] .'_seq'; if(!defined('DBTYPE')) { throw new exception(__METHOD__ .": required constant 'DBTYPE' not set"); } - if(!isset($this->config['CONFIG_FILE_LOCATION'])) { - throw new exception(__METHOD__ .": required setting 'CONFIG_FILE_LOCATION' not found"); + + if(!file_exists($upgradeConfigFile) || !is_readable($upgradeConfigFile)) { + throw new exception(__METHOD__ .": required upgrade config file location (". $upgradeConfigFile .") not set or unreadable"); } + else { + $this->config['UPGRADE_CONFIG_FILE'] = $upgradeConfigFile; + } if(!strlen($versionFileLocation) || !file_exists($versionFileLocation)) { throw new exception(__METHOD__ .": unable to locate version file (". $versionFileLocation .")"); } - if(!isset($this->config['RWDIR']) || !is_dir($this->config['RWDIR']) || !is_readable($this->config['RWDIR']) || !is_writable($this->config['RWDIR'])) { - throw new exception(__METHOD__ .": missing RWDIR (". $this->config['RWDIR'] .") or isn't readable/writable"); + $this->set_version_file_location($versionFileLocation); + + if(!defined(__CLASS__ .'-RWDIR') || !is_dir(constant(__CLASS__ .'-RWDIR')) || !is_readable(constant(__CLASS__ .'-RWDIR')) || !is_writable(constant(__CLASS__ .'-RWDIR'))) { + throw new exception(__METHOD__ .": missing RWDIR (". constant(__CLASS__ .'-RWDIR') .") or isn't readable/writable"); } - $this->lockfile = $this->config['RWDIR'] .'/upgrade.lock'; + else { + $this->config['RWDIR'] = constant(__CLASS__ .'-RWDIR'); + } + if(is_null($lockFile) || !strlen($lockFile)) { + $lockFile = 'upgrade.lock'; + } + $this->lockfile = $this->config['RWDIR'] .'/'. $lockFile; $this->db = new cs_phpDB(constant('DBTYPE')); try { @@ -140,12 +145,15 @@ if($this->check_lockfile()) { //there is an existing lockfile... - $this->error_handler(__METHOD__ .": upgrade in progress: ". $this->fsObj->read($this->lockfile)); + throw new exception(__METHOD__ .": upgrade in progress: ". $this->fsObj->read($this->lockfile)); } $this->check_internal_upgrades(); - try { - $this->connect_logger("Upgrade"); + + try { + $loggerDb = new cs_phpDB(constant('DBTYPE')); + $loggerDb->connect($this->config['DBPARAMS'], true); + $this->logsObj = new cs_webdblogger($loggerDb, "Upgrade ". $this->projectName, false); } catch(exception $e) { throw new exception(__METHOD__ .": failed to create logger::: ". $e->getMessage()); @@ -167,17 +175,12 @@ $this->config['UPGRADE_CONFIG_FILE'] = dirname(__FILE__) .'/upgrades/upgrade.xml'; - //connect the logger... - try { - $this->connect_logger("Internal Upgrade"); - } - catch(exception $e) { - $this->error_handler($e->getMessage()); - } + //set a status flag so we can store log messages (for now). + $this->internalUpgradeInProgress = true; //do stuff here... - $this->versionFileLocation = dirname(__FILE__) .'/VERSION'; + $this->set_version_file_location(dirname(__FILE__) .'/VERSION'); $this->read_version_file(); //if there is an error, then... uh... yeah. @@ -185,7 +188,7 @@ $this->get_database_version(); } catch(exception $e) { - #throw new exception(__METHOD__ .": error while retrieving database version: ". $e->getMessage()); + throw new exception(__METHOD__ .": error while retrieving database version: ". $e->getMessage()); //try creating the version. $this->load_initial_version(); @@ -193,12 +196,13 @@ //do upgrades here... $this->check_versions(true); + $this->internalUpgradeInProgress = false; //reset internal vars. - $this->versionFileLocation = $oldVersionFileLocation; + $this->set_version_file_location($oldVersionFileLocation); $this->config['UPGRADE_CONFIG_FILE'] = $oldUpgradeConfigFile; $this->read_version_file(); @@ -223,7 +227,7 @@ //check to see if the lock files for upgrading exist. if($this->upgrade_in_progress()) { - $this->logsObj->log_by_class("Upgrade in progress", 'notice'); + $this->do_log("Upgrade in progress", 'notice'); throw new exception(__METHOD__ .": upgrade in progress"); } else { @@ -325,6 +329,7 @@ //========================================================================= private function perform_upgrade() { + $this->logsObj->suspendLogging=true; //make sure there's not already a lockfile. if($this->upgrade_in_progress()) { //ew. Can't upgrade. @@ -334,7 +339,7 @@ $lockConfig = $this->upgrade_in_progress(TRUE); $this->fsObj->cd("/"); - $this->logsObj->log_by_class("Starting upgrade process...", 'begin'); + $this->do_log("Starting upgrade process...", 'begin'); //TODO: not only should the "create_file()" method be run, but also do a sanity check by calling lock_file_exists(). if($lockConfig === 0) { @@ -342,7 +347,7 @@ $this->error_handler(__METHOD__ .": failed to set 'upgrade in progress'"); } else { - $this->logsObj->log_by_class(__METHOD__ .": result of creating lockfile: (". $lockConfig .")", 'debug'); + $this->do_log(__METHOD__ .": result of creating lockfile: (". $lockConfig .")", 'debug'); //push data into our internal "config" array. $this->read_upgrade_config_file(); @@ -353,39 +358,38 @@ if($versionConflictInfo !== false) { - $this->logsObj->log_by_class("Upgrading ". $versionConflictInfo ." versions, from " . + $this->do_log("Upgrading ". $versionConflictInfo ." versions, from " . "(". $this->databaseVersion .") to (". $this->versionFileVersion .")", 'info'); } $upgradeList = $this->get_upgrade_list(); - try { $i=0; - $this->logsObj->log_by_class(__METHOD__ .": starting to run through the upgrade list, starting at (". $this->databaseVersion ."), " . + $this->do_log(__METHOD__ .": starting to run through the upgrade list, starting at (". $this->databaseVersion ."), " . "total number of upgrades to perform: ". count($upgradeList), 'debug'); $this->db->beginTrans(__METHOD__); foreach($upgradeList as $fromVersion=>$toVersion) { $details = __METHOD__ .": upgrading from ". $fromVersion ." to ". $toVersion ."... "; - $this->logsObj->log_by_class($details, 'system'); + $this->do_log($details, 'system'); $this->do_single_upgrade($fromVersion, $toVersion); $this->get_database_version(); $i++; $details = __METHOD__ .": finished upgrade #". $i .", now at version (". $this->databaseVersion .")"; - $this->logsObj->log_by_class($details, 'system'); + $this->do_log($details, 'system'); } if($i < count($upgradeList)) { - $this->logsObj->log_by_class(__METHOD__ .": completed upgrade ". $i ." of ". count($upgradeList), 'debug'); + $this->do_log(__METHOD__ .": completed upgrade ". $i ." of ". count($upgradeList), 'debug'); } else { if($this->databaseVersion == $this->versionFileVersion) { - $this->logsObj->log_by_class(__METHOD__ .": finished upgrading after performing (". $i .") upgrades", 'debug'); + $this->do_log(__METHOD__ .": finished upgrading after performing (". $i .") upgrades", 'debug'); $this->newVersion = $this->databaseVersion; } else { - $this->logsObj->log_by_class(__METHOD__ .": upgradeList::: ". $this->gfObj->debug_print($upgradeList,0), 'debug'); + $this->do_log(__METHOD__ .": upgradeList::: ". $this->gfObj->debug_print($upgradeList,0), 'debug'); $this->error_handler(__METHOD__ .": finished upgrade, but version wasn't updated (expecting '". $this->versionFileVersion ."', got '". $this->databaseVersion ."')!!!"); } } @@ -394,12 +398,16 @@ $this->db->commitTrans(); } catch(exception $e) { - $this->error_handler(__METHOD__ .": upgrade aborted:::". $e->getMessage()); + $transactionStatus = $this->db->get_transaction_status(false); + $this->error_handler(__METHOD__ .": transaction status=(". $transactionStatus ."), upgrade aborted:::". $e->getMessage()); $this->db->rollbackTrans(); } - $this->logsObj->log_by_class("Upgrade process complete", 'end'); + $this->logsObj->suspendLogging=false; + $this->do_log("Upgrade process complete", 'end'); } } + $this->logsObj->suspendLogging=false; + $logsHandled = $this->logsObj->handle_suspended_logs(); }//end perform_upgrade() //========================================================================= @@ -607,7 +615,7 @@ $this->error_handler(__METHOD__ .": target version not specified, unable to proceed with upgrade for ". $versionIndex); } } - $this->logsObj->log_by_class("Finished upgrade to ". $this->newVersion, 'system'); + $this->do_log("Finished upgrade to ". $this->newVersion, 'system'); }//end do_single_upgrade() //========================================================================= @@ -666,7 +674,7 @@ } if(!$retval) { - $this->logsObj->log_by_class("Version check failed, versionString=(". $versionString ."), checkVersion=(". $this->newVersion .")", 'FATAL'); + $this->do_log("Version check failed, versionString=(". $versionString ."), checkVersion=(". $this->newVersion .")", 'FATAL'); } } @@ -684,20 +692,16 @@ private function do_scripted_upgrade(array $upgradeData) { $myConfigFile = $upgradeData['SCRIPT_NAME']; - $this->logsObj->log_by_class("Preparing to run script '". $myConfigFile ."'", 'debug'); + $this->do_log("Preparing to run script '". $myConfigFile ."'", 'debug'); //we've got the filename, see if it exists. - if(isset($this->config['UPGRADE_SCRIPTS_DIR'])) { - $scriptsDir = $this->config['UPGRADE_SCRIPTS_DIR']; - } - else { - $this->logsObj->log_by_class("No UPGRADE_SCRIPTS_DIR config setting", 'warning'); - $scriptsDir = dirname($this->config['UPGRADE_CONFIG_FILE']); - } + + $scriptsDir = dirname($this->config['UPGRADE_CONFIG_FILE']); $fileName = $scriptsDir .'/'. $myConfigFile; + if(file_exists($fileName)) { - - $this->logsObj->log_by_class("Performing scripted upgrade (". $myConfigFile .")", 'DEBUG'); + + $this->do_log("(". __CLASS__ .") Performing scripted upgrade (". $myConfigFile .") from file '". $fileName ."'", 'DEBUG'); $createClassName = $upgradeData['CLASS_NAME']; $classUpgradeMethod = $upgradeData['CALL_METHOD']; require_once($fileName); @@ -710,12 +714,12 @@ if($upgradeResult === true) { //yay, it worked! - $this->logsObj->log_by_class("Upgrade succeeded (". $upgradeResult .")", 'success'); + $this->do_log("Upgrade succeeded (". $upgradeResult .")", 'success'); } else { $this->error_handler(__METHOD__ .": upgrade failed (". $upgradeResult .")"); } - $this->logsObj->log_by_class("Finished running ". $createClassName ."::". $classUpgradeMethod ."(), result was (". $upgradeResult .")", 'debug'); + $this->do_log("Finished running ". $createClassName ."::". $classUpgradeMethod ."(), result was (". $upgradeResult .")", 'debug'); } else { $this->error_handler(__METHOD__ .": upgrade method doesn't exist (". $createClassName ."::". $classUpgradeMethod @@ -788,11 +792,11 @@ $retval[$matchVersion] = $data['TARGET_VERSION']; } else { - $this->logsObj->log_by_class(__METHOD__ .": entry in upgrade.xml (". $matchVersion .") is higher than the VERSION file (". $this->versionFileVersion .")", 'warning'); + $this->do_log(__METHOD__ .": entry in upgrade.xml (". $matchVersion .") is higher than the VERSION file (". $this->versionFileVersion .")", 'warning'); } } else { - $this->logsObj->log_by_class(__METHOD__ .": SKIPPING (". $matchVersion .")", 'debug'); + $this->do_log(__METHOD__ .": SKIPPING (". $matchVersion .")", 'debug'); } } @@ -802,7 +806,7 @@ } else { //no intermediary upgrades: just pass back the latest version. - $this->logsObj->log_by_class(__METHOD__ .": no intermediary upgrades", 'debug'); + $this->do_log(__METHOD__ .": no intermediary upgrades", 'debug'); $retval[$dbVersion] = $this->versionFileVersion; } @@ -856,7 +860,7 @@ $a2p = new cs_arrayToPath($config); } catch(exception $e) { - $this->logsObj->log_by_class(__METHOD__ .': encountered exception: '. $e->getMessage()); + $this->do_log(__METHOD__ .': encountered exception: '. $e->getMessage()); $this->error_handler($e->getMessage()); } if(!is_array($this->tempXmlConfig)) { @@ -866,7 +870,7 @@ $myA2p = new cs_arrayToPath(&$this->tempXmlConfig); } catch(exception $e) { - $this->logsObj->log_by_class(__METHOD__ .': encountered exception: '. $e->getMessage()); + $this->do_log(__METHOD__ .': encountered exception: '. $e->getMessage()); $this->error_handler($e->getMessage()); } @@ -930,7 +934,7 @@ $logRes = 'Failed to load'; $logType = 'error'; } - $this->logsObj->log_by_class($logRes .' table ('. $this->config['DB_TABLE'] .') into ' . + $this->do_log($logRes .' table ('. $this->config['DB_TABLE'] .') into ' . 'database::: '. $loadTableResult, $logType); return($loadTableResult); @@ -1026,7 +1030,12 @@ //========================================================================= public function error_handler($details) { //log the error. - $this->logsObj->log_by_class($details, 'exception in code'); + if(!is_object($this->logsObj)) { + throw new exception(__METHOD__ .": error while running an internal upgrade::: ". $details); + } + if($this->internalUpgradeInProgress === false) { + $this->do_log($details, 'exception in code'); + } //now throw an exception so other code can catch it. throw new exception($details); @@ -1039,19 +1048,24 @@ public function load_initial_version() { //if there's an INITIAL_VERSION in the upgrade config file, use that. $this->read_upgrade_config_file(); + $insertData = array(); if(isset($this->config['UPGRADELIST']['INITIALVERSION'])) { - $insertData = $this->parse_version_string($this->config['UPGRADELIST']['INITIALVERSION']); + $parseThis = $this->config['UPGRADELIST']['INITIALVERSION']; } else { - $insertData = $this->parse_version_string($this->versionFileVersion); + $parseThis = $this->versionFileVersion; } - $insertData['project_name'] = $this->projectName; + $versionInfo = $this->parse_version_string($parseThis); + $insertData = array( + 'project_name' => $this->projectName, + 'version_string' => $versionInfo['version_string'] + ); $sql = 'INSERT INTO '. $this->config['DB_TABLE'] . $this->gfObj->string_from_array($insertData, 'insert'); if($this->db->run_insert($sql, $this->sequenceName)) { $loadRes = true; - $this->logsObj->log_by_class("Created data for '". $this->projectName ."' with version '". $insertData['version_string'] ."'", 'initialize'); + $this->do_log("Created data for '". $this->projectName ."' with version '". $insertData['version_string'] ."'", 'initialize'); } else { $this->error_handler(__METHOD__ .": failed to load initial version::: ". $e->getMessage()); @@ -1064,11 +1078,15 @@ //========================================================================= - private function connect_logger($logCategory) { - $loggerDb = new cs_phpDB(constant('DBTYPE')); - $loggerDb->connect($this->config['DBPARAMS'], true); - $this->logsObj = new cs_webdblogger($loggerDb, $logCategory); - }//end connect_logger() + protected function do_log($message, $type) { + $this->debugLogs[] = array('project'=>$this->projectName,'upgradeFile'=>$this->config['UPGRADE_CONFIG_FILE'],'message'=>$message,'type'=>$type); + if($this->internalUpgradeInProgress === true) { + $this->storedLogs[] = func_get_args(); + } + else { + $this->logsObj->log_by_class($message, $type); + } + }//end do_log() //========================================================================= This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |