commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-new / civicrm / Civi / Core / Transaction / Frame.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 namespace Civi\Core\Transaction;
29
30 /**
31 * A "frame" is a layer in a series of nested transactions. Generally,
32 * the outermost frame is a normal SQL transaction (BEGIN/ROLLBACK/COMMIT)
33 * and any nested frames are SQL savepoints (SAVEPOINT foo/ROLLBACK TO SAVEPOINT).
34 *
35 * @package Civi
36 * @copyright CiviCRM LLC (c) 2004-2015
37 */
38 class Frame {
39
40 const F_NEW = 0, F_ACTIVE = 1, F_DONE = 2, F_FORCED = 3;
41
42 /**
43 * @var \CRM_Core_DAO
44 */
45 private $dao;
46
47 /**
48 * @var string|null e.g. "BEGIN" or "SAVEPOINT foo"
49 */
50 private $beginStmt;
51
52 /**
53 * @var string|null e.g. "COMMIT"
54 */
55 private $commitStmt;
56
57 /**
58 * @var string|null e.g. "ROLLBACK" or "ROLLBACK TO SAVEPOINT foo"
59 */
60 private $rollbackStmt;
61
62 /**
63 * @var int
64 */
65 private $refCount = 0;
66 private $callbacks;
67 private $doCommit = TRUE;
68
69 /**
70 * @var int
71 */
72 private $state = self::F_NEW;
73
74 /**
75 * @param \CRM_Core_DAO $dao
76 * @param string|null $beginStmt e.g. "BEGIN" or "SAVEPOINT foo"
77 * @param string|null $commitStmt e.g. "COMMIT"
78 * @param string|null $rollbackStmt e.g. "ROLLBACK" or "ROLLBACK TO SAVEPOINT foo"
79 */
80 public function __construct($dao, $beginStmt, $commitStmt, $rollbackStmt) {
81 $this->dao = $dao;
82 $this->beginStmt = $beginStmt;
83 $this->commitStmt = $commitStmt;
84 $this->rollbackStmt = $rollbackStmt;
85
86 $this->callbacks = array(
87 \CRM_Core_Transaction::PHASE_PRE_COMMIT => array(),
88 \CRM_Core_Transaction::PHASE_POST_COMMIT => array(),
89 \CRM_Core_Transaction::PHASE_PRE_ROLLBACK => array(),
90 \CRM_Core_Transaction::PHASE_POST_ROLLBACK => array(),
91 );
92 }
93
94 public function inc() {
95 $this->refCount++;
96 }
97
98 public function dec() {
99 $this->refCount--;
100 }
101
102 /**
103 * @return bool
104 */
105 public function isEmpty() {
106 return ($this->refCount == 0);
107 }
108
109 /**
110 * @return bool
111 */
112 public function isRollbackOnly() {
113 return !$this->doCommit;
114 }
115
116 public function setRollbackOnly() {
117 $this->doCommit = FALSE;
118 }
119
120 public function begin() {
121 assert('$this->state === self::F_NEW');
122 $this->state = self::F_ACTIVE;
123 if ($this->beginStmt) {
124 $this->dao->query($this->beginStmt);
125 }
126 }
127
128 /**
129 * @param int $newState
130 * @void
131 */
132 public function finish($newState = self::F_DONE) {
133 if ($this->state == self::F_FORCED) {
134 return;
135 }
136 assert('$this->state === self::F_ACTIVE');
137 $this->state = $newState;
138
139 if ($this->doCommit) {
140 $this->invokeCallbacks(\CRM_Core_Transaction::PHASE_PRE_COMMIT);
141 if ($this->commitStmt) {
142 $this->dao->query($this->commitStmt);
143 }
144 $this->invokeCallbacks(\CRM_Core_Transaction::PHASE_POST_COMMIT);
145 }
146 else {
147 $this->invokeCallbacks(\CRM_Core_Transaction::PHASE_PRE_ROLLBACK);
148 if ($this->rollbackStmt) {
149 $this->dao->query($this->rollbackStmt);
150 }
151 $this->invokeCallbacks(\CRM_Core_Transaction::PHASE_POST_ROLLBACK);
152 }
153 }
154
155 public function forceRollback() {
156 $this->setRollbackOnly();
157 $this->finish(self::F_FORCED);
158 }
159
160 /**
161 * Add a transaction callback.
162 *
163 * Pre-condition: isActive()
164 *
165 * @param int $phase
166 * A constant; one of: self::PHASE_{PRE,POST}_{COMMIT,ROLLBACK}.
167 * @param mixed $callback
168 * A PHP callback.
169 * @param array|NULL $params Optional values to pass to callback.
170 * See php manual call_user_func_array for details.
171 * @param null $id
172 */
173 public function addCallback($phase, $callback, $params = NULL, $id = NULL) {
174 if ($id) {
175 $this->callbacks[$phase][$id] = array(
176 'callback' => $callback,
177 'parameters' => (is_array($params) ? $params : array($params)),
178 );
179 }
180 else {
181 $this->callbacks[$phase][] = array(
182 'callback' => $callback,
183 'parameters' => (is_array($params) ? $params : array($params)),
184 );
185 }
186 }
187
188 /**
189 * @param int $phase
190 */
191 public function invokeCallbacks($phase) {
192 if (is_array($this->callbacks[$phase])) {
193 foreach ($this->callbacks[$phase] as $cb) {
194 call_user_func_array($cb['callback'], $cb['parameters']);
195 }
196 }
197 }
198
199 }