From 890565e278851c6bba8bb805075d7580e070a672 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Mon, 12 Jul 2010 12:55:32 +0000 Subject: [PATCH] #154 Application too slow - no need to check the DB format anytime! SVN:trunk[594] --- core/metamodel.class.php | 22 +- core/sqlquery.class.inc.php | 20 +- core/test.class.inc.php | 1073 +++++++++++++++-------------- pages/ITopConsultant.php | 2 +- setup/index.php | 13 +- setup/xmldataloader.class.inc.php | 4 +- 6 files changed, 565 insertions(+), 569 deletions(-) diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 851941948..229061a95 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -3089,25 +3089,15 @@ abstract class MetaModel } } - public static function Startup($sConfigFile, $bAllowMissingDB = false) + public static function Startup($sConfigFile, $bModelOnly = false) { self::LoadConfig($sConfigFile); - if (self::DBExists()) -// !!!! #@# - //if (true) - { - CMDBSource::SelectDB(self::$m_sDBName); + if ($bModelOnly) return; - // Some of the init could not be done earlier (requiring classes to be declared and DB to be accessible) - self::InitPlugins(); - } - else - { - if (!$bAllowMissingDB) - { - throw new CoreException('Database not found, check your configuration file', array('config_file'=>$sConfigFile, 'db_name'=>self::$m_sDBName)); - } - } + CMDBSource::SelectDB(self::$m_sDBName); + + // Some of the init could not be done earlier (requiring classes to be declared and DB to be accessible) + self::InitPlugins(); } public static function LoadConfig($sConfigFile) diff --git a/core/sqlquery.class.inc.php b/core/sqlquery.class.inc.php index a4a1a994e..36daf2c50 100644 --- a/core/sqlquery.class.inc.php +++ b/core/sqlquery.class.inc.php @@ -66,10 +66,12 @@ class SQLQuery public function __construct($sTable, $sTableAlias, $aFields, $oConditionExpr, $aFullTextNeedles, $bToDelete = true, $aValues = array()) { - if (!CMDBSource::IsTable($sTable)) - { - throw new CoreException("Unknown table '$sTable'"); - } + // This check is not needed but for developping purposes + //if (!CMDBSource::IsTable($sTable)) + //{ + // throw new CoreException("Unknown table '$sTable'"); + //} + // $aFields must be an array of "alias"=>"expr" // $oConditionExpr must be a condition tree // $aValues is an array of "alias"=>value @@ -157,10 +159,12 @@ class SQLQuery private function AddJoin($sJoinType, $oSQLQuery, $sLeftField, $sRightField, $sRightTableAlias = '') { assert((get_class($oSQLQuery) == __CLASS__) || is_subclass_of($oSQLQuery, __CLASS__)); - if (!CMDBSource::IsField($this->m_sTable, $sLeftField)) - { - throw new CoreException("Unknown field '$sLeftField' in table '".$this->m_sTable); - } + // No need to check this here but for development purposes + //if (!CMDBSource::IsField($this->m_sTable, $sLeftField)) + //{ + // throw new CoreException("Unknown field '$sLeftField' in table '".$this->m_sTable); + //} + if (empty($sRightTableAlias)) { $sRightTableAlias = $oSQLQuery->m_sTableAlias; diff --git a/core/test.class.inc.php b/core/test.class.inc.php index b6a654c43..8aceb3c17 100644 --- a/core/test.class.inc.php +++ b/core/test.class.inc.php @@ -1,536 +1,537 @@ - - * @author Romain Quetiez - * @author Denis Flaven - * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL - */ - - -require_once('coreexception.class.inc.php'); -require_once('attributedef.class.inc.php'); -require_once('filterdef.class.inc.php'); -require_once('stimulus.class.inc.php'); -require_once('MyHelpers.class.inc.php'); - -require_once('expression.class.inc.php'); -require_once('cmdbsource.class.inc.php'); -require_once('sqlquery.class.inc.php'); - -require_once('log.class.inc.php'); - -require_once('dbobject.class.php'); -require_once('dbobjectsearch.class.php'); -require_once('dbobjectset.class.php'); - -require_once('userrights.class.inc.php'); - -require_once('../webservices/webservices.class.inc.php'); - - -// Just to differentiate programmatically triggered exceptions and other kind of errors (usefull?) -class UnitTestException extends Exception -{} - - -/** - * Improved display of the backtrace - * - * @package iTopORM - */ -class ExceptionFromError extends Exception -{ - public function getTraceAsHtml() - { - $aBackTrace = $this->getTrace(); - return MyHelpers::get_callstack_html(0, $this->getTrace()); - // return "
\n".$this->getTraceAsString()."
\n"; - } -} - - -/** - * Test handler API and basic helpers - * - * @package iTopORM - */ -abstract class TestHandler -{ - protected $m_aSuccesses; - protected $m_aWarnings; - protected $m_aErrors; - protected $m_sOutput; - - public function __construct() - { - $this->m_aSuccesses = array(); - $this->m_aWarnings = array(); - $this->m_aErrors = array(); - } - - abstract static public function GetName(); - abstract static public function GetDescription(); - - protected function DoPrepare() {return true;} - abstract protected function DoExecute(); - protected function DoCleanup() {return true;} - - protected function ReportSuccess($sMessage, $sSubtestId = '') - { - $this->m_aSuccesses[] = $sMessage; - } - - protected function ReportWarning($sMessage, $sSubtestId = '') - { - $this->m_aWarnings[] = $sMessage; - } - - protected function ReportError($sMessage, $sSubtestId = '') - { - $this->m_aErrors[] = $sMessage; - } - - public function GetResults() - { - return $this->m_aSuccesses; - } - - public function GetWarnings() - { - return $this->m_aWarnings; - } - - public function GetErrors() - { - return $this->m_aErrors; - } - - public function GetOutput() - { - return $this->m_sOutput; - } - - public function error_handler($errno, $errstr, $errfile, $errline) - { - // Note: return false to call the default handler (stop the program if an error) - - switch ($errno) - { - case E_USER_ERROR: - $this->ReportError($errstr); - //throw new ExceptionFromError("Fatal error in line $errline of file $errfile: $errstr"); - break; - case E_USER_WARNING: - $this->ReportWarning($errstr); - break; - case E_USER_NOTICE: - $this->ReportWarning($errstr); - break; - default: - $this->ReportWarning("Unknown error type: [$errno] $errstr in $errfile at $errline"); - echo "Unknown error type: [$errno] $errstr in $errfile at $errline
\n"; - break; - } - return true; // do not call the default handler - } - - public function Execute() - { - ob_start(); - set_error_handler(array($this, 'error_handler')); - try - { - $this->DoPrepare(); - $this->DoExecute(); - } - catch (ExceptionFromError $e) - { - $this->ReportError($e->getMessage().' - '.$e->getTraceAsHtml()); - } - catch (CoreException $e) - { - //$this->ReportError($e->getMessage()); - //$this->ReportError($e->__tostring()); - $this->ReportError($e->getMessage().' - '.$e->getTraceAsHtml()); - } - catch (Exception $e) - { - //$this->ReportError($e->getMessage()); - //$this->ReportError($e->__tostring()); - $this->ReportError('class '.get_class($e).' --- '.$e->getMessage().' - '.$e->getTraceAsString()); - } - restore_error_handler(); - $this->m_sOutput = ob_get_clean(); - return (count($this->GetErrors()) == 0); - } -} - - - - -/** - * Test to execute a piece of code (checks if an error occurs) - * - * @package iTopORM - */ -abstract class TestFunction extends TestHandler -{ - // simply overload DoExecute (temporary) -} - - -/** - * Test to execute a piece of code (checks if an error occurs) - * - * @package iTopORM - */ -abstract class TestWebServices extends TestHandler -{ - // simply overload DoExecute (temporary) - - static protected function DoPostRequestAuth($sRelativeUrl, $aData, $sLogin = 'admin', $sPassword = 'admin', $sOptionnalHeaders = null) - { - $aDataAndAuth = $aData; - $aDataAndAuth['operation'] = 'login'; - $aDataAndAuth['auth_user'] = $sLogin; - $aDataAndAuth['auth_pwd'] = $sPassword; - $sHost = $_SERVER['HTTP_HOST']; - $sRawPath = $_SERVER['SCRIPT_NAME']; - $sPath = dirname($sRawPath); - $sUrl = "http://$sHost/$sPath/$sRelativeUrl"; - - return self::DoPostRequest($sUrl, $aDataAndAuth, $sOptionnalHeaders); - } - - // Source: http://netevil.org/blog/2006/nov/http-post-from-php-without-curl - // originaly named after do_post_request - // Partially adapted to our coding conventions - static protected function DoPostRequest($sUrl, $aData, $sOptionnalHeaders = null) - { - // $sOptionnalHeaders is a string containing additional HTTP headers that you would like to send in your request. - - $sData = http_build_query($aData); - - $aParams = array('http' => array( - 'method' => 'POST', - 'content' => $sData, - 'header'=> "Content-type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($sData)."\r\n", - )); - if ($sOptionnalHeaders !== null) - { - $aParams['http']['header'] .= $sOptionnalHeaders; - } - $ctx = stream_context_create($aParams); - - $fp = @fopen($sUrl, 'rb', false, $ctx); - if (!$fp) - { - throw new Exception("Problem with $sUrl, $php_errormsg"); - } - $response = @stream_get_contents($fp); - if ($response === false) - { - throw new Exception("Problem reading data from $sUrl, $php_errormsg"); - } - return $response; - } -} - -/** - * Test to execute a piece of code (checks if an error occurs) - * - * @package iTopORM - */ -abstract class TestSoapWebService extends TestHandler -{ - // simply overload DoExecute (temporary) - - function __construct() - { - parent::__construct(); - } -} - -/** - * Test to check that a function outputs some values depending on its input - * - * @package iTopORM - */ -abstract class TestFunctionInOut extends TestFunction -{ - abstract static public function GetCallSpec(); // parameters to call_user_func - abstract static public function GetInOut(); // array of input => output - - protected function DoExecute() - { - $aTests = $this->GetInOut(); - if (is_array($aTests)) - { - foreach ($aTests as $iTestId => $aTest) - { - $ret = call_user_func_array($this->GetCallSpec(), $aTest['args']); - if ($ret != $aTest['output']) - { - // Note: to be improved to cope with non string parameters - $this->ReportError("Found '$ret' while expecting '".$aTest['output']."'", $iTestId); - } - else - { - $this->ReportSuccess("Found the expected output '$ret'", $iTestId); - } - } - } - else - { - $ret = call_user_func($this->GetCallSpec()); - $this->ReportSuccess('Finished successfully'); - } - } -} - - -/** - * Test to check an URL (Searches for Error/Warning/Etc keywords) - * - * @package iTopORM - */ -abstract class TestUrl extends TestHandler -{ - abstract static public function GetUrl(); - abstract static public function GetErrorKeywords(); - abstract static public function GetWarningKeywords(); - - protected function DoExecute() - { - return true; - } -} - - -/** - * Test to check a user management module - * - * @package iTopORM - */ -abstract class TestUserRights extends TestHandler -{ - protected function DoExecute() - { - return true; - } -} - - -/** - * Test to execute a scenario on a given DB - * - * @package iTopORM - */ -abstract class TestScenarioOnDB extends TestHandler -{ - abstract static public function GetDBHost(); - abstract static public function GetDBUser(); - abstract static public function GetDBPwd(); - abstract static public function GetDBName(); - - protected function DoPrepare() - { - $sDBHost = $this->GetDBHost(); - $sDBUser = $this->GetDBUser(); - $sDBPwd = $this->GetDBPwd(); - $sDBName = $this->GetDBName(); - - CMDBSource::Init($sDBHost, $sDBUser, $sDBPwd); - if (CMDBSource::IsDB($sDBName)) - { - CMDBSource::DropDB($sDBName); - } - CMDBSource::CreateDB($sDBName); - } - - protected function DoCleanup() - { - // CMDBSource::DropDB($this->GetDBName()); - } -} - - -/** - * Test to use a business model on a given DB - * - * @package iTopORM - */ -abstract class TestBizModel extends TestHandler -{ -// abstract static public function GetDBSubName(); -// abstract static public function GetBusinessModelFile(); - abstract static public function GetConfigFile(); - - protected function DoPrepare() - { - MetaModel::Startup($this->GetConfigFile(), true); // allow missing DB - MetaModel::CheckDefinitions(); - - // something here to create records... but that's another story - } - - protected $m_oChange; - protected function ObjectToDB($oNew, $bReload = false) - { - list($bRes, $aIssues) = $oNew->CheckToInsert(); - if (!$bRes) - { - throw new CoreException('Could not create object, unexpected values', array('attributes' => $aIssues)); - } - if ($oNew instanceof CMDBObject) - { - if (!isset($this->m_oChange)) - { - new CMDBChange(); - $oMyChange = MetaModel::NewObject("CMDBChange"); - $oMyChange->Set("date", time()); - $oMyChange->Set("userinfo", "Someone doing some tests"); - $iChangeId = $oMyChange->DBInsertNoReload(); - $this->m_oChange = $oMyChange; - } - if ($bReload) - { - $iId = $oNew->DBInsertTracked($this->m_oChange); - } - else - { - $iId = $oNew->DBInsertTrackedNoReload($this->m_oChange); - } - } - else - { - if ($bReload) - { - $iId = $oNew->DBInsert(); - } - else - { - $iId = $oNew->DBInsertNoReload(); - } - } - return $iId; - } - - protected function ResetDB() - { - if (MetaModel::DBExists(false)) - { - MetaModel::DBDrop(); - } - MetaModel::DBCreate(); - } - - static protected function show_list($oObjectSet) - { - $oObjectSet->Rewind(); - $aData = array(); - while ($oItem = $oObjectSet->Fetch()) - { - $aValues = array(); - foreach(MetaModel::GetAttributesList(get_class($oItem)) as $sAttCode) - { - $aValues[$sAttCode] = $oItem->GetAsHTML($sAttCode); - } - //echo $oItem->GetKey()." => ".implode(", ", $aValues)."
\n"; - $aData[] = $aValues; - } - echo MyHelpers::make_table_from_assoc_array($aData); - } - - static protected function search_and_show_list(DBObjectSearch $oMyFilter) - { - $oObjSet = new CMDBObjectSet($oMyFilter); - echo $oMyFilter->__DescribeHTML()."' - Found ".$oObjSet->Count()." items.
\n"; - self::show_list($oObjSet); - } - - static protected function search_and_show_list_from_oql($sOQL) - { - echo $sOQL."...
\n"; - $oNewFilter = DBObjectSearch::FromOQL($sOQL); - self::search_and_show_list($oNewFilter); - } -} - - -/** - * Test to execute a scenario common to any business model (tries to build all the possible queries, etc.) - * - * @package iTopORM - */ -abstract class TestBizModelGeneric extends TestBizModel -{ - static public function GetName() - { - return 'Full test on a given business model'; - } - - static public function GetDescription() - { - return 'Systematic tests: gets each and every existing class and tries every attribute, search filters, etc.'; - } - - protected function DoPrepare() - { - parent::DoPrepare(); - - if (!MetaModel::DBExists(false)) - { - MetaModel::DBCreate(); - } - // something here to create records... but that's another story - } - - protected function DoExecute() - { - foreach(MetaModel::GetClasses() as $sClassName) - { - if (MetaModel::HasTable($sClassName)) continue; - - $oNobody = MetaModel::GetObject($sClassName, 123); - $oBaby = new $sClassName; - $oFilter = new DBObjectSearch($sClassName); - - // Challenge reversibility of OQL / filter object - // - $sExpr1 = $oFilter->ToOQL(); - $oNewFilter = DBObjectSearch::FromOQL($sExpr1); - $sExpr2 = $oNewFilter->ToOQL(); - if ($sExpr1 != $sExpr2) - { - $this->ReportError("Found two different OQL expression out of the (same?) filter: $sExpr1 != $sExpr2"); - } - - // Use the filter (perform the query) - // - $oSet = new CMDBObjectSet($oFilter); - $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName"); - } - return true; - } -} - - -?> + + * @author Romain Quetiez + * @author Denis Flaven + * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL + */ + + +require_once('coreexception.class.inc.php'); +require_once('attributedef.class.inc.php'); +require_once('filterdef.class.inc.php'); +require_once('stimulus.class.inc.php'); +require_once('MyHelpers.class.inc.php'); + +require_once('expression.class.inc.php'); +require_once('cmdbsource.class.inc.php'); +require_once('sqlquery.class.inc.php'); + +require_once('log.class.inc.php'); + +require_once('dbobject.class.php'); +require_once('dbobjectsearch.class.php'); +require_once('dbobjectset.class.php'); + +require_once('userrights.class.inc.php'); + +require_once('../webservices/webservices.class.inc.php'); + + +// Just to differentiate programmatically triggered exceptions and other kind of errors (usefull?) +class UnitTestException extends Exception +{} + + +/** + * Improved display of the backtrace + * + * @package iTopORM + */ +class ExceptionFromError extends Exception +{ + public function getTraceAsHtml() + { + $aBackTrace = $this->getTrace(); + return MyHelpers::get_callstack_html(0, $this->getTrace()); + // return "
\n".$this->getTraceAsString()."
\n"; + } +} + + +/** + * Test handler API and basic helpers + * + * @package iTopORM + */ +abstract class TestHandler +{ + protected $m_aSuccesses; + protected $m_aWarnings; + protected $m_aErrors; + protected $m_sOutput; + + public function __construct() + { + $this->m_aSuccesses = array(); + $this->m_aWarnings = array(); + $this->m_aErrors = array(); + } + + abstract static public function GetName(); + abstract static public function GetDescription(); + + protected function DoPrepare() {return true;} + abstract protected function DoExecute(); + protected function DoCleanup() {return true;} + + protected function ReportSuccess($sMessage, $sSubtestId = '') + { + $this->m_aSuccesses[] = $sMessage; + } + + protected function ReportWarning($sMessage, $sSubtestId = '') + { + $this->m_aWarnings[] = $sMessage; + } + + protected function ReportError($sMessage, $sSubtestId = '') + { + $this->m_aErrors[] = $sMessage; + } + + public function GetResults() + { + return $this->m_aSuccesses; + } + + public function GetWarnings() + { + return $this->m_aWarnings; + } + + public function GetErrors() + { + return $this->m_aErrors; + } + + public function GetOutput() + { + return $this->m_sOutput; + } + + public function error_handler($errno, $errstr, $errfile, $errline) + { + // Note: return false to call the default handler (stop the program if an error) + + switch ($errno) + { + case E_USER_ERROR: + $this->ReportError($errstr); + //throw new ExceptionFromError("Fatal error in line $errline of file $errfile: $errstr"); + break; + case E_USER_WARNING: + $this->ReportWarning($errstr); + break; + case E_USER_NOTICE: + $this->ReportWarning($errstr); + break; + default: + $this->ReportWarning("Unknown error type: [$errno] $errstr in $errfile at $errline"); + echo "Unknown error type: [$errno] $errstr in $errfile at $errline
\n"; + break; + } + return true; // do not call the default handler + } + + public function Execute() + { + ob_start(); + set_error_handler(array($this, 'error_handler')); + try + { + $this->DoPrepare(); + $this->DoExecute(); + } + catch (ExceptionFromError $e) + { + $this->ReportError($e->getMessage().' - '.$e->getTraceAsHtml()); + } + catch (CoreException $e) + { + //$this->ReportError($e->getMessage()); + //$this->ReportError($e->__tostring()); + $this->ReportError($e->getMessage().' - '.$e->getTraceAsHtml()); + } + catch (Exception $e) + { + //$this->ReportError($e->getMessage()); + //$this->ReportError($e->__tostring()); + $this->ReportError('class '.get_class($e).' --- '.$e->getMessage().' - '.$e->getTraceAsString()); + } + restore_error_handler(); + $this->m_sOutput = ob_get_clean(); + return (count($this->GetErrors()) == 0); + } +} + + + + +/** + * Test to execute a piece of code (checks if an error occurs) + * + * @package iTopORM + */ +abstract class TestFunction extends TestHandler +{ + // simply overload DoExecute (temporary) +} + + +/** + * Test to execute a piece of code (checks if an error occurs) + * + * @package iTopORM + */ +abstract class TestWebServices extends TestHandler +{ + // simply overload DoExecute (temporary) + + static protected function DoPostRequestAuth($sRelativeUrl, $aData, $sLogin = 'admin', $sPassword = 'admin', $sOptionnalHeaders = null) + { + $aDataAndAuth = $aData; + $aDataAndAuth['operation'] = 'login'; + $aDataAndAuth['auth_user'] = $sLogin; + $aDataAndAuth['auth_pwd'] = $sPassword; + $sHost = $_SERVER['HTTP_HOST']; + $sRawPath = $_SERVER['SCRIPT_NAME']; + $sPath = dirname($sRawPath); + $sUrl = "http://$sHost/$sPath/$sRelativeUrl"; + + return self::DoPostRequest($sUrl, $aDataAndAuth, $sOptionnalHeaders); + } + + // Source: http://netevil.org/blog/2006/nov/http-post-from-php-without-curl + // originaly named after do_post_request + // Partially adapted to our coding conventions + static protected function DoPostRequest($sUrl, $aData, $sOptionnalHeaders = null) + { + // $sOptionnalHeaders is a string containing additional HTTP headers that you would like to send in your request. + + $sData = http_build_query($aData); + + $aParams = array('http' => array( + 'method' => 'POST', + 'content' => $sData, + 'header'=> "Content-type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($sData)."\r\n", + )); + if ($sOptionnalHeaders !== null) + { + $aParams['http']['header'] .= $sOptionnalHeaders; + } + $ctx = stream_context_create($aParams); + + $fp = @fopen($sUrl, 'rb', false, $ctx); + if (!$fp) + { + throw new Exception("Problem with $sUrl, $php_errormsg"); + } + $response = @stream_get_contents($fp); + if ($response === false) + { + throw new Exception("Problem reading data from $sUrl, $php_errormsg"); + } + return $response; + } +} + +/** + * Test to execute a piece of code (checks if an error occurs) + * + * @package iTopORM + */ +abstract class TestSoapWebService extends TestHandler +{ + // simply overload DoExecute (temporary) + + function __construct() + { + parent::__construct(); + } +} + +/** + * Test to check that a function outputs some values depending on its input + * + * @package iTopORM + */ +abstract class TestFunctionInOut extends TestFunction +{ + abstract static public function GetCallSpec(); // parameters to call_user_func + abstract static public function GetInOut(); // array of input => output + + protected function DoExecute() + { + $aTests = $this->GetInOut(); + if (is_array($aTests)) + { + foreach ($aTests as $iTestId => $aTest) + { + $ret = call_user_func_array($this->GetCallSpec(), $aTest['args']); + if ($ret != $aTest['output']) + { + // Note: to be improved to cope with non string parameters + $this->ReportError("Found '$ret' while expecting '".$aTest['output']."'", $iTestId); + } + else + { + $this->ReportSuccess("Found the expected output '$ret'", $iTestId); + } + } + } + else + { + $ret = call_user_func($this->GetCallSpec()); + $this->ReportSuccess('Finished successfully'); + } + } +} + + +/** + * Test to check an URL (Searches for Error/Warning/Etc keywords) + * + * @package iTopORM + */ +abstract class TestUrl extends TestHandler +{ + abstract static public function GetUrl(); + abstract static public function GetErrorKeywords(); + abstract static public function GetWarningKeywords(); + + protected function DoExecute() + { + return true; + } +} + + +/** + * Test to check a user management module + * + * @package iTopORM + */ +abstract class TestUserRights extends TestHandler +{ + protected function DoExecute() + { + return true; + } +} + + +/** + * Test to execute a scenario on a given DB + * + * @package iTopORM + */ +abstract class TestScenarioOnDB extends TestHandler +{ + abstract static public function GetDBHost(); + abstract static public function GetDBUser(); + abstract static public function GetDBPwd(); + abstract static public function GetDBName(); + + protected function DoPrepare() + { + $sDBHost = $this->GetDBHost(); + $sDBUser = $this->GetDBUser(); + $sDBPwd = $this->GetDBPwd(); + $sDBName = $this->GetDBName(); + + CMDBSource::Init($sDBHost, $sDBUser, $sDBPwd); + if (CMDBSource::IsDB($sDBName)) + { + CMDBSource::DropDB($sDBName); + } + CMDBSource::CreateDB($sDBName); + } + + protected function DoCleanup() + { + // CMDBSource::DropDB($this->GetDBName()); + } +} + + +/** + * Test to use a business model on a given DB + * + * @package iTopORM + */ +abstract class TestBizModel extends TestHandler +{ +// abstract static public function GetDBSubName(); +// abstract static public function GetBusinessModelFile(); + abstract static public function GetConfigFile(); + + protected function DoPrepare() + { + MetaModel::Startup($this->GetConfigFile(), true); // Load model only +// #@# Temporary disabled by Romain +// MetaModel::CheckDefinitions(); + + // something here to create records... but that's another story + } + + protected $m_oChange; + protected function ObjectToDB($oNew, $bReload = false) + { + list($bRes, $aIssues) = $oNew->CheckToInsert(); + if (!$bRes) + { + throw new CoreException('Could not create object, unexpected values', array('attributes' => $aIssues)); + } + if ($oNew instanceof CMDBObject) + { + if (!isset($this->m_oChange)) + { + new CMDBChange(); + $oMyChange = MetaModel::NewObject("CMDBChange"); + $oMyChange->Set("date", time()); + $oMyChange->Set("userinfo", "Someone doing some tests"); + $iChangeId = $oMyChange->DBInsertNoReload(); + $this->m_oChange = $oMyChange; + } + if ($bReload) + { + $iId = $oNew->DBInsertTracked($this->m_oChange); + } + else + { + $iId = $oNew->DBInsertTrackedNoReload($this->m_oChange); + } + } + else + { + if ($bReload) + { + $iId = $oNew->DBInsert(); + } + else + { + $iId = $oNew->DBInsertNoReload(); + } + } + return $iId; + } + + protected function ResetDB() + { + if (MetaModel::DBExists(false)) + { + MetaModel::DBDrop(); + } + MetaModel::DBCreate(); + } + + static protected function show_list($oObjectSet) + { + $oObjectSet->Rewind(); + $aData = array(); + while ($oItem = $oObjectSet->Fetch()) + { + $aValues = array(); + foreach(MetaModel::GetAttributesList(get_class($oItem)) as $sAttCode) + { + $aValues[$sAttCode] = $oItem->GetAsHTML($sAttCode); + } + //echo $oItem->GetKey()." => ".implode(", ", $aValues)."
\n"; + $aData[] = $aValues; + } + echo MyHelpers::make_table_from_assoc_array($aData); + } + + static protected function search_and_show_list(DBObjectSearch $oMyFilter) + { + $oObjSet = new CMDBObjectSet($oMyFilter); + echo $oMyFilter->__DescribeHTML()."' - Found ".$oObjSet->Count()." items.
\n"; + self::show_list($oObjSet); + } + + static protected function search_and_show_list_from_oql($sOQL) + { + echo $sOQL."...
\n"; + $oNewFilter = DBObjectSearch::FromOQL($sOQL); + self::search_and_show_list($oNewFilter); + } +} + + +/** + * Test to execute a scenario common to any business model (tries to build all the possible queries, etc.) + * + * @package iTopORM + */ +abstract class TestBizModelGeneric extends TestBizModel +{ + static public function GetName() + { + return 'Full test on a given business model'; + } + + static public function GetDescription() + { + return 'Systematic tests: gets each and every existing class and tries every attribute, search filters, etc.'; + } + + protected function DoPrepare() + { + parent::DoPrepare(); + + if (!MetaModel::DBExists(false)) + { + MetaModel::DBCreate(); + } + // something here to create records... but that's another story + } + + protected function DoExecute() + { + foreach(MetaModel::GetClasses() as $sClassName) + { + if (MetaModel::HasTable($sClassName)) continue; + + $oNobody = MetaModel::GetObject($sClassName, 123); + $oBaby = new $sClassName; + $oFilter = new DBObjectSearch($sClassName); + + // Challenge reversibility of OQL / filter object + // + $sExpr1 = $oFilter->ToOQL(); + $oNewFilter = DBObjectSearch::FromOQL($sExpr1); + $sExpr2 = $oNewFilter->ToOQL(); + if ($sExpr1 != $sExpr2) + { + $this->ReportError("Found two different OQL expression out of the (same?) filter: $sExpr1 != $sExpr2"); + } + + // Use the filter (perform the query) + // + $oSet = new CMDBObjectSet($oFilter); + $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName"); + } + return true; + } +} + + +?> diff --git a/pages/ITopConsultant.php b/pages/ITopConsultant.php index 2ae597a0b..1976d01b7 100644 --- a/pages/ITopConsultant.php +++ b/pages/ITopConsultant.php @@ -433,7 +433,7 @@ if (empty($sConfigFile)) exit; } -MetaModel::Startup($sConfigFile, true); // allow missing DB +MetaModel::Startup($sConfigFile, true); // load data model only $sBaseArgs = "config=".urlencode($sConfigFile); diff --git a/setup/index.php b/setup/index.php index 859e82336..fc96082da 100644 --- a/setup/index.php +++ b/setup/index.php @@ -342,10 +342,10 @@ function CheckServerConnection(SetupWebPage $oP, $sDBServer, $sDBUser, $sDBPwd) * Helper function to initialize the ORM and load the data model * from the given file * @param $sConfigFileName string The name of the configuration file to load - * @param $bAllowMissingDatabase boolean Whether or not to allow loading a data model with no corresponding DB + * @param $bModelOnly boolean Whether or not to allow loading a data model with no corresponding DB * @return none */ -function InitDataModel(SetupWebPage $oP, $sConfigFileName, $bAllowMissingDatabase = true) +function InitDataModel(SetupWebPage $oP, $sConfigFileName, $bModelOnly = true) { require_once('../core/log.class.inc.php'); require_once('../core/coreexception.class.inc.php'); @@ -361,8 +361,9 @@ function InitDataModel(SetupWebPage $oP, $sConfigFileName, $bAllowMissingDatabas require_once('../core/dbobjectsearch.class.php'); require_once('../core/dbobjectset.class.php'); require_once('../core/userrights.class.inc.php'); - $oP->log("Info - MetaModel::Startup from file '$sConfigFileName' (AllowMissingDB = $bAllowMissingDatabase)"); - MetaModel::Startup($sConfigFileName, $bAllowMissingDatabase); + $oP->log("Info - MetaModel::Startup from file '$sConfigFileName' (ModelOnly = $bModelOnly)"); + + MetaModel::Startup($sConfigFileName, $bModelOnly); } /** * Helper function to create the database structure @@ -410,7 +411,7 @@ function CreateDatabaseStructure(SetupWebPage $oP, Config $oConfig, $sDBName, $s function CreateAdminAccount(SetupWebPage $oP, Config $oConfig, $sAdminUser, $sAdminPwd, $sLanguage) { $oP->log('Info - CreateAdminAccount'); - InitDataModel($oP, TMP_CONFIG_FILE, true); // allow missing DB + InitDataModel($oP, TMP_CONFIG_FILE, true); // load data model only if (UserRights::CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage)) { $oP->ok("Administrator account '$sAdminUser' created."); @@ -943,7 +944,7 @@ function SetupFinished(SetupWebPage $oP, $aParamValues, $iCurrentStep, Config $o $oConfig->WriteToFile(FINAL_CONFIG_FILE); // Start the application - InitDataModel($oP, FINAL_CONFIG_FILE, false); // DO NOT allow missing DB + InitDataModel($oP, FINAL_CONFIG_FILE, false); // Load model and startup DB if (UserRights::Login($sAuthUser, $sAuthPwd)) { $_SESSION['auth_user'] = $sAuthUser; diff --git a/setup/xmldataloader.class.inc.php b/setup/xmldataloader.class.inc.php index c0f4c9a5d..d92880577 100644 --- a/setup/xmldataloader.class.inc.php +++ b/setup/xmldataloader.class.inc.php @@ -85,7 +85,7 @@ class XMLDataLoader /** * Initializes the ORM (MetaModel) */ - protected function InitDataModel($sConfigFileName, $bAllowMissingDatabase = true) + protected function InitDataModel($sConfigFileName) { require_once('../core/log.class.inc.php'); require_once('../core/coreexception.class.inc.php'); @@ -101,7 +101,7 @@ class XMLDataLoader require_once('../core/dbobjectsearch.class.php'); require_once('../core/dbobjectset.class.php'); require_once('../core/userrights.class.inc.php'); - MetaModel::Startup($sConfigFileName, $bAllowMissingDatabase); + MetaModel::Startup($sConfigFileName); } /**