Passed
Push — master ( caa32e...4f267a )
by Jean-Christophe
09:15
created

DatabaseTransactionsTrait   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Test Coverage

Coverage 75%

Importance

Changes 7
Bugs 0 Features 0
Metric Value
wmc 24
eloc 50
c 7
b 0
f 0
dl 0
loc 140
ccs 42
cts 56
cp 0.75
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A commitAll() 0 2 1
A nestable() 0 2 1
A rollBackToLevel() 0 6 3
A callInTransaction() 0 20 5
A rollBackAll() 0 2 1
A rollBack() 0 9 3
A commitToLevel() 0 6 3
A commit() 0 9 3
A beginTransaction() 0 11 3
A inTransaction() 0 2 1
1
<?php
2
3
namespace Ubiquity\db\traits;
4
5
use Ubiquity\exceptions\DBException;
6
use Ubiquity\log\Logger;
7
8
/**
9
 * Manages database transactions.
10
 * Ubiquity\db\traits$DatabaseTransactionsTrait
11
 * This class is part of Ubiquity
12
 *
13
 * @author jcheron <[email protected]>
14
 * @version 1.1.0
15
 * @property \Ubiquity\db\providers\AbstractDbWrapper $wrapperObject
16
 * @property string $dbType
17
 */
18
trait DatabaseTransactionsTrait {
19
	protected $transactionLevel = 0;
20
21 4
	protected function nestable() {
22 4
		return $this->wrapperObject->nestable ();
23
	}
24
25
	/**
26
	 * Initiates a transaction
27
	 *
28
	 * @return boolean true on success or false on failure
29
	 */
30 8
	public function beginTransaction() {
31 8
		if ($this->transactionLevel == 0 || ! $this->nestable ()) {
32 8
			$ret = $this->wrapperObject->beginTransaction ();
33 8
			Logger::info ( 'Transactions', 'Start transaction', 'beginTransaction' );
34 8
			$this->transactionLevel ++;
35 8
			return $ret;
36
		}
37 4
		$this->wrapperObject->savePoint ( $this->transactionLevel );
38 4
		Logger::info ( 'Transactions', 'Savepoint level', 'beginTransaction', $this->transactionLevel );
39 4
		$this->transactionLevel ++;
40 4
		return true;
41
	}
42
43
	/**
44
	 * Commits a transaction
45
	 *
46
	 * @return boolean true on success or false on failure
47
	 */
48 4
	public function commit() {
49 4
		$this->transactionLevel --;
50 4
		if ($this->transactionLevel == 0 || ! $this->nestable ()) {
51 4
			Logger::info ( 'Transactions', 'Commit transaction', 'commit' );
52 4
			return $this->wrapperObject->commit ();
53
		}
54 2
		$this->wrapperObject->releasePoint ( $this->transactionLevel );
55 2
		Logger::info ( 'Transactions', 'Release savepoint level', 'commit', $this->transactionLevel );
56 2
		return true;
57
	}
58
59
	/**
60
	 * Commits nested transactions up to level $transactionLevel
61
	 *
62
	 * @param int $transactionLevel
63
	 * @return boolean true on success or false on failure
64
	 */
65 1
	public function commitToLevel($transactionLevel) {
66 1
		$res = true;
67 1
		while ( $res && $this->transactionLevel > $transactionLevel ) {
68 1
			$res = $this->commit ();
69
		}
70 1
		return $res;
71
	}
72
73
	/**
74
	 * Commits all nested transactions (up to level 0)
75
	 *
76
	 * @return boolean true on success or false on failure
77
	 */
78 1
	public function commitAll() {
79 1
		return $this->commitToLevel ( 0 );
80
	}
81
82
	/**
83
	 * Rolls back a transaction
84
	 *
85
	 * @return boolean true on success or false on failure
86
	 */
87 3
	public function rollBack() {
88 3
		$this->transactionLevel --;
89 3
		if ($this->transactionLevel == 0 || ! $this->nestable ()) {
90 3
			Logger::info ( 'Transactions', 'Rollback transaction', 'rollBack' );
91 3
			return $this->wrapperObject->rollBack ();
92
		}
93 2
		$this->wrapperObject->rollbackPoint ( $this->transactionLevel );
94 2
		Logger::info ( 'Transactions', 'Rollback to savepoint level', 'rollBack', $this->transactionLevel );
95 2
		return true;
96
	}
97
98
	/**
99
	 * Rolls back nested transactions up to level $transactionLevel
100
	 *
101
	 * @param int $transactionLevel
102
	 * @return boolean true on success or false on failure
103
	 */
104 1
	public function rollBackToLevel($transactionLevel) {
105 1
		$res = true;
106 1
		while ( $res && $this->transactionLevel > $transactionLevel ) {
107 1
			$res = $this->rollBack ();
108
		}
109 1
		return $res;
110
	}
111
112
	/**
113
	 * Rolls back all nested transactions (up to level 0)
114
	 *
115
	 * @return boolean true on success or false on failure
116
	 */
117 1
	public function rollBackAll() {
118 1
		return $this->rollBackToLevel ( 0 );
119
	}
120
121
	/**
122
	 * Checks if inside a transaction
123
	 *
124
	 * @return boolean
125
	 */
126
	public function inTransaction() {
127
		return $this->wrapperObject->inTransaction ();
128
	}
129
130
	/**
131
	 * Call a callback with an array of parameters in a transaction
132
	 *
133
	 * @param callable $callback
134
	 * @param mixed ...$parameters
135
	 * @throws \Exception
136
	 * @return mixed
137
	 */
138
	public function callInTransaction($callback, ...$parameters) {
139
		if ($this->beginTransaction ()) {
140
			try {
141
				$ret = call_user_func_array ( $callback, $parameters );
142
			} catch ( \Exception $e ) {
143
				$this->wrapperObject->rollBack ();
144
				throw $e;
145
			}
146
147
			if ($ret) {
148
				if (! $this->commit ()) {
149
					throw new DBException ( 'Transaction was not committed.' );
150
				}
151
			} else {
152
				$this->rollBack ();
153
			}
154
155
			return $ret;
156
		}
157
		throw new DBException ( 'Transaction was not started.' );
158
	}
159
}
160