ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilAtomQueryBase.php
Go to the documentation of this file.
1<?php
2
11abstract class ilAtomQueryBase implements ilAtomQuery
12{
13 const ITERATIONS = 10;
17 protected static $available_isolations_levels = array(
22 );
26 protected static $possible_anomalies = array(
31 );
35 protected static $anomalies_map = array(
41 ),
45 ),
48 ),
50 );
58 protected $tables = array();
62 protected $query = null;
66 protected $ilDBInstance;
67
68
76 {
77 static::checkIsolationLevel($isolation_level);
78 $this->ilDBInstance = $ilDBInstance;
79 $this->isolation_level = $isolation_level;
80 }
81
82 //
83 //
84 //
88 public function getRisks()
89 {
90 return static::getPossibleAnomalies($this->getIsolationLevel());
91 }
92
93
105 public function addTableLock($table_name)
106 {
107 $ilTableLock = new ilTableLock($table_name, $this->ilDBInstance);
108 $ilTableLock->setLockLevel($this->getDeterminedLockLevel());
109 $this->tables[] = $ilTableLock;
110
111 return $ilTableLock;
112 }
113
114
118 protected function getDeterminedLockLevel()
119 {
120 switch ($this->getIsolationLevel()) {
123 // Currently only ISOLATION_SERIALIZABLE is allowed
124 }
125
127 }
128
129
150 public function addQueryCallable(callable $query)
151 {
152 if ($this->query) {
154 }
155 if (!$this->checkCallable($query)) {
157 }
158 $this->query = $query;
159 }
160
161
166 public function replaceQueryCallable(callable $query)
167 {
168 if (!$this->checkCallable($query)) {
170 }
171 $this->query = $query;
172 }
173
174
180 abstract public function run();
181 //
182 //
183 //
187 public function getIsolationLevel()
188 {
190 }
191
192
199 public static function isThereRiskThat($isolation_level, $anomaly)
200 {
201 static::checkIsolationLevel($isolation_level);
202 static::checkAnomaly($anomaly);
203
204 return in_array($anomaly, static::getPossibleAnomalies($isolation_level));
205 }
206
207
213 {
214 static::checkIsolationLevel($isolation_level);
215
216 return self::$anomalies_map[$isolation_level];
217 }
218
219
224 public static function checkIsolationLevel($isolation_level)
225 {
226 // The following Isolations are currently not supported
227 if (in_array($isolation_level, array(
231 ))) {
233 }
234 // Check if a available Isolation level is selected
235 if (!in_array($isolation_level, self::$available_isolations_levels)) {
237 }
238 }
239
240
245 public static function checkAnomaly($anomalie)
246 {
247 if (!in_array($anomalie, self::$possible_anomalies)) {
249 }
250 }
251
252
256 protected function checkQueries()
257 {
258 if ((is_array($this->query) && 0 === count($this->query)) && !($this->query instanceof \Traversable)) {
260 }
261
262 foreach ($this->query as $query) {
263 if (!$this->checkCallable($query)) {
265 }
266 }
267 }
268
269
274 public function checkCallable(callable $query)
275 {
276 if (!is_callable($query)) {
277 return false; // Won't be triggered sidn type-hinting already checks this
278 }
279 if (is_array($query)) {
280 return false;
281 }
282 if (is_string($query)) {
283 return false;
284 }
285 $classname = get_class($query);
286 $is_a_closure = $classname == 'Closure';
287 if (!$is_a_closure) {
288 $ref = new ReflectionClass($query);
289 foreach ($ref->getMethods() as $method) {
290 if ($method->getName() == '__invoke') {
291 return true;
292 }
293 }
294
295 return false;
296 }
297 if ($is_a_closure) {
298 $ref = new ReflectionFunction($query);
299 $parameters = $ref->getParameters();
300 if (count($parameters) !== 1) {
301 return false;
302 }
303 $reflectionClass = $parameters[0]->getClass();
304 if ($reflectionClass && $reflectionClass->getName() == 'ilDBInterface') {
305 return true;
306 }
307
308 return false;
309 }
310
311 return true;
312 }
313
314
318 protected function hasWriteLocks()
319 {
320 $has_write_locks = false;
324 foreach ($this->tables as $table) {
325 if ($table->getLockLevel() == ilAtomQuery::LOCK_WRITE) {
326 $has_write_locks = true;
327 }
328 }
329
330 return $has_write_locks;
331 }
332
333
337 protected function runQueries()
338 {
340 $query($this->ilDBInstance);
341 }
342
343
347 protected function checkBeforeRun()
348 {
349 $this->checkQueries();
350
351 if ($this->hasWriteLocks() && $this->getIsolationLevel() != ilAtomQuery::ISOLATION_SERIALIZABLE) {
353 }
354
355 if (count($this->tables) === 0) {
357 }
358 }
359}
An exception for terminatinating execution or to throw for unit testing.
Class ilAtomQuery.
addTableLock($table_name)
Add table-names which are influenced by your queries, MyISAm has to lock those tables.
static getPossibleAnomalies($isolation_level)
__construct(ilDBInterface $ilDBInstance, $isolation_level=ilAtomQuery::ISOLATION_SERIALIZABLE)
ilAtomQuery constructor.
static checkAnomaly($anomalie)
static checkIsolationLevel($isolation_level)
addQueryCallable(callable $query)
All action on the database during this isolation has to be passed as Callable to ilAtomQuery.
checkCallable(callable $query)
static isThereRiskThat($isolation_level, $anomaly)
run()
Fire your Queries.
replaceQueryCallable(callable $query)
Class ilAtomQueryException.
Class ilTableLock.
Interface ilAtomQuery.
Interface ilDBInterface.