From 47c698faf42fe9a3675c9c7d346ed8bfa8c9302e Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 19 May 2022 15:48:06 +0200 Subject: [PATCH] ENHANCEMENT: using querybuilder Signed-off-by: Jeroen De Meerleer --- src/Controller/JobController.php | 3 +- src/Repository/JobRepository.php | 35 ++++++----- src/Repository/RunRepository.php | 101 +++++++++++++++++++++---------- 3 files changed, 89 insertions(+), 50 deletions(-) diff --git a/src/Controller/JobController.php b/src/Controller/JobController.php index d3bd5c5..3e108fe 100644 --- a/src/Controller/JobController.php +++ b/src/Controller/JobController.php @@ -81,7 +81,8 @@ class JobController extends AbstractController public function runNowAction(Request $request, ManagerRegistry $doctrine, int $id) { if($request->getMethod() == 'GET') { $jobRepo = $doctrine->getRepository(Job::class); - return new JsonResponse($jobRepo->runNow($id)); + $job = $jobRepo->find($id); + return new JsonResponse($jobRepo->runNow($job)); } } } \ No newline at end of file diff --git a/src/Repository/JobRepository.php b/src/Repository/JobRepository.php index f8dc6fd..e45969b 100644 --- a/src/Repository/JobRepository.php +++ b/src/Repository/JobRepository.php @@ -340,9 +340,7 @@ class JobRepository extends EntityRepository $manual = $this->getTempVar($job, 'manual'); $this->deleteTempVar($job, 'manual'); - $jobsSql = "UPDATE job SET running = :status WHERE id = :id"; - $jobsStmt = $this->getEntityManager()->getConnection()->prepare($jobsSql); - $jobsStmt->executeQuery([':id' => $job->getId(), ':status' => 1]); + $this->setJobRunning($job, true); if (!empty($job->getData('vars'))) { foreach ($job->getData('vars') as $key => $var) { @@ -374,13 +372,16 @@ class JobRepository extends EntityRepository * @throws \Doctrine\DBAL\Exception */ public function runNow(Job &$job, $console = false) { + $em = $this->getEntityManager(); $this->parseJob($job, true); $runRepo = $this->getEntityManager()->getRepository(Run::class); - if($console == false && ($runRepo->isSlowJob($job->getId()) || count($job->getRuns()) == 0 || $job->getData('crontype') === 'reboot')) { - $jobsSql = "UPDATE job SET running = :status WHERE id = :id AND running IN (0,1,2)"; - $jobsStmt = $this->getEntityManager()->getConnection()->prepare($jobsSql); - $jobsStmt->executeQuery([':id' => $job->getId(), ':status' => 2]); + if($console == false && ($runRepo->isSlowJob($job)) || count($job->getRuns()) == 0 || $job->getData('crontype') === 'reboot') { + if(in_array($job->getRunning(), [0,1,2])) { + $job->setRunning(2); + $em->persist($job); + $em->flush(); + } } else { $output = $this->runJob($job, true); if(!(isset($output['status']) && $output['status'] == 'deferred')) @@ -477,18 +478,20 @@ class JobRepository extends EntityRepository * @return void * @throws \Doctrine\DBAL\Exception */ - public function unlockJob(int $id = 0): void + public function unlockJob(?Job $job = NULL): void { - $jobsSql = "UPDATE job SET running = :status WHERE running = 1"; - $params = [':status' => 0]; + $qb = $this->createQueryBuilder('job'); + $qry = $qb + ->update() + ->set('job.running', 0) + ->where('job.running = 1'); - if($id != 0) { - $jobsSql .= " AND id = :id"; - $params[':id'] = $id; + if($job !== NULL) { + $qry = $qry + ->andWhere('job = :job') + ->setParameter(':job', $job); } - $jobsStmt = $this->getEntityManager()->getConnection()->prepare($jobsSql); - $jobsStmt->executeQuery($params); - return; + $qry->getQuery()->execute(); } /** diff --git a/src/Repository/RunRepository.php b/src/Repository/RunRepository.php index f77bf27..654e4e1 100644 --- a/src/Repository/RunRepository.php +++ b/src/Repository/RunRepository.php @@ -5,6 +5,7 @@ namespace App\Repository; use App\Entity\Job; +use App\Entity\Run; use Doctrine\DBAL\Exception; use Doctrine\ORM\EntityRepository; @@ -32,65 +33,99 @@ class RunRepository extends EntityRepository return $runs->getQuery()->getResult(); } - public function addRun(int $jobid, string $exitcode, int $starttime, float $runtime, string $output, array $flags): void + public function addRun(Job $job, string $exitcode, int $starttime, float $runtime, string $output, array $flags): void { - // handling of response - $addRunSql = 'INSERT INTO run(job_id, exitcode, output, runtime, timestamp,flags) VALUES (:job_id, :exitcode, :output, :runtime, :timestamp, :flags)'; - $addRunStmt = $this->getEntityManager()->getConnection()->prepare($addRunSql); - $addRunStmt->executeQuery([':job_id' => $jobid, ':exitcode' => $exitcode, 'output' => $output, 'runtime' => $runtime, ':timestamp' => $starttime, ':flags' => implode("", $flags)]); + $em = $this->getEntityManager(); + + $run = new Run(); + $run + ->setJob($job) + ->setExitcode($exitcode) + ->setTimestamp($starttime) + ->setRuntime($runtime) + ->setOutput($output) + ->setFlags(implode($flags)); + $em->persist($run); + $em->flush(); } - public function getLastRun(int $jobid): array + public function getLastRun(Job $job): array { - $lastRunSql = 'SELECT * FROM run WHERE job_id = :jobid ORDER BY timestamp DESC LIMIT 1'; - $lastRun = $this->getEntityManager()->getConnection()->prepare($lastRunSql)->executeQuery([':jobid' => $jobid])->fetchAssociative(); - return $lastRun; + $em = $this->getEntityManager(); + $qb = $this->createQueryBuilder('run'); + + $lastrun = $qb + ->where('run.job = :job') + ->orderBy('run.timestamp', 'DESC') + ->setParameter(':job', $job) + ->getQuery()->getFirstResult(); + + return $lastrun; } - public function isSlowJob(int $jobid, int $timelimit = 5): bool + public function isSlowJob(Job $job, int $timelimit = 5): bool { - $slowJobSql = 'SELECT AVG(runtime) as average FROM run WHERE job_id = :jobid LIMIT 5'; - $slowJob = $this->getEntityManager()->getConnection()->prepare($slowJobSql)->executeQuery([':jobid' => $jobid])->fetchAssociative(); - return $slowJob['average'] > $timelimit; + $qb = $this->createQueryBuilder('run'); + + $slowJob = $qb + ->select('AVG(run.runtime) AS average') + ->where('run.job = :job') + ->setMaxResults(5) + ->setParameter(':job', $job) + ->getQuery()->getArrayResult(); + + return $slowJob[0]['average'] > $timelimit; } public function cleanupRuns(array $jobids, int $maxage = NULL): int { - $jobRepo = $this->getEntityManager()->getRepository(Job::class); - $allJobs = $jobRepo->getAllJobs(true); + $em = $this->getEntityManager(); + $jobRepo = $em->getRepository(Job::class); + $allJobs = []; + if(empty($jobids)) { + $allJobs = $jobRepo->getAllJobs(true); foreach($allJobs as $key=>$job) { $jobids[] = $key; } + } else { + foreach($jobids as $jobid) { + $job = $em->find($jobid); + $jobRepo->parseJob($job); + $allJobs[] = $job; + } } - $sqldelete = []; + $qb = $this->createQueryBuilder('run'); + $delete = $qb->delete(); if($maxage == NULL) { foreach ($allJobs as $key=>$job) { $jobData = $job->getData(); if(isset($jobData['retention']) && in_array($key, $jobids)) { - $sqldelete[] = '( job_id = :job' . $key . ' AND timestamp < :timestamp' . $key . ')'; - $params[':job' . $key] = $key; - $params[':timestamp' . $key] = time() - ($jobData['retention'] * 24 * 60 * 60); + $delete = $delete + ->orWhere( + $qb->expr()->andX( + $qb->expr()->eq('run.job', ':job' . $key), + $qb->expr()->lt('run.timestamp', ':timestamp' . $key) + ) + ) + ->setParameter(':job' . $key, $job) + ->setParameter(':timestamp' . $key, time() - ($jobData['retention'] * 24 * 60 * 60)); } } } else { - $sqljobids = ''; if(!empty($jobids)) { - $jobidsql = []; - foreach($jobids as $key=>$jobid){ - $jobidsql[] = ':job' . $key; - $params[':job' . $key] = $jobid; + $jobexpr = $qb->expr()->orX(); + foreach($allJobs as $key=>$job){ + $jobexpr->add('run.job = :job' . $key); + $delete = $delete->setParameter(':job' . $key, $job); } - $sqljobids = ' AND job_id in (' . implode(',', $jobidsql) . ')'; + $delete = $delete + ->where($jobexpr); } - $params[':timestamp'] = time() - ($maxage * 24 * 60 * 60); - $sqldelete[] = 'timestamp < :timestamp' . $sqljobids; - } - $sql = 'DELETE FROM run WHERE ' . implode(' OR ', $sqldelete); - try { - return $this->getEntityManager()->getConnection()->prepare($sql)->executeStatement($params); - } catch(Exception $exception) { - throw $exception; + $delete = $delete + ->andWhere('run.timestamp < :timestamp') + ->setParameter(':timestamp', time() - ($maxage * 24 * 60 * 60)); } + return $delete->getQuery()->execute(); } } \ No newline at end of file