FOSSology  4.4.0
Open Source License Compliance by Open Source Software
ShowJobsDao.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2015-2018 Siemens AG
4  Author: Shaheem Azmal<shaheem.azmal@siemens.com>, Anupam Ghosh <anupam.ghosh@siemens.com>
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
9 namespace Fossology\Lib\Dao;
10 
13 use Monolog\Logger;
14 
16 {
18  private $dbManager;
20  private $uploadDao;
22  private $logger;
24  private $maxJobsPerPage = 10; /* max number of jobs to display on a page */
26  private $nhours = 672; /* 672=24*28 (4 weeks) What is considered a recent number of hours for "My Recent Jobs" */
27 
28  function __construct(DbManager $dbManager, UploadDao $uploadDao)
29  {
30  $this->dbManager = $dbManager;
31  $this->uploadDao = $uploadDao;
32  $this->logger = new Logger(self::class);
33  }
34 
43  function uploads2Jobs($upload_pks, $page = 0)
44  {
45  $jobArray = array();
46  $jobCount = count($upload_pks);
47  if ($jobCount == 0) {
48  return $jobArray;
49  }
50 
51  /* calculate index of starting upload_pk */
52  $offset = empty($page) ? 0 : $page * $this->maxJobsPerPage;
53  $totalPages = floor($jobCount / $this->maxJobsPerPage);
54 
55  /* Get the job_pk's for each for each upload_pk */
56  $lastOffset = ($jobCount < $this->maxJobsPerPage) ? $offset+$jobCount : $this->maxJobsPerPage;
57  $statementName = __METHOD__."upload_pkforjob";
58  $this->dbManager->prepare($statementName, "SELECT job_pk FROM job WHERE job_upload_fk=$1 ORDER BY job_pk ASC");
59  for (; $offset < $lastOffset; $offset++) {
60  $upload_pk = $upload_pks[$offset];
61 
62  $result = $this->dbManager->execute($statementName, array($upload_pk));
63  while ($row = $this->dbManager->fetchArray($result)) {
64  $jobArray[] = $row['job_pk'];
65  }
66  $this->dbManager->freeResult($result);
67  }
68  return array($jobArray, $totalPages);
69  } /* uploads2Jobs() */
70 
76  public function getJobName($uploadId)
77  {
78  $statementName = __METHOD__."forjob_name";
79  /* upload has been deleted so try to get the job name from the original upload job record */
80  $row = $this->dbManager->getSingleRow(
81  "SELECT job_name FROM job WHERE job_upload_fk= $1 ORDER BY job_pk ASC",
82  array($uploadId),
83  $statementName
84  );
85  return (empty($row['job_name']) ? $uploadId : $row['job_name']);
86  } /* getJobName */
87 
96  public function myJobs($allusers, $page = 0)
97  {
98  $jobArray = array();
99  $offset = empty($page) ? 0 : ($page * $this->maxJobsPerPage) - 1;
100 
101  $allusers_str = ($allusers == 0) ? "job_user_fk='" . Auth::getUserId() .
102  "' and " : "";
103 
104  $statementName = __METHOD__ . ".countJobs." . $allusers_str;
105  $sql = "SELECT count(*) AS cnt FROM job WHERE $allusers_str " .
106  "job_queued >= (now() - interval '" . $this->nhours . " hours');";
107 
108  $countJobs = $this->dbManager->getSingleRow($sql, [], $statementName)['cnt'];
109  $totalPages = floor($countJobs / $this->maxJobsPerPage);
110 
111  $statementName = __METHOD__ . "." . $allusers_str;
112  $this->dbManager->prepare($statementName,
113  "SELECT job_pk, job_upload_fk FROM job " . "WHERE $allusers_str " .
114  "job_queued >= (now() - interval '" . $this->nhours . " hours') " .
115  "ORDER BY job_queued DESC OFFSET $1 LIMIT " . $this->maxJobsPerPage);
116  $result = $this->dbManager->execute($statementName, [$offset]);
117  while ($row = $this->dbManager->fetchArray($result)) {
118  if (! empty($row['job_upload_fk'])) {
119  $uploadIsAccessible = $this->uploadDao->isAccessible(
120  $row['job_upload_fk'], Auth::getGroupId());
121  if (! $uploadIsAccessible) {
122  continue;
123  }
124  }
125  $jobArray[] = $row['job_pk'];
126  }
127  $this->dbManager->freeResult($result);
128 
129  return array($jobArray, $totalPages);
130  } /* myJobs() */
131 
157  public function getJobInfo($job_pks)
158  {
159  /* Output data array */
160  $jobData = array();
161  foreach ($job_pks as $job_pk) {
162  /* Get job table data */
163  $statementName = __METHOD__ . "JobRec";
164  $jobRec = $this->dbManager->getSingleRow(
165  "SELECT * FROM job WHERE job_pk= $1", array($job_pk),
166  $statementName);
167  $jobData[$job_pk]["job"] = $jobRec;
168  if (! empty($jobRec["job_upload_fk"])) {
169  $upload_pk = $jobRec["job_upload_fk"];
170  /* Get Upload record for job */
171  $statementName = __METHOD__ . "UploadRec";
172  $uploadRec = $this->dbManager->getSingleRow(
173  "SELECT * FROM upload WHERE upload_pk= $1", array($upload_pk),
174  $statementName);
175  if (! empty($uploadRec)) {
176  $jobData[$job_pk]["upload"] = $uploadRec;
177  /* Get Upload record for uploadtree */
178  $uploadtree_tablename = $uploadRec["uploadtree_tablename"];
179  $statementName = __METHOD__ . "uploadtreeRec";
180  $uploadtreeRec = $this->dbManager->getSingleRow(
181  "SELECT * FROM $uploadtree_tablename where upload_fk = $1 and parent is null",
182  array($upload_pk), $statementName);
183  $jobData[$job_pk]["uploadtree"] = $uploadtreeRec;
184  } else {
185  $statementName = __METHOD__ . "uploadRecord";
186  $uploadRec = $this->dbManager->getSingleRow(
187  "SELECT * FROM upload right join job on upload_pk = job_upload_fk where job_upload_fk = $1",
188  array($upload_pk), $statementName);
189  /*
190  * upload has been deleted so try to get the job name from the
191  * original upload job record
192  */
193  $jobName = $this->getJobName($uploadRec["job_upload_fk"]);
194  $uploadRec["upload_filename"] = "Deleted Upload: " .
195  $uploadRec["job_upload_fk"] . "(" . $jobName . ")";
196  $uploadRec["upload_pk"] = $uploadRec["job_upload_fk"];
197  $jobData[$job_pk]["upload"] = $uploadRec;
198  }
199  }
200  /* Get jobqueue table data */
201  $statementName = __METHOD__ . "job_pkforjob";
202  $this->dbManager->prepare($statementName,
203  "SELECT jq.*,jd.jdep_jq_depends_fk FROM jobqueue jq LEFT OUTER JOIN jobdepends jd ON jq.jq_pk=jd.jdep_jq_fk WHERE jq.jq_job_fk=$1 ORDER BY jq_pk ASC");
204  $result = $this->dbManager->execute($statementName, array(
205  $job_pk
206  ));
207  $rows = $this->dbManager->fetchAll($result);
208  if (! empty($rows)) {
209  foreach ($rows as $jobQueueRec) {
210  $jq_pk = $jobQueueRec["jq_pk"];
211  if (array_key_exists($job_pk, $jobData) &&
212  array_key_exists('jobqueue', $jobData[$job_pk]) &&
213  array_key_exists($jq_pk, $jobData[$job_pk]['jobqueue'])) {
214  $jobData[$job_pk]['jobqueue'][$jq_pk]["depends"][] = $jobQueueRec["jdep_jq_depends_fk"];
215  } else {
216  $jobQueueRec["depends"] = array($jobQueueRec["jdep_jq_depends_fk"]);
217  $jobData[$job_pk]['jobqueue'][$jq_pk] = $jobQueueRec;
218  }
219  }
220  } else {
221  unset($jobData[$job_pk]);
222  }
223  $this->dbManager->freeResult($result);
224  }
225  return $jobData;
226  } /* getJobInfo() */
227 
234  public function getNumItemsPerSec($itemsprocessed, $numSecs)
235  {
236  return ($numSecs > 0) ? $itemsprocessed/$numSecs : 0;
237  }
238 
247  public function getEstimatedTime($job_pk, $jq_Type='', $filesPerSec=0, $uploadId=0, $timeInSec=0)
248  {
249  if (!empty($uploadId)) {
250  $itemCount = $this->dbManager->getSingleRow(
251  "SELECT jq_itemsprocessed FROM jobqueue INNER JOIN job ON jq_job_fk=job_pk "
252  . " WHERE jq_type LIKE 'ununpack' AND jq_end_bits ='1' AND job_upload_fk=$1",
253  array($uploadId),
254  __METHOD__.'.ununpack_might_be_in_other_job'
255  );
256  } else {
257  $itemCount = $this->dbManager->getSingleRow(
258  "SELECT jq_itemsprocessed FROM jobqueue WHERE jq_type LIKE 'ununpack' AND jq_end_bits ='1' AND jq_job_fk =$1",
259  array($job_pk),
260  __METHOD__.'.ununpack_must_be_in_this_job'
261  );
262  }
263 
264  if (!empty($itemCount['jq_itemsprocessed']) && $jq_Type !== 'decider') {
265 
266  $selectCol = "jq_type, jq_endtime, jq_starttime, jq_itemsprocessed";
267  if (empty($jq_Type)) {
268  $removeType = "jq_type NOT LIKE 'ununpack' AND jq_type NOT LIKE 'reportgen' AND jq_type NOT LIKE 'decider' AND jq_type NOT LIKE 'softwareHeritage' AND";
269  /* get starttime endtime and jobtype form jobqueue for a jobid except $removeType */
270  $statementName = __METHOD__."$selectCol.$removeType";
271  $this->dbManager->prepare($statementName,
272  "SELECT $selectCol FROM jobqueue WHERE $removeType jq_job_fk =$1 ORDER BY jq_type DESC");
273  } else {
274  $statementName = __METHOD__."$selectCol.$jq_Type";
275  $this->dbManager->prepare($statementName,
276  "SELECT $selectCol FROM jobqueue WHERE jq_type LIKE '$jq_Type' AND jq_job_fk =$1");
277  }
278  $result = $this->dbManager->execute($statementName, array($job_pk));
279  $estimatedArray = array(); // estimate time for each agent
280 
281  while ($row = $this->dbManager->fetchArray($result)) {
282  $timeOfCompletion = 0;
283  if (empty($row['jq_endtime']) && !empty($row['jq_starttime'])) { // for agent started and not ended
284  if (empty($filesPerSec)) {
285  $burnTime = time() - strtotime($row['jq_starttime']);
286  $filesPerSec = $this->getNumItemsPerSec($row['jq_itemsprocessed'], $burnTime);
287  }
288 
289  if (!empty($filesPerSec)) {
290  $timeOfCompletion = ($itemCount['jq_itemsprocessed'] - $row['jq_itemsprocessed']) / $filesPerSec;
291  }
292  $estimatedArray[] = $timeOfCompletion;
293  }
294  }
295  if (empty($estimatedArray)) {
296  return "";
297  } else {
298  $estimatedTime = round(max($estimatedArray)); // collecting max agent time in seconds
299  if (!empty($timeInSec)) {
300  return intval(!empty($estimatedTime) ? $estimatedTime : 0);
301  }
302  return intval($estimatedTime/3600).gmdate(":i:s", $estimatedTime); // convert seconds to time and return
303  }
304  }
305  }/* getEstimatedTime() */
306 
312  public function getDataForASingleJob($jq_pk)
313  {
314  $statementName = __METHOD__."getDataForASingleJob";
315  $this->dbManager->prepare($statementName,
316  "SELECT *, jq_endtime-jq_starttime as elapsed FROM jobqueue LEFT JOIN job ON job.job_pk = jobqueue.jq_job_fk WHERE jobqueue.jq_pk =$1");
317  $result = $this->dbManager->execute($statementName, array($jq_pk));
318  $row = $this->dbManager->fetchArray($result);
319  $this->dbManager->freeResult($result);
320  return $row;
321  } /* getDataForASingleJob */
322 
327  public function getJobStatus($jqPk)
328  {
329  $statementName = __METHOD__."forjq_pk";
330  $row = $this->dbManager->getSingleRow(
331  "SELECT jq_end_bits FROM jobqueue WHERE jq_pk = $1",
332  array($jqPk),
333  $statementName
334  );
335  if ($row['jq_end_bits'] == 1 || $row['jq_end_bits'] == 2) {
336  return false;
337  } else {
338  return true;
339  }
340  }
341 
347  public function getItemsProcessedForDecider($jqType, $jobId)
348  {
349  $statementName = __METHOD__."forjqTypeAndjobId";
350  $row = $this->dbManager->getSingleRow(
351  "SELECT jq_itemsprocessed, job.job_upload_fk FROM jobqueue JOIN job ON jobqueue.jq_job_fk = job.job_pk WHERE jq_type = $1 AND jq_end_bits = 0 AND jq_job_fk IN (SELECT job_pk FROM job WHERE job_upload_fk = (SELECT job_upload_fk FROM job WHERE job_pk = $2 LIMIT 1)) LIMIT 1",
352  array($jqType, $jobId),
353  $statementName
354  );
355  if (!empty($row['jq_itemsprocessed'])) {
356  return array($row['jq_itemsprocessed'], $row['job_upload_fk']);
357  } else {
358  return array();
359  }
360  }
361 
366  public function getJobsForAll()
367  {
368  $sql = "SELECT jq_type AS job, jq_job_fk, job_upload_fk AS upload_fk, " .
369  "CASE WHEN (jq_endtext IS NULL AND jq_end_bits = 0) THEN 'pending' " .
370  "WHEN (jq_endtext = ANY('{Started,Restarted,Paused}')) THEN 'running' " .
371  "ELSE '' END AS status " .
372  "FROM jobqueue INNER JOIN job " .
373  "ON jq_job_fk = job_pk " .
374  "AND job_queued >= (now() - interval '" . $this->nhours . " hours') " .
375  "WHERE jq_endtime IS NULL;";
376  $statement = __METHOD__ . ".getAllUnFinishedJobs";
377  return $this->dbManager->getRows($sql, [], $statement);
378  }
379 }
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
static getUserId()
Get the current user's id.
Definition: Auth.php:68
static getGroupId()
Get the current user's group id.
Definition: Auth.php:80
uploads2Jobs($upload_pks, $page=0)
Find all the jobs for a given set of uploads.
Definition: ShowJobsDao.php:43
getJobName($uploadId)
Return job name. Used for deleted jobs.
Definition: ShowJobsDao.php:76
getItemsProcessedForDecider($jqType, $jobId)
myJobs($allusers, $page=0)
Find all of my jobs submitted within the last n hours.
Definition: ShowJobsDao.php:96
getEstimatedTime($job_pk, $jq_Type='', $filesPerSec=0, $uploadId=0, $timeInSec=0)
Returns Estimated time using jobid.
getDataForASingleJob($jq_pk)
Return total Job data with time elapsed.
getNumItemsPerSec($itemsprocessed, $numSecs)
Returns Number of files/items processed per sec.
getJobInfo($job_pks)
Get job queue data from db.
FUNCTION int max(int permGroup, int permPublic)
Get the maximum group privilege.
Definition: libfossagent.c:295
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16