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 
47  // only use the uploads the user / group has access to
48  $upload_pks = array_filter($upload_pks, function($upload_pk) {
49  return $upload_pk !== null && $this->uploadDao->isAccessible($upload_pk, Auth::getGroupId());
50  });
51 
52  // get count of upload pks, return empty array if count equals 0
53  $jobCount = count($upload_pks);
54  if ($jobCount == 0) {
55  return $jobArray;
56  }
57 
58  /* calculate index of starting upload_pk */
59  $offset = empty($page) ? 0 : $page * $this->maxJobsPerPage;
60  $totalPages = floor($jobCount / $this->maxJobsPerPage);
61 
62  /* Get the job_pk's for each for each upload_pk */
63  $lastOffset = ($jobCount < $this->maxJobsPerPage) ? $offset+$jobCount : $this->maxJobsPerPage;
64  $statementName = __METHOD__."upload_pkforjob";
65  $this->dbManager->prepare($statementName, "SELECT job_pk FROM job WHERE job_upload_fk=$1 ORDER BY job_pk ASC");
66  for (; $offset < $lastOffset; $offset++) {
67  $upload_pk = $upload_pks[$offset];
68 
69  $result = $this->dbManager->execute($statementName, array($upload_pk));
70  while ($row = $this->dbManager->fetchArray($result)) {
71  $jobArray[] = $row['job_pk'];
72  }
73  $this->dbManager->freeResult($result);
74  }
75  return array($jobArray, $totalPages);
76  } /* uploads2Jobs() */
77 
83  public function getJobName($uploadId)
84  {
85  $statementName = __METHOD__."forjob_name";
86  /* upload has been deleted so try to get the job name from the original upload job record */
87  $row = $this->dbManager->getSingleRow(
88  "SELECT job_name FROM job WHERE job_upload_fk= $1 ORDER BY job_pk ASC",
89  array($uploadId),
90  $statementName
91  );
92  return (empty($row['job_name']) ? $uploadId : $row['job_name']);
93  } /* getJobName */
94 
103  public function myJobs($allusers, $page = 0)
104  {
105  $jobArray = array();
106  $offset = empty($page) ? 0 : ($page * $this->maxJobsPerPage) - 1;
107 
108  $allusers_str = ($allusers == 0) ? "job_user_fk='" . Auth::getUserId() .
109  "' and " : "";
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");
116  $result = $this->dbManager->execute($statementName);
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 
128  // calculate total pages for jobs accessible to current group
129  $totalPages = floor(count($jobArray) / $this->maxJobsPerPage);
130 
131  // get jobs for current page only
132  $pageJobs = array_slice($jobArray, $offset, $this->maxJobsPerPage);
133 
134  $this->dbManager->freeResult($result);
135 
136  return array($pageJobs, $totalPages);
137  } /* myJobs() */
138 
164  public function getJobInfo($job_pks)
165  {
166  /* Output data array */
167  $jobData = array();
168  foreach ($job_pks as $job_pk) {
169  /* Get job table data */
170  $statementName = __METHOD__ . "JobRec";
171  $jobRec = $this->dbManager->getSingleRow(
172  "SELECT * FROM job WHERE job_pk= $1", array($job_pk),
173  $statementName);
174  $jobData[$job_pk]["job"] = $jobRec;
175  if (! empty($jobRec["job_upload_fk"])) {
176  $upload_pk = $jobRec["job_upload_fk"];
177  /* Get Upload record for job */
178  $statementName = __METHOD__ . "UploadRec";
179  $uploadRec = $this->dbManager->getSingleRow(
180  "SELECT * FROM upload WHERE upload_pk= $1", array($upload_pk),
181  $statementName);
182  if (! empty($uploadRec)) {
183  $jobData[$job_pk]["upload"] = $uploadRec;
184  /* Get Upload record for uploadtree */
185  $uploadtree_tablename = $uploadRec["uploadtree_tablename"];
186  $statementName = __METHOD__ . "uploadtreeRec";
187  $uploadtreeRec = $this->dbManager->getSingleRow(
188  "SELECT * FROM $uploadtree_tablename where upload_fk = $1 and parent is null",
189  array($upload_pk), $statementName);
190  $jobData[$job_pk]["uploadtree"] = $uploadtreeRec;
191  } else {
192  $statementName = __METHOD__ . "uploadRecord";
193  $uploadRec = $this->dbManager->getSingleRow(
194  "SELECT * FROM upload right join job on upload_pk = job_upload_fk where job_upload_fk = $1",
195  array($upload_pk), $statementName);
196  /*
197  * upload has been deleted so try to get the job name from the
198  * original upload job record
199  */
200  $jobName = $this->getJobName($uploadRec["job_upload_fk"]);
201  $uploadRec["upload_filename"] = "Deleted Upload: " .
202  $uploadRec["job_upload_fk"] . "(" . $jobName . ")";
203  $uploadRec["upload_pk"] = $uploadRec["job_upload_fk"];
204  $jobData[$job_pk]["upload"] = $uploadRec;
205  }
206  }
207  /* Get jobqueue table data */
208  $statementName = __METHOD__ . "job_pkforjob";
209  $this->dbManager->prepare($statementName,
210  "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");
211  $result = $this->dbManager->execute($statementName, array(
212  $job_pk
213  ));
214  $rows = $this->dbManager->fetchAll($result);
215  if (! empty($rows)) {
216  foreach ($rows as $jobQueueRec) {
217  $jq_pk = $jobQueueRec["jq_pk"];
218  if (array_key_exists($job_pk, $jobData) &&
219  array_key_exists('jobqueue', $jobData[$job_pk]) &&
220  array_key_exists($jq_pk, $jobData[$job_pk]['jobqueue'])) {
221  $jobData[$job_pk]['jobqueue'][$jq_pk]["depends"][] = $jobQueueRec["jdep_jq_depends_fk"];
222  } else {
223  $jobQueueRec["depends"] = array($jobQueueRec["jdep_jq_depends_fk"]);
224  $jobData[$job_pk]['jobqueue'][$jq_pk] = $jobQueueRec;
225  }
226  }
227  } else {
228  unset($jobData[$job_pk]);
229  }
230  $this->dbManager->freeResult($result);
231  }
232  return $jobData;
233  } /* getJobInfo() */
234 
241  public function getNumItemsPerSec($itemsprocessed, $numSecs)
242  {
243  return ($numSecs > 0) ? $itemsprocessed/$numSecs : 0;
244  }
245 
254  public function getEstimatedTime($job_pk, $jq_Type='', $filesPerSec=0, $uploadId=0, $timeInSec=0)
255  {
256  if (!empty($uploadId)) {
257  $itemCount = $this->dbManager->getSingleRow(
258  "SELECT jq_itemsprocessed FROM jobqueue INNER JOIN job ON jq_job_fk=job_pk "
259  . " WHERE jq_type LIKE 'ununpack' AND jq_end_bits ='1' AND job_upload_fk=$1",
260  array($uploadId),
261  __METHOD__.'.ununpack_might_be_in_other_job'
262  );
263  } else {
264  $itemCount = $this->dbManager->getSingleRow(
265  "SELECT jq_itemsprocessed FROM jobqueue WHERE jq_type LIKE 'ununpack' AND jq_end_bits ='1' AND jq_job_fk =$1",
266  array($job_pk),
267  __METHOD__.'.ununpack_must_be_in_this_job'
268  );
269  }
270 
271  if (!empty($itemCount['jq_itemsprocessed']) && $jq_Type !== 'decider') {
272 
273  $selectCol = "jq_type, jq_endtime, jq_starttime, jq_itemsprocessed";
274  if (empty($jq_Type)) {
275  $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";
276  /* get starttime endtime and jobtype form jobqueue for a jobid except $removeType */
277  $statementName = __METHOD__."$selectCol.$removeType";
278  $this->dbManager->prepare($statementName,
279  "SELECT $selectCol FROM jobqueue WHERE $removeType jq_job_fk =$1 ORDER BY jq_type DESC");
280  } else {
281  $statementName = __METHOD__."$selectCol.$jq_Type";
282  $this->dbManager->prepare($statementName,
283  "SELECT $selectCol FROM jobqueue WHERE jq_type LIKE '$jq_Type' AND jq_job_fk =$1");
284  }
285  $result = $this->dbManager->execute($statementName, array($job_pk));
286  $estimatedArray = array(); // estimate time for each agent
287 
288  while ($row = $this->dbManager->fetchArray($result)) {
289  $timeOfCompletion = 0;
290  if (empty($row['jq_endtime']) && !empty($row['jq_starttime'])) { // for agent started and not ended
291  if (empty($filesPerSec)) {
292  $burnTime = time() - strtotime($row['jq_starttime']);
293  $filesPerSec = $this->getNumItemsPerSec($row['jq_itemsprocessed'], $burnTime);
294  }
295 
296  if (!empty($filesPerSec)) {
297  $timeOfCompletion = ($itemCount['jq_itemsprocessed'] - $row['jq_itemsprocessed']) / $filesPerSec;
298  }
299  $estimatedArray[] = $timeOfCompletion;
300  }
301  }
302  if (empty($estimatedArray)) {
303  return "";
304  } else {
305  $estimatedTime = round(max($estimatedArray)); // collecting max agent time in seconds
306  if (!empty($timeInSec)) {
307  return intval(!empty($estimatedTime) ? $estimatedTime : 0);
308  }
309  return intval($estimatedTime/3600).gmdate(":i:s", $estimatedTime); // convert seconds to time and return
310  }
311  }
312  }/* getEstimatedTime() */
313 
319  public function getDataForASingleJob($jq_pk)
320  {
321  $statementName = __METHOD__."getDataForASingleJob";
322  $this->dbManager->prepare($statementName,
323  "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");
324  $result = $this->dbManager->execute($statementName, array($jq_pk));
325  $row = $this->dbManager->fetchArray($result);
326  $this->dbManager->freeResult($result);
327  return $row;
328  } /* getDataForASingleJob */
329 
334  public function getJobStatus($jqPk)
335  {
336  $statementName = __METHOD__."forjq_pk";
337  $row = $this->dbManager->getSingleRow(
338  "SELECT jq_end_bits FROM jobqueue WHERE jq_pk = $1",
339  array($jqPk),
340  $statementName
341  );
342  if ($row['jq_end_bits'] == 1 || $row['jq_end_bits'] == 2) {
343  return false;
344  } else {
345  return true;
346  }
347  }
348 
354  public function getItemsProcessedForDecider($jqType, $jobId)
355  {
356  $statementName = __METHOD__."forjqTypeAndjobId";
357  $row = $this->dbManager->getSingleRow(
358  "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",
359  array($jqType, $jobId),
360  $statementName
361  );
362  if (!empty($row['jq_itemsprocessed'])) {
363  return array($row['jq_itemsprocessed'], $row['job_upload_fk']);
364  } else {
365  return array();
366  }
367  }
368 
373  public function getJobsForAll()
374  {
375  $sql = "SELECT jq_type AS job, jq_job_fk, job_upload_fk AS upload_fk, " .
376  "CASE WHEN (jq_endtext IS NULL AND jq_end_bits = 0) THEN 'pending' " .
377  "WHEN (jq_endtext = ANY('{Started,Restarted,Paused}')) THEN 'running' " .
378  "ELSE '' END AS status " .
379  "FROM jobqueue INNER JOIN job " .
380  "ON jq_job_fk = job_pk " .
381  "AND job_queued >= (now() - interval '" . $this->nhours . " hours') " .
382  "WHERE jq_endtime IS NULL;";
383  $statement = __METHOD__ . ".getAllUnFinishedJobs";
384  return $this->dbManager->getRows($sql, [], $statement);
385  }
386 
391  public function isJobIdPresentInReportGen($jobId)
392  {
393  $statementName = __METHOD__ . "forJobIdCheck";
394  $row = $this->dbManager->getSingleRow(
395  "SELECT 1 FROM reportgen WHERE job_fk = $1",
396  array($jobId),
397  $statementName
398  );
399  return !empty($row);
400  }
401 }
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:83
getItemsProcessedForDecider($jqType, $jobId)
myJobs($allusers, $page=0)
Find all of my jobs submitted within the last n hours.
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