ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilDBStepExecutionDB.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
27{
28 public const TABLE_NAME = "il_db_steps";
29
30 public const FIELD_CLASS = "class";
31 public const FIELD_STEP = "step";
32 public const FIELD_STARTED = "started";
33 public const FIELD_FINISHED = "finished";
34 protected $get_now;
35
40 public function __construct(protected ilDBInterface $db, callable $get_now)
41 {
42 $this->get_now = $get_now;
43 }
44
48 public function started(string $class, int $step): void
49 {
50 $this->throwIfClassNameTooLong($class);
51
52 $last_started_step = $this->getLastStartedStep($class);
53 if ($last_started_step >= $step) {
54 throw new \RuntimeException(
55 "The last started step for $class was $last_started_step, which" .
56 " is higher then the step $step started now."
57 );
58 }
59
60 $last_finished_step = $this->getLastFinishedStep($class);
61 if ($last_started_step !== $last_finished_step) {
62 throw new \RuntimeException(
63 "Step $step should be started for $class, but last step $last_started_step " .
64 "has not finished by now."
65 );
66 }
67
68 $this->db->insert(
69 self::TABLE_NAME,
70 [
71 self::FIELD_CLASS => ["text", $class],
72 self::FIELD_STEP => ["integer", $step],
73 self::FIELD_STARTED => ["text", $this->getFormattedNow()]
74 ]
75 );
76 }
77
81 public function finished(string $class, int $step): void
82 {
83 $this->throwIfClassNameTooLong($class);
84
85 $last_started_step = $this->getLastStartedStep($class);
86 if ($last_started_step !== $step) {
87 throw new \RuntimeException(
88 "The step $step for $class is supposed to be finished, but" .
89 " $last_started_step was $step started last."
90 );
91 }
92
93 $this->db->update(
94 self::TABLE_NAME,
95 [
96 self::FIELD_FINISHED => ["text", $this->getFormattedNow()]
97 ],
98 [
99 self::FIELD_CLASS => ["text", $class],
100 self::FIELD_STEP => ["integer", $step]
101 ]
102 );
103 }
104
105 public function getLastStartedStep(string $class): int
106 {
107 $this->throwIfClassNameTooLong($class);
108
109 $res = $this->db->query(
110 "SELECT MAX(" . self::FIELD_STEP . ") AS " . self::FIELD_STEP .
111 " FROM " . self::TABLE_NAME .
112 " WHERE " . self::FIELD_CLASS . " = " . $this->db->quote($class, "text")
113 );
114
115 $row = $this->db->fetchAssoc($res);
116 return (int) ($row[self::FIELD_STEP] ?? 0);
117 }
118
119 public function getLastFinishedStep(string $class): int
120 {
121 $this->throwIfClassNameTooLong($class);
122
123 $res = $this->db->query(
124 "SELECT MAX(" . self::FIELD_STEP . ") AS " . self::FIELD_STEP .
125 " FROM " . self::TABLE_NAME .
126 " WHERE " . self::FIELD_CLASS . " = " . $this->db->quote($class, "text") .
127 " AND " . self::FIELD_FINISHED . " IS NOT NULL"
128 );
129
130 $row = $this->db->fetchAssoc($res);
131 return (int) ($row[self::FIELD_STEP] ?? 0);
132 }
133
134 protected function throwIfClassNameTooLong(string $class): void
135 {
136 if (strlen($class) > 200) {
137 throw new \InvalidArgumentException(
138 "This ilDatabaseUpdateStepExecutionLog only supports class names up to 200 chars."
139 );
140 }
141 }
142
143 protected function getFormattedNow(): string
144 {
145 $now = ($this->get_now)();
146 if (!($now instanceof \DateTime)) {
147 throw new \LogicException(
148 "Expected \$get_now to return a DateTime."
149 );
150 }
151 return $now->format("Y-m-d H:i:s.u");
152 }
153}
This logs the execution of database update steps.
started(string $class, int $step)
__construct(protected ilDBInterface $db, callable $get_now)
finished(string $class, int $step)
getLastStartedStep(string $class)
Returns 0 as "first" step.
getLastFinishedStep(string $class)
Returns 0 as "first" step.
Interface ilDBInterface.
This logs the execution of database update steps.
$res
Definition: ltiservices.php:69