ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilAtomQueryBase.php
Go to the documentation of this file.
1<?php
2require_once('./Services/Database/interfaces/interface.ilAtomQuery.php');
3require_once('./Services/Database/classes/Atom/class.ilTableLock.php');
4
13abstract class ilAtomQueryBase implements ilAtomQuery
14{
15 const ITERATIONS = 10;
19 protected static $available_isolations_levels = array(
24 );
28 protected static $possible_anomalies = array(
33 );
37 protected static $anomalies_map = array(
43 ),
47 ),
50 ),
52 );
60 protected $tables = array();
64 protected $query = null;
68 protected $ilDBInstance;
69
70
78 {
79 static::checkIsolationLevel($isolation_level);
80 $this->ilDBInstance = $ilDBInstance;
81 $this->isolation_level = $isolation_level;
82 }
83
84 //
85 //
86 //
90 public function getRisks()
91 {
92 return static::getPossibleAnomalies($this->getIsolationLevel());
93 }
94
95
107 public function addTableLock($table_name)
108 {
109 $ilTableLock = new ilTableLock($table_name, $this->ilDBInstance);
110 $ilTableLock->setLockLevel($this->getDeterminedLockLevel());
111 $this->tables[] = $ilTableLock;
112
113 return $ilTableLock;
114 }
115
116
120 protected function getDeterminedLockLevel()
121 {
122 switch ($this->getIsolationLevel()) {
125 // Currently only ISOLATION_SERIALIZABLE is allowed
126 }
127
129 }
130
131
152 public function addQueryCallable(callable $query)
153 {
154 if ($this->query) {
156 }
157 if (!$this->checkCallable($query)) {
159 }
160 $this->query = $query;
161 }
162
163
168 public function replaceQueryCallable(callable $query)
169 {
170 if (!$this->checkCallable($query)) {
172 }
173 $this->query = $query;
174 }
175
176
182 abstract public function run();
183 //
184 //
185 //
189 public function getIsolationLevel()
190 {
192 }
193
194
201 public static function isThereRiskThat($isolation_level, $anomaly)
202 {
203 static::checkIsolationLevel($isolation_level);
204 static::checkAnomaly($anomaly);
205
206 return in_array($anomaly, static::getPossibleAnomalies($isolation_level));
207 }
208
209
215 {
216 static::checkIsolationLevel($isolation_level);
217
218 return self::$anomalies_map[$isolation_level];
219 }
220
221
226 public static function checkIsolationLevel($isolation_level)
227 {
228 // The following Isolations are currently not supported
229 if (in_array($isolation_level, array(
233 ))) {
235 }
236 // Check if a available Isolation level is selected
237 if (!in_array($isolation_level, self::$available_isolations_levels)) {
239 }
240 }
241
242
247 public static function checkAnomaly($anomalie)
248 {
249 if (!in_array($anomalie, self::$possible_anomalies)) {
251 }
252 }
253
254
258 protected function checkQueries()
259 {
260 if ((is_array($this->query) && 0 === count($this->query))) {
262 }
263 foreach ($this->query as $query) {
264 if (!$this->checkCallable($query)) {
266 }
267 }
268 }
269
270
275 public function checkCallable(callable $query)
276 {
277 if (!is_callable($query)) {
278 return false; // Won't be triggered sidn type-hinting already checks this
279 }
280 if (is_array($query)) {
281 return false;
282 }
283 if (is_string($query)) {
284 return false;
285 }
286 $classname = get_class($query);
287 $is_a_closure = $classname == 'Closure';
288 if (!$is_a_closure) {
289 $ref = new ReflectionClass($query);
290 foreach ($ref->getMethods() as $method) {
291 if ($method->getName() == '__invoke') {
292 return true;
293 }
294 }
295
296 return false;
297 }
298 if ($is_a_closure) {
299 $ref = new ReflectionFunction($query);
300 $parameters = $ref->getParameters();
301 if (count($parameters) !== 1) {
302 return false;
303 }
304 $reflectionClass = $parameters[0]->getClass();
305 if ($reflectionClass && $reflectionClass->getName() == 'ilDBInterface') {
306 return true;
307 }
308
309 return false;
310 }
311
312 return true;
313 }
314
315
319 protected function hasWriteLocks()
320 {
321 $has_write_locks = false;
325 foreach ($this->tables as $table) {
326 if ($table->getLockLevel() == ilAtomQuery::LOCK_WRITE) {
327 $has_write_locks = true;
328 }
329 }
330
331 return $has_write_locks;
332 }
333
334
338 protected function runQueries()
339 {
341 $query($this->ilDBInstance);
342 }
343
344
348 protected function checkBeforeRun()
349 {
350 $this->checkQueries();
351
352 if ($this->hasWriteLocks() && $this->getIsolationLevel() != ilAtomQuery::ISOLATION_SERIALIZABLE) {
354 }
355
356 if (count($this->tables) === 0) {
358 }
359 }
360}
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.
if(empty($password)) $table
Definition: pwgen.php:24