FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
ShowJobsDao.php
1 <?php
2 /*
3  Copyright (C) 2015-2018, Siemens AG
4  Author: Shaheem Azmal<shaheem.azmal@siemens.com>,
5  Anupam Ghosh <anupam.ghosh@siemens.com>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License
9  version 2 as published by the Free Software Foundation.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License along
17  with this program; if not, write to the Free Software Foundation, Inc.,
18  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20 
21 namespace Fossology\Lib\Dao;
22 
25 use Monolog\Logger;
26 
28 {
30  private $dbManager;
32  private $uploadDao;
34  private $logger;
36  private $maxJobsPerPage = 10; /* max number of jobs to display on a page */
38  private $nhours = 672; /* 672=24*28 (4 weeks) What is considered a recent number of hours for "My Recent Jobs" */
39 
40  function __construct(DbManager $dbManager, UploadDao $uploadDao)
41  {
42  $this->dbManager = $dbManager;
43  $this->uploadDao = $uploadDao;
44  $this->logger = new Logger(self::class);
45  }
46 
55  function uploads2Jobs($upload_pks, $page = 0)
56  {
57  $jobArray = array();
58  $jobCount = count($upload_pks);
59  if ($jobCount == 0) {
60  return $jobArray;
61  }
62 
63  /* calculate index of starting upload_pk */
64  $offset = empty($page) ? 0 : $page * $this->maxJobsPerPage;
65  $totalPages = floor($jobCount / $this->maxJobsPerPage);
66 
67  /* Get the job_pk's for each for each upload_pk */
68  $lastOffset = ($jobCount < $this->maxJobsPerPage) ? $offset+$jobCount : $this->maxJobsPerPage;
69  $statementName = __METHOD__."upload_pkforjob";
70  $this->dbManager->prepare($statementName, "SELECT job_pk FROM job WHERE job_upload_fk=$1 ORDER BY job_pk ASC");
71  for (; $offset < $lastOffset; $offset++) {
72  $upload_pk = $upload_pks[$offset];
73 
74  $result = $this->dbManager->execute($statementName, array($upload_pk));
75  while ($row = $this->dbManager->fetchArray($result)) {
76  $jobArray[] = $row['job_pk'];
77  }
78  $this->dbManager->freeResult($result);
79  }
80  return array($jobArray, $totalPages);
81  } /* uploads2Jobs() */
82 
88  public function getJobName($uploadId)
89  {
90  $statementName = __METHOD__."forjob_name";
91  /* upload has been deleted so try to get the job name from the original upload job record */
92  $row = $this->dbManager->getSingleRow(
93  "SELECT job_name FROM job WHERE job_upload_fk= $1 ORDER BY job_pk ASC",
94  array($uploadId),
95  $statementName
96  );
97  return (empty($row['job_name']) ? $uploadId : $row['job_name']);
98  } /* getJobName */
99 
108  public function myJobs($allusers, $page = 0)
109  {
110  $jobArray = array();
111  $offset = empty($page) ? 0 : ($page * $this->maxJobsPerPage) - 1;
112 
113  $allusers_str = ($allusers == 0) ? "job_user_fk='" . Auth::getUserId() .
114  "' and " : "";
115 
116  $statementName = __METHOD__ . ".countJobs." . $allusers_str;
117  $sql = "SELECT count(*) AS cnt FROM job WHERE $allusers_str " .
118  "job_queued >= (now() - interval '" . $this->nhours . " hours');";
119 
120  $countJobs = $this->dbManager->getSingleRow($sql, [], $statementName)['cnt'];
121  $totalPages = floor($countJobs / $this->maxJobsPerPage);
122 
123  $statementName = __METHOD__ . "." . $allusers_str;
124  $this->dbManager->prepare($statementName,
125  "SELECT job_pk, job_upload_fk FROM job " . "WHERE $allusers_str " .
126  "job_queued >= (now() - interval '" . $this->nhours . " hours') " .
127  "ORDER BY job_queued DESC OFFSET $1 LIMIT " . $this->maxJobsPerPage);
128  $result = $this->dbManager->execute($statementName, [$offset]);
129  while ($row = $this->dbManager->fetchArray($result)) {
130  if (! empty($row['job_upload_fk'])) {
131  $uploadIsAccessible = $this->uploadDao->isAccessible(
132  $row['job_upload_fk'], Auth::getGroupId());
133  if (! $uploadIsAccessible) {
134  continue;
135  }
136  }
137  $jobArray[] = $row['job_pk'];
138  }
139  $this->dbManager->freeResult($result);
140 
141  return array($jobArray, $totalPages);
142  } /* myJobs() */
143 
169  public function getJobInfo($job_pks)
170  {
171  /* Output data array */
172  $jobData = array();
173  foreach ($job_pks as $job_pk) {
174  /* Get job table data */
175  $statementName = __METHOD__ . "JobRec";
176  $jobRec = $this->dbManager->getSingleRow(
177  "SELECT * FROM job WHERE job_pk= $1", array($job_pk),
178  $statementName);
179  $jobData[$job_pk]["job"] = $jobRec;
180  if (! empty($jobRec["job_upload_fk"])) {
181  $upload_pk = $jobRec["job_upload_fk"];
182  /* Get Upload record for job */
183  $statementName = __METHOD__ . "UploadRec";
184  $uploadRec = $this->dbManager->getSingleRow(
185  "SELECT * FROM upload WHERE upload_pk= $1", array($upload_pk),
186  $statementName);
187  if (! empty($uploadRec)) {
188  $jobData[$job_pk]["upload"] = $uploadRec;
189  /* Get Upload record for uploadtree */
190  $uploadtree_tablename = $uploadRec["uploadtree_tablename"];
191  $statementName = __METHOD__ . "uploadtreeRec";
192  $uploadtreeRec = $this->dbManager->getSingleRow(
193  "SELECT * FROM $uploadtree_tablename where upload_fk = $1 and parent is null",
194  array($upload_pk), $statementName);
195  $jobData[$job_pk]["uploadtree"] = $uploadtreeRec;
196  } else {
197  $statementName = __METHOD__ . "uploadRecord";
198  $uploadRec = $this->dbManager->getSingleRow(
199  "SELECT * FROM upload right join job on upload_pk = job_upload_fk where job_upload_fk = $1",
200  array($upload_pk), $statementName);
201  /*
202  * upload has been deleted so try to get the job name from the
203  * original upload job record
204  */
205  $jobName = $this->getJobName($uploadRec["job_upload_fk"]);
206  $uploadRec["upload_filename"] = "Deleted Upload: " .
207  $uploadRec["job_upload_fk"] . "(" . $jobName . ")";
208  $uploadRec["upload_pk"] = $uploadRec["job_upload_fk"];
209  $jobData[$job_pk]["upload"] = $uploadRec;
210  }
211  }
212  /* Get jobqueue table data */
213  $statementName = __METHOD__ . "job_pkforjob";
214  $this->dbManager->prepare($statementName,
215  "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");
216  $result = $this->dbManager->execute($statementName, array(
217  $job_pk
218  ));
219  $rows = $this->dbManager->fetchAll($result);
220  if (! empty($rows)) {
221  foreach ($rows as $jobQueueRec) {
222  $jq_pk = $jobQueueRec["jq_pk"];
223  if (array_key_exists($job_pk, $jobData) &&
224  array_key_exists('jobqueue', $jobData[$job_pk]) &&
225  array_key_exists($jq_pk, $jobData[$job_pk]['jobqueue'])) {
226  $jobData[$job_pk]['jobqueue'][$jq_pk]["depends"][] = $jobQueueRec["jdep_jq_depends_fk"];
227  } else {
228  $jobQueueRec["depends"] = array($jobQueueRec["jdep_jq_depends_fk"]);
229  $jobData[$job_pk]['jobqueue'][$jq_pk] = $jobQueueRec;
230  }
231  }
232  } else {
233  unset($jobData[$job_pk]);
234  }
235  $this->dbManager->freeResult($result);
236  }
237  return $jobData;
238  } /* getJobInfo() */
239 
246  public function getNumItemsPerSec($itemsprocessed, $numSecs)
247  {
248  $filesPerSec = ($numSecs > 0) ? $itemsprocessed/$numSecs : 0;
249  return $filesPerSec;
250  }
251 
260  public function getEstimatedTime($job_pk, $jq_Type='', $filesPerSec=0, $uploadId=0, $timeInSec=0)
261  {
262  if (!empty($uploadId)) {
263  $itemCount = $this->dbManager->getSingleRow(
264  "SELECT jq_itemsprocessed FROM jobqueue INNER JOIN job ON jq_job_fk=job_pk "
265  . " WHERE jq_type LIKE 'ununpack' AND jq_end_bits ='1' AND job_upload_fk=$1",
266  array($uploadId),
267  __METHOD__.'.ununpack_might_be_in_other_job'
268  );
269  } else {
270  $itemCount = $this->dbManager->getSingleRow(
271  "SELECT jq_itemsprocessed FROM jobqueue WHERE jq_type LIKE 'ununpack' AND jq_end_bits ='1' AND jq_job_fk =$1",
272  array($job_pk),
273  __METHOD__.'.ununpack_must_be_in_this_job'
274  );
275  }
276 
277  if (!empty($itemCount['jq_itemsprocessed']) && $jq_Type !== 'decider') {
278 
279  $selectCol = "jq_type, jq_endtime, jq_starttime, jq_itemsprocessed";
280  if (empty($jq_Type)) {
281  $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";
282  /* get starttime endtime and jobtype form jobqueue for a jobid except $removeType */
283  $statementName = __METHOD__."$selectCol.$removeType";
284  $this->dbManager->prepare($statementName,
285  "SELECT $selectCol FROM jobqueue WHERE $removeType jq_job_fk =$1 ORDER BY jq_type DESC");
286  $result = $this->dbManager->execute($statementName, array($job_pk));
287  } else {
288  $statementName = __METHOD__."$selectCol.$jq_Type";
289  $this->dbManager->prepare($statementName,
290  "SELECT $selectCol FROM jobqueue WHERE jq_type LIKE '$jq_Type' AND jq_job_fk =$1");
291  $result = $this->dbManager->execute($statementName, array($job_pk));
292  }
293  $estimatedArray = array(); // estimate time for each agent
294 
295  while ($row = $this->dbManager->fetchArray($result)) {
296  $timeOfCompletion = 0;
297  if (empty($row['jq_endtime']) && !empty($row['jq_starttime'])) { // for agent started and not ended
298  if (empty($filesPerSec)) {
299  $burnTime = time() - strtotime($row['jq_starttime']);
300  $filesPerSec = $this->getNumItemsPerSec($row['jq_itemsprocessed'], $burnTime);
301  }
302 
303  if (!empty($filesPerSec)) {
304  $timeOfCompletion = ($itemCount['jq_itemsprocessed'] - $row['jq_itemsprocessed']) / $filesPerSec;
305  }
306  array_push($estimatedArray, $timeOfCompletion);
307  }
308  }
309  if (empty($estimatedArray)) {
310  return "";
311  } else {
312  $estimatedTime = round(max($estimatedArray)); // collecting max agent time in seconds
313  if (!empty($timeInSec)) {
314  return intval(!empty($estimatedTime) ? $estimatedTime : 0);
315  }
316  return intval($estimatedTime/3600).gmdate(":i:s", $estimatedTime); // convert seconds to time and return
317  }
318  }
319  }/* getEstimatedTime() */
320 
326  public function getDataForASingleJob($jq_pk)
327  {
328  $statementName = __METHOD__."getDataForASingleJob";
329  $this->dbManager->prepare($statementName,
330  "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");
331  $result = $this->dbManager->execute($statementName, array($jq_pk));
332  $row = $this->dbManager->fetchArray($result);
333  $this->dbManager->freeResult($result);
334  return $row;
335  } /* getDataForASingleJob */
336 
341  public function getJobStatus($jqPk)
342  {
343  $statementName = __METHOD__."forjq_pk";
344  $row = $this->dbManager->getSingleRow(
345  "SELECT jq_end_bits FROM jobqueue WHERE jq_pk = $1",
346  array($jqPk),
347  $statementName
348  );
349  if ($row['jq_end_bits'] == 1 || $row['jq_end_bits'] == 2) {
350  return false;
351  } else {
352  return true;
353  }
354  }
355 
361  public function getItemsProcessedForDecider($jqType, $jobId)
362  {
363  $statementName = __METHOD__."forjqTypeAndjobId";
364  $row = $this->dbManager->getSingleRow(
365  "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",
366  array($jqType, $jobId),
367  $statementName
368  );
369  if (!empty($row['jq_itemsprocessed'])) {
370  return array($row['jq_itemsprocessed'], $row['job_upload_fk']);
371  } else {
372  return array();
373  }
374  }
375 
380  public function getJobsForAll()
381  {
382  $sql = "SELECT jq_type AS job, jq_job_fk, job_upload_fk AS upload_fk, " .
383  "CASE WHEN (jq_endtext IS NULL AND jq_end_bits = 0) THEN 'pending' " .
384  "WHEN (jq_endtext = ANY('{Started,Restarted,Paused}')) THEN 'running' " .
385  "ELSE '' END AS status " .
386  "FROM jobqueue INNER JOIN job " .
387  "ON jq_job_fk = job_pk " .
388  "WHERE jq_endtime IS NULL;";
389  $statement = __METHOD__ . ".getAllUnFinishedJobs";
390  return $this->dbManager->getRows($sql, [], $statement);
391  }
392 }
getDataForASingleJob($jq_pk)
Return total Job data with time elapsed.
static getUserId()
Get the current user&#39;s id.
Definition: Auth.php:69
getNumItemsPerSec($itemsprocessed, $numSecs)
Returns Number of files/items processed per sec.
getItemsProcessedForDecider($jqType, $jobId)
Return array.
getJobStatus($jqPk)
Return boolean.
uploads2Jobs($upload_pks, $page=0)
Find all the jobs for a given set of uploads.
Definition: ShowJobsDao.php:55
getEstimatedTime($job_pk, $jq_Type='', $filesPerSec=0, $uploadId=0, $timeInSec=0)
Returns Estimated time using jobid.
myJobs($allusers, $page=0)
Find all of my jobs submitted within the last n hours.
getJobName($uploadId)
Return job name. Used for deleted jobs.
Definition: ShowJobsDao.php:88
getJobInfo($job_pks)
Get job queue data from db.
FUNCTION int max(int permGroup, int permPublic)
Get the maximum group privilege.
Definition: libfossagent.c:309
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:28
static getGroupId()
Get the current user&#39;s group id.
Definition: Auth.php:78