diff --git a/core/Command/Background/Queue/Delete.php b/core/Command/Background/Queue/Delete.php
new file mode 100644
index 000000000000..89a80493a774
--- /dev/null
+++ b/core/Command/Background/Queue/Delete.php
@@ -0,0 +1,65 @@
+
+ *
+ * @copyright Copyright (c) 2018, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OC\Core\Command\Background\Queue;
+
+use OCP\BackgroundJob\IJobList;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Delete extends Command {
+
+ /** @var \OCP\BackgroundJob\IJobList */
+ private $jobList;
+
+ public function __construct(IJobList $jobList) {
+ $this->jobList = $jobList;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('background:queue:delete')
+ ->setDescription('Delete a job from the queue')
+ ->addArgument('id', InputArgument::REQUIRED, 'id of the job to be deleted');
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return int
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $id = $input->getArgument('id');
+
+ $job = $this->jobList->getById($id);
+ if ($job === null) {
+ $output->writeln("Job with id <$id> is not known.");
+ return 1;
+ }
+
+ $this->jobList->removeById($id);
+ $output->writeln('Job has been deleted.');
+ return 0;
+ }
+}
diff --git a/core/Command/Background/Queue/Status.php b/core/Command/Background/Queue/Status.php
new file mode 100644
index 000000000000..1a2f7f572b05
--- /dev/null
+++ b/core/Command/Background/Queue/Status.php
@@ -0,0 +1,60 @@
+
+ *
+ * @copyright Copyright (c) 2018, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OC\Core\Command\Background\Queue;
+
+use OCP\BackgroundJob\IJob;
+use OCP\BackgroundJob\IJobList;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Status extends Command {
+
+ /** @var \OCP\BackgroundJob\IJobList */
+ private $jobList;
+
+ public function __construct(IJobList $jobList) {
+ $this->jobList = $jobList;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('background:queue:status')
+ ->setDescription('List queue status');
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return void
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $t = new Table($output);
+ $t->setHeaders(['Id', 'Job', 'Last run', 'Job Arguments']);
+ $this->jobList->listJobs(function (IJob $job) use ($t) {
+ $t->addRow([$job->getId(), \get_class($job), \date('c', $job->getLastRun()), $job->getArgument()]);
+ });
+ $t->render();
+ }
+}
diff --git a/core/register_command.php b/core/register_command.php
index 7a40e12b89aa..d13bf529bbde 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -72,6 +72,8 @@
$application->add(new OC\Core\Command\Background\Cron(\OC::$server->getConfig()));
$application->add(new OC\Core\Command\Background\WebCron(\OC::$server->getConfig()));
$application->add(new OC\Core\Command\Background\Ajax(\OC::$server->getConfig()));
+ $application->add(new OC\Core\Command\Background\Queue\Status(\OC::$server->getJobList()));
+ $application->add(new OC\Core\Command\Background\Queue\Delete(\OC::$server->getJobList()));
$application->add(new OC\Core\Command\Config\App\DeleteConfig(\OC::$server->getConfig()));
$application->add(new OC\Core\Command\Config\App\GetConfig(\OC::$server->getConfig()));
diff --git a/db_structure.xml b/db_structure.xml
index e65060897583..f6f07ae002b3 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -724,7 +724,6 @@
false
-
last_checked
diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php
index 23f7bbe14e85..1a57d4b07282 100644
--- a/lib/private/BackgroundJob/JobList.php
+++ b/lib/private/BackgroundJob/JobList.php
@@ -108,7 +108,7 @@ public function remove($job, $argument = null) {
/**
* @param int $id
*/
- protected function removeById($id) {
+ public function removeById($id) {
$query = $this->connection->getQueryBuilder();
$query->delete('jobs')
->where($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
@@ -305,9 +305,7 @@ public function getLastJob() {
}
/**
- * set the lastRun of $job to now
- *
- * @param IJob $job
+ * @inheritdoc
*/
public function setLastRun($job) {
$query = $this->connection->getQueryBuilder();
@@ -324,4 +322,24 @@ public function setExecutionTime($job, $timeTaken) {
->where($query->expr()->eq('id', $query->createNamedParameter($job->getId(), IQueryBuilder::PARAM_INT)));
$query->execute();
}
+
+ /**
+ * @inheritdoc
+ */
+ public function listJobs(\Closure $callback) {
+ $query = $this->connection->getQueryBuilder();
+ $query->select('*')
+ ->from('jobs');
+ $result = $query->execute();
+
+ while ($row = $result->fetch()) {
+ $job = $this->buildJob($row);
+ if ($job) {
+ if ($callback($job) === false) {
+ break;
+ }
+ }
+ }
+ $result->closeCursor();
+ }
}
diff --git a/lib/public/BackgroundJob/IJobList.php b/lib/public/BackgroundJob/IJobList.php
index 0120fb0ecbc7..7cf6431b5832 100644
--- a/lib/public/BackgroundJob/IJobList.php
+++ b/lib/public/BackgroundJob/IJobList.php
@@ -127,4 +127,19 @@ public function setLastRun($job);
* @since 10.0.0
*/
public function setExecutionTime($job, $timeTaken);
+
+ /**
+ * iterate over all jobs in the queue
+ *
+ * @return void
+ * @since 10.0.9
+ */
+ public function listJobs(\Closure $callback);
+
+ /**
+ * remove a specific job by id
+ * @return void
+ * @since 10.0.9
+ */
+ public function removeById($id);
}
diff --git a/tests/Core/Command/Background/Queue/DeleteTest.php b/tests/Core/Command/Background/Queue/DeleteTest.php
new file mode 100644
index 000000000000..40c18ccdd6b4
--- /dev/null
+++ b/tests/Core/Command/Background/Queue/DeleteTest.php
@@ -0,0 +1,72 @@
+
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace Tests\Core\Command\Background\Queue;
+
+use OC\Core\Command\Background\Queue\Delete;
+use OCP\BackgroundJob\IJobList;
+use Symfony\Component\Console\Tester\CommandTester;
+use Test\TestCase;
+
+/**
+ * Class DeleteTest
+ *
+ * @group DB
+ */
+class DeleteTest extends TestCase {
+
+ /** @var CommandTester */
+ private $commandTester;
+ /** @var IJobList */
+ private $jobList;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->jobList = $this->createMock(IJobList::class);
+ $this->jobList->expects($this->any())->method('getById')
+ ->willReturnCallback(function ($id) {
+ return ($id !== '666') ? true : null;
+ });
+
+ $command = new Delete($this->jobList);
+ $this->commandTester = new CommandTester($command);
+ }
+
+ /**
+ * @dataProvider providesJobIds
+ * @param $jobId
+ * @param $expectedOutput
+ */
+ public function testCommandInput($jobId, $expectedOutput) {
+ $input = ['id' => $jobId];
+ $this->commandTester->execute($input);
+ $output = $this->commandTester->getDisplay();
+ $this->assertContains($expectedOutput, $output);
+ }
+
+ public function providesJobIds() {
+ return [
+ ['666', 'Job with id <666> is not known.'],
+ ['1', 'Job has been deleted.'],
+ ];
+ }
+}
diff --git a/tests/Core/Command/Background/Queue/StatusTest.php b/tests/Core/Command/Background/Queue/StatusTest.php
new file mode 100644
index 000000000000..19015c041197
--- /dev/null
+++ b/tests/Core/Command/Background/Queue/StatusTest.php
@@ -0,0 +1,72 @@
+
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace Tests\Core\Command\Background\Queue;
+
+use OC\BackgroundJob\Legacy\RegularJob;
+use OC\Core\Command\Background\Queue\Status;
+use OCP\BackgroundJob\IJobList;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Tester\CommandTester;
+use Test\TestCase;
+
+/**
+ * Class StatusTest
+ *
+ * @group DB
+ */
+class StatusTest extends TestCase {
+
+ /** @var CommandTester */
+ private $commandTester;
+ /** @var IJobList */
+ private $jobList;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->jobList = $this->createMock(IJobList::class);
+ $this->jobList->expects($this->any())->method('listJobs')
+ ->willReturnCallback(function (\Closure $callBack) {
+ $job = new RegularJob();
+ $job->setId(666);
+ $callBack($job);
+ });
+
+ $command = new Status($this->jobList);
+ $command->setApplication(new Application());
+ $this->commandTester = new CommandTester($command);
+ }
+
+ public function testCommandInput() {
+ $this->commandTester->execute([]);
+ $output = $this->commandTester->getDisplay();
+ $expected = <<assertContains($expected, $output);
+ }
+}