diff --git a/db/update18.3.sql b/db/update18.3.sql index 862b938b97..abd6f921da 100644 --- a/db/update18.3.sql +++ b/db/update18.3.sql @@ -389,7 +389,17 @@ CHANGE `reviewedBy` `reviewedBy` varchar(255) NOT NULL DEFAULT '', CHANGE `reviewedDate` `reviewedDate` date NULL, CHANGE `lastEditedDate` `lastEditedDate` datetime NULL, CHANGE `lastRunner` `lastRunner` varchar(30) NOT NULL DEFAULT '', -CHANGE `lastRunDate` `lastRunDate` datetime NULL; +CHANGE `lastRunDate` `lastRunDate` datetime NULL, +CHANGE `frame` `frame` varchar(10) NOT NULL DEFAULT '', +CHANGE `stage` `stage` varchar(255) NOT NULL DEFAULT '', +CHANGE `howRun` `howRun` varchar(30) NOT NULL DEFAULT '', +CHANGE `script` `script` longtext NULL, +CHANGE `scriptStatus` `scriptStatus` varchar(30) NOT NULL DEFAULT '', +CHANGE `scriptLocation` `scriptLocation` varchar(255) NOT NULL DEFAULT '', +CHANGE `linkCase` `linkCase` varchar(255) NOT NULL DEFAULT '', +CHANGE `fromBug` `fromBug` mediumint unsigned NOT NULL DEFAULT '0', +CHANGE `fromCaseID` `fromCaseID` mediumint unsigned NOT NULL DEFAULT '0', +CHANGE `lastRunResult` `lastRunResult` char(30) NOT NULL DEFAULT ''; ALTER TABLE `zt_chart` CHANGE `editedBy` `editedBy` varchar(30) NOT NULL DEFAULT '', diff --git a/db/zentao.sql b/db/zentao.sql index 0a01d6be19..cb8c4047af 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -373,14 +373,14 @@ CREATE TABLE IF NOT EXISTS `zt_case` ( `pri` tinyint(3) unsigned NOT NULL default '3', `type` char(30) NOT NULL default '1', `auto` varchar(10) NOT NULL default 'no', - `frame` varchar(10) NOT NULL, - `stage` varchar(255) NOT NULL, - `howRun` varchar(30) NOT NULL, - `script` longtext NOT NULL, + `frame` varchar(10) NOT NULL DEFAULT '', + `stage` varchar(255) NOT NULL DEFAULT '', + `howRun` varchar(30) NOT NULL DEFAULT '', + `script` longtext NULL, `scriptedBy` varchar(30) NOT NULL DEFAULT '', `scriptedDate` date NULL, - `scriptStatus` varchar(30) NOT NULL, - `scriptLocation` varchar(255) NOT NULL, + `scriptStatus` varchar(30) NOT NULL DEFAULT '', + `scriptLocation` varchar(255) NOT NULL DEFAULT '', `status` char(30) NOT NULL default '1', `subStatus` varchar(30) NOT NULL default '', `color` char(7) NOT NULL, @@ -393,14 +393,14 @@ CREATE TABLE IF NOT EXISTS `zt_case` ( `lastEditedBy` char(30) NOT NULL default '', `lastEditedDate` datetime NULL, `version` tinyint(3) unsigned NOT NULL default '0', - `linkCase` varchar(255) NOT NULL, - `fromBug` mediumint(8) unsigned NOT NULL, - `fromCaseID` mediumint(8) unsigned NOT NULL, + `linkCase` varchar(255) NOT NULL DEFAULT '', + `fromBug` mediumint(8) unsigned NOT NULL DEFAULT 0, + `fromCaseID` mediumint(8) unsigned NOT NULL DEFAULT 0, `fromCaseVersion` mediumint(8) unsigned NOT NULL default '1', `deleted` enum('0','1') NOT NULL default '0', `lastRunner` varchar(30) NOT NULL DEFAULT '', `lastRunDate` datetime NULL, - `lastRunResult` char(30) NOT NULL, + `lastRunResult` char(30) NOT NULL DEFAULT '', `scene` int(11) NOT NULL default '0', `sort` int(11) NOT NULL default '0', PRIMARY KEY (`id`), @@ -2379,22 +2379,39 @@ CREATE TABLE IF NOT EXISTS `zt_report` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE UNIQUE INDEX `code` ON `zt_report`(`code`); -CREATE OR REPLACE VIEW `ztv_executionsummary` AS select `zt_task`.`execution` AS `execution`,sum(if((`zt_task`.`parent` >= '0'),`zt_task`.`estimate`,0)) AS `estimate`,sum(if((`zt_task`.`parent` >= '0'),`zt_task`.`consumed`,0)) AS `consumed`,sum(if(((`zt_task`.`status` <> 'cancel') and (`zt_task`.`status` <> 'closed') and (`zt_task`.`parent` >= '0')),`zt_task`.`left`,0)) AS `left`,count(0) AS `number`,sum(if(((`zt_task`.`status` <> 'done') and (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,sum((if((`zt_task`.`parent` >= '0'),`zt_task`.`consumed`,0) + if(((`zt_task`.`status` <> 'cancel') and (`zt_task`.`status` <> 'closed') and (`zt_task`.`parent` >= '0')),`zt_task`.`left`,0))) AS `totalReal` from `zt_task` where (`zt_task`.`deleted` = '0') group by `zt_task`.`execution`; -CREATE OR REPLACE VIEW `ztv_projectsummary` AS select `zt_task`.`project` AS `project`,sum(if((`zt_task`.`parent` >= '0'),`zt_task`.`estimate`,0)) AS `estimate`,sum(if((`zt_task`.`parent` >= '0'),`zt_task`.`consumed`,0)) AS `consumed`,sum(if(((`zt_task`.`status` <> 'cancel') and (`zt_task`.`status` <> 'closed') and (`zt_task`.`parent` >= '0')),`zt_task`.`left`,0)) AS `left`,count(0) AS `number`,sum(if(((`zt_task`.`status` <> 'done') and (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,sum((if((`zt_task`.`parent` >= '0'),`zt_task`.`consumed`,0) + if(((`zt_task`.`status` <> 'cancel') and (`zt_task`.`status` <> 'closed') and (`zt_task`.`parent` >= '0')),`zt_task`.`left`,0))) AS `totalReal` from `zt_task` where (`zt_task`.`deleted` = '0') group by `zt_task`.`project`; +-- DROP VIEW IF EXISTS `ztv_executionsummary`; +CREATE OR REPLACE VIEW `ztv_executionsummary` AS select `zt_task`.`execution` AS `execution`,sum(if((`zt_task`.`parent` >= '0'),`zt_task`.`estimate`,0)) AS `estimate`,sum(if((`zt_task`.`parent` >= '0'),`zt_task`.`consumed`,0)) AS `consumed`,sum(if(((`zt_task`.`status` <> 'cancel') and (`zt_task`.`status` <> 'closed') and (`zt_task`.`parent` >= '0')),`zt_task`.`left`,0)) AS `left`,count(0) AS `number`,sum(if(((`zt_task`.`status` <> 'done') and (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,sum(if(`zt_task`.`parent` >= '0',`zt_task`.`consumed`,0) + if(`zt_task`.`status` <> 'cancel' and `zt_task`.`status` <> 'closed' and `zt_task`.`parent` >= '0',`zt_task`.`left`,0)) AS `totalReal` from `zt_task` where (`zt_task`.`deleted` = '0') group by `zt_task`.`execution`; +-- DROP VIEW IF EXISTS `ztv_projectsummary`; +CREATE OR REPLACE VIEW `ztv_projectsummary` AS select `zt_task`.`project` AS `project`,sum(if(`zt_task`.`parent` >= '0',`zt_task`.`estimate`,0)) AS `estimate`,sum(if(`zt_task`.`parent` >= '0',`zt_task`.`consumed`,0)) AS `consumed`,sum(if((`zt_task`.`status` <> 'cancel') and (`zt_task`.`status` <> 'closed') and (`zt_task`.`parent` >= '0'),`zt_task`.`left`,0)) AS `left`,count(0) AS `number`,sum(if(((`zt_task`.`status` <> 'done') and (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,sum(if(`zt_task`.`parent` >= '0',`zt_task`.`consumed`,0) + if(`zt_task`.`status` <> 'cancel' and `zt_task`.`status` <> 'closed' and `zt_task`.`parent` >= '0',`zt_task`.`left`,0)) AS `totalReal` from `zt_task` where (`zt_task`.`deleted` = '0') group by `zt_task`.`project`; +-- DROP VIEW IF EXISTS `ztv_projectstories`; CREATE OR REPLACE VIEW `ztv_projectstories` AS select `t1`.`project` AS `execution`,count('*') AS `stories`,sum(if((`t2`.`status` = 'closed'),0,1)) AS `undone` from ((`zt_projectstory` `t1` left join `zt_story` `t2` on((`t1`.`story` = `t2`.`id`))) left join `zt_project` `t3` on((`t1`.`project` = `t3`.`id`))) where ((`t2`.`deleted` = '0') and (`t3`.`type` in ('sprint','stage'))) group by `t1`.`project`; +-- DROP VIEW IF EXISTS `ztv_projectteams`; CREATE OR REPLACE VIEW `ztv_projectteams` AS select `zt_team`.`root` AS `execution`,count('*') AS `teams` from `zt_team` where (`zt_team`.`type` = 'execution') group by `zt_team`.`root`; +-- DROP VIEW IF EXISTS `ztv_projectbugs`; CREATE OR REPLACE VIEW `ztv_projectbugs` AS select `zt_bug`.`execution` AS `execution`,count(0) AS `bugs`,sum(if((`zt_bug`.`resolution` = ''),0,1)) AS `resolutions`,sum(if((`zt_bug`.`severity` <= 2),1,0)) AS `seriousBugs` from `zt_bug` where (`zt_bug`.`deleted` = '0') group by `zt_bug`.`execution`; +-- DROP VIEW IF EXISTS `ztv_productbugs`; CREATE OR REPLACE VIEW `ztv_productbugs` AS select `zt_bug`.`product` AS `product`,count(0) AS `bugs`,sum(if((`zt_bug`.`resolution` = ''),0,1)) AS `resolutions`,sum(if((`zt_bug`.`severity` <= 2),1,0)) AS `seriousBugs` from `zt_bug` where (`zt_bug`.`deleted` = '0') group by `zt_bug`.`product`; +-- DROP VIEW IF EXISTS `ztv_productstories`; CREATE OR REPLACE VIEW `ztv_productstories` AS select `zt_story`.`product` AS `product`,count('*') AS `stories`,sum(if((`zt_story`.`status` = 'closed'),0,1)) AS `undone` from `zt_story` where (`zt_story`.`deleted` = '0') group by `zt_story`.`product`; +-- DROP VIEW IF EXISTS `ztv_dayuserlogin`; CREATE OR REPLACE VIEW `ztv_dayuserlogin` AS select count(*) AS `userlogin`,left(`zt_action`.`date`,10) AS `day` from `zt_action` where ((`zt_action`.`objectType` = 'user') and (`zt_action`.`action` = 'login')) group by left(`zt_action`.`date`,10); +-- DROP VIEW IF EXISTS `ztv_dayeffort`; CREATE OR REPLACE VIEW `ztv_dayeffort` AS select round(sum(`zt_effort`.`consumed`),1) AS `consumed`,`zt_effort`.`date` AS `date` from `zt_effort` group by `zt_effort`.`date`; +-- DROP VIEW IF EXISTS `ztv_daystoryopen`; CREATE OR REPLACE VIEW `ztv_daystoryopen` AS select count(*) AS `storyopen`,left(`zt_action`.`date`,10) AS `day` from `zt_action` where ((`zt_action`.`objectType` = 'story') and (`zt_action`.`action` = 'opened')) group by left(`zt_action`.`date`,10); +-- DROP VIEW IF EXISTS `ztv_daystoryclose`; CREATE OR REPLACE VIEW `ztv_daystoryclose` AS select count(*) AS `storyclose`,left(`zt_action`.`date`,10) AS `day` from `zt_action` where ((`zt_action`.`objectType` = 'story') and (`zt_action`.`action` = 'closed')) group by left(`zt_action`.`date`,10); +-- DROP VIEW IF EXISTS `ztv_daytaskopen`; CREATE OR REPLACE VIEW `ztv_daytaskopen` AS select count(*) AS `taskopen`,left(`zt_action`.`date`,10) AS `day` from `zt_action` where ((`zt_action`.`objectType` = 'task') and (`zt_action`.`action` = 'opened')) group by left(`zt_action`.`date`,10); +-- DROP VIEW IF EXISTS `ztv_daytaskfinish`; CREATE OR REPLACE VIEW `ztv_daytaskfinish` AS select count(*) AS `taskfinish`,left(`zt_action`.`date`,10) AS `day` from `zt_action` where ((`zt_action`.`objectType` = 'task') and (`zt_action`.`action` = 'finished')) group by left(`zt_action`.`date`,10); +-- DROP VIEW IF EXISTS `ztv_daybugopen`; CREATE OR REPLACE VIEW `ztv_daybugopen` AS select count(*) AS `bugopen`,left(`zt_action`.`date`,10) AS `day` from `zt_action` where ((`zt_action`.`objectType` = 'bug') and (`zt_action`.`action` = 'opened')) group by left(`zt_action`.`date`,10); +-- DROP VIEW IF EXISTS `ztv_daybugresolve`; CREATE OR REPLACE VIEW `ztv_daybugresolve` AS select count(*) AS `bugresolve`,left(`zt_action`.`date`,10) AS `day` from `zt_action` where ((`zt_action`.`objectType` = 'bug') and (`zt_action`.`action` = 'resolved')) group by left(`zt_action`.`date`,10); +-- DROP VIEW IF EXISTS `ztv_dayactions`; CREATE OR REPLACE VIEW `ztv_dayactions` AS select count(*) AS `actions`,left(`zt_action`.`date`,10) AS `day` from `zt_action` group by left(`zt_action`.`date`,10); +-- DROP VIEW IF EXISTS `ztv_normalproduct`; CREATE OR REPLACE VIEW `ztv_normalproduct` AS SELECT * FROM `zt_product` WHERE `shadow` = 0; --REPLACE INTO `zt_report` (`code`, `name`, `module`, `sql`, `vars`, `langs`, `params`, `step`, `desc`, `addedBy`, `addedDate`) VALUES @@ -13386,14 +13403,8 @@ CREATE OR REPLACE VIEW `ztv_scenecase` AS SELECT `zt_case`.`scene` AS `scene`, ifnull(`zt_scene`.`grade` + 1 , 1) AS `grade`, ifnull( - concat( - `zt_scene`.`path`, - `zt_case`.`id`, - ',' - ), - CONVERT( - concat(',' , `zt_case`.`id` , ',') USING utf8 - ) + concat( `zt_scene`.`path`, `zt_case`.`id`, ','), + concat(',' , `zt_case`.`id` , ',') ) AS `path`, 1 AS `isCase` FROM (`zt_case` LEFT JOIN `zt_scene` ON( `zt_case`.`scene` = `zt_scene`.`id`+100000000)) diff --git a/lib/dao/dm.class.php b/lib/dao/dm.class.php index a0c8ac4e14..62f1b4da39 100644 --- a/lib/dao/dm.class.php +++ b/lib/dao/dm.class.php @@ -118,7 +118,7 @@ class dm extends dao if(stripos($originField, 'if(') !== false) { - $originField = $this->formatIfFunction($originField); + $originField = $this->dbh->formatDmIfFunction($originField); } elseif(strcasecmp($originField, 'distinct') !== 0) { @@ -147,6 +147,7 @@ class dm extends dao * @access private * @return string */ + /* private function formatIfFunction($field) { preg_match('/if\(.+\)+/i', $field, $matches); @@ -158,7 +159,7 @@ class dm extends dao $if = substr($if, 0, $pos+1); } - /* fix sum(if(..., 1, 0)) , count(if(..., 1, 0)) */ + // * fix sum(if(..., 1, 0)) , count(if(..., 1, 0)) * // if(substr($if, strlen($if)-2) == '))' and (stripos($field, 'sum(') == 0 or stripos($field, 'count(') == 0)) $if = substr($if, 0, strlen($if)-1); $parts = explode(',', substr($if, 3, strlen($if)-4)); // remove 'if(' and ')' @@ -167,6 +168,7 @@ class dm extends dao return $field; } + */ /** * 创建WHERE部分。 diff --git a/lib/dbh/dbh.class.php b/lib/dbh/dbh.class.php index 5bd3a1377c..49d0d1d22b 100644 --- a/lib/dbh/dbh.class.php +++ b/lib/dbh/dbh.class.php @@ -277,10 +277,36 @@ class dbh if(strpos($sql, '\\\\') !== FALSE) $sql = str_replace('\\\\', '\\', $sql); break; case 'CREATE': - if(stripos($sql, 'CREATE OR REPLACE VIEW ') === 0) return ''; if(stripos($sql, 'CREATE VIEW') === 0) return ''; if(stripos($sql, 'CREATE FUNCTION') === 0) return ''; - if(stripos($sql, 'CREATE UNIQUE INDEX') === 0) + + if(stripos($sql, 'CREATE OR REPLACE VIEW ') === 0) + { + // Modify if function. + $fieldsBegin = stripos($sql, 'select'); + $fieldsEnd = stripos($sql, 'from'); + $fields = substr($sql, $fieldsBegin+6, $fieldsEnd-$fieldsBegin-6); + $fieldList = preg_split("/,(?![^(]+\))/", $fields); + foreach($fieldList as $key => $field) + { + $aliasPos = stripos($field, ' AS '); + $subField = substr($field, 0, $aliasPos); + if(stripos($field, 'SUM(') === 0) $subField = substr($subField, 4, -1); + + $fieldParts = preg_split("/\+(?![^(]+\))/", $subField); + foreach($fieldParts as $pkey => $fieldPart) + { + $originField = trim($fieldPart); + if(stripos($originField, 'if(') === false) continue; + $fieldParts[$pkey] = $this->formatDmIfFunction($originField); + } + $fieldList[$key] = str_replace($subField, implode(' + ', $fieldParts), $field); + } + $fields = implode(',', $fieldList); + $sql = substr($sql, 0, $fieldsBegin+6) . $fields . substr($sql, $fieldsEnd); + return str_replace('CREATE OR REPLACE VIEW ', 'CREATE VIEW ', $sql); + } + elseif(stripos($sql, 'CREATE UNIQUE INDEX') === 0) { preg_match('/ON\ +[0-9a-zA-Z\_\.]+\`([0-9a-zA-Z\_]+)\`/', $sql, $matches); $tableName = explode('_', $matches[1]); @@ -337,6 +363,34 @@ class dbh } } + /** + * Format if function of dmdb. + * + * @param string $field + * @access private + * @return string + */ + public function formatDmIfFunction($field) + { + preg_match('/if\(.+\)+/i', $field, $matches); + + $if = $matches[0]; + if(substr_count($if, '(') == 1) + { + $pos = strpos($if, ')'); + $if = substr($if, 0, $pos+1); + } + + /* fix sum(if(..., 1, 0)) , count(if(..., 1, 0)) */ + if(substr($if, strlen($if)-2) == '))' and (stripos($field, 'sum(') == 0 or stripos($field, 'count(') == 0)) $if = substr($if, 0, strlen($if)-1); + + $parts = explode(',', substr($if, 3, strlen($if)-4)); // remove 'if(' and ')' + $case = 'CASE WHEN ' . implode(',', array_slice($parts, 0, count($parts)-2)) . ' THEN ' . $parts[count($parts)-2] . ' ELSE ' . $parts[count($parts)-1] . ' END'; + $field = str_ireplace($if, $case, $field); + + return $field; + } + /** * Format attribute of field. * diff --git a/module/story/model.php b/module/story/model.php index 74e046257d..414d0a087d 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -342,6 +342,7 @@ class storyModel extends model $reviewData->story = $storyID; $reviewData->version = 1; $reviewData->reviewer = $reviewer; + $reviewData->result = ''; $this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec(); } } @@ -3384,13 +3385,13 @@ class storyModel extends model */ public function getRevertStoryIDList($productID) { - $review = $this->dao->select('objectID')->from(TABLE_ACTION) + $review = $this->dao->select('objectID')->from(TABLE_ACTION) ->where('product')->like("%,$productID,%") ->andWhere('action')->eq('reviewed') ->andWhere('objectType')->eq('story') ->andWhere('extra')->eq('Revert') ->groupBy('objectID') - ->orderBy('id_desc') + ->orderBy('objectID_desc') ->fetchPairs(); return $review; } diff --git a/module/task/model.php b/module/task/model.php index b06863b093..a5483a9a19 100755 --- a/module/task/model.php +++ b/module/task/model.php @@ -3587,10 +3587,10 @@ class taskModel extends model */ public function getDataOffinishedTasksPerDay() { - $tasks = $this->dao->select('id, DATE_FORMAT(finishedDate, "%Y-%m-%d") AS date')->from(TABLE_TASK)->alias('t1') + $tasks = $this->dao->select("id, DATE_FORMAT(`finishedDate`, '%Y-%m-%d') AS `date`")->from(TABLE_TASK) ->where($this->reportCondition()) - ->having('date != "0000-00-00"') - ->orderBy('date asc') + ->andWhere('finishedDate')->notZeroDatetime() + ->orderBy('finishedDate asc') ->fetchAll('id'); if(!$tasks) return array();