Update Horde_Lock
authorMichael M Slusarz <slusarz@curecanti.org>
Thu, 18 Mar 2010 08:46:35 +0000 (02:46 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Thu, 18 Mar 2010 17:33:34 +0000 (11:33 -0600)
Bring into line with H4 conventions.
Remove some Core-specific code/configuration.
Fix exception throwing in Horde_Lock package

framework/Lock/lib/Horde/Lock.php
framework/Lock/lib/Horde/Lock/Driver.php [new file with mode: 0644]
framework/Lock/lib/Horde/Lock/Exception.php
framework/Lock/lib/Horde/Lock/Sql.php
framework/Lock/package.xml

index 59d4e93..af68992 100644 (file)
  */
 class Horde_Lock
 {
+    /* Class constants. */
     const TYPE_EXCLUSIVE = 1;
     const TYPE_SHARED = 2;
 
     /**
-     * Local copy of driver parameters
-     * @var $_params
-     */
-    protected $_params;
-
-    /**
-     * Horde_Lock constructor
-     *
-     * @param array $params  Parameters for the specific Horde_Lock driver
-     *
-     * @return Horde_Lock    Instance of Horde_Lock
-     */
-    public function __construct($params = array())
-    {
-        $this->_params = $params;
-        return $this;
-    }
-
-    /**
-     * Return an array of information about the requested lock.
-     *
-     * @param string $lockid   Lock ID to look up
-     *
-     * @return mixed           Array of lock information
-     * @throws Horde_Log_Exception
-     */
-    public function getLockInfo($lockid)
-    {
-        throw new Horde_Log_Exception(_("No lock driver configured!"));
-    }
-
-    /**
-     * Return a list of valid locks with the option to limit the results
-     * by principal, scope and/or type.
+     * Singleton instances.
      *
-     * @param string $scope      The scope of the lock.  Typically the name of
-     *                           the application requesting the lock or some
-     *                           other identifier used to group locks together.
-     * @param string $principal  Principal for which to check for locks
-     * @param int $type          Only return locks of the given type.
-     *                           Defaults to null, or all locks
-     *
-     * @return array  Array of locks with the ID as the key and the lock details
-     *                as the value. If there are no current locks this will
-     *                return an empty array.
-     *
-     * @throws Horde_Log_Exception
+     * @var array
      */
-    public function getLocks($scope = null, $principal = null, $type = null)
-    {
-        throw new Horde_Log_Exception(_("No lock driver configured!"));
-    }
+    static protected $_instances = array();
 
     /**
-     * Extend the valid lifetime of a valid lock to now + $extend.
-     *
-     * @param string $lockid  Lock ID to reset.  Must be a valid, non-expired
-     *                        lock.
-     * @param int $extend     Extend lock this many seconds from now.
+     * Attempts to return a concrete instance based on $driver.
      *
-     * @return boolean
-     * @throws Horde_Log_Exception
-     */
-    public function resetLock($lockid, $extend)
-    {
-        throw new Horde_Log_Exception(_("No lock driver configured!"));
-    }
-
-    /**
-     * Sets a lock on the requested principal and returns the generated lock ID.
-     * NOTE: No security checks are done in the Horde_Lock API.  It is expected
-     * that the calling application has done all necessary security checks
-     * before requesting a lock be granted.
-     *
-     * @param string $requestor  User ID of the lock requestor.
-     * @param string $scope      The scope of the lock.  Typically the name of
-     *                           the application requesting the lock or some
-     *                           other identifier used to group locks together.
-     * @param string $principal  A principal on which a lock should be granted.
-     *                           The format can be any string but is suggested
-     *                           to be in URI form.
-     * @param int $lifetime      Time (in seconds) for which the lock will be
-     *                           considered valid.
-     * @param string exclusive   One of self::TYPE_SHARED or
-     *                           self::TYPE_EXCLUSIVE.
-     *                           - An exclusive lock will be enforced strictly
-     *                             and must be interpreted to mean that the
-     *                             resource can not be modified.  Only one
-     *                             exclusive lock per principal is allowed.
-     *                           - A shared lock is one that notifies other
-     *                             potential lock requestors that the resource
-     *                             is in use.  This lock can be overridden
-     *                             (cleared or replaced with a subsequent
-     *                             call to setLock()) by other users.  Multiple
-     *                             users may request (and will be granted) a
-     *                             shared lock on a given principal.  All locks
-     *                             will be considered valid until they are
-     *                             cleared or expire.
-     *
-     * @return mixed   A string lock ID.
-     * @throws Horde_Log_Exception
-     */
-    public function setLock($requestor, $scope, $principal,
-                     $lifetime = 1, $exclusive = self::TYPE_SHARED)
-    {
-        throw new Horde_Log_Exception(_("No lock driver configured!"));
-    }
-
-    /**
-     * Removes a lock given the lock ID.
-     * NOTE: No security checks are done in the Horde_Lock API.  It is expected
-     * that the calling application has done all necessary security checks
-     * before requesting a lock be cleared.
-     *
-     * @param string $lockid  The lock ID as generated by a previous call
-     *                        to setLock()
-     *
-     * @return boolean
-     * @throws Horde_Log_Exception
-     */
-    public function clearLock($lockid)
-    {
-        throw new Horde_Log_Exception(_("No lock driver configured!"));
-    }
-
-    /**
-     * Attempts to return a concrete Horde_Lock instance based on $driver.
-     *
-     * @param mixed $driver  The type of concrete Horde_Lock subclass to return.
+     * @param mixed $driver  The type of concrete subclass to return.
      *                       This is based on the storage driver ($driver).
-     *                       The code is dynamically included. If $driver is an
-     *                       array, then we will look in $driver[0]/lib/Lock/
-     *                       for the subclass implementation named
-     *                       $driver[1].php.
+     *                       The code is dynamically included.
      * @param array $params  A hash containing any additional configuration or
      *                       connection parameters a subclass might need.
      *
-     * @return Horde_Lock    The newly created concrete Lock instance.
-     * @throws Horde_Log_Exception
+     * @return Horde_Lock_Driver  The newly created concrete instance.
+     * @throws Horde_Lock_Exception
      */
-    public static function factory($driver, $params = null)
+    static public function factory($driver, $params = array())
     {
-        if (is_array($driver)) {
-            $app = $driver[0];
-            $driver = $driver[1];
-        }
-
         $driver = Horde_String::ucfirst(basename($driver));
-        if (empty($driver) || ($driver == 'None')) {
-            return new self();
-        }
-
-        if (is_null($params)) {
-            $params = Horde::getDriverConfig('lock', $driver);
-        }
-
         $class = __CLASS__ . '_' . $driver;
 
         if (class_exists($class)) {
             return new $class($params);
         }
 
-        throw new Horde_Log_Exception('Horde_Lock Driver (' . $class . ') not found');
+        throw new Horde_Lock_Exception('Horde_Lock driver (' . $class . ') not found');
     }
 
     /**
-     * Attempts to return a reference to a concrete Horde_Lock instance based on
-     * $driver. It will only create a new instance if no Horde_Lock instance
+     * Attempts to return a reference to a concrete instance based on
+     * $driver. It will only create a new instance if no instance
      * with the same parameters currently exists.
      *
      * This should be used if multiple authentication sources (and, thus,
@@ -197,24 +63,18 @@ class Horde_Lock
      * @param array $params   A hash containing any additional configuration or
      *                        connection parameters a subclass might need.
      *
-     * @return Horde_Lock     The concrete Horde_Lock reference
-     * @throws Horde_Log_Exception
+     * @return Horde_Lock_Driver  The concrete reference.
+     * @throws Horde_Lock_Exception
      */
-    public static function singleton($driver, $params = null)
+    static public function singleton($driver, $params = array())
     {
-        static $instances = array();
-
-        if (is_null($params)) {
-            $params = Horde::getDriverConfig('lock',
-                is_array($driver) ? $driver[1] : $driver);
-        }
-
-        $signature = serialize(array($driver, $params));
-        if (empty($instances[$signature])) {
-            $instances[$signature] = self::factory($driver, $params);
+        ksort($params);
+        $signature = hash('md5', serialize(array($driver, $params)));
+        if (empty(self::$_instances[$signature])) {
+            self::$_instances[$signature] = self::factory($driver, $params);
         }
 
-        return $instances[$signature];
+        return self::$_instances[$signature];
     }
 
 }
diff --git a/framework/Lock/lib/Horde/Lock/Driver.php b/framework/Lock/lib/Horde/Lock/Driver.php
new file mode 100644 (file)
index 0000000..0628092
--- /dev/null
@@ -0,0 +1,141 @@
+<?php
+/**
+ * The Horde_Lock_Driver class defines the Horde_Lock driver API.
+ *
+ * Copyright 2008-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did
+ * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
+ *
+ * @author  Ben Klang <ben@alkaloid.net>
+ * @package Horde_Lock
+ */
+abstract class Horde_Lock_Driver
+{
+    /**
+     * Driver parameters.
+     *
+     * @var array
+     */
+    protected $_params;
+
+    /**
+     * Logger.
+     *
+     * @var Horde_Log_Logger
+     */
+    protected $_logger;
+
+    /**
+     * Constructor.
+     *
+     * @param array $params  Configuration parameters:
+     * <pre>
+     * 'logger' - (Horde_Log_Logger) A logger instance.
+     * </pre>
+     */
+    public function __construct($params = array())
+    {
+        if (!empty($params['logger'])) {
+            $this->_logger = $params['logger'];
+            unset($params['logger']);
+        }
+
+        $this->_params = $params;
+    }
+
+    /**
+     * Return an array of information about the requested lock.
+     *
+     * @param string $lockid  Lock ID to look up.
+     *
+     * @return array  Lock information.
+     * @throws Horde_Lock_Exception
+     */
+    abstract public function getLockInfo($lockid);
+
+    /**
+     * Return a list of valid locks with the option to limit the results
+     * by principal, scope and/or type.
+     *
+     * @param string $scope      The scope of the lock.  Typically the name of
+     *                           the application requesting the lock or some
+     *                           other identifier used to group locks together.
+     * @param string $principal  Principal for which to check for locks
+     * @param integer $type      Only return locks of the given type.
+     *                           Defaults to null, or all locks
+     *
+     * @return array  Array of locks with the ID as the key and the lock details
+     *                as the value. If there are no current locks this will
+     *                return an empty array.
+     * @throws Horde_Lock_Exception
+     */
+    abstract public function getLocks($scope = null, $principal = null,
+                                      $type = null);
+
+    /**
+     * Extend the valid lifetime of a valid lock to now + $extend.
+     *
+     * @param string $lockid   Lock ID to reset. Must be a valid, non-expired
+     *                         lock.
+     * @param integer $extend  Extend lock this many seconds from now.
+     *
+     * @return boolean  TODO
+     * @throws Horde_Lock_Exception
+     */
+    abstract public function resetLock($lockid, $extend);
+
+    /**
+     * Sets a lock on the requested principal and returns the generated lock
+     * ID. NOTE: No security checks are done in the Horde_Lock API. It is
+     * expected that the calling application has done all necessary security
+     * checks before requesting a lock be granted.
+     *
+     * @param string $requestor  User ID of the lock requestor.
+     * @param string $scope      The scope of the lock.  Typically the name of
+     *                           the application requesting the lock or some
+     *                           other identifier used to group locks
+     *                           together.
+     * @param string $principal  A principal on which a lock should be
+     *                           granted. The format can be any string but is
+     *                           suggested to be in URI form.
+     * @param integer $lifetime  Time (in seconds) for which the lock will be
+     *                           considered valid.
+     * @param string exclusive   One of Horde_Lock::TYPE_SHARED or
+     *                           Horde_Lock::TYPE_EXCLUSIVE.
+     *                           - An exclusive lock will be enforced strictly
+     *                             and must be interpreted to mean that the
+     *                             resource can not be modified. Only one
+     *                             exclusive lock per principal is allowed.
+     *                           - A shared lock is one that notifies other
+     *                             potential lock requestors that the resource
+     *                             is in use. This lock can be overridden
+     *                             (cleared or replaced with a subsequent
+     *                             call to setLock()) by other users. Multiple
+     *                             users may request (and will be granted) a
+     *                             shared lock on a given principal. All locks
+     *                             will be considered valid until they are
+     *                             cleared or expire.
+     *
+     * @return mixed   A string lock ID.
+     * @throws Horde_Lock_Exception
+     */
+    abstract public function setLock($requestor, $scope, $principal,
+                                     $lifetime = 1,
+                                     $exclusive = Horde_Lock::TYPE_SHARED);
+
+    /**
+     * Removes a lock given the lock ID.
+     * NOTE: No security checks are done in the Horde_Lock API.  It is
+     * expected that the calling application has done all necessary security
+     * checks before requesting a lock be cleared.
+     *
+     * @param string $lockid  The lock ID as generated by a previous call
+     *                        to setLock()
+     *
+     * @return boolean  TODO
+     * @throws Horde_Lock_Exception
+     */
+    abstract public function clearLock($lockid);
+
+}
index 2fe1b4a..6f7a20d 100644 (file)
@@ -1,4 +1,14 @@
 <?php
-class Horde_Lock_Exception extends Exception
-{
-}
+/**
+ * Exception handler for the Horde_Lock package.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @package  Horde_Lock
+ */
+class Horde_Lock_Exception extends Horde_Exception_Prior {}
index b10f740..b3f669f 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 /**
- * The Horde_Lock_sql driver implements a storage backend for the Horde_Lock API
+ * The Horde_Lock_Sql driver implements a storage backend for the Horde_Lock
+ * API.
  *
  * Required parameters:<pre>
  *   'phptype'      The database type (ie. 'pgsql', 'mysql', etc.).</pre>
@@ -50,7 +51,7 @@
  * @author  Ben Klang <ben@alkaloid.net>
  * @package Horde_Lock
  */
-class Horde_Lock_Sql extends Horde_Lock
+class Horde_Lock_Sql extends Horde_Lock_Driver
 {
     /**
      * Handle for the current database connection.
@@ -81,22 +82,18 @@ class Horde_Lock_Sql extends Horde_Lock
      */
     public function __construct($params = array())
     {
-        $options = array(
+        $this->_params = array_merge(array(
             'database' => '',
-            'username' => '',
-            'password' => '',
             'hostspec' => '',
-            'table' => '',
-        );
-        $this->_params = array_merge($options, $params);
-        if (empty($this->_params['table'])) {
-            $this->_params['table'] = 'horde_locks';
-        }
+            'password' => '',
+            'table' => 'horde_locks',
+            'username' => ''
+        ), $params);
 
         /* Only do garbage collection if asked for, and then only 0.1% of the
          * time we create an object. */
         if (rand(0, 999) == 0) {
-            register_shutdown_function(array(&$this, '_doGC'));
+            register_shutdown_function(array($this, '_doGC'));
         }
 
         parent::__construct($this->_params);
@@ -105,14 +102,11 @@ class Horde_Lock_Sql extends Horde_Lock
     /**
      * Return an array of information about the requested lock.
      *
-     * @see Horde_Lock::getLockInfo
+     * @see Horde_Lock_Driver::getLockInfo()
      */
     public function getLockInfo($lockid)
     {
-       if (is_a(($result = $this->_connect()), 'PEAR_Error')) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Lock_Exception(_("Internal database error.  Details have been logged for the administrator."));
-        }
+        $this->_connect();
 
         $now = time();
         $sql = 'SELECT lock_id, lock_owner, lock_scope, lock_principal, ' .
@@ -121,15 +115,18 @@ class Horde_Lock_Sql extends Horde_Lock
                ' WHERE lock_id = ? AND lock_expiry_timestamp >= ?';
         $values = array($lockid, $now);
 
-        Horde::logMessage('SQL Query by Horde_Lock_sql::getLockInfo(): ' . $sql, 'DEBUG');
+        if ($this->_logger) {
+            $this->_logger->log('SQL Query by Horde_Lock_sql::getLockInfo(): ' . $sql, 'DEBUG');
+        }
+
         $result = $this->_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            throw new Horde_Lock_Exception($result->getMessage());
+        if ($result instanceof PEAR_Error) {
+            throw new Horde_Lock_Exception($result);
         }
 
         $locks = array();
         $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-        if (is_a($row, 'PEAR_Error')) {
+        if ($row instanceof PEAR_Error) {
             return false;
         }
 
@@ -141,14 +138,11 @@ class Horde_Lock_Sql extends Horde_Lock
      * Return a list of valid locks with the option to limit the results
      * by principal, scope and/or type.
      *
-     * @see Horde_Lock::getLocks
+     * @see Horde_Lock_Driver::getLocks()
      */
     public function getLocks($scope = null, $principal = null, $type = null)
     {
-        if (is_a(($result = $this->_connect()), 'PEAR_Error')) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Lock_Exception(_("Internal database error.  Details have been logged for the administrator."));
-        }
+        $this->_connect();
 
         $now = time();
         $sql = 'SELECT lock_id, lock_owner, lock_scope, lock_principal, ' .
@@ -162,7 +156,7 @@ class Horde_Lock_Sql extends Horde_Lock
             $sql .= ' AND lock_principal = ?';
             $values[] = $principal;
         }
-        if(!empty($scope)) {
+        if (!empty($scope)) {
             $sql .= ' AND lock_scope = ?';
             $values[] = $scope;
         }
@@ -171,84 +165,81 @@ class Horde_Lock_Sql extends Horde_Lock
             $values[] = $type;
         }
 
-        Horde::logMessage('SQL Query by Horde_Lock_sql::getLocks(): ' . $sql, 'DEBUG');
+        if ($this->_logger) {
+            $this->_logger->log('SQL Query by Horde_Lock_sql::getLocks(): ' . $sql, 'DEBUG');
+        }
+
         $result = $this->_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            throw new Horde_Lock_Exception($result->getMessage());
+        if ($result instanceof PEAR_Error) {
+            throw new Horde_Lock_Exception($result);
         }
 
         $locks = array();
         $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-        while ($row && !is_a($row, 'PEAR_Error')) {
+        while ($row && !($row instanceof PEAR_Error)) {
             $locks[$row['lock_id']] = $row;
             /* Advance to the new row in the result set. */
             $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
         }
         $result->free();
+
         return $locks;
     }
 
     /**
      * Extend the valid lifetime of a valid lock to now + $newtimeout.
      *
-     * @see Horde_Lock::resetLock
+     * @see Horde_Lock_Driver::resetLock()
      */
     public function resetLock($lockid, $extend)
     {
-       if (is_a(($result = $this->_connect()), 'PEAR_Error')) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Lock_Exception(_("Internal database error.  Details have been logged for the administrator."));
-        }
+        $this->_connect();
 
         $now = time();
 
-        $lockinfo = $this->getLockInfo($lockid);
-        if ($lockinfo === true) {
-            $expiry = $now + $extend;
-            $sql = 'UPDATE ' . $this->_params['table'] . ' SET ' .
-                   'lock_update_timestamp = ?, lock_expiry_timestamp = ? ' .
-                   'WHERE lock_id = ?';
-            $values = array($now, $expiry, $lockid);
-
-            Horde::logMessage('SQL Query by Horde_Lock_sql::resetLock(): ' . $sql, 'DEBUG');
-            $result = $this->_write_db->query($sql, $values);
-            if (is_a($result, 'PEAR_Error')) {
-                throw new Horde_Lock_Exception($result->getMessage());
-            }
-            Horde::logMessage(sprintf('Lock %s reset successfully.', $lockid), 'DEBUG');
-            return true;
-        } elseif (is_a($lockinfo, 'PEAR_Error')) {
-            throw new Horde_Lock_Exception($lockinfo->getMessage());
-        } else {
-            // $lockinfo is false indicating the lock is no longer valid.
+        if (!$this->getLockInfo($lockid)) {
             return false;
         }
+
+        $expiry = $now + $extend;
+        $sql = 'UPDATE ' . $this->_params['table'] . ' SET ' .
+               'lock_update_timestamp = ?, lock_expiry_timestamp = ? ' .
+               'WHERE lock_id = ?';
+        $values = array($now, $expiry, $lockid);
+
+        if ($this->_logger) {
+            $this->_logger->log('SQL Query by Horde_Lock_sql::resetLock(): ' . $sql, 'DEBUG');
+        }
+
+        $result = $this->_write_db->query($sql, $values);
+        if ($result instanceof PEAR_Error) {
+            throw new Horde_Lock_Exception($result);
+        }
+
+        if ($this->_logger) {
+            $this->_logger->log(sprintf('Lock %s reset successfully.', $lockid), 'DEBUG');
+        }
+        return true;
     }
 
     /**
-     * Sets a lock on the requested principal and returns the generated lock ID.
-     * NOTE: No security checks are done in the Horde_Lock API.  It is expected
-     * that the calling application has done all necessary security checks
-     * before requesting a lock be granted.
+     * Sets a lock on the requested principal and returns the generated lock
+     * ID.
      *
-     * @see Horde_Lock::setLock
+     * @see Horde_Lock_Driver::setLock()
      */
     public function setLock($requestor, $scope, $principal,
-                     $lifetime = 1, $type = self::TYPE_SHARED)
+                            $lifetime = 1, $type = Horde_Lock::TYPE_SHARED)
     {
-       if (is_a(($result = $this->_connect()), 'PEAR_Error')) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Lock_Exception(_("Internal database error.  Details have been logged for the administrator."));
-        }
+        $this->_connect();
 
-        $oldlocks = $this->getLocks($scope, $principal,  self::TYPE_EXCLUSIVE);
-        if (is_a($oldlocks, 'PEAR_Error')) {
-            throw new Horde_Lock_Exception($oldlocks->getMessage());
-        }
+        $oldlocks = $this->getLocks($scope, $principal, Horde_Lock::TYPE_EXCLUSIVE);
 
         if (count($oldlocks) != 0) {
             // An exclusive lock exists.  Deny the new request.
-            Horde::logMessage(sprintf('Lock requested for %s denied due to existing exclusive lock.', $principal), 'NOTICE');
+            if ($this->_logger) {
+                $this->_logger->log(sprintf('Lock requested for %s denied due to existing exclusive lock.', $principal), 'NOTICE');
+            }
             return false;
         }
 
@@ -260,33 +251,33 @@ class Horde_Lock_Sql extends Horde_Lock
         $values = array($lockid, $requestor, $scope, $principal, $now, $now,
                         $expiration, $type);
 
-        Horde::logMessage('SQL Query by Horde_Lock_sql::setLock(): ' . $sql, 'DEBUG');
+        if ($this->_logger) {
+            $this->_logger->log('SQL Query by Horde_Lock_sql::setLock(): ' . $sql, 'DEBUG');
+        }
+
         $result = $this->_write_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            throw new Horde_Lock_Exception($result->getMessage());
+        if ($result instanceof PEAR_Error) {
+            throw new Horde_Lock_Exception($result);
+        }
+
+        if ($this->_logger) {
+            $this->_logger->log(sprintf('Lock %s set successfully by %s in scope %s on "%s"', $lockid, $requestor, $scope, $principal), 'DEBUG');
         }
 
-        Horde::logMessage(sprintf('Lock %s set successfully by %s in scope %s on "%s"', $lockid, $requestor, $scope, $principal), 'DEBUG');
         return $lockid;
     }
 
     /**
      * Removes a lock given the lock ID.
-     * NOTE: No security checks are done in the Horde_Lock API.  It is expected
-     * that the calling application has done all necessary security checks
-     * before requesting a lock be cleared.
      *
-     * @see Horde_Lock::clearLock
+     * @see Horde_Lock_Driver::clearLock()
      */
     public function clearLock($lockid)
     {
-        if (is_a(($result = $this->_connect()), 'PEAR_Error')) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Lock_Exception(_("Internal database error.  Details have been logged for the administrator."));
-        }
+        $this->_connect();
 
         if (empty($lockid)) {
-            throw new Horde_Lock_Exception(_("Must supply a valid lock ID."));
+            throw new Horde_Lock_Exception('Must supply a valid lock ID.');
         }
 
         // Since we're trying to clear the lock we don't care
@@ -295,42 +286,50 @@ class Horde_Lock_Sql extends Horde_Lock
         $sql = 'DELETE FROM ' . $this->_params['table'] . ' WHERE lock_id = ?';
         $values = array($lockid);
 
-        Horde::logMessage('SQL Query by Horde_Lock_sql::clearLock(): ' . $sql, 'DEBUG');
+        if ($this->_logger) {
+            $this->_logger->log('SQL Query by Horde_Lock_sql::clearLock(): ' . $sql, 'DEBUG');
+        }
+
         $result = $this->_write_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            throw new Horde_Lock_Exception($result->getMessage());
+        if ($result instanceof PEAR_Error) {
+            throw new Horde_Lock_Exception($result);
+        }
+
+        if ($this->_logger) {
+            $this->_logger->log(sprintf('Lock %s cleared successfully.', $lockid), 'DEBUG');
         }
 
-        Horde::logMessage(sprintf('Lock %s cleared successfully.', $lockid), 'DEBUG');
         return true;
     }
 
     /**
      * Opens a connection to the SQL server.
-     *
-     * @return boolean  True on success, a PEAR_Error object on failure.
      */
     private function _connect()
     {
         if ($this->_connected) {
-            return true;
+            return;
         }
 
         try {
             Horde_Util::assertDriverConfig($this->_params, array('phptype'), 'Lock SQL');
         } catch (Horde_Exception $e) {
-            Horde::logMessage($e, 'ERR');
+            if ($this->_logger) {
+                $this->_logger->log($e, 'ERR');
+            }
             throw new Horde_Lock_Exception($e);
         }
 
-        $this->_write_db = &DB::connect(
+        $this->_write_db = DB::connect(
             $this->_params,
             array('persistent' => !empty($this->_params['persistent']),
                   'ssl' => !empty($this->_params['ssl']))
         );
-        if (is_a($this->_write_db, 'PEAR_Error')) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Lock_Exception($this->_write_db->getMessage());
+        if ($this->_write_db instanceof PEAR_Error) {
+            if ($this->_logger) {
+                $this->_logger->log($this->_write_db, 'ERR');
+            }
+            throw new Horde_Lock_Exception($this->_write_db);
         }
 
         // Set DB portability options.
@@ -344,14 +343,16 @@ class Horde_Lock_Sql extends Horde_Lock
          * seperately. */
         if (!empty($this->_params['splitread'])) {
             $params = array_merge($this->_params, $this->_params['read']);
-            $this->_db = &DB::connect(
+            $this->_db = DB::connect(
                 $params,
                 array('persistent' => !empty($params['persistent']),
                       'ssl' => !empty($params['ssl']))
             );
-            if (is_a($this->_db, 'PEAR_Error')) {
-                Horde::logMessage($result, 'ERR');
-                throw new Horde_Lock_Exception($this->_db->getMessage());
+            if ($this->_db instanceof PEAR_Error) {
+                if ($this->_logger) {
+                    $this->_logger->log($this->_db, 'ERR');
+                }
+                throw new Horde_Lock_Exception($this->_db);
             }
 
             // Set DB portability options.
@@ -366,36 +367,33 @@ class Horde_Lock_Sql extends Horde_Lock
         }
 
         $this->_connected = true;
-        return true;
     }
 
     /**
      * Do garbage collection needed for the driver.
-     *
-     * @access private
      */
     private function _doGC()
     {
-        if (is_a(($result = $this->_connect()), 'PEAR_Error')) {
-            Horde::logMessage($result, 'ERR');
-            return false;
+        try {
+            $this->_connect();
+        } catch (Horde_Lock_Exception $e) {
+            return;
         }
 
         $now = time();
-
         $query = 'DELETE FROM ' . $this->_params['table'] . ' WHERE ' .
                  'lock_expiry_timestamp < ? AND lock_expiry_timestamp != 0';
         $values = array($now);
 
-        Horde::logMessage('SQL Query by Horde_Lock_sql::_doGC(): ' .  $sql, 'DEBUG');
         $result = $this->_write_db->query($query, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            Horde::logMessage($result, 'ERR');
-            return false;
+        if ($this->_logger) {
+            $this->_logger->log('SQL Query by Horde_Lock_sql::_doGC(): ' .  $sql, 'DEBUG');
+            if ($result instanceof PEAR_Error) {
+                $this->_logger->log($result, 'ERR');
+            } else {
+                $this->_logger->log(sprintf('Lock garbage collection cleared %d locks.', $this->_write_db->affectedRows()), 'DEBUG');
+            }
         }
-
-        Horde::logMessage(sprintf('Lock garbage collection cleared %d locks.', $this->_write_db->affectedRows()), 'DEBUG');
-        return true;
     }
 
 }
index 4764b90..43bc797 100644 (file)
@@ -32,8 +32,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
    <dir name="lib">
     <dir name="Horde">
      <dir name="Lock">
-      <file name="Sql.php" role="php" />
+      <file name="Driver.php" role="php" />
       <file name="Exception.php" role="php" />
+      <file name="Sql.php" role="php" />
      </dir> <!-- /lib/Horde/Lock -->
      <file name="Lock.php" role="php" />
     </dir> <!-- /lib/Horde -->
@@ -43,13 +44,13 @@ http://pear.php.net/dtd/package-2.0.xsd">
  <dependencies>
   <required>
    <php>
-    <min>4.0.0</min>
+    <min>5.2.0</min>
    </php>
    <pearinstaller>
-    <min>1.4.0b1</min>
+    <min>1.7.0</min>
    </pearinstaller>
    <package>
-    <name>Horde_Framework</name>
+    <name>Core</name>
     <channel>pear.horde.org</channel>
    </package>
    <package>
@@ -66,15 +67,16 @@ http://pear.php.net/dtd/package-2.0.xsd">
   </required>
   <optional>
    <package>
-    <name>Horde_Tree</name>
+    <name>Log</name>
     <channel>pear.horde.org</channel>
    </package>
   </optional>
  </dependencies>
  <phprelease>
   <filelist>
-   <install name="lib/Horde/Lock/Sql.php" as="Horde/Lock/Sql.php" />
+   <install name="lib/Horde/Lock/Driver.php" as="Horde/Lock/Driver.php" />
    <install name="lib/Horde/Lock/Exception.php" as="Horde/Lock/Exception.php" />
+   <install name="lib/Horde/Lock/Sql.php" as="Horde/Lock/Sql.php" />
    <install name="lib/Horde/Lock.php" as="Horde/Lock.php" />
   </filelist>
  </phprelease>