testlist.inc.php 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  1. <?php
  2. class TestSQLQuery extends TestScenarioOnDB
  3. {
  4. static public function GetName() {return 'SQLQuery';}
  5. static public function GetDescription() {return 'SQLQuery does not depend on the rest of the framework, therefore it makes sense to have a separate test framework for it';}
  6. static public function GetDBHost() {return 'localhost';}
  7. static public function GetDBUser() {return 'RomainDBLogin';}
  8. static public function GetDBPwd() {return '';}
  9. static public function GetDBName() {return 'TestSQLQuery';}
  10. static public function GetDBSubName() {return 'taratata';}
  11. protected function DoPrepare()
  12. {
  13. parent::DoPrepare();
  14. cmdbSource::CreateTable('CREATE TABLE `myTable` (myKey INT(11) NOT NULL auto_increment, column1 VARCHAR(255), column2 VARCHAR(255), PRIMARY KEY (`myKey`)) ENGINE = innodb');
  15. cmdbSource::CreateTable('CREATE TABLE `myTable1` (myKey1 INT(11) NOT NULL auto_increment, column1_1 VARCHAR(255), column1_2 VARCHAR(255), PRIMARY KEY (`myKey1`)) ENGINE = innodb');
  16. cmdbSource::CreateTable('CREATE TABLE `myTable2` (myKey2 INT(11) NOT NULL auto_increment, column2_1 VARCHAR(255), column2_2 VARCHAR(255), PRIMARY KEY (`myKey2`)) ENGINE = innodb');
  17. }
  18. protected function DoExecute()
  19. {
  20. $oQuery = new SQLQuery(
  21. $sTable = 'myTable',
  22. $sTableAlias = 'myTableAlias',
  23. $aFields = array('column1'=>new FieldExpression('column1', 'myTableAlias'), 'column2'=>new FieldExpression('column2', 'myTableAlias')),
  24. $oCondition = new BinaryExpression(new FieldExpression('column1', 'myTableAlias'), 'LIKE', new ScalarExpression('trash')),
  25. $aFullTextNeedles = array('column1'),
  26. $bToDelete = false,
  27. $aValues = array()
  28. );
  29. $oQuery->AddCondition(Expression::FromOQL('DATE(NOW() - 1200 * 2) > \'2008-07-31\''));
  30. $oSubQuery1 = new SQLQuery(
  31. $sTable = 'myTable1',
  32. $sTableAlias = 'myTable1Alias',
  33. $aFields = array('column1_1'=>new FieldExpression('column1', 'myTableAlias'), 'column1_2'=>new FieldExpression('column1', 'myTableAlias')),
  34. $oCondition = new TrueSQLExpression,
  35. $aFullTextNeedles = array(),
  36. $bToDelete = false,
  37. $aValues = array()
  38. );
  39. $oSubQuery2 = new SQLQuery(
  40. $sTable = 'myTable2',
  41. $sTableAlias = 'myTable2Alias',
  42. $aFields = array('column2_1'=>new FieldExpression('column2', 'myTableAlias'), 'column2_2'=>new FieldExpression('column2', 'myTableAlias')),
  43. $oCondition = new TrueSQLExpression,
  44. $aFullTextNeedles = array(),
  45. $bToDelete = false,
  46. $aValues = array()
  47. );
  48. $oQuery->AddInnerJoin($oSubQuery1, 'column1', 'column1_1');
  49. $oQuery->AddLeftJoin($oSubQuery2, 'column2', 'column2_2');
  50. $oQuery->DisplayHtml();
  51. $oQuery->RenderDelete();
  52. $oQuery->RenderUpdate();
  53. echo '<p>'.$oQuery->RenderSelect().'</p>';
  54. $oQuery->RenderSelect(array('column1'));
  55. $oQuery->RenderSelect(array('column1', 'column2'));
  56. }
  57. }
  58. class TestOQLParser extends TestFunction
  59. {
  60. static public function GetName() {return 'Check OQL parsing';}
  61. static public function GetDescription() {return 'Attempts a series of queries, and in particular those with a bad syntax';}
  62. protected function CheckQuery($sQuery, $bIsCorrectQuery)
  63. {
  64. $oOql = new OqlInterpreter($sQuery);
  65. try
  66. {
  67. $oTrash = $oOql->Parse(); // Not expecting a given format, otherwise use ParseExpression/ParseObjectQuery/ParseValueSetQuery
  68. MyHelpers::var_dump_html($oTrash, true);
  69. }
  70. catch (OQLException $OqlException)
  71. {
  72. if ($bIsCorrectQuery)
  73. {
  74. echo "<p>More info on this unexpected failure:<br/>".$OqlException->getHtmlDesc()."</p>\n";
  75. throw $OqlException;
  76. return false;
  77. }
  78. else
  79. {
  80. // Everything is fine :-)
  81. echo "<p>More info on this expected failure:<br/>".$OqlException->getHtmlDesc()."</p>\n";
  82. return true;
  83. }
  84. }
  85. // The query was correctly parsed, was it expected to be correct ?
  86. if ($bIsCorrectQuery)
  87. {
  88. return true;
  89. }
  90. else
  91. {
  92. throw new UnitTestException("The query '$sQuery' was parsed with success, while it shouldn't (?)");
  93. return false;
  94. }
  95. }
  96. protected function TestQuery($sQuery, $bIsCorrectQuery)
  97. {
  98. if (!$this->CheckQuery($sQuery, $bIsCorrectQuery))
  99. {
  100. return false;
  101. }
  102. return true;
  103. }
  104. public function DoExecute()
  105. {
  106. $aQueries = array(
  107. 'SELECT toto' => true,
  108. 'SELECT toto WHERE toto.a = 1' => true,
  109. 'SELECT toto WHERE toto.a=1' => true,
  110. 'SELECT toto WHERE toto.a = "1"' => true,
  111. 'SELECT toto WHHHERE toto.a = "1"' => false,
  112. 'SELECT toto WHERE toto.a == "1"' => false,
  113. 'SELECT toto WHERE toto.a % 1' => false,
  114. //'SELECT toto WHERE toto.a LIKE 1' => false,
  115. 'SELECT toto WHERE toto.a like \'arg\'' => false,
  116. 'SELECT toto WHERE toto.a NOT LIKE "That\'s it"' => true,
  117. 'SELECT toto WHERE toto.a NOT LIKE "That\'s "it""' => false,
  118. 'SELECT toto WHERE toto.a NOT LIKE "That\'s \\"it\\""' => true,
  119. 'SELECT toto WHERE toto.a NOT LIKE \'That"s it\'' => true,
  120. 'SELECT toto WHERE toto.a NOT LIKE \'That\'s it\'' => false,
  121. 'SELECT toto WHERE toto.a NOT LIKE \'That\\\'s it\'' => true,
  122. 'SELECT toto WHERE toto.a NOT LIKE "blah \\ truc"' => false,
  123. 'SELECT toto WHERE toto.a NOT LIKE "blah \\\\ truc"' => true,
  124. 'SELECT toto WHERE toto.a NOT LIKE \'blah \\ truc\'' => false,
  125. 'SELECT toto WHERE toto.a NOT LIKE \'blah \\\\ truc\'' => true,
  126. 'SELECT toto WHERE toto.a NOT LIKE "\\\\"' => true,
  127. 'SELECT toto WHERE toto.a NOT LIKE "\\""' => true,
  128. 'SELECT toto WHERE toto.a NOT LIKE "\\"\\\\"' => true,
  129. 'SELECT toto WHERE toto.a NOT LIKE "\\\\\\""' => true,
  130. 'SELECT toto WHERE toto.a NOT LIKE ""' => true,
  131. 'SELECT toto WHERE toto.a NOT LIKE "\\\\"' => true,
  132. "SELECT UserRightsMatrixClassGrant WHERE UserRightsMatrixClassGrant.class = 'lnkContactRealObject' AND UserRightsMatrixClassGrant.action = 'modify' AND UserRightsMatrixClassGrant.login = 'Denis'" => true,
  133. "SELECT A WHERE A.col1 = 'lit1' AND A.col2 = 'lit2' AND A.col3 = 'lit3'" => true,
  134. 'SELECT toto WHERE toto.a NOT LIKE "blah" AND toto.b LIKE "foo"' => true,
  135. //'SELECT toto WHERE toto.a > \'asd\'' => false,
  136. 'SELECT toto WHERE toto.a = 1 AND toto.b LIKE "x" AND toto.f >= 12345' => true,
  137. 'SELECT Device JOIN Site ON Device.site = Site.id' => true,
  138. 'SELECT Device JOIN Site ON Device.site = Site.id JOIN Country ON Site.location = Country.id' => true,
  139. "SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 = 123 AND B.col1 = 'aa') OR (A.col3 = 'zzz' AND B.col4 > 100)" => true,
  140. "SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 = B.col2 AND B.col1 = A.col2) OR (A.col3 = '' AND B.col4 > 100)" => true,
  141. "SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + B.col2 * B.col1 = A.col2" => true,
  142. "SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + (B.col2 * B.col1) = A.col2" => true,
  143. "SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 + B.col2) * B.col1 = A.col2" => true,
  144. 'SELECT Device AS D_ JOIN Site AS S_ ON D_.site = S_.id WHERE S_.country = "Francia"' => true,
  145. );
  146. $iErrors = 0;
  147. foreach($aQueries as $sQuery => $bIsCorrectQuery)
  148. {
  149. $sIsOk = $bIsCorrectQuery ? 'good' : 'bad';
  150. echo "<h4>Testing query: $sQuery ($sIsOk)</h4>\n";
  151. $bRet = $this->TestQuery($sQuery, $bIsCorrectQuery);
  152. if (!$bRet) $iErrors++;
  153. }
  154. return ($iErrors == 0);
  155. }
  156. }
  157. class TestGenericItoMyModel extends TestBizModelGeneric
  158. {
  159. static public function GetName()
  160. {
  161. return 'Generic RO test on '.self::GetConfigFile();
  162. }
  163. static public function GetConfigFile() {return '../config-test-mymodel.php';}
  164. }
  165. class TestGenericItopBigModel extends TestBizModelGeneric
  166. {
  167. static public function GetName()
  168. {
  169. return 'Generic RO test on '.self::GetConfigFile();
  170. }
  171. static public function GetConfigFile() {return '../config-test-itopv06.php';}
  172. }
  173. class TestUserRightsMatrixItop extends TestUserRights
  174. {
  175. static public function GetName()
  176. {
  177. return 'User rights test on user rights matrix';
  178. }
  179. static public function GetDescription()
  180. {
  181. return 'blah blah blah';
  182. }
  183. public function DoPrepare()
  184. {
  185. parent::DoPrepare();
  186. MetaModel::Startup('../config-test-itopv06.php');
  187. }
  188. protected function DoExecute()
  189. {
  190. $sUser = 'Romain';
  191. echo "<p>Totor: ".(UserRights::Login('Totor', 'toto') ? 'ok' : 'NO')."</p>\n";
  192. echo "<p>Romain: ".(UserRights::Login('Romain', 'toto') ? 'ok' : 'NO')."</p>\n";
  193. echo "<p>User: ".UserRights::GetUser()."</p>\n";
  194. echo "<p>On behalf of...".UserRights::GetRealUser()."</p>\n";
  195. echo "<p>Denis (impersonate) : ".(UserRights::Impersonate('Denis', 'tutu') ? 'ok' : 'NO')."</p>\n";
  196. echo "<p>User: ".UserRights::GetUser()."</p>\n";
  197. echo "<p>On behalf of...".UserRights::GetRealUser()."</p>\n";
  198. UserRights::GetFilter('bizOrganization'); // returns a filter object
  199. $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT bizOrganization"));
  200. echo "<p>IsActionAllowed...".(UserRights::IsActionAllowed('bizOrganization', UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  201. echo "<p>IsStimulusAllowed...".(UserRights::IsStimulusAllowed('bizOrganization', 'myStimulus', $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  202. echo "<p>IsActionAllowedOnAttribute...".(UserRights::IsActionAllowedOnAttribute('bizOrganization', 'myattribute', UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES ? 'ok' : 'NO')."</p>\n";
  203. return true;
  204. }
  205. }
  206. ///////////////////////////////////////////////////////////////////////////
  207. // Test a complex biz model on the fly
  208. ///////////////////////////////////////////////////////////////////////////
  209. class TestMyBizModel extends TestBizModel
  210. {
  211. static public function GetName()
  212. {
  213. return 'A series of tests on a weird business model';
  214. }
  215. static public function GetDescription()
  216. {
  217. return 'Attempts various operations and build complex queries';
  218. }
  219. static public function GetConfigFile() {return '../config-test-mymodel.php';}
  220. function test_linksinfo()
  221. {
  222. echo "<h4>Enum links</h4>";
  223. MyHelpers::var_dump_html(MetaModel::EnumReferencedClasses("cmdbTeam"));
  224. MyHelpers::var_dump_html(MetaModel::EnumReferencingClasses("Organization"));
  225. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses());
  226. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses("cmdbContact"));
  227. MyHelpers::var_dump_html(MetaModel::EnumLinkingClasses("cmdWorkshop"));
  228. MyHelpers::var_dump_html(MetaModel::GetLinkLabel("Liens_entre_contacts_et_workshop", "toworkshop"));
  229. }
  230. function test_list_attributes()
  231. {
  232. echo "<h4>List attributes</h4>";
  233. foreach(MetaModel::ListAttributeDefs("cmdbTeam") as $sAttCode=>$oAttDef)
  234. {
  235. echo $oAttDef->GetLabel()." / ".$oAttDef->GetDescription()." / ".$oAttDef->GetType()."</br>\n";
  236. }
  237. }
  238. function test_search()
  239. {
  240. echo "<h4>Two searches</h4>";
  241. $oFilterAllDevs = new DBObjectSearch("cmdbTeam");
  242. $oAllDevs = new DBObjectSet($oFilterAllDevs);
  243. echo "Found ".$oAllDevs->Count()." items.</br>\n";
  244. while ($oDev = $oAllDevs->Fetch())
  245. {
  246. $aValues = array();
  247. foreach(MetaModel::GetAttributesList($oAllDevs->GetClass()) as $sAttCode)
  248. {
  249. $aValues[] = MetaModel::GetLabel(get_class($oDev), $sAttCode)." (".MetaModel::GetDescription(get_class($oDev), $sAttCode).") = ".$oDev->GetAsHTML($sAttCode);
  250. }
  251. echo $oDev->GetKey()." => ".implode(", ", $aValues)."</br>\n";
  252. }
  253. // a second one
  254. $oMyFilter = new DBObjectSearch("cmdbContact");
  255. //$oMyFilter->AddCondition("name", "aii", "Finishes with");
  256. $oMyFilter->AddCondition("name", "aii");
  257. $this->search_and_show_list($oMyFilter);
  258. }
  259. function test_reload()
  260. {
  261. echo "<h4>Reload</h4>";
  262. $team = MetaModel::GetObject("cmdbContact", "2");
  263. echo "Chargement de l'attribut headcount: {$team->Get("headcount")}</br>\n";
  264. MyHelpers::var_dump_html($team);
  265. }
  266. function test_setattribute()
  267. {
  268. echo "<h4>Set attribute and update</h4>";
  269. $team = MetaModel::GetObject("cmdbTeam", "2");
  270. $team->Set("headcount", rand(1,1000));
  271. $team->Set("email", "Luis ".rand(9,250));
  272. MyHelpers::var_dump_html($team->ListChanges());
  273. echo "New headcount = {$team->Get("headcount")}</br>\n";
  274. echo "Computed name = {$team->Get("name")}</br>\n";
  275. $oMyChange = MetaModel::NewObject("CMDBChange");
  276. $oMyChange->Set("date", time());
  277. $oMyChange->Set("userinfo", "test_setattribute / Made by robot #".rand(1,100));
  278. $iChangeId = $oMyChange->DBInsert();
  279. //MetaModel::StartDebugQuery();
  280. $team->DBUpdateTracked($oMyChange);
  281. //MetaModel::StopDebugQuery();
  282. echo "<h4>Check the modified team</h4>";
  283. $oTeam = MetaModel::GetObject("cmdbTeam", "2");
  284. MyHelpers::var_dump_html($oTeam);
  285. }
  286. function test_newobject()
  287. {
  288. $oMyChange = MetaModel::NewObject("CMDBChange");
  289. $oMyChange->Set("date", time());
  290. $oMyChange->Set("userinfo", "test_newobject / Made by robot #".rand(1,100));
  291. $iChangeId = $oMyChange->DBInsert();
  292. echo "<h4>Create a new object (team)</h4>";
  293. $oNewTeam = MetaModel::NewObject("cmdbTeam");
  294. $oNewTeam->Set("name", "ekip2choc #".rand(1000, 2000));
  295. $oNewTeam->Set("email", "machin".rand(1,100)."@tnut.com");
  296. $oNewTeam->Set("email", null);
  297. $oNewTeam->Set("owner", "ITOP");
  298. $oNewTeam->Set("headcount", "0".rand(38000, 38999)); // should be reset to an int value
  299. $iId = $oNewTeam->DBInsertTracked($oMyChange);
  300. echo "Created new team: $iId</br>";
  301. echo "<h4>Delete team #$iId</h4>";
  302. $oTeam = MetaModel::GetObject("cmdbTeam", $iId);
  303. $oTeam->DBDeleteTracked($oMyChange);
  304. echo "Deleted team: $iId</br>";
  305. MyHelpers::var_dump_html($oTeam);
  306. }
  307. function test_updatecolumn()
  308. {
  309. $oMyChange = MetaModel::NewObject("CMDBChange");
  310. $oMyChange->Set("date", time());
  311. $oMyChange->Set("userinfo", "test_updatecolumn / Made by robot #".rand(1,100));
  312. $iChangeId = $oMyChange->DBInsert();
  313. $sNewEmail = "updatecol".rand(9,250)."@quedlaballe.com";
  314. echo "<h4>Update a the email: set to '$sNewEmail'</h4>";
  315. $oMyFilter = new DBObjectSearch("cmdbContact");
  316. $oMyFilter->AddCondition("name", "o", "Contains");
  317. echo "Candidates before:</br>";
  318. $this->search_and_show_list($oMyFilter);
  319. MetaModel::BulkUpdateTracked($oMyChange, $oMyFilter, array("email" => $sNewEmail));
  320. echo "Candidates after:</br>";
  321. $this->search_and_show_list($oMyFilter);
  322. }
  323. function test_error()
  324. {
  325. trigger_error("Stop requested", E_USER_ERROR);
  326. }
  327. function test_changetracking()
  328. {
  329. echo "<h4>Create a change</h4>";
  330. $oMyChange = MetaModel::NewObject("CMDBChange");
  331. $oMyChange->Set("date", time());
  332. $oMyChange->Set("userinfo", "Made by robot #".rand(1,100));
  333. $iChangeId = $oMyChange->DBInsert();
  334. echo "Created new change: $iChangeId</br>";
  335. MyHelpers::var_dump_html($oMyChange);
  336. echo "<h4>Create a new object (team)</h4>";
  337. $oNewTeam = MetaModel::NewObject("cmdbTeam");
  338. $oNewTeam->Set("name", "ekip2choc #".rand(1000, 2000));
  339. $oNewTeam->Set("email", "machin".rand(1,100)."@tnut.com");
  340. $oNewTeam->Set("email", null);
  341. $oNewTeam->Set("owner", "ITOP");
  342. $oNewTeam->Set("headcount", "0".rand(38000, 38999)); // should be reset to an int value
  343. $iId = $oNewTeam->DBInsertTracked($oMyChange);
  344. echo "Created new team: $iId</br>";
  345. echo "<h4>Delete team #$iId</h4>";
  346. $oTeam = MetaModel::GetObject("cmdbTeam", $iId);
  347. $oTeam->DBDeleteTracked($oMyChange);
  348. echo "Deleted team: $iId</br>";
  349. MyHelpers::var_dump_html($oTeam);
  350. }
  351. function test_zlist()
  352. {
  353. echo "<h4>Test ZLists</h4>";
  354. $aZLists = MetaModel::EnumZLists();
  355. foreach ($aZLists as $sListCode)
  356. {
  357. $aListInfos = MetaModel::GetZListInfo($sListCode);
  358. echo "<h4>List '".$sListCode."' (".$aListInfos["description"].") of type '".$aListInfos["type"]."'</h5>\n";
  359. foreach (MetaModel::GetSubclasses("cmdbObjectHomeMade") as $sKlass)
  360. {
  361. $aItems = MetaModel::GetZListItems($sKlass, $sListCode);
  362. if (count($aItems) == 0) continue;
  363. echo "$sKlass - $sListCode : {".implode(", ", $aItems)."}</br>\n";
  364. }
  365. }
  366. echo "<h4>IsAttributeInZList()... </h4>";
  367. echo "Liens_entre_contacts_et_workshop::ws_info in list1 ? ".(MetaModel::IsAttributeInZList("Liens_entre_contacts_et_workshop", "list1", "ws_info") ? "yes" : "no")."</br>\n";
  368. echo "Liens_entre_contacts_et_workshop::toworkshop in list1 ? ".(MetaModel::IsAttributeInZList("Liens_entre_contacts_et_workshop", "list1", "toworkshop") ? "yes" : "no")."</br>\n";
  369. }
  370. function test_SibuSQL()
  371. {
  372. echo "<h4>Simple But Structured Query Language</h4>";
  373. $oMyFilter = new DBObjectSearch("cmdbContact");
  374. echo "Tous les contacts: ".$oMyFilter->ToSibuSQL()."<br/>\n";
  375. $oNewFilter = DBObjectSearch::FromSibuSQL($oMyFilter->ToSibuSQL());
  376. echo "En passant par un filtre, ca revient en : ".$oNewFilter->ToSibuSQL()."</br>\n";
  377. $this->search_and_show_list($oNewFilter);
  378. $sFilterDesc = "cmdbContact: name Begins with '$[debutnom:as:debut du nom]' AND ownername NotLike $[ddd::]";
  379. echo "Construction d'un filtre a partir de sa description en SibuSQL: $sFilterDesc<br/>\n";
  380. MyHelpers::var_dump_html(DBObjectSearch::ListSibusQLParams($sFilterDesc));
  381. $oNewFilter = DBObjectSearch::FromSibuSQL($sFilterDesc, array('ddd'=>123));
  382. echo "Ca revient en: ".$oNewFilter->ToSibuSQL();
  383. }
  384. function test_pkey()
  385. {
  386. echo "<h4>Test search on pkey</h4>";
  387. $sExpr1 = "cmdbContact: pkey IN {40, 42}";
  388. $sExpr2 = "cmdbContact: pkey NOTIN {40, 42}";
  389. $this->search_and_show_list_from_sibusql($sExpr1);
  390. $this->search_and_show_list_from_sibusql($sExpr2);
  391. echo "Et maintenant, on fusionne....</br>\n";
  392. $oSet1 = new CMDBObjectSet(DBObjectSearch::FromSibuSQL($sExpr1));
  393. $oSet2 = new CMDBObjectSet(DBObjectSearch::FromSibuSQL($sExpr2));
  394. $oIntersect = $oSet1->CreateIntersect($oSet2);
  395. $oDelta = $oSet1->CreateDelta($oSet2);
  396. $oMerge = clone $oSet1;
  397. $oMerge->Merge($oSet2);
  398. $oMerge->Merge($oSet2);
  399. echo "Set1 - Found ".$oSet1->Count()." items.</br>\n";
  400. echo "Set2 - Found ".$oSet2->Count()." items.</br>\n";
  401. echo "Intersect - Found ".$oIntersect->Count()." items.</br>\n";
  402. echo "Delta - Found ".$oDelta->Count()." items.</br>\n";
  403. echo "Merge - Found ".$oMerge->Count()." items.</br>\n";
  404. //$this->show_list($oObjSet);
  405. }
  406. function test_relations()
  407. {
  408. echo "<h4>Test relations</h4>";
  409. //MyHelpers::var_dump_html(MetaModel::EnumRelationQueries("cmdbObjectHomeMade", "Potes"));
  410. MyHelpers::var_dump_html(MetaModel::EnumRelationQueries("cmdbContact", "Potes"));
  411. $iMaxDepth = 9;
  412. echo "Max depth = $iMaxDepth</br>\n";
  413. $oObj = MetaModel::GetObject("cmdbContact", 18);
  414. $aRels = $oObj->GetRelatedObjects("Potes", $iMaxDepth);
  415. echo $oObj->Get('name')." has some 'Potes'...</br>\n";
  416. foreach ($aRels as $sClass => $aObjs)
  417. {
  418. echo "$sClass, count = ".count($aObjs)." =&gt; ".implode(', ', array_keys($aObjs))."</br>\n";
  419. $oObjectSet = CMDBObjectSet::FromArray($sClass, $aObjs);
  420. $this->show_list($oObjectSet);
  421. }
  422. echo "<h4>Test relations - same results, by the mean of a SibuSQL</h4>";
  423. $this->search_and_show_list_from_sibusql("cmdbContact: RELATED (Potes, $iMaxDepth) TO (cmdbContact: pkey = 18)");
  424. }
  425. function test_linkedset()
  426. {
  427. echo "<h4>Linked set attributes</h4>\n";
  428. $oObj = MetaModel::GetObject("cmdbContact", 18);
  429. echo "<h5>Current workshops</h5>\n";
  430. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  431. $this->show_list($oSetWorkshopsCurr);
  432. echo "<h5>Setting workshops</h5>\n";
  433. $oNewLink = new cmdbLiens();
  434. $oNewLink->Set('toworkshop', 2);
  435. $oNewLink->Set('function', 'mafonctioooon');
  436. $oNewLink->Set('a1', 'tralala1');
  437. $oNewLink->Set('a2', 'F7M');
  438. $oSetWorkshops = CMDBObjectSet::FromArray("cmdbLiens", array($oNewLink));
  439. $oObj->Set("myworkshops", $oSetWorkshops);
  440. $this->show_list($oSetWorkshops);
  441. echo "<h5>New workshops</h5>\n";
  442. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  443. $this->show_list($oSetWorkshopsCurr);
  444. $oMyChange = MetaModel::NewObject("CMDBChange");
  445. $oMyChange->Set("date", time());
  446. $oMyChange->Set("userinfo", "test_linkedset / Made by robot #".rand(1,100));
  447. $iChangeId = $oMyChange->DBInsert();
  448. $oObj->DBUpdateTracked($oMyChange);
  449. $oObj = MetaModel::GetObject("cmdbContact", 18);
  450. echo "<h5>After the write</h5>\n";
  451. $oSetWorkshopsCurr = $oObj->Get("myworkshops");
  452. $this->show_list($oSetWorkshopsCurr);
  453. }
  454. function test_object_lifecycle()
  455. {
  456. echo "<h4>Test object lifecycle</h4>";
  457. MyHelpers::var_dump_html(MetaModel::GetStateAttributeCode("cmdbContact"));
  458. MyHelpers::var_dump_html(MetaModel::EnumStates("cmdbContact"));
  459. MyHelpers::var_dump_html(MetaModel::EnumStimuli("cmdbContact"));
  460. foreach(MetaModel::EnumStates("cmdbContact") as $sStateCode => $aStateDef)
  461. {
  462. echo "<p>Transition from <strong>$sStateCode</strong></p>\n";
  463. MyHelpers::var_dump_html(MetaModel::EnumTransitions("cmdbContact", $sStateCode));
  464. }
  465. $oObj = MetaModel::GetObject("cmdbContact", 18);
  466. echo "Current state: ".$oObj->GetState()."... let's go to school...";
  467. MyHelpers::var_dump_html($oObj->EnumTransitions());
  468. $oObj->ApplyStimulus("toschool");
  469. echo "New state: ".$oObj->GetState()."... let's get older...";
  470. MyHelpers::var_dump_html($oObj->EnumTransitions());
  471. $oObj->ApplyStimulus("raise");
  472. echo "New state: ".$oObj->GetState()."... let's try to go further... (should give an error)";
  473. MyHelpers::var_dump_html($oObj->EnumTransitions());
  474. $oObj->ApplyStimulus("raise"); // should give an error
  475. }
  476. protected function DoExecute()
  477. {
  478. // $this->ReportError("Found two different SibuSQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  479. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  480. //$this->test_linksinfo();
  481. //$this->test_list_attributes();
  482. //$this->test_search();
  483. //$this->test_reload();
  484. //$this->test_newobject();
  485. $this->test_setattribute();
  486. //$this->test_updatecolumn();
  487. //$this->test_error();
  488. //$this->test_changetracking();
  489. $this->test_zlist();
  490. $this->test_SibuSQL();
  491. //$this->test_pkey();
  492. $this->test_relations();
  493. $this->test_linkedset();
  494. $this->test_object_lifecycle();
  495. return true;
  496. }
  497. }
  498. ///////////////////////////////////////////////////////////////////////////
  499. // Test a complex biz model on the fly
  500. ///////////////////////////////////////////////////////////////////////////
  501. class TestQueriesOnFarm extends TestBizModel
  502. {
  503. static public function GetName()
  504. {
  505. return 'Farm test';
  506. }
  507. static public function GetDescription()
  508. {
  509. return 'A series of tests on the farm business model (SQL generation)';
  510. }
  511. static public function GetConfigFile() {return '../config-test-farm.php';}
  512. protected function DoPrepare()
  513. {
  514. parent::DoPrepare();
  515. $this->ResetDB();
  516. MetaModel::DBCheckIntegrity();
  517. }
  518. protected $m_oChange;
  519. protected function ObjectToDB(CMDBObject $oNew)
  520. {
  521. if (!isset($this->m_oChange))
  522. {
  523. new CMDBChange();
  524. $oMyChange = MetaModel::NewObject("CMDBChange");
  525. $oMyChange->Set("date", time());
  526. $oMyChange->Set("userinfo", "Administrator");
  527. $iChangeId = $oMyChange->DBInsertNoReload();
  528. $this->m_oChange = $oMyChange;
  529. }
  530. $iId = $oNew->DBInsertTrackedNoReload($this->m_oChange);
  531. return $iId;
  532. }
  533. protected function InsertMammal($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $sName, $iHeight, $sBirth)
  534. {
  535. $oNew = MetaModel::NewObject('Mammal');
  536. $oNew->Set('species', $sSpecies);
  537. $oNew->Set('sex', $sSex);
  538. $oNew->Set('speed', $iSpeed);
  539. $oNew->Set('mother', $iMotherid);
  540. $oNew->Set('father', $iFatherId);
  541. $oNew->Set('name', $sName);
  542. $oNew->Set('height', $iHeight);
  543. $oNew->Set('birth', $sBirth);
  544. return $this->ObjectToDB($oNew);
  545. }
  546. protected function InsertBird($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId)
  547. {
  548. $oNew = MetaModel::NewObject('Bird');
  549. $oNew->Set('species', $sSpecies);
  550. $oNew->Set('sex', $sSex);
  551. $oNew->Set('speed', $iSpeed);
  552. $oNew->Set('mother', $iMotherid);
  553. $oNew->Set('father', $iFatherId);
  554. return $this->ObjectToDB($oNew);
  555. }
  556. protected function InsertFlyingBird($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $iFlyingSpeed)
  557. {
  558. $oNew = MetaModel::NewObject('FlyingBird');
  559. $oNew->Set('species', $sSpecies);
  560. $oNew->Set('sex', $sSex);
  561. $oNew->Set('speed', $iSpeed);
  562. $oNew->Set('mother', $iMotherid);
  563. $oNew->Set('father', $iFatherId);
  564. $oNew->Set('flyingspeed', $iFlyingSpeed);
  565. return $this->ObjectToDB($oNew);
  566. }
  567. private function InsertGroup($sName, $iLeaderId)
  568. {
  569. $oNew = MetaModel::NewObject('Group');
  570. $oNew->Set('name', $sName);
  571. $oNew->Set('leader', $iLeaderId);
  572. $iId = $oNew->DBInsertNoReload();
  573. return $iId;
  574. }
  575. protected function CheckQuery($sQuery, $bIsCorrectQuery)
  576. {
  577. if ($bIsCorrectQuery)
  578. {
  579. echo "<h4 style=\"color:green;\">$sQuery</h4>\n";
  580. }
  581. else
  582. {
  583. echo "<h4 style=\"color:red;\">$sQuery</h3>\n";
  584. }
  585. try
  586. {
  587. //$oOql = new OqlInterpreter($sQuery);
  588. //$oTrash = $oOql->ParseObjectQuery();
  589. //MyHelpers::var_dump_html($oTrash, true);
  590. $oMyFilter = DBObjectSearch::FromOQL($sQuery);
  591. }
  592. catch (OQLException $oOqlException)
  593. {
  594. if ($bIsCorrectQuery)
  595. {
  596. echo "<p>More info on this unexpected failure:<br/>".$oOqlException->getHtmlDesc()."</p>\n";
  597. throw $oOqlException;
  598. return false;
  599. }
  600. else
  601. {
  602. // Everything is fine :-)
  603. echo "<p>More info on this expected failure:\n";
  604. echo "<ul>\n";
  605. echo "<li>".get_class($oOqlException)."</li>\n";
  606. echo "<li>".$oOqlException->getMessage()."</li>\n";
  607. echo "<li>".$oOqlException->getHtmlDesc()."</li>\n";
  608. echo "</ul>\n";
  609. echo "</p>\n";
  610. return true;
  611. }
  612. }
  613. // The query was correctly parsed, was it expected to be correct ?
  614. if (!$bIsCorrectQuery)
  615. {
  616. throw new UnitTestException("The query '$sQuery' was parsed with success, while it shouldn't (?)");
  617. return false;
  618. }
  619. echo "<p>To OQL: ".$oMyFilter->ToOQL()."</p>";
  620. $this->search_and_show_list($oMyFilter);
  621. //echo "<p>first pass<p>\n";
  622. //MyHelpers::var_dump_html($oMyFilter, true);
  623. $sQuery1 = MetaModel::MakeSelectQuery($oMyFilter);
  624. //echo "<p>second pass<p>\n";
  625. //MyHelpers::var_dump_html($oMyFilter, true);
  626. //$sQuery1 = MetaModel::MakeSelectQuery($oMyFilter);
  627. $sSerialize = $oMyFilter->serialize();
  628. echo "<p>Serialized:$sSerialize</p>\n";
  629. $oFilter2 = DBObjectSearch::unserialize($sSerialize);
  630. try
  631. {
  632. $sQuery2 = MetaModel::MakeSelectQuery($oFilter2);
  633. }
  634. catch (Exception $e)
  635. {
  636. echo "<p>Could not compute the query after unserialize</p>\n";
  637. echo "<p>Query 1: $sQuery1</p>\n";
  638. MyHelpers::var_cmp_html($oMyFilter, $oFilter2);
  639. throw $e;
  640. }
  641. //if ($oFilter2 != $oMyFilter) no, they may differ while the resulting query is the same!
  642. if ($sQuery1 != $sQuery2)
  643. {
  644. echo "<p>serialize/unserialize mismatch :-(</p>\n";
  645. MyHelpers::var_cmp_html($sQuery1, $sQuery2);
  646. MyHelpers::var_cmp_html($oMyFilter, $oFilter2);
  647. return false;
  648. }
  649. return true;
  650. }
  651. protected function DoExecute()
  652. {
  653. // $this->ReportError("Found two different SibuSQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  654. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  655. echo "<h3>Create protagonists...</h3>";
  656. $iId1 = $this->InsertMammal('human', 'male', 10, 0, 0, 'romanoff', 192, '1971-07-19');
  657. $iId2 = $this->InsertMammal('human', 'female', 9, 0, 0, 'rouanita', 165, '1983-01-23');
  658. $this->InsertMammal('human', 'female', 3, $iId2, $iId1, 'pomme', 169, '2008-02-23');
  659. $this->InsertMammal('pig', 'female', 3, 0, 0, 'grouinkette', 85, '2006-06-01');
  660. $this->InsertMammal('donkey', 'female', 3, 0, 0, 'muleta', 124, '2003-11-11');
  661. $this->InsertBird('rooster', 'male', 12, 0, 0);
  662. $this->InsertFlyingBird('pie', 'female', 11, 0, 0, 35);
  663. // Benchmarking
  664. //
  665. if (false)
  666. {
  667. define ('COUNT_BENCHMARK', 10);
  668. echo "<h3>Parsing a long query, ".COUNT_BENCHMARK." times</h3>";
  669. $sQuery = "SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.birth < DATE_SUB(CURRENT_DATE(), INTERVAL 10 YEAR) AND Dad.height * 2 <= ROUND(TO_DAYS(Dad.birth) / (3 + 1) * 5 - 3)";
  670. $fStart = MyHelpers::getmicrotime();
  671. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  672. {
  673. $oMyFilter = DBObjectSearch::FromOQL($sQuery);
  674. }
  675. $fDuration = MyHelpers::getmicrotime() - $fStart;
  676. $fParsingDuration = $fDuration / COUNT_BENCHMARK;
  677. echo "<p>Mean time by op: $fParsingDuration</p>";
  678. }
  679. echo "<h3>Test queries...</h3>";
  680. $aQueries = array(
  681. 'SELECT Animal' => true,
  682. 'SELECT Animal WHERE Animal.pkey = 1' => false,
  683. 'SELECT Animal WHERE Animal.id = 1' => true,
  684. 'SELECT Aniiimal' => false,
  685. 'SELECTe Animal' => false,
  686. 'SELECT * FROM Animal' => false,
  687. 'SELECT Animal AS zoo WHERE zoo.species = \'human\'' => true,
  688. 'SELECT Animal AS zoo WHERE species = \'human\'' => true,
  689. 'SELECT Animal AS zoo WHERE espece = \'human\'' => false,
  690. 'SELECT Animal AS zoo WHERE zoo.species IN (\'human\', "pig")' => true,
  691. 'SELECT Animal AS zoo WHERE CONCATENATION(zoo.species, zoo.sex) LIKE "hum%male"' => false,
  692. 'SELECT Animal AS zoo WHERE CONCAT(zoo.species, zoo.sex) LIKE "hum%male"' => true,
  693. 'SELECT Animal AS zoo WHERE zoo.species NOT IN (\'human\', "pig")' => true,
  694. 'SELECT Animal AS zoo WHERE zoo.kind = \'human\'' => false,
  695. 'SELECT Animal WHERE Animal.species = \'human\' AND Animal.sex = \'female\'' => true,
  696. 'SELECT Mammal AS x WHERE (x.species = \'human\' AND x.name LIKE \'ro%\') OR (x.species = \'donkey\' AND x.name LIKE \'po%\')' => true,
  697. 'SELECT Mammal AS x WHERE x.species = \'human\' AND x.name LIKE \'ro%\' OR x.species = \'donkey\' AND x.name LIKE \'po%\'' => true,
  698. 'SELECT Mammal AS m WHERE MONTH(m.birth) = 7' => true,
  699. 'SELECT Mammal AS m WHERE DAY(m.birth) = 19' => true,
  700. 'SELECT Mammal AS m WHERE YEAR(m.birth) = 1971' => true,
  701. 'SELECT Mammal AS m WHERE m.birth < DATE_SUB(CURRENT_DATE(), INTERVAL 10 YEAR)' => true,
  702. 'SELECT Mammal AS m WHERE m.birth > DATE_SUB(NOW(), INTERVAL 2000 DAY)' => true,
  703. 'SELECT Mammal AS m WHERE (TO_DAYS(NOW()) - TO_DAYS(m.birth)) > 2000' => true,
  704. 'SELECT Mammal AS m WHERE m.name = IF(FLOOR(ROUND(m.height)) > 2, "pomme", "romain")' => true,
  705. 'SELECT Mammal AS m WHERE (1 + 2' => false,
  706. 'SELECT Mammal AS m WHERE (1 + 2 * 4 / 23) > 0' => true,
  707. 'SELECT Mammal AS m WHERE (4 / 23 * 2 + 1) > 0' => true,
  708. 'SELECT Mammal AS m WHERE 1/0' => true,
  709. 'SELECT Mammal AS m WHERE MONTH(m.birth) = 7' => true,
  710. 'SELECT Animal JOIN Group ON Group.leader = Animal.id' => true,
  711. 'SELECT Group JOIN Animal ON Group.leader = Animal.id' => true,
  712. 'SELECT Animal AS A JOIN Group AS G1 ON G1.leader = A.id' => true,
  713. 'SELECT Animal AS A JOIN Group AS G ON FooClass.leader = A.id' => false,
  714. 'SELECT Animal AS A JOIN Group AS G ON G.leader = FooClass.id' => false,
  715. 'SELECT Animal AS A JOIN Group AS G ON G.masterchief = A.id' => false,
  716. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.pkey' => false,
  717. 'SELECT Animal AS A JOIN Group AS G ON A.id = G.leader' => false,
  718. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.sex=\'male\' OR G.qwerty = 123' => false,
  719. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.sex=\'male\' OR G.name LIKE "a%"' => true,
  720. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.id = 1' => true,
  721. 'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE id = 1' => false,
  722. 'SELECT Animal AS A JOIN Group AS G ON A.member = G.id' => false,
  723. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id' => true,
  724. 'SELECT Mammal AS M JOIN Group AS G ON A.member = G.id' => false,
  725. 'SELECT Mammal AS myAlias JOIN Group AS myAlias ON myAlias.member = myAlias.id' => false,
  726. 'SELECT Mammal AS Mammal JOIN Group AS Mammal ON Mammal.member = Mammal.id' => false,
  727. 'SELECT Group AS G WHERE G.leader_name LIKE "%"' => true,
  728. 'SELECT Group AS G WHERE G.leader_speed < 100000' => true,
  729. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_name LIKE "%"' => true,
  730. 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_speed < 100000' => true,
  731. 'SELECT Mammal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  732. 'SELECT Mammal AS Child JOIN Animal AS Dad ON Child.father = Dad.id' => true,
  733. 'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  734. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id' => true,
  735. 'SELECT Animal AS Dad JOIN Animal AS Child ON Child.father = Dad.id' => true,
  736. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id' => true,
  737. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.id = 1' => true,
  738. 'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\'' => false,
  739. 'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
  740. 'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\' OR Mum.speed = 0' => true,
  741. 'SELECT Animal AS Dad JOIN Animal AS Child ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id' => true,
  742. 'SELECT Mammal AS Dad JOIN Mammal AS Child ON Child.father = Dad.id' => true,
  743. 'SELECT Mammal AS Dad JOIN Mammal AS Child ON Child.father = Dad.id JOIN Mammal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\' OR Mum.name=\'chloe\' OR Child.name=\'bizounours\'' => true,
  744. );
  745. //$aQueries = array(
  746. // 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_name LIKE "%"' => true,
  747. //);
  748. foreach($aQueries as $sQuery => $bIsCorrect)
  749. {
  750. $this->CheckQuery($sQuery, $bIsCorrect);
  751. }
  752. return true;
  753. }
  754. }
  755. ///////////////////////////////////////////////////////////////////////////
  756. // Test data load
  757. ///////////////////////////////////////////////////////////////////////////
  758. class TestBulkChangeOnFarm extends TestBizModel
  759. {
  760. static public function GetName()
  761. {
  762. return 'Farm test - data load';
  763. }
  764. static public function GetDescription()
  765. {
  766. return 'Bulk load';
  767. }
  768. static public function GetConfigFile() {return '../config-test-farm.php';}
  769. protected function DoPrepare()
  770. {
  771. parent::DoPrepare();
  772. $this->ResetDB();
  773. MetaModel::DBCheckIntegrity();
  774. }
  775. protected function DoExecute()
  776. {
  777. // $this->ReportError("Found two different SibuSQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
  778. // $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
  779. $oParser = new CSVParser("#denomination,hauteur,age
  780. suzy,123,2009-01-01
  781. chita,456,
  782. ");
  783. $oParser->SetSeparator(',');
  784. $aData = $oParser->ToArray(array('_name', '_height', '_birth'));
  785. MyHelpers::var_dump_html($aData);
  786. $oBulk = new BulkChange(
  787. 'Mammal',
  788. $aData,
  789. array('name' => '_name', 'height' => '_height', 'birth' => '_birth'),
  790. array('name'),
  791. array()
  792. );
  793. $oMyChange = MetaModel::NewObject("CMDBChange");
  794. $oMyChange->Set("date", time());
  795. $oMyChange->Set("userinfo", "Testor");
  796. $iChangeId = $oMyChange->DBInsert();
  797. // echo "Created new change: $iChangeId</br>";
  798. echo "<h3>Planned for loading...</h3>";
  799. $aRes = $oBulk->Process();
  800. print_r($aRes);
  801. echo "<h3>Go for loading...</h3>";
  802. $aRes = $oBulk->Process($oMyChange);
  803. print_r($aRes);
  804. return true;
  805. $oRawData = array(
  806. 'Mammal',
  807. array('species', 'sex', 'speed', 'mother', 'father', 'name', 'height', 'birth'),
  808. "human,male,23,0,0,romulus,192,1971
  809. human,male,23,0,0,remus,154,-50
  810. human,male,23,0,0,julius,160,-49
  811. human,female,23,0,0,cleopatra,142,-50
  812. pig,female,23,0,0,confucius,50,2003"
  813. );
  814. }
  815. }
  816. ///////////////////////////////////////////////////////////////////////////
  817. // Benchmark queries
  818. ///////////////////////////////////////////////////////////////////////////
  819. class TestItopEfficiency extends TestBizModel
  820. {
  821. static public function GetName()
  822. {
  823. return 'Itop - benchmark';
  824. }
  825. static public function GetDescription()
  826. {
  827. return 'Measure time to perform the queries';
  828. }
  829. static public function GetConfigFile() {return '../config-itop.php';}
  830. protected function DoBenchmark($sOqlQuery)
  831. {
  832. echo "<h3>Testing query: $sOqlQuery</h3>";
  833. $fStart = MyHelpers::getmicrotime();
  834. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  835. {
  836. $oFilter = DBObjectSearch::FromOQL($sOqlQuery);
  837. }
  838. $fDuration = MyHelpers::getmicrotime() - $fStart;
  839. $fParsingDuration = $fDuration / COUNT_BENCHMARK;
  840. $fStart = MyHelpers::getmicrotime();
  841. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  842. {
  843. $sSQL = MetaModel::MakeSelectQuery($oFilter);
  844. }
  845. $fDuration = MyHelpers::getmicrotime() - $fStart;
  846. $fBuildDuration = $fDuration / COUNT_BENCHMARK;
  847. $fStart = MyHelpers::getmicrotime();
  848. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  849. {
  850. $res = CMDBSource::Query($sSQL);
  851. }
  852. $fDuration = MyHelpers::getmicrotime() - $fStart;
  853. $fQueryDuration = $fDuration / COUNT_BENCHMARK;
  854. // The fetch could not be repeated with the same results
  855. // But we've seen so far that is was very very quick to exec
  856. // So it makes sense to benchmark it a single time
  857. $fStart = MyHelpers::getmicrotime();
  858. $aRow = CMDBSource::FetchArray($res);
  859. $fDuration = MyHelpers::getmicrotime() - $fStart;
  860. $fFetchDuration = $fDuration;
  861. $fStart = MyHelpers::getmicrotime();
  862. for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
  863. {
  864. $sOql = $oFilter->ToOQL();
  865. }
  866. $fDuration = MyHelpers::getmicrotime() - $fStart;
  867. $fToOqlDuration = $fDuration / COUNT_BENCHMARK;
  868. echo "<ul>\n";
  869. echo "<li>Parsing: $fParsingDuration</li>\n";
  870. echo "<li>Build: $fBuildDuration</li>\n";
  871. echo "<li>Query: $fQueryDuration</li>\n";
  872. echo "<li>Fetch: $fFetchDuration</li>\n";
  873. echo "<li>ToOql: $fToOqlDuration</li>\n";
  874. echo "</ul>\n";
  875. // Everything but the ToOQL (wich is interesting, anyhow)
  876. $fTotal = $fParsingDuration + $fBuildDuration + $fQueryDuration + $fFetchDuration;
  877. return array(
  878. 'rows' => CMDBSource::NbRows($res),
  879. 'duration (s)' => round($fTotal, 4),
  880. 'parsing (%)' => round(100 * $fParsingDuration / $fTotal, 1),
  881. 'build SQL (%)' => round(100 * $fBuildDuration / $fTotal, 1),
  882. 'query exec (%)' => round(100 * $fQueryDuration / $fTotal, 1),
  883. 'fetch (%)' => round(100 * $fFetchDuration / $fTotal, 1),
  884. 'to OQL (%)' => round(100 * $fToOqlDuration / $fTotal, 1),
  885. 'parsing+build (%)' => round(100 * ($fParsingDuration + $fBuildDuration) / $fTotal, 1),
  886. );
  887. }
  888. protected function DoExecute()
  889. {
  890. define ('COUNT_BENCHMARK', 3);
  891. echo "<p>The test will be repeated ".COUNT_BENCHMARK." times</p>";
  892. $aQueries = array(
  893. 'SELECT CMDBChangeOpSetAttribute',
  894. 'SELECT CMDBChangeOpSetAttribute WHERE id=10',
  895. 'SELECT CMDBChangeOpSetAttribute WHERE id=123456789',
  896. 'SELECT CMDBChangeOpSetAttribute WHERE CMDBChangeOpSetAttribute.id=10',
  897. 'SELECT bizIncidentTicket',
  898. 'SELECT bizIncidentTicket WHERE id=1',
  899. 'SELECT bizPerson',
  900. 'SELECT bizPerson WHERE id=1',
  901. 'SELECT bizIncidentTicket JOIN bizPerson ON bizIncidentTicket.agent_id = bizPerson.id WHERE bizPerson.id = 5',
  902. );
  903. $aStats = array();
  904. foreach ($aQueries as $sOQL)
  905. {
  906. $aStats[$sOQL] = $this->DoBenchmark($sOQL);
  907. }
  908. $aData = array();
  909. foreach ($aStats as $sOQL => $aResults)
  910. {
  911. $aValues = array();
  912. $aValues['OQL'] = htmlentities($sOQL);
  913. foreach($aResults as $sDesc => $sInfo)
  914. {
  915. $aValues[$sDesc] = htmlentities($sInfo);
  916. }
  917. $aData[] = $aValues;
  918. }
  919. echo MyHelpers::make_table_from_assoc_array($aData);
  920. return true;
  921. }
  922. }
  923. ///////////////////////////////////////////////////////////////////////////
  924. // Test data load
  925. ///////////////////////////////////////////////////////////////////////////
  926. class TestItopWebServices extends TestWebServices
  927. {
  928. static public function GetName()
  929. {
  930. return 'Itop - web services';
  931. }
  932. static public function GetDescription()
  933. {
  934. return 'Bulk load and ???';
  935. }
  936. protected function DoExecSingleLoad($aLoadSpec)
  937. {
  938. $sTitle = 'Load: '.$aLoadSpec['class'];
  939. $sClass = $aLoadSpec['class'];
  940. $sCsvData = $aLoadSpec['csvdata'];
  941. $aPostData = array('class' => $sClass, 'csvdata' => $sCsvData);
  942. $sRes = self::DoPostRequestAuth('webservices/import.php', $aPostData);
  943. echo "<div><h3>$sTitle</h3><pre>$sCsvData</pre><div>$sRes</div></div>";
  944. }
  945. protected function DoExecute()
  946. {
  947. $aLoads = array(
  948. array(
  949. 'class' => 'bizOrganization',
  950. 'csvdata' => "name;code\nWorldCompany;WCY"
  951. ),
  952. array(
  953. 'class' => 'bizLocation',
  954. 'csvdata' => "name;org_id;address\nParis;1;Centre de la Franca"
  955. ),
  956. array(
  957. 'class' => 'bizPerson',
  958. 'csvdata' => "email;name;first_name;org_id;phone\njohn.foo@starac.com;Foo;John;1;+33(1)23456789"
  959. ),
  960. array(
  961. 'class' => 'bizTeam',
  962. 'csvdata' => "name;org_id;location_id\nSquadra Azzura;1;1"
  963. ),
  964. array(
  965. 'class' => 'bizWorkgroup',
  966. 'csvdata' => "name;org_id;team_id\ntravailleurs alpins;1;6"
  967. ),
  968. array(
  969. 'class' => 'bizIncidentTicket',
  970. 'csvdata' => "name;title;type;org_id;initial_situation;start_date;next_update;caller_id;workgroup_id;agent_id\nOVSD-12345;server down;Network;1;server was found down;2009-04-10 12:00;2009-04-10 15:00;3;317;5"
  971. ),
  972. );
  973. foreach ($aLoads as $aLoadSpec)
  974. {
  975. $this->DoExecSingleLoad($aLoadSpec);
  976. }
  977. return true;
  978. }
  979. }
  980. ?>