8 namespace Fossology\Lib\Proxy;
20 const OPT_SKIP_THESE =
'skipThese';
21 const OPT_ITEM_FILTER =
'ut.filter';
22 const OPT_GROUP_ID =
'groupId';
23 const OPT_REALPARENT =
'realParent';
24 const OPT_RANGE =
'lft,rgt';
25 const OPT_EXT =
'ext';
26 const OPT_HEAD =
'head';
27 const OPT_AGENT_SET =
'agentArray';
28 const OPT_SCAN_REF =
'scanRef';
29 const OPT_CONCLUDE_REF =
'conRef';
30 const OPT_SKIP_ALREADY_CLEARED =
'alreadyCleared';
33 private $uploadTreeTableName;
37 private $params = array();
44 public function __construct($uploadId, $options, $uploadTreeTableName, $uploadTreeViewName=
null)
46 $this->uploadId = $uploadId;
47 $this->uploadTreeTableName = $uploadTreeTableName;
48 $dbViewName = $uploadTreeViewName ?:
'UploadTreeView'.(isset($this->dbViewName) ?:
'');
50 parent::__construct($dbViewQuery, $dbViewName);
58 return $this->uploadTreeTableName;
68 if (empty($options)) {
73 $this->dbViewName =
'';
75 $uploadDao = $GLOBALS[
'container']->get(
'dao.upload');
76 $applyGlobal = $uploadDao->getGlobalDecisionSettingsFromInfo($this->uploadId);
77 if ($applyGlobal == 1) {
83 if (array_key_exists(self::OPT_REALPARENT, $options)) {
84 $filter .=
" AND ut.ufile_mode & (1<<28) = 0 AND ut.realparent=".$this->addParamAndGetExpr(
'realParent',$options[self::OPT_REALPARENT]);
85 $this->dbViewName .=
"_".self::OPT_REALPARENT;
86 } elseif (array_key_exists(self::OPT_RANGE,$options)) {
87 $itemBounds = $options[self::OPT_RANGE];
88 $filter .=
" AND ut.ufile_mode & (3<<28) = 0 AND (ut.lft BETWEEN ".$this->addParamAndGetExpr(
'lft',$itemBounds->getLeft()).
89 " AND ".$this->addParamAndGetExpr(
'rgt',$itemBounds->getRight()).
")";
90 $this->dbViewName .=
"_".self::OPT_RANGE;
93 if (array_key_exists(self::OPT_EXT, $options)) {
94 $filter .=
" AND ufile_name ILIKE ".$this->addParamAndGetExpr(
'patternExt',
'%.'.$options[self::OPT_EXT]);
95 $this->dbViewName .=
"_".self::OPT_EXT;
98 if (array_key_exists(self::OPT_HEAD, $options)) {
99 $filter .=
" AND ufile_name ILIKE ".$this->addParamAndGetExpr(
'patternHead',$options[self::OPT_HEAD].
'%');
100 $this->dbViewName .=
"_".self::OPT_HEAD;
103 if (array_key_exists(self::OPT_SCAN_REF,$options)) {
104 $filter .= $this->addScanFilter($options);
107 if (array_key_exists(self::OPT_CONCLUDE_REF, $options) && array_key_exists(self::OPT_GROUP_ID, $options)) {
108 $filter .= $this->addConFilter($options);
111 if (array_key_exists(self::OPT_SKIP_ALREADY_CLEARED, $options) && array_key_exists(self::OPT_GROUP_ID, $options)
112 && array_key_exists(self::OPT_AGENT_SET, $options)) {
113 $agentIdSet =
'{' . implode(
',', array_values($options[self::OPT_AGENT_SET])) .
'}';
114 $agentFilter =
" AND agent_fk=ANY(".$this->addParamAndGetExpr(
'agentIdSet', $agentIdSet).
")";
115 $this->dbViewName .=
"_".self::OPT_SKIP_ALREADY_CLEARED;
116 $groupAlias = $this->addParamAndGetExpr(
'groupId', $options[self::OPT_GROUP_ID]);
117 if (array_key_exists(self::OPT_RANGE, $options)) {
118 $filter .=
' AND '.self::getQueryCondition(self::OPT_SKIP_ALREADY_CLEARED, $options, $groupAlias, $agentFilter, $applyGlobal);
119 } elseif (array_key_exists(self::OPT_SKIP_ALREADY_CLEARED, $options) && array_key_exists(self::OPT_GROUP_ID, $options)
120 && array_key_exists(self::OPT_AGENT_SET, $options) && array_key_exists(self::OPT_REALPARENT, $options)) {
121 $childFilter = self::getQueryCondition(self::OPT_SKIP_ALREADY_CLEARED, $options, $groupAlias, $agentFilter, $applyGlobal);
122 $filter .=
' AND EXISTS(SELECT * FROM '.$this->uploadTreeTableName.
' utc WHERE utc.upload_fk='.$this->uploadId
123 .
' AND (utc.lft BETWEEN ut.lft AND ut.rgt) AND utc.ufile_mode&(3<<28)=0 AND '
124 .preg_replace(
'/([a-z])ut\./',
'\1utc.', $childFilter).
')';
128 if (array_key_exists(self::OPT_ITEM_FILTER, $options)) {
129 $filter .=
' '.$options[self::OPT_ITEM_FILTER];
130 $this->dbViewName .=
"_".md5($options[self::OPT_ITEM_FILTER]);
132 $options[self::OPT_ITEM_FILTER] = $filter;
136 private function addConFilter($options)
139 if (array_key_exists(self::OPT_REALPARENT, $options)) {
140 $filter .=
" AND EXISTS(SELECT * FROM ".$this->uploadTreeTableName.
" usub"
141 .
" WHERE (usub.lft BETWEEN ut.lft AND ut.rgt) AND upload_fk=".$this->uploadId
142 .
" AND ".$this->subqueryConcludeRefMatches(
'usub', $options) .
")";
143 $this->dbViewName .=
"_".self::OPT_CONCLUDE_REF;
144 } elseif (array_key_exists(self::OPT_RANGE, $options)) {
145 $filter.=
" AND ".$this->subqueryConcludeRefMatches(
'ut', $options);
146 $this->dbViewName .=
"_".self::OPT_CONCLUDE_REF;
151 private function addScanFilter($options)
153 $this->dbViewName .=
"_".self::OPT_SCAN_REF;
154 if (array_key_exists(self::OPT_AGENT_SET, $options)) {
155 $this->dbViewName .=
"_".self::OPT_AGENT_SET;
157 if (array_key_exists(self::OPT_REALPARENT, $options)) {
158 return " AND EXISTS(SELECT * FROM ".$this->uploadTreeTableName.
" usub, "
159 . $this->subqueryLicenseFileMatchWhere($options)
160 .
" usub.pfile_fk=license_file.pfile_fk"
161 .
" AND (usub.lft BETWEEN ut.lft AND ut.rgt) AND upload_fk=".$this->uploadId.
")";
163 if (array_key_exists(self::OPT_RANGE, $options)) {
164 return " AND EXISTS(SELECT * FROM " . $this->subqueryLicenseFileMatchWhere($options)
165 .
" ut.pfile_fk=license_file.pfile_fk)";
169 private function subqueryLicenseFileMatchWhere($options)
171 $filter =
" license_file LEFT JOIN license_map ON license_file.rf_fk=license_map.rf_fk"
172 .
" AND usage=".LicenseMap::CONCLUSION.
" WHERE";
173 if (array_key_exists(self::OPT_AGENT_SET, $options)) {
174 $agentIdSet =
'{' . implode(
',', array_values($options[self::OPT_AGENT_SET])) .
'}';
175 $filter .=
" agent_fk=ANY(".$this->addParamAndGetExpr(
'agentIdSet', $agentIdSet).
") AND";
177 $rfId = $this->addParamAndGetExpr(
'scanRef', $options[self::OPT_SCAN_REF]);
178 return $filter .
" (license_file.rf_fk=$rfId OR rf_parent=$rfId) AND ";
181 private function subqueryConcludeRefMatches($itemTable,$options)
186 $uploadDao = $GLOBALS[
'container']->get(
'dao.upload');
187 $applyGlobal = $uploadDao->getGlobalDecisionSettingsFromInfo($this->uploadId);
188 if ($applyGlobal == 1) {
191 $applyGlobal =
false;
194 $globalSql =
"OR (cd.scope=" . DecisionScopes::REPO .
195 " AND cd.pfile_fk=$itemTable.pfile_fk)";
196 $orderByGlobal =
"CASE cd.scope WHEN " . DecisionScopes::REPO .
197 " THEN 1 ELSE 0 END,";
199 return "NOT(SELECT (removed OR cd.decision_type=".DecisionTypes::IRRELEVANT.
") excluded"
200 .
" FROM clearing_decision cd, clearing_decision_event cde, clearing_event ce"
201 .
" WHERE ((cd.group_fk=".$this->addParamAndGetExpr(
'groupId', $options[self::OPT_GROUP_ID])
202 .
" AND cd.uploadtree_fk=$itemTable.uploadtree_pk)"
204 .
") AND clearing_decision_pk=clearing_decision_fk"
205 .
" AND clearing_event_fk=clearing_event_pk"
206 .
" AND rf_fk=".$this->addParamAndGetExpr(
'conId',$options[self::OPT_CONCLUDE_REF])
207 .
" AND cd.decision_type!=".DecisionTypes::WIP
208 .
" ORDER BY $orderByGlobal cd.date_added DESC LIMIT 1)";
220 if (
'uploadtree' === $uploadTreeTableName ||
'uploadtree_a' == $uploadTreeTableName) {
221 $condition =
" WHERE ut.upload_fk=$uploadId $additionalCondition";
222 } elseif ($additionalCondition) {
223 $condition =
" WHERE 1=1 $additionalCondition";
225 $uploadTreeView =
"SELECT * FROM $uploadTreeTableName ut $condition";
226 return $uploadTreeView;
236 private static function getUploadTreeView($uploadId, $options, $uploadTreeTableName, $applyGlobal =
false)
238 $additionalCondition = array_key_exists(self::OPT_ITEM_FILTER, $options) ? $options[self::OPT_ITEM_FILTER] :
'';
239 $skipThese = array_key_exists(self::OPT_SKIP_THESE,$options) ? $options[self::OPT_SKIP_THESE] :
'none';
240 $groupId = array_key_exists(self::OPT_GROUP_ID, $options) ? $options[self::OPT_GROUP_ID] :
null;
241 $agentFilter = self::getAgentFilter($options, $uploadId);
243 switch ($skipThese) {
245 case self::OPT_SKIP_ALREADY_CLEARED:
251 $queryCondition = self::getQueryCondition($skipThese, $options, $groupId, $agentFilter, $applyGlobal).
" ".$additionalCondition;
252 if (
'uploadtree' === $uploadTreeTableName ||
'uploadtree_a' == $uploadTreeTableName) {
253 $queryCondition =
"ut.upload_fk=$uploadId AND ($queryCondition)";
255 $uploadTreeView =
"SELECT * FROM $uploadTreeTableName ut WHERE $queryCondition";
263 return $uploadTreeView;
266 private static function getAgentFilter($options,$uploadId=0)
268 if (!array_key_exists(self::OPT_SKIP_THESE, $options)) {
271 $skipThese = $options[self::OPT_SKIP_THESE];
272 if ($skipThese !=
"noLicense" && $skipThese != self::OPT_SKIP_ALREADY_CLEARED) {
276 if (array_key_exists(self::OPT_AGENT_SET, $options)) {
277 $agentIds =
'array[' . implode(
',',$options[self::OPT_AGENT_SET]) .
']';
278 $agentFilter =
" AND lf.agent_fk = ANY($agentIds)";
280 $scanJobProxy =
new ScanJobProxy($GLOBALS[
'container']->
get(
'dao.agent'),$uploadId);
281 $scanJobProxy->createAgentStatus(array_keys(AgentRef::AGENT_LIST));
282 $latestAgentIds = $scanJobProxy->getLatestSuccessfulAgentIds();
283 $agentFilter = $latestAgentIds ?
" AND lf.agent_fk = ANY(array[".implode(
',',$latestAgentIds).
"])" :
"AND 0=1";
296 private static function getQueryCondition($skipThese, $options, $groupId =
null, $agentFilter=
'', $applyGlobal =
false)
300 $licenseDao = $container->get(
'dao.license');
301 $licensesToRemove = [];
302 foreach ([
'No_license_found',
'Void'] as $licenseName) {
303 $license = $licenseDao->getLicenseByShortName($licenseName);
305 $licensesToRemove[] =
"lf.rf_fk != " . $license->getId();
308 $licensesToRemove = implode(
' AND ', $licensesToRemove);
309 if (!empty($licensesToRemove)) {
310 $licensesToRemove =
"($licensesToRemove) AND ";
314 ut.uploadtree_pk = cd.uploadtree_fk AND cd.group_fk = $groupId
315 AND cd.scope = ".DecisionScopes::ITEM.
"
317 cd.pfile_fk = ut.pfile_fk AND cd.scope=" . DecisionScopes::REPO .
"
320 $globalSql =
"ut.uploadtree_pk = cd.uploadtree_fk AND cd.group_fk = $groupId";
322 $conditionQueryHasLicense =
"(EXISTS (SELECT 1 FROM license_file lf " .
323 "WHERE ($licensesToRemove" .
324 "lf.pfile_fk = ut.pfile_fk $agentFilter))" .
325 "OR EXISTS (SELECT 1 FROM clearing_decision AS cd " .
326 "WHERE cd.group_fk = $groupId AND ut.uploadtree_pk = cd.uploadtree_fk))";
328 switch ($skipThese) {
330 return $conditionQueryHasLicense;
331 case self::OPT_SKIP_ALREADY_CLEARED:
333 SELECT cd.decision_type
334 FROM clearing_decision cd
336 ORDER BY cd.clearing_decision_pk DESC LIMIT 1";
337 return " $conditionQueryHasLicense
338 AND NOT EXISTS (SELECT 1 FROM ($decisionQuery) AS latest_decision WHERE latest_decision.decision_type IN (".DecisionTypes::IRRELEVANT.
",".DecisionTypes::IDENTIFIED.
",".DecisionTypes::DO_NOT_USE.
",".DecisionTypes::NON_FUNCTIONAL.
"))";
340 return "EXISTS (SELECT copyright_pk FROM copyright cp WHERE cp.pfile_fk=ut.pfile_fk and cp.hash is not null )".
341 " OR EXISTS (SELECT 1 FROM copyright_decision AS cd WHERE ut.pfile_fk = cd.pfile_fk)";
343 return "EXISTS (SELECT ipra_pk FROM ipra cp WHERE cp.pfile_fk=ut.pfile_fk and cp.hash is not null )".
344 " OR EXISTS (SELECT 1 FROM ipra_decision AS cd WHERE ut.pfile_fk = cd.pfile_fk)";
346 return "EXISTS (SELECT ecc_pk FROM ecc cp WHERE cp.pfile_fk=ut.pfile_fk and cp.hash is not null )".
347 " OR EXISTS (SELECT 1 FROM ecc_decision AS cd WHERE ut.pfile_fk = cd.pfile_fk)";
349 return "EXISTS (SELECT keyword_pk FROM keyword cp WHERE cp.pfile_fk=ut.pfile_fk and cp.hash is not null )";
361 $dbManager = $GLOBALS[
'container']->get(
'db.manager');
362 $params = $this->params;
363 if (array_key_exists(
'uploadId', $params)) {
364 $uploadExpr =
'$'.(1+array_search(
'uploadId', array_keys($params)));
366 $params[] = $this->uploadId;
367 $uploadExpr =
'$'.count($params);
370 $parentExpr =
'$'.count($params);
372 $sql =
"SELECT count(*) cnt, u.uploadtree_pk, u.ufile_mode FROM ".$this->uploadTreeTableName.
" u, "
374 .
" AND v.lft BETWEEN u.lft and u.rgt and u.parent=$parentExpr GROUP BY u.uploadtree_pk, u.ufile_mode";
376 if (!$this->materialized) {
377 $sql = $this->
asCTE().
' '.$sql;
380 $dbManager->prepare($stmt,$sql);
381 $res = $dbManager->execute($stmt,$params);
383 $artifactContainers = array();
384 while ($row=$dbManager->fetchArray($res)) {
385 $children[$row[
'uploadtree_pk']] = $row[
'cnt'];
386 if (($row[
'ufile_mode'] & (3<<28)) == (3<<28)) {
387 $artifactContainers[] = $row[
'uploadtree_pk'];
390 $dbManager->freeResult($res);
391 foreach ($artifactContainers as $ac) {
393 $children[$utid] = $cnt;
405 $uploadExpr =
'$'.(count($this->params)+1);
406 $lftExpr =
'$'.(count($this->params)+2);
407 $rgtExpr =
'$'.(count($this->params)+3);
408 $dbManager = $GLOBALS[
'container']->get(
'db.manager');
409 $sql =
"SELECT u.uploadtree_pk FROM ".$this->getDbViewName().
" u "
410 .
"WHERE u.upload_fk=$uploadExpr AND (u.lft BETWEEN $lftExpr AND $rgtExpr) AND u.ufile_mode & (3<<28) = 0";
412 if (!$this->materialized) {
413 $sql = $this->
asCTE().
' '.$sql;
416 $dbManager->prepare($stmt,$sql);
417 $params = array_merge($this->params,
419 $res = $dbManager->execute($stmt,$params);
420 $descendants = array();
421 while ($row = $dbManager->fetchArray($res)) {
422 $descendants[$row[
'uploadtree_pk']] = 1;
424 $dbManager->freeResult($res);
434 $dbManager = $container->get(
'db.manager');
435 if ($this->materialized) {
436 $sql =
"SELECT count(*) FROM $this->dbViewName";
438 $sql =
"SELECT count(*) FROM ($this->dbViewQuery) $this->dbViewName";
440 $summary = $dbManager->getSingleRow($sql,$this->params,$this->dbViewName);
441 return $summary[
'count'];
444 private function addParamAndGetExpr($key,$value)
446 if (array_key_exists($key, $this->params)) {
447 return '$' . (1 + array_search($key, array_keys($this->params)));
450 $this->params[] = $value;
451 return '$'.count($this->params);
454 public function getParams()
456 return $this->params;
Wrapper class for license map.
asCTE()
Common Table Expressions.
__construct($uploadId, $options, $uploadTreeTableName, $uploadTreeViewName=null)
countMaskedNonArtifactChildren($parent)
count elements childrenwise (or grandchildrenwise if child is artifact)
static getUploadTreeView($uploadId, $options, $uploadTreeTableName, $applyGlobal=false)
createUploadTreeViewQuery($options, $uploadTreeTableName)
static getDefaultUploadTreeView($uploadId, $uploadTreeTableName, $additionalCondition='')
getNonArtifactDescendants(ItemTreeBounds $itemTreeBounds)