17 require_once SQ_CORE_PACKAGE_PATH.
'/system/locking/locking_method/locking_method.inc';
53 parent::__construct($assetid);
84 public static function acquireLock($lockid, $source_lockid=
'', $expires=0)
86 $current_lock = $GLOBALS[
'SQ_SYSTEM']->getLockInfo($lockid);
89 if (!empty($current_lock)) {
92 if ($current_lock[
'userid'] == $GLOBALS[
'SQ_SYSTEM']->currentUserid()) {
93 return self::updateLock($lockid, $expires);
95 $user = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($current_lock[
'userid']);
96 throw new Exception(
'Lock already held by "'.$user->name.
'"');
101 if (empty($source_lockid)) $source_lockid = $lockid;
103 if (!is_null($expires)) {
104 $expires = (empty($expires)) ? (time() + SQ_CONF_LOCK_LENGTH) : (
int) $expires;
105 $expires = ts_iso8601($expires);
108 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
109 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
111 $sql =
'INSERT INTO sq_lock
112 (lockid, source_lockid, userid, expires)
114 (:lockid, :source_lockid, :userid, :expires)';
123 }
catch (Exception $e) {
126 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
127 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
128 throw new Exception(
'DB error: '.$e->getMessage());
131 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
132 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
160 $current_lock = self::getLockInfo($lockid);
164 if (empty($current_lock) || empty($current_lock[
'expires'])) {
168 if (!is_null($expires)) {
169 $expires = (!$expires) ? (time() + SQ_CONF_LOCK_LENGTH) : (
int) $expires;
170 $expires = ts_iso8601($expires);
173 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
174 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
176 $sql =
'UPDATE sq_lock
177 SET expires = :expires
178 WHERE source_lockid = :source_lockid';
185 }
catch (Exception $e) {
187 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
188 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
189 throw new Exception(
'DB error: '.$e->getMessage());
192 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
193 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
213 $current_lock = self::getLockInfo($lockid, FALSE, FALSE);
214 if (empty($current_lock))
return TRUE;
216 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
217 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
219 $sql =
'DELETE FROM sq_lock
220 WHERE source_lockid = :source_lockid';
226 }
catch (Exception $e) {
229 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
230 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
231 throw new Exception(
'DB error: '.$e->getMessage());
234 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
236 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
261 public static function getLockInfo($lockid, $full_chain=FALSE, $check_expires=TRUE, $allow_only_one=TRUE)
264 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
268 $locks_passed = Array();
269 if (is_array($lockid)) {
270 $where =
' WHERE lockid IN (';
271 foreach ($lockid as $lock_key => $lock_value) {
272 $where .=
':lockid'.$lock_key.
',';
273 $locks_passed[
'lockid'.$lock_key] = $lock_value;
275 $where = rtrim($where,
',');
278 $where =
' WHERE lockid = :lockid';
279 $locks_passed[
'lockid'] = $lockid;
282 $sql =
'SELECT lockid, source_lockid, userid, expires
283 FROM sq_lock'.$where;
287 foreach($locks_passed as $bind_var => $bind_val) {
291 }
catch (Exception $e) {
292 $lock_error = (is_array($lockid)) ? (
's '.implode(
', ', $lockid)) : (
' '.$lockid);
293 throw new Exception(
'Unable to get lock information for lock ID"'.$lock_error.
'" due to database error: '.$e->getMessage());
296 if (!empty($results)) {
297 foreach ($results as $result_key => $result) {
298 $results[$result_key][
'expires'] = empty($result[
'expires']) ? NULL : iso8601_ts($result[
'expires']);
299 if ($check_expires && !empty($result[
'expires'])) {
300 if ($results[$result_key][
'expires'] < time()) {
301 self::releaseLock($lockid);
303 if (count($results) > 1) {
305 unset($results[$result_key]);
316 $results[$result_key][
'chained_assets'] = Array();
317 foreach ($locks_passed as $lock_to_test) {
318 $sql =
'SELECT lockid, source_lockid, userid, expires
320 WHERE source_lockid = :source_lockid
321 AND lockid <> :lockid';
328 }
catch (Exception $e) {
329 throw new Exception(
'Unable to get lock chain information for source lock ID "'.$result[
'source_lockid'].
'" due to database error: '.$e->getMessage());
332 foreach ($chain as $lock_row) {
333 $lock_row[
'expires'] = (empty($lock_row[
'expires'])) ? NULL : iso8601_ts($lock_row[
'expires']);
334 $results[$result_key][
'chained_assets'][$lock_row[
'lockid']] = $lock_row;
340 if (!empty($results) && $allow_only_one) {
341 $results = $results[0];
344 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
362 public static function getActiveLocks($owner_assetid=NULL, $include_expired=FALSE)
365 $bind_vars = Array();
367 if ($include_expired === FALSE) {
368 $bind_vars[
'expire_time'] = ts_iso8601(time());
370 $bind_vars[
'expire_time'] = NULL;
373 if ($owner_assetid !== NULL) {
374 $bind_vars[
'owner_assetid'] = $owner_assetid;
376 $bind_vars[
'owner_assetid'] = NULL;
381 }
catch (Exception $e) {
420 'old_userid' => $old_assetid,
421 'new_userid' => $new_assetid,
453 public static function deleteExpiredLocks()
455 $bind_vars[
'expire_time'] = ts_iso8601(time());