joblist.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /**
  3. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  4. * @author Morris Jobke <hey@morrisjobke.de>
  5. * @author Robin Appelman <icewind@owncloud.com>
  6. * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
  7. * @author Thomas Müller <thomas.mueller@tmit.eu>
  8. *
  9. * @copyright Copyright (c) 2015, ownCloud, Inc.
  10. * @license AGPL-3.0
  11. *
  12. * This code is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Affero General Public License, version 3,
  14. * as published by the Free Software Foundation.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License, version 3,
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>
  23. *
  24. */
  25. namespace OC\BackgroundJob;
  26. use OCP\BackgroundJob\IJobList;
  27. class JobList implements IJobList {
  28. /**
  29. * @var \OCP\IDBConnection
  30. */
  31. private $conn;
  32. /**
  33. * @var \OCP\IConfig $config
  34. */
  35. private $config;
  36. /**
  37. * @param \OCP\IDBConnection $conn
  38. * @param \OCP\IConfig $config
  39. */
  40. public function __construct($conn, $config) {
  41. $this->conn = $conn;
  42. $this->config = $config;
  43. }
  44. /**
  45. * @param Job|string $job
  46. * @param mixed $argument
  47. */
  48. public function add($job, $argument = null) {
  49. if (!$this->has($job, $argument)) {
  50. if ($job instanceof Job) {
  51. $class = get_class($job);
  52. } else {
  53. $class = $job;
  54. }
  55. $argument = json_encode($argument);
  56. if (strlen($argument) > 4000) {
  57. throw new \InvalidArgumentException('Background job arguments can\'t exceed 4000 characters (json encoded)');
  58. }
  59. $query = $this->conn->prepare('INSERT INTO `*PREFIX*jobs`(`class`, `argument`, `last_run`) VALUES(?, ?, 0)');
  60. $query->execute(array($class, $argument));
  61. }
  62. }
  63. /**
  64. * @param Job|string $job
  65. * @param mixed $argument
  66. */
  67. public function remove($job, $argument = null) {
  68. if ($job instanceof Job) {
  69. $class = get_class($job);
  70. } else {
  71. $class = $job;
  72. }
  73. if (!is_null($argument)) {
  74. $argument = json_encode($argument);
  75. $query = $this->conn->prepare('DELETE FROM `*PREFIX*jobs` WHERE `class` = ? AND `argument` = ?');
  76. $query->execute(array($class, $argument));
  77. } else {
  78. $query = $this->conn->prepare('DELETE FROM `*PREFIX*jobs` WHERE `class` = ?');
  79. $query->execute(array($class));
  80. }
  81. }
  82. /**
  83. * check if a job is in the list
  84. *
  85. * @param Job|string $job
  86. * @param mixed $argument
  87. * @return bool
  88. */
  89. public function has($job, $argument) {
  90. if ($job instanceof Job) {
  91. $class = get_class($job);
  92. } else {
  93. $class = $job;
  94. }
  95. $argument = json_encode($argument);
  96. $query = $this->conn->prepare('SELECT `id` FROM `*PREFIX*jobs` WHERE `class` = ? AND `argument` = ?');
  97. $query->execute(array($class, $argument));
  98. return (bool)$query->fetch();
  99. }
  100. /**
  101. * get all jobs in the list
  102. *
  103. * @return Job[]
  104. */
  105. public function getAll() {
  106. $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs`');
  107. $query->execute();
  108. $jobs = array();
  109. while ($row = $query->fetch()) {
  110. $job = $this->buildJob($row);
  111. if ($job) {
  112. $jobs[] = $job;
  113. }
  114. }
  115. return $jobs;
  116. }
  117. /**
  118. * get the next job in the list
  119. *
  120. * @return Job
  121. */
  122. public function getNext() {
  123. $lastId = $this->getLastJob();
  124. $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` WHERE `id` > ? ORDER BY `id` ASC', 1);
  125. $query->execute(array($lastId));
  126. if ($row = $query->fetch()) {
  127. return $this->buildJob($row);
  128. } else {
  129. //begin at the start of the queue
  130. $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` ORDER BY `id` ASC', 1);
  131. $query->execute();
  132. if ($row = $query->fetch()) {
  133. return $this->buildJob($row);
  134. } else {
  135. return null; //empty job list
  136. }
  137. }
  138. }
  139. /**
  140. * @param int $id
  141. * @return Job|null
  142. */
  143. public function getById($id) {
  144. $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` WHERE `id` = ?');
  145. $query->execute(array($id));
  146. if ($row = $query->fetch()) {
  147. return $this->buildJob($row);
  148. } else {
  149. return null;
  150. }
  151. }
  152. /**
  153. * get the job object from a row in the db
  154. *
  155. * @param array $row
  156. * @return Job
  157. */
  158. private function buildJob($row) {
  159. $class = $row['class'];
  160. /**
  161. * @var Job $job
  162. */
  163. if (!class_exists($class)) {
  164. // job from disabled app or old version of an app, no need to do anything
  165. return null;
  166. }
  167. $job = new $class();
  168. $job->setId($row['id']);
  169. $job->setLastRun($row['last_run']);
  170. $job->setArgument(json_decode($row['argument'], true));
  171. return $job;
  172. }
  173. /**
  174. * set the job that was last ran
  175. *
  176. * @param Job $job
  177. */
  178. public function setLastJob($job) {
  179. $this->config->setAppValue('backgroundjob', 'lastjob', $job->getId());
  180. }
  181. /**
  182. * get the id of the last ran job
  183. *
  184. * @return string
  185. */
  186. public function getLastJob() {
  187. return $this->config->getAppValue('backgroundjob', 'lastjob', 0);
  188. }
  189. /**
  190. * set the lastRun of $job to now
  191. *
  192. * @param Job $job
  193. */
  194. public function setLastRun($job) {
  195. $query = $this->conn->prepare('UPDATE `*PREFIX*jobs` SET `last_run` = ? WHERE `id` = ?');
  196. $query->execute(array(time(), $job->getId()));
  197. }
  198. }