ILIAS  release_8 Revision v8.24
class.ilAtomQueryBase.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
27abstract class ilAtomQueryBase
28{
29 protected const ITERATIONS = 10;
33 protected static array $available_isolations_levels = array(
38 );
42 protected static array $possible_anomalies = array(
47 );
51 protected static array $anomalies_map = array(
57 ),
61 ),
64 ),
66 );
71 protected array $tables = array();
75 protected $query;
76 protected \ilDBInterface $ilDBInstance;
77
83 {
84 static::checkIsolationLevel($isolation_level);
85 $this->ilDBInstance = $ilDBInstance;
86 $this->isolation_level = $isolation_level;
87 }
88
89 //
90 //
91 //
95 public function getRisks(): array
96 {
97 return static::getPossibleAnomalies($this->getIsolationLevel());
98 }
99
106 public function addTableLock(string $table_name): ilTableLockInterface
107 {
108 $ilTableLock = new ilTableLock($table_name, $this->ilDBInstance);
109 $ilTableLock->setLockLevel($this->getDeterminedLockLevel());
110 $this->tables[] = $ilTableLock;
111
112 return $ilTableLock;
113 }
114
115 protected function getDeterminedLockLevel(): int
116 {
118 }
119
135 public function addQueryCallable(callable $query): void
136 {
137 if ($this->query) {
139 }
140 if (!$this->checkCallable($query)) {
142 }
143 $this->query = $query;
144 }
145
149 public function replaceQueryCallable(callable $query): void
150 {
151 if (!$this->checkCallable($query)) {
153 }
154 $this->query = $query;
155 }
156
161 abstract public function run(): void;
162
163 public function getIsolationLevel(): int
164 {
166 }
167
171 public static function isThereRiskThat(int $isolation_level, int $anomaly): bool
172 {
173 static::checkIsolationLevel($isolation_level);
174 static::checkAnomaly($anomaly);
175
176 return in_array($anomaly, static::getPossibleAnomalies($isolation_level));
177 }
178
182 public static function getPossibleAnomalies(int $isolation_level): array
183 {
184 static::checkIsolationLevel($isolation_level);
185
186 return self::$anomalies_map[$isolation_level];
187 }
188
192 public static function checkIsolationLevel(int $isolation_level): void
193 {
194 // The following Isolations are currently not supported
195 if (in_array($isolation_level, array(
199 ))) {
201 }
202 // Check if a available Isolation level is selected
203 if (!in_array($isolation_level, self::$available_isolations_levels)) {
205 }
206 }
207
211 public static function checkAnomaly(int $anomaly): void
212 {
213 if (!in_array($anomaly, self::$possible_anomalies)) {
215 }
216 }
217
221 protected function checkQueries(): void
222 {
223 if (!($this->query instanceof \Traversable) && (is_array($this->query) && 0 === count($this->query))) {
225 }
226
227 foreach ($this->query as $query) {
228 if (!$this->checkCallable($query)) {
230 }
231 }
232 }
233
234 public function checkCallable(callable $query): bool
235 {
236 if (!is_callable($query)) {
237 return false; // Won't be triggered sidn type-hinting already checks this
238 }
239 if (is_array($query)) {
240 return false;
241 }
242 if (is_string($query)) {
243 return false;
244 }
245
246 $is_a_closure = ($query instanceof Closure);
247 if (!$is_a_closure) {
248 $ref = new ReflectionClass($query);
249 foreach ($ref->getMethods() as $method) {
250 if ($method->getName() === '__invoke') {
251 return true;
252 }
253 }
254
255 return false;
256 }
257 if ($is_a_closure) {
258 $ref = new ReflectionFunction($query);
259 $parameters = $ref->getParameters();
260 if (count($parameters) !== 1) {
261 return false;
262 }
263 $reflectionClass = $parameters[0]->getType();
264 return $reflectionClass && $reflectionClass->getName() === ilDBInterface::class;
265 }
266
267 return true;
268 }
269
270 protected function hasWriteLocks(): bool
271 {
272 $has_write_locks = false;
273 foreach ($this->tables as $table) {
274 if ($table->getLockLevel() === ilAtomQuery::LOCK_WRITE) {
275 $has_write_locks = true;
276 }
277 }
278
279 return $has_write_locks;
280 }
281
285 protected function runQueries(): void
286 {
288 $query($this->ilDBInstance);
289 }
290
294 protected function checkBeforeRun(): void
295 {
296 $this->checkQueries();
297
300 }
301
302 if (count($this->tables) === 0) {
304 }
305 }
306}
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addTableLock(string $table_name)
Add table-names which are influenced by your queries, MyISAm has to lock those tables.
static getPossibleAnomalies(int $isolation_level)
static checkAnomaly(int $anomaly)
__construct(ilDBInterface $ilDBInstance, int $isolation_level=ilAtomQuery::ISOLATION_SERIALIZABLE)
ilAtomQuery constructor.
static array $possible_anomalies
static array $available_isolations_levels
static checkIsolationLevel(int $isolation_level)
static isThereRiskThat(int $isolation_level, int $anomaly)
addQueryCallable(callable $query)
All action on the database during this isolation has to be passed as Callable to ilAtomQuery.
checkCallable(callable $query)
run()
Fire your Queries.
replaceQueryCallable(callable $query)
ilDBInterface $ilDBInstance
static array $anomalies_map
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface ilDBInterface.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...