PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/install/migration/Migrator.php

https://bitbucket.org/pfernandez/testlink1.9.6
PHP | 592 lines | 473 code | 68 blank | 51 comment | 38 complexity | 8953890174d393986b78952f3d5a5bdf MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, GPL-3.0
  1. <?php
  2. /*
  3. * TestLink Open Source Project - http://testlink.sourceforge.net/
  4. * $Id: Migrator.php,v 1.5 2008/01/25 14:49:53 franciscom Exp $
  5. *
  6. * BUGID 1328 - LEFT without AS
  7. */
  8. require_once("migrate_16_to_17_functions.php");
  9. class Migrator
  10. {
  11. // tmp table for test cases
  12. private $tmp_table_count = 0;
  13. private $tmp_table_name = "tc_tmp_table";
  14. // tmp table for test plans
  15. private $tp_tmp_table_name = "tp_tmp_table";
  16. private $tp_tmp_table_count = 0;
  17. // tmp table for results
  18. private $results_tmp_table_name = "results_tmp_table";
  19. private $results_tmp_table_count = 0;
  20. private $source_db;
  21. private $target_db;
  22. private $users = null;
  23. private $old_new = array();
  24. private $msg_click_to_show=" [Click to show details] ";
  25. private $products;
  26. private $map_tc_tcversion;
  27. private $builds;
  28. function __construct($source_db, $target_db)
  29. {
  30. $this->source_db = $source_db;
  31. $this->target_db = $target_db;
  32. $this->get_users();
  33. $this->get_old_new();
  34. }
  35. // Migrate everything in the correct order
  36. public function migrate_all()
  37. {
  38. $this->select_testcases();
  39. $this->select_testplans();
  40. $this->select_results();
  41. $this->testcases_migration();
  42. $this->users_migration();
  43. $this->products_components_categories_migration();
  44. $this->keywords_migration();
  45. $this->builds_migration();
  46. $this->testplan_migration();
  47. $this->results_migration();
  48. $this->bugs_migration();
  49. $this->users_test_plan_assignments_migration();
  50. $this->milestones_migration();
  51. $this->risk_migration();
  52. $this->requirements_specification_migration();
  53. $this->requirements_migration();
  54. $this->requirements_coverage_migration();
  55. }
  56. // get the value of the users var from the db
  57. function get_users()
  58. {
  59. // only do a query if the variable hasn't already been set
  60. if ($this->users == null)
  61. {
  62. // Get list of 1.6 users
  63. $sql="SELECT * FROM user";
  64. $this->users=$this->source_db->fetchRowsIntoMap($sql,'login');
  65. }
  66. return $this->users;
  67. }
  68. function get_old_new()
  69. {
  70. if (count($this->old_new) == 0)
  71. {
  72. $this->old_new['product']=array();
  73. $this->old_new['tplan']=array();
  74. $this->old_new['mgtcomp']=array();
  75. $this->old_new['mgtcat']=array();
  76. $this->old_new['mgttc']=array();
  77. $this->old_new['build']=array();
  78. $this->old_new['bug']=array();
  79. $this->old_new['result']=array();
  80. }
  81. return $this->old_new;
  82. }
  83. // determine the number of test cases we are dealing with in the tmp table
  84. function get_tmp_table_count($table_name=null)
  85. {
  86. if(null==$table_name)
  87. {
  88. echo "<br>getting normal tmp_table count<br>";
  89. if ($this->tmp_table_count == 0)
  90. {
  91. $sql = "SELECT COUNT(*) as count FROM " . $this->tmp_table_name;
  92. $this->tmp_table_count = $this->source_db->fetchFirstRowSingleColumn($sql, 'count');
  93. }
  94. return $this->tmp_table_count;
  95. }
  96. else if("tp"==$table_name)
  97. {
  98. echo "<br>getting count for tp_tmp_table<br>";
  99. if ($this->tp_tmp_table_count == 0)
  100. {
  101. $sql = "SELECT COUNT(*) as count FROM " . $this->tp_tmp_table_name;
  102. $this->tp_tmp_table_count = $this->source_db->fetchFirstRowSingleColumn($sql, 'count');
  103. }
  104. return $this->tp_tmp_table_count;
  105. }
  106. else if("results"==$table_name)
  107. {
  108. echo "<br>getting count for results_tmp_table<br>";
  109. if ($this->results_tmp_table_count == 0)
  110. {
  111. $sql = "SELECT COUNT(*) as count FROM " . $this->results_tmp_table_name;
  112. $this->results_tmp_table_count = $this->source_db->fetchFirstRowSingleColumn($sql, 'count');
  113. }
  114. return $this->results_tmp_table_count;
  115. }
  116. }
  117. // TODO: create a separate function to print the section header that is copied and
  118. // used in most of the functions
  119. function print_section_header()
  120. {
  121. }
  122. function select_testcases()
  123. {
  124. // -----------------------------------------------------------------------------------
  125. // To preserve test case ID, I will create first all test cases.
  126. // Using all these joins we will considered only well formed tc =>
  127. // no dangling records.
  128. //
  129. // 20070103 - franciscom - added prodid column in results record set.
  130. //
  131. // 20070807 - asielb - store results in temporary table to avoid requiring
  132. // excessive amounts of memory for php
  133. // 20071212 - asielb = select only first 100 chars of title fixing bug 1125
  134. $tmp_table_name = "tmp_good_testcases";
  135. $sql="CREATE TEMPORARY TABLE " . $this->tmp_table_name . " " .
  136. "SELECT mtc.id, " .
  137. "LEFT(mtc.title,100) AS title," .
  138. "mtc.steps," .
  139. "mtc.exresult," .
  140. "mtc.keywords," .
  141. "mtc.catid," .
  142. "mtc.version," .
  143. "mtc.summary," .
  144. "mtc.author," .
  145. "mtc.create_date," .
  146. "mtc.reviewer," .
  147. "mtc.modified_date," .
  148. "mtc.TCorder," .
  149. "mc.prodid " .
  150. " FROM mgtproduct mp, mgtcomponent mc, mgtcategory mk, mgttestcase mtc " .
  151. " WHERE mc.prodid=mp.id " .
  152. " AND mk.compid=mc.id " .
  153. " AND mtc.catid=mk.id " .
  154. " ORDER BY mtc.id";
  155. echo "<br />creating temporary table for good testcases<br />";
  156. //echo "<br />using sql: $sql";
  157. $this->source_db->exec_query($sql);
  158. return $this->get_tmp_table_count();
  159. }
  160. function select_testplans()
  161. {
  162. // use a temporary table to avoid requiring excessive amounts of memory for php
  163. $sql="CREATE TEMPORARY TABLE " . $this->tp_tmp_table_name . " SELECT tplan.name " .
  164. "AS tplan_name,tplan.id AS projid,k.compid,tc.mgttcid AS mgttcid " .
  165. "FROM component c,category k,testcase tc," .
  166. " mgtcomponent mc, mgtcategory mk,mgttestcase mtc,project tplan " .
  167. "where c.id=k.compid " .
  168. "AND k.id=tc.catid " .
  169. "AND k.mgtcatid = mk.id " .
  170. "AND c.mgtcompid = mc.id " .
  171. "AND tc.mgttcid=mtc.id " .
  172. "AND c.projid = tplan.id " .
  173. "ORDER BY projid ";
  174. echo "<br />creating temporary table for test plans<br />";
  175. //echo "testplan sql is $sql";
  176. $this->source_db->exec_query($sql);
  177. return $this->get_tmp_table_count("tp");
  178. }
  179. function select_results()
  180. {
  181. // 20070120 - franciscom
  182. // added join with build, to filter out results records that belong to deleted builds
  183. //
  184. // 20070113 - franciscom
  185. // added filter on status, because executions with NOT RUN will not be migrated
  186. //
  187. $sql="CREATE TEMPORARY TABLE " . $this->results_tmp_table_name .
  188. " SELECT MGT.id as mgttcid, R.tcid, R.build_id,R.daterun," .
  189. " R.runby,R.notes,R.status " .
  190. " FROM mgttestcase MGT,testcase TC,results R, build B " .
  191. " WHERE TC.mgttcid=MGT.id " .
  192. " AND TC.id=R.tcid AND R.status <> 'n'" .
  193. " AND B.id=R.build_id " .
  194. " ORDER BY tcid,build_id";
  195. echo "<br />creating temporary table for results";
  196. $this->source_db->exec_query($sql);
  197. return $this->get_tmp_table_count("results");
  198. }
  199. function users_migration()
  200. {
  201. $msg='Users: ';
  202. $hhmmss=date("H:i:s");
  203. if(!is_null($this->get_users()))
  204. {
  205. $users_qty=count($this->get_users());
  206. $msg .= " (Found " . $users_qty . " users to migrate) ";
  207. }
  208. else
  209. {
  210. $msg .= " Ooops! no users to migrate !!!! ";
  211. }
  212. echo "<a onclick=\"return DetailController.toggle('details-users')\" href=\"users/\">
  213. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>{$msg} {$this->msg_click_to_show} {$hhmmss}</a>";
  214. echo '<div class="detail-container" id="details-users" style="display: none;">';
  215. if(!is_null($this->get_users()))
  216. {
  217. migrate_users($this->target_db,$this->get_users());
  218. }
  219. echo "</div><p>";
  220. }
  221. function testcases_migration()
  222. {
  223. $tcspecs_msg="Test Case Specifications: (Found " . $this->get_tmp_table_count() .
  224. " test cases to migrate)";
  225. $msg=$tcspecs_msg;
  226. $hhmmss=date("H:i:s");
  227. echo "<a onclick=\"return DetailController.toggle('details-tcspecs')\" href=\"tcspecs/\">
  228. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>{$msg} {$this->msg_click_to_show} {$hhmmss}</a>";
  229. echo '<div class="detail-container" id="details-tcspecs" style="display: none;">';
  230. if(!$this->get_tmp_table_count() > 0)
  231. {
  232. echo "<span class='notok'>There are no test cases to be migrated!</span></b>";
  233. }
  234. else
  235. {
  236. $this->map_tc_tcversion=migrate_tc_specs($this->source_db,$this->target_db,$this->tmp_table_name,$this->users,$this);
  237. }
  238. echo "</div><p>";
  239. }
  240. function products_components_categories_migration()
  241. {
  242. $hhmmss=date("H:i:s");
  243. echo "<a onclick=\"return DetailController.toggle('details-pcc')\" href=\"pcc/\">
  244. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>
  245. Products, Components & Categories migration: {$this->msg_click_to_show} {$hhmmss}</a>";
  246. echo '<div class="detail-container" id="details-pcc" style="display: none;">';
  247. // Get list of 1.6 Products
  248. $sql="SELECT * FROM mgtproduct";
  249. $this->products=$this->source_db->fetchRowsIntoMap($sql,'id');
  250. if(is_null($this->products))
  251. {
  252. echo "<span class='notok'>Failed!</span></b> - Getting products:" .
  253. $source_db->error_msg() ."<br>";
  254. }
  255. migrate_cc_specs($this->source_db,$this->target_db,$this->products,$this->old_new);
  256. echo "</div><p>";
  257. }
  258. function keywords_migration()
  259. {
  260. $hhmmss=date("H:i:s");
  261. echo "<a onclick=\"return DetailController.toggle('details-kw')\" href=\"kw/\">
  262. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Keywords migration: {$this->msg_click_to_show} {$hhmmss}</a>";
  263. echo '<div class="detail-container" id="details-kw" style="display: none;">';
  264. $prod_keyword_tc=extract_kw_tc_links($this->source_db,$this->target_db,$this->tmp_table_name,$this);
  265. migrate_keywords($this->source_db,$this->target_db,$this->products,$prod_keyword_tc,$this->old_new);
  266. echo "</div><p>";
  267. $hhmmss=date("H:i:s");
  268. echo "<a onclick=\"return DetailController.toggle('details-tcpu')\" href=\"tcpu/\">
  269. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Test case parent update: {$this->msg_click_to_show} {$hhmmss}</a>";
  270. echo '<div class="detail-container" id="details-tcpu" style="display: none;">';
  271. // asielb - modified to use the tmp_table
  272. update_tc_specs_parents($this->source_db,$this->target_db,$this->tmp_table_name,$this->old_new, $this);
  273. echo "</div><p>";
  274. $hhmmss=date("H:i:s");
  275. echo "<a onclick=\"return DetailController.toggle('details-tplan')\" href=\"tplan/\">
  276. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Test plans: {$this->msg_click_to_show} {$hhmmss}</a>";
  277. echo '<div class="detail-container" id="details-tplan" style="display: none;">';
  278. $sql="SELECT * FROM project ORDER BY ID";
  279. $tplans=$this->source_db->fetchRowsIntoMap($sql,'id');
  280. if(is_null($tplans))
  281. {
  282. echo "<span class='notok'>There are no test plans to be migrated!</span></b>";
  283. }
  284. else
  285. {
  286. migrate_test_plans($this->source_db,$this->target_db,$tplans,$this->old_new);
  287. }
  288. echo "</div><p>";
  289. }
  290. function builds_migration()
  291. {
  292. $hhmmss=date("H:i:s");
  293. echo "<a onclick=\"return DetailController.toggle('details-builds')\" href=\"tplan/\">
  294. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Builds: {$this->msg_click_to_show} {$hhmmss}</a>";
  295. echo '<div class="detail-container" id="details-builds" style="display: none;">';
  296. // find the number of duplicate build names that will get blown away
  297. $sql = "SELECT COUNT(*) - COUNT(DISTINCT build.name, build.projid) AS duplicate_names FROM build";
  298. $duplicate_builds = $this->source_db->fetchFirstRowSingleColumn($sql, "duplicate_names");
  299. echo "will be deleting $duplicate_builds duplicate builds";
  300. // select everything but the duplicates that will violate the unique constraint in 1.7
  301. $sql="SELECT build.*, project.name AS TPLAN_NAME FROM build,project WHERE build.projid=project.id" .
  302. " GROUP BY build.name, build.projid HAVING COUNT(*)=1 ORDER BY project.id";
  303. $this->builds=$this->source_db->fetchRowsIntoMap($sql,'id');
  304. if(is_null($this->builds))
  305. {
  306. echo "<span class='notok'>There are no builds to be migrated!</span></b>";
  307. }
  308. else
  309. {
  310. migrate_builds($this->source_db,$this->target_db,$this->builds,$this->old_new);
  311. }
  312. echo "</div><p>";
  313. }
  314. function testplan_migration()
  315. {
  316. $hhmmss=date("H:i:s");
  317. echo "<a onclick=\"return DetailController.toggle('details-tctpa')\" href=\"tplan/\">
  318. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Test case -> test plan assignments: {$this->msg_click_to_show} {$hhmmss}</a>";
  319. echo '<div class="detail-container" id="details-tctpa" style="display: none;">';
  320. $count=$this->get_tmp_table_count("tp");
  321. if (0==$count)
  322. {
  323. echo "<br>somehow count was 0 for tp_tmp_table<br>";
  324. $count=$this->select_testplans();
  325. }
  326. // check if the count still is 0
  327. if (0==$count)
  328. {
  329. echo "<span class='notok'>All test plans are empty!</span></b>";
  330. }
  331. else
  332. {
  333. //migrate_tplan_contents(&$source_db,&$target_db,&$tmp_table_name,&$tc_tcversion,&$old_new,&$migrator)
  334. migrate_tplan_contents($this->source_db,$this->target_db,$this->tp_tmp_table_name,
  335. $this->map_tc_tcversion,$this->old_new,$this);
  336. }
  337. echo "</div><p>";
  338. }
  339. function results_migration()
  340. {
  341. $hhmmss=date("H:i:s");
  342. echo "<a onclick=\"return DetailController.toggle('details-results')\" href=\"tplan/\">
  343. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Executions results: {$this->msg_click_to_show} {$hhmmss}</a>";
  344. echo '<div class="detail-container" id="details-results" style="display: none;">';
  345. $count=$this->get_tmp_table_count("results");
  346. if (0==$count)
  347. {
  348. $count=$this->select_results();
  349. }
  350. // if count is still 0 we have a problem
  351. if (0==$count)
  352. {
  353. echo "<span class='notok'>There are no results to migrate!</span></b>";
  354. }
  355. else
  356. {
  357. migrate_results($this->source_db,$this->target_db,$this->results_tmp_table_name,
  358. $this->builds,$this->get_users(),$this->map_tc_tcversion,$this->old_new, $this);
  359. }
  360. echo "<br />Finished migrating execution results";
  361. echo "</div><p>";
  362. }
  363. function bugs_migration()
  364. {
  365. $hhmmss=date("H:i:s");
  366. echo "<a onclick=\"return DetailController.toggle('details-bugs')\" href=\"tplan/\">
  367. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Executions bugs: {$this->msg_click_to_show} {$hhmmss}</a>";
  368. echo '<div class="detail-container" id="details-bugs" style="display: none;">';
  369. $sql="SELECT bugs.tcid,bugs.build_id,bugs.bug,mgt.id AS mgttcid " .
  370. "FROM bugs,mgttestcase mgt,testcase t " .
  371. "WHERE bugs.tcid=t.id " .
  372. "AND t.mgttcid=mgt.id";
  373. $bugs=$this->source_db->get_recordset($sql);
  374. if(is_null($bugs))
  375. {
  376. echo "<span class='notok'>There are no bugs to be migrated!</span></b>";
  377. }
  378. else
  379. {
  380. migrate_bugs($this->source_db,$this->target_db,$bugs,$this->builds,$this->map_tc_tcversion,$this->old_new);
  381. }
  382. echo "</div><p>";
  383. }
  384. function users_test_plan_assignments_migration()
  385. {
  386. //---USERS TEST PLAN ASSIGNMENTS MIGRATION---
  387. $hhmmss=date("H:i:s");
  388. echo "<a onclick=\"return DetailController.toggle('details-user_tpa')\" href=\"tplan/\">
  389. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Users - Test plan assignments: {$this->msg_click_to_show} {$hhmmss}</a>";
  390. echo '<div class="detail-container" id="details-user_tpa" style="display: none;">';
  391. // 20070317 - BUGID 738
  392. migrate_tesplan_assignments($this->source_db,$this->target_db,$this->old_new);
  393. echo "</div><p>";
  394. //---PRIORITY RULES MIGRATION---
  395. $hhmmss=date("H:i:s");
  396. echo "<a onclick=\"return DetailController.toggle('details-prior')\" href=\"tplan/\">
  397. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Priority Rules: {$this->msg_click_to_show} {$hhmmss}</a>";
  398. echo '<div class="detail-container" id="details-prior" style="display: none;">';
  399. $sql="SELECT * from priority";
  400. $prules=$this->source_db->fetchRowsIntoMap($sql,'projid');
  401. if(is_null($prules))
  402. {
  403. echo "<span class='notok'>There are no priority rules to be migrated!</span></b>";
  404. }
  405. else
  406. {
  407. migrate_prules($this->source_db,$this->target_db,$prules,$this->old_new);
  408. }
  409. echo "</div><p>";
  410. }
  411. function milestones_migration()
  412. {
  413. $hhmmss=date("H:i:s");
  414. echo "<a onclick=\"return DetailController.toggle('details-Milestones')\" href=\"tplan/\">
  415. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Milestones: {$this->msg_click_to_show} {$hhmmss}</a>";
  416. echo '<div class="detail-container" id="details-Milestones" style="display: none;">';
  417. $sql="SELECT * from milestone";
  418. $ms=$this->source_db->fetchRowsIntoMap($sql,'projid');
  419. if(is_null($ms))
  420. {
  421. echo "<span class='notok'>There are no results to be migrated!</span></b>";
  422. }
  423. else
  424. {
  425. migrate_milestones($this->source_db,$this->target_db,$ms,$this->old_new);
  426. }
  427. echo "</div><p>";
  428. }
  429. function risk_migration()
  430. {
  431. echo "<a onclick=\"return DetailController.toggle('details-risk')\" href=\"tplan/\">
  432. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Risk TO BE DONE - No data wll be migrated:</a>";
  433. echo '<div class="detail-container" id="details-risk" style="display: none;">';
  434. echo "</div><p>";
  435. $sql="SELECT tplan.name as tplan_name,tplan.id as projid," .
  436. " k.mgtcatid,k.risk,k.importance,k.owner,tc.mgttcid " .
  437. "FROM component c,category k,testcase tc," .
  438. " mgtcomponent mc, mgtcategory mk,mgttestcase mtc,project tplan " .
  439. "WHERE c.id=k.compid " .
  440. "AND k.id=tc.catid " .
  441. "AND k.mgtcatid = mk.id " .
  442. "AND c.mgtcompid = mc.id " .
  443. "AND tc.mgttcid=mtc.id " .
  444. "AND c.projid = tplan.id " .
  445. "ORDER BY projid ";
  446. $tp4risk_own=$this->source_db->get_recordset($sql);
  447. $hhmmss=date("H:i:s");
  448. echo "<a onclick=\"return DetailController.toggle('details-own')\" href=\"tplan/\">
  449. <img src='../img/icon-foldout.gif' align='top' title='show/hide'>Ownership (becomes user assignment=test_execution): {$this->msg_click_to_show} {$hhmmss}</a>";
  450. echo '<div class="detail-container" id="details-own" style="display: none;">';
  451. if(is_null($tp4risk_own))
  452. {
  453. echo "<span class='notok'>There are no data to be migrated!</span></b>";
  454. }
  455. else
  456. {
  457. migrate_ownership($this->source_db,$this->target_db,$tp4risk_own,$this->map_tc_tcversion,$this->old_new);
  458. }
  459. echo "</div><p>";
  460. }
  461. function requirements_specification_migration()
  462. {
  463. $hhmmss=date("H:i:s");
  464. echo "<a onclick=\"return DetailController.toggle('details-req_spec_table')\" href=\"tplan/\">
  465. <img src='../img/icon-foldout.gif' align='top' title='show/hide'> Requirement Specification: {$this->msg_click_to_show} {$hhmmss}</a>";
  466. echo '<div class="detail-container" id="details-req_spec_table" style="display: none;">';
  467. $sql="SELECT * from req_spec";
  468. $rspec=$this->source_db->fetchRowsIntoMap($sql,'id');
  469. if(is_null($rspec))
  470. {
  471. echo "<span class='notok'>There are no req specs to be migrated!</span></b>";
  472. }
  473. else
  474. {
  475. migrate_req_specs($this->source_db,$this->target_db,$rspec,$this->old_new);
  476. }
  477. echo "</div><p>";
  478. }
  479. function requirements_migration()
  480. {
  481. $hhmmss=date("H:i:s");
  482. echo "<a onclick=\"return DetailController.toggle('details-reqtable')\" href=\"tplan/\">
  483. <img src='../img/icon-foldout.gif' align='top' title='show/hide'> Requirements: {$this->msg_click_to_show} {$hhmmss}</a>";
  484. echo '<div class="detail-container" id="details-reqtable" style="display: none;">';
  485. // 20070103 - franciscom - added filter on NULL
  486. // select everything but the duplicates that will violate the unique constraint in 1.7
  487. $sql="SELECT * from requirements " .
  488. " WHERE req_doc_id <> NULL OR req_doc_id <> '' " .
  489. " GROUP BY id_srs, req_doc_id HAVING COUNT(*)=1";
  490. $req=$this->source_db->fetchRowsIntoMap($sql,'id');
  491. if(is_null($req))
  492. {
  493. echo "<span class='notok'>There are no requirements to be migrated!</span></b>";
  494. }
  495. else
  496. {
  497. migrate_requirements($this->source_db,$this->target_db,$req,$this->old_new);
  498. }
  499. echo "</div><p>";
  500. }
  501. function requirements_coverage_migration()
  502. {
  503. $hhmmss=date("H:i:s");
  504. echo "<a onclick=\"return DetailController.toggle('details-req_coverage')\" href=\"tplan/\">
  505. <img src='../img/icon-foldout.gif' align='top' title='show/hide'> Req. Coverage (requirement / test case relationship): {$this->msg_click_to_show} {$hhmmss}</a>";
  506. echo '<div class="detail-container" id="details-req_coverage" style="display: none;">';
  507. $sql="SELECT * from req_coverage";
  508. // 20061203 - franciscom - id (wrong) -> id_req
  509. //$req_cov=$this->source_db->fetchRowsIntoMap($sql,'id_req'); //970 items no duplicate ids
  510. // 20071213 - havlatm: 0001112: Requirements coverage migration from 1.6.3 to 1.7.0 final
  511. $result = $this->source_db->get_recordset($sql);
  512. if(is_null($result))
  513. {
  514. echo "<span class='notok'>There are no req specs to be migrated!</span></b>";
  515. }
  516. else
  517. {
  518. // 20071213 - havlatm: 0001112: Requirements coverage migration from 1.6.3 to 1.7.0 final
  519. migrate_req_coverage($this->source_db,$this->target_db,$result,$this->old_new);
  520. }
  521. echo "</div><p>";
  522. }
  523. }
  524. ?>