- <?php
- require_once('Driver.php');
- require_once('MDB2.php');
-
- /**
- * A driver that use MDB2 as data store
- */
- class AJAX_Locking_Driver_MDB2 extends AJAX_Locking_Driver
- {
- /**
- * Instance of a MDB2 connection
- *
- * @var MBD2 connection
- */
- var $mdb2;
-
- /**
- * Default table and columns names
- *
- * @var array
- */
- var $names = array(
- 'table' => 'ajax_locks',
- 'columns' => array(
- 'type' => 'type',
- 'id' => 'id',
- 'user' => '[user]',
- 'time' => '[time]'
- )
- );
-
- /**
- * Constructor
- *
- * @param mixed $dsn DSN for MDB2 connection
- * @param array $names names of table and its columns where store data
- * @param int $timeout session timeout
- * @return AJAX_Locking_Driver
- */
- function AJAX_Locking_Driver_MDB2($dsn = false, $names = false, $timeout = false)
- {
- parent::AJAX_Locking_Driver($timeout);
-
- $this->mdb2 =& MDB2::factory($dsn);
- if (PEAR::isError($this->mdb2)) {
- die($this->mdb2->getMessage());
- }
-
- // eventually override default names of table and columns
- if ($names && is_array($names)) {
- $names['columns'] = array_merge($this->names['columns'], $names['columns']);
- $this->names = array_merge($this->names, $names);
- }
- }
-
- /**
- * Locks an object
- *
- * @param mixed $user id of the user who wants to lock
- * @param string $type type/classname of the object
- * @param mixed $id id of the object
- * @return boolean true if the unlock was successfull, false otherwise
- */
- function lock($user, $type, $id)
- {
- $result = false;
- $this->mdb2->beginTransaction();
-
- $sql = $this->_getStatusSQL($type, $id);
- $rs = $this->mdb2->query($sql);
- if (PEAR::isError($rs)) {
- die($rs->getMessage());
- }
- $row = $rs->fetchRow();
- if (!$row) {
- // object is unlocked: lock it
- $sql = $this->_getLockSQL($user, $type, $id);
- $affected =& $this->mdb2->exec($sql);
- if (PEAR::isError($affected)) {
- die($affected->getMessage());
- }
- $result = true;
- } else {
- // object is locked: check if lock expired
- $time = $row[3];
- if (time() - $time > $this->timeout) {
- // lock expired: remove it and lock
- $sql = $this->_getUnlockSQL($type, $id);
- $this->mdb2->exec($sql);
- $sql = $this->_getLockSQL($user, $type, $id);
- $this->mdb2->exec($sql);
- $result = true;
- } else {
- // object properly locked by (another?) user
- $result = ($owner == $user);
- }
- }
-
- $this->mdb2->commit();
-
- return $result;
- }
-
- /**
- * Unlocks an object
- *
- * @param mixed $user id of the user who wants to unlock
- * @param string $type type/classname of the object
- * @param mixed $id id of the object
- * @return boolean true if the unlock was successfull, false otherwise
- */
- function unlock($user, $type, $id)
- {
- $result = false;
- $this->mdb2->beginTransaction();
-
- $sql = $this->_getStatusSQL($type, $id);
- $rs = $this->mdb2->query($sql);
- if (PEAR::isError($rs)) {
- die($rs->getMessage());
- }
- $row = $rs->fetchRow();
- if (!$row) {
- // object was not locked
- $result = false;
- } else {
- // check if user is owner of the lock
- $owner = $row[2];
- if ($user == $owner) {
- // unlock it
- $sql = $this->_getUnlockSQL($type, $id);
- $this->mdb2->exec($sql);
- $result = true;
- } else {
- // user cannot unlock it
- $result = false;
- }
- }
-
- $this->mdb2->commit();
- return $result;
- }
-
- /**
- * Returns the status of the object (lock or unlocked)
- *
- * @param mixed $user id of the user who wants to know the object's status
- * @param string $type type/classname of the object
- * @param mixed $id id of the object
- * @return string the status and the owner of the object
- */
- function status($user, $type, $id)
- {
- $result = "~";
- $this->mdb2->beginTransaction();
-
- $sql = $this->_getStatusSQL($type, $id);
- $rs = $this->mdb2->query($sql);
- if (PEAR::isError($rs)) {
- die($rs->getMessage());
- }
- $row = $rs->fetchRow();
- if (!$row) {
- // object is unlocked
- $result = AJAX_LOCKING_UNLOCKED . '~' . 'noboby';
- } else {
- // object is locked:
- // 1. check if current user is owner of the lock
- // 2. check if lock expired
- $owner = $row[2]; $time = $row[3];
- $timeout = (time() - $time > $this->timeout);
- if ($owner == $user) {
- if ($timeout) {
- // lock expired: remove it and inform it's ower
- $sql = $this->_getUnlockSQL($type, $id);
- $this->mdb2->exec($sql);
- $result = AJAX_LOCKING_TIMEOUT . '~' . $owner;
- } else {
- $result = AJAX_LOCKING_OWNED . '~' . $owner;
- }
- } else {
- if ($timeout) {
- // lock expired: remove it
- $sql = $this->_getUnlockSQL($type, $id);
- $this->mdb2->exec($sql);
- $result = AJAX_LOCKING_UNLOCKED . '~' . 'nobody';
- } else {
- $result = AJAX_LOCKING_LOCKED . '~' . $owner;
- }
- }
- }
-
- $this->mdb2->commit();
- return $result;
- }
-
- /**
- * Returns the list of all active locks for administration purpose
- *
- * @return array of locks (owner, type, id), false if not implemented
- */
- function getLocks()
- {
- $locks = array();
-
- $sql = $this->_getListSQL($type, $id);
- $rs = $this->mdb2->query($sql);
- if (PEAR::isError($rs)) {
- die($rs->getMessage());
- }
- while (($row = $rs->fetchRow())) {
- list($owner, $type, $id, $time) = $row;
- $timeout = (time() - $time > $this->timeout);
- if (!$timeout) {
- $locks[] = array(
- 'owner' => $owner,
- 'type' => $type,
- 'id' => $id
- );
- }
- }
-
- return $locks;
- }
-
- /**
- * Administrately delete lock
- *
- * @param string $type
- * @param mixed $id
- *
- * @return true if the lock is deleted successfully, false otherwise
- */
- function delete($type, $id)
- {
- $sql = $this->_getUnlockSQL($type, $id);
- return $this->mdb2->exec($sql);
- }
-
-
- function _getStatusSQL($type, $id)
- {
- $sql = sprintf("select * from %s where %s = %s and %s = %s",
- $this->names['table'],
- $this->names['columns']['type'], $this->mdb2->quote($type),
- $this->names['columns']['id'], $this->mdb2->quote($id));
- return $sql;
- }
-
- function _getLockSQL($user, $type, $id)
- {
- $timestamp = time();
- $sql = sprintf("insert into %s (%s, %s, %s, %s) values(%s, %s, %s, %s)",
- $this->names['table'],
- $this->names['columns']['type'], $this->names['columns']['id'], $this->names['columns']['user'], $this->names['columns']['time'],
- $this->mdb2->quote($type),
- $this->mdb2->quote($id),
- $this->mdb2->quote($user),
- $timestamp);
- return $sql;
- }
-
- function _getUnlockSQL($type, $id)
- {
- $sql = sprintf("delete from %s where %s = %s and %s = %s",
- $this->names['table'],
- $this->names['columns']['type'], $this->mdb2->quote($type),
- $this->names['columns']['id'], $this->mdb2->quote($id));
- return $sql;
- }
-
- function _getListSQL($type, $id)
- {
- $sql = sprintf("select * from %s",
- $this->names['table']);
- return $sql;
- }
-
- }
- ?>