Move DB init out of classes and into binders
authorMichael M Slusarz <slusarz@curecanti.org>
Thu, 13 May 2010 08:30:35 +0000 (02:30 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Thu, 13 May 2010 18:02:16 +0000 (12:02 -0600)
16 files changed:
framework/Alarm/lib/Horde/Alarm/Sql.php
framework/Alarm/package.xml
framework/Cache/lib/Horde/Cache/Sql.php
framework/Core/lib/Horde/Core/Binder/Alarm.php
framework/Core/lib/Horde/Core/Binder/Cache.php
framework/Core/lib/Horde/Core/Binder/Common.php [new file with mode: 0644]
framework/Core/lib/Horde/Core/Binder/Lock.php
framework/Core/lib/Horde/Core/Binder/Perms.php
framework/Core/lib/Horde/Core/Binder/SessionHandler.php [new file with mode: 0644]
framework/Core/lib/Horde/Core/Binder/Token.php
framework/Core/lib/Horde/Registry.php
framework/Core/package.xml
framework/Lock/lib/Horde/Lock/Sql.php
framework/Perms/lib/Horde/Perms.php
framework/Perms/lib/Horde/Perms/Sql.php
framework/SessionHandler/lib/Horde/SessionHandler/Sql.php

index 601d715..63c18e9 100644 (file)
  * The Horde_Alarm_sql class is a Horde_Alarm storage implementation using the
  * PEAR DB package.
  *
- * Required values for $params:<pre>
- * 'phptype' - (string) The database type (e.g. 'pgsql', 'mysql', etc.).
- * 'charset' - (string) The database's internal charset.</pre>
- *
- * Optional values for $params:<pre>
- * 'table' - (string) The name of the foo table in 'database'.
- *
- * Required by some database implementations:<pre>
- * 'database' - The name of the database.
- * 'hostspec' - The hostname of the database server.
- * 'protocol' - The communication protocol ('tcp', 'unix', etc.).
- * 'username' - The username with which to connect to the database.
- * 'password' - The password associated with 'username'.
- * 'options' - Additional options to pass to the database.
- * 'tty' - The TTY on which to connect to the database.
- * 'port' - The port on which to connect to the database.</pre>
- *
  * The table structure can be created by the
  * horde/scripts/sql/horde_alarm.sql script.
  *
@@ -53,6 +36,39 @@ class Horde_Alarm_Sql extends Horde_Alarm
     protected $_write_db;
 
     /**
+     * Constructor.
+     *
+     * @param array $params  Configuration parameters:
+     * <pre>
+     * 'db' - (DB) [REQUIRED] The DB instance.
+     * 'table' - (string) The name of the tokens table in 'database'.
+     *           DEFAULT: 'horde_alarms'
+     * 'write_db' - (DB) The write DB instance.
+     * </pre>
+     *
+     * @throws Horde_Alarm_Exception
+     */
+    public function __construct(array $params = array())
+    {
+        if (!isset($params['db'])) {
+            throw new Horde_Alarm_Exception('Missing db parameter.');
+        }
+        $this->_db = $params['db'];
+
+        if (isset($params['write_db'])) {
+            $this->_write_db = $params['write_db'];
+        }
+
+        unset($params['db'], $params['write_db']);
+
+        $params = array_merge(array(
+            'table' => 'horde_alarms'
+        ), $params);
+
+        parent::__construct($params);
+    }
+
+    /**
      * Returns a list of alarms from the backend.
      *
      * @param Horde_Date $time  The time when the alarms should be active.
@@ -432,68 +448,23 @@ class Horde_Alarm_Sql extends Horde_Alarm
     }
 
     /**
-     * Attempts to open a connection to the SQL server.
+     * Initialization tasks.
      *
      * @throws Horde_Alarm_Exception
      */
     public function initialize()
     {
-        Horde::assertDriverConfig($this->_params, 'sql',
-                                  array('phptype', 'charset'));
-
-        $this->_params = array_merge(array(
-            'database' => '',
-            'username' => '',
-            'hostspec' => '',
-            'table' => 'horde_alarms'
-        ), $this->_params);
-
-        /* Connect to the SQL server using the supplied parameters. */
-        $this->_write_db = DB::connect($this->_params,
-                                       array('persistent' => !empty($this->_params['persistent']),
-                                             'ssl' => !empty($this->_params['ssl'])));
-        if ($this->_write_db instanceof PEAR_Error) {
-            if ($this->_logger) {
-                $this->_logger->log($this->_write_db, 'INFO');
-            }
-            throw new Horde_Alarm_Exception($this->_write_db);
-        }
-        $this->_initConn($this->_write_db);
-
-        /* Check if we need to set up the read DB connection seperately. */
-        if (!empty($this->_params['splitread'])) {
-            $params = array_merge($this->_params, $this->_params['read']);
-            $this->_db = DB::connect($params,
-                                     array('persistent' => !empty($params['persistent']),
-                                           'ssl' => !empty($params['ssl'])));
-            if ($this->_db instanceof PEAR_Error) {
-                if ($this->_logger) {
-                    $this->_logger->log($this->_db, 'INFO');
-                }
-                throw new Horde_Alarm_Exception($this->_db);
-            }
-            $this->_initConn($this->_db);
-        } else {
-            /* Default to the same DB handle for the writer too. */
-            $this->_db = $this->_write_db;
+        $this->_initConn($this->_db);
+        if ($this->_write_db) {
+            $this->_initConn($this->_write_db);
         }
     }
 
     /**
+     * Alarm specific initialization tasks.
      */
     protected function _initConn(DB_common $db)
     {
-        // Set DB portability options.
-        switch ($db->phptype) {
-        case 'mssql':
-            $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
-            break;
-
-        default:
-            $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-            break;
-        }
-
         /* Handle any database specific initialization code to run. */
         switch ($db->dbsyntax) {
         case 'oci8':
index 1c5b526..24ddf73 100644 (file)
   </required>
   <optional>
    <package>
+    <name>DB</name>
+    <channel>pear.php.net</channel>
+   </package>
+   <package>
     <name>Mail</name>
     <channel>pear.horde.org</channel>
    </package>
index 38d9fee..1b11b33 100644 (file)
@@ -46,13 +46,6 @@ class Horde_Cache_Sql extends Horde_Cache_Base
     protected $_write_db;
 
     /**
-     * Boolean indicating whether or not we're connected to the SQL server.
-     *
-     * @var boolean
-     */
-    protected $_connected = false;
-
-    /**
      * The memory cache object to use, if configured.
      *
      * @var Horde_Cache
@@ -60,55 +53,42 @@ class Horde_Cache_Sql extends Horde_Cache_Base
     protected $_mc = null;
 
     /**
-     * Constructs a new Horde_Cache_Sql object.
+     * Constructor.
      *
-     * @param array $params  Configuration parameters:
+     * @param array $params  Parameters:
      * <pre>
-     * Required parameters:
-     * 'phptype' - The database type (ie. 'pgsql', 'mysql', etc.).
-     *
-     * Required by some database implementations:
-     * 'database' - The name of the database.
-     * 'hostspec' - The hostname of the database server.
-     * 'username' - The username with which to connect to the database.
-     * 'password' - The password associated with 'username'.
-     * 'options' - Additional options to pass to the database.
-     * 'tty' - The TTY on which to connect to the database.
-     * 'port' - The port on which to connect to the database.
-     *
-     * Optional parameters:
-     * 'table' - The name of the cache table in 'database'.
-     *           DEFAULT: 'horde_cache'.
-     * 'use_memorycache' -  Use this Horde_Cache memory caching object to
-     *                      cache the data (to avoid DB accesses).
-     *
-     * Optional values when using separate reading and writing servers, for
-     * example in replication settings:
-     * 'splitread' - (boolean) Whether to implement the separation.
-     * 'read' - (array) Parameters which are different for the read database
-     *          connection, currently supported only 'hostspec' and 'port'
-     *          parameters.
+     * 'db' - (DB) [REQUIRED] The DB instance.
+     * 'table' - (string) The name of the cache table in 'database'.
+     *           DEFAULT: 'horde_cache'
+     * 'use_memorycache' - (Horde_Cache) Use this memory caching object to
+     *                     cache the data (to avoid DB accesses).
+     * 'write_db' - (DB) The write DB instance.
      * </pre>
+     *
+     * @throws Horde_Exception
      */
     public function __construct($params = array())
     {
-        $options = array(
-            'database' => '',
-            'username' => '',
-            'password' => '',
-            'hostspec' => '',
-            'table' => '',
-        );
-        $this->_params = array_merge($options, $params);
-        if (empty($this->_params['table'])) {
-            $this->_params['table'] = 'horde_cache';
+        if (!isset($params['db'])) {
+            throw new Horde_Exception('Missing db parameter.');
+        }
+        $this->_db = $params['db'];
+
+        if (isset($params['write_db'])) {
+            $this->_write_db = $params['write_db'];
         }
 
-        if (!empty($this->_params['use_memorycache'])) {
-            $this->_mc = $this->_params['use_memorycache'];
+        if (isset($params['use_memorycache'])) {
+            $this->_mc = $params['use_memorycache'];
         }
 
-        parent::__construct($this->_params);
+        unset($params['db'], $params['use_memorycache'], $params['write_db']);
+
+        $params = array_merge(array(
+            'table' => 'horde_cache',
+        ), $params);
+
+        parent::__construct($params);
     }
 
     /**
@@ -121,15 +101,6 @@ class Horde_Cache_Sql extends Horde_Cache_Base
             return;
         }
 
-        try {
-            $this->_connect();
-        } catch (Horde_Exception $e) {
-            if ($this->_logger) {
-                $this->_logger->log($e, 'ERR');
-            }
-            return;
-        }
-
         $query = 'DELETE FROM ' . $this->_params['table'] .
                  ' WHERE cache_expiration < ? AND cache_expiration <> 0';
         $values = array(time());
@@ -163,15 +134,6 @@ class Horde_Cache_Sql extends Horde_Cache_Base
             }
         }
 
-        try {
-            $this->_connect();
-        } catch (Horde_Exception $e) {
-            if ($this->_logger) {
-                $this->_logger->log($e, 'ERR');
-            }
-            return false;
-        }
-
         $timestamp = time();
         $maxage = $timestamp - $lifetime;
 
@@ -230,15 +192,6 @@ class Horde_Cache_Sql extends Horde_Cache_Base
             $this->_mc->set($key, $data);
         }
 
-        try {
-            $this->_connect();
-        } catch (Horde_Exception $e) {
-            if ($this->_logger) {
-                $this->_logger->log($e, 'ERR');
-            }
-            return false;
-        }
-
         $timestamp = time();
 
         // 0 lifetime indicates the object should not be GC'd.
@@ -291,15 +244,6 @@ class Horde_Cache_Sql extends Horde_Cache_Base
             return true;
         }
 
-        try {
-            $this->_connect();
-        } catch (Horde_Exception $e) {
-            if ($this->_logger) {
-                $this->_logger->log($e, 'ERR');
-            }
-            return false;
-        }
-
         /* Build SQL query. */
         $query = 'SELECT 1 FROM ' . $this->_params['table'] .
                  ' WHERE cache_id = ?';
@@ -349,15 +293,6 @@ class Horde_Cache_Sql extends Horde_Cache_Base
             $this->_mc->expire($key);
         }
 
-        try {
-            $this->_connect();
-        } catch (Horde_Exception $e) {
-            if ($this->_logger) {
-                $this->_logger->log($e, 'ERR');
-            }
-            return false;
-        }
-
         $query = 'DELETE FROM ' . $this->_params['table'] .
                  ' WHERE cache_id = ?';
         $values = array($key);
@@ -373,60 +308,4 @@ class Horde_Cache_Sql extends Horde_Cache_Base
         return true;
     }
 
-    /**
-     * Opens a connection to the SQL server.
-     *
-     * @throws Horde_Exception
-     */
-    protected function _connect()
-    {
-        if ($this->_connected) {
-            return true;
-        }
-
-        Horde_Util::assertDriverConfig($this->_params, array('phptype'), 'cache SQL');
-
-        $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')) {
-            throw new Horde_Exception($this->_write_db->getMessage());
-        }
-
-        // Set DB portability options.
-        $portability = DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS;
-        if ($this->_write_db->phptype) {
-            $portability |= DB_PORTABILITY_RTRIM;
-        }
-        $this->_write_db->setOption('portability', $portability);
-
-        /* Check if we need to set up the read DB connection
-         * seperately. */
-        if (!empty($this->_params['splitread'])) {
-            $params = array_merge($this->_params, $this->_params['read']);
-            $this->_db = DB::connect(
-                $params,
-                array('persistent' => !empty($params['persistent']),
-                      'ssl' => !empty($params['ssl']))
-            );
-            if (is_a($this->_db, 'PEAR_Error')) {
-                throw new Horde_Exception($this->_db->getMessage());
-            }
-
-            // Set DB portability options.
-            $portability = DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS;
-            if ($this->_db->phptype) {
-                $portability |= DB_PORTABILITY_RTRIM;
-            }
-            $this->_db->setOption('portability', $portability);
-        } else {
-            /* Default to the same DB handle for read. */
-            $this->_db = $this->_write_db;
-        }
-
-        $this->_connected = true;
-    }
-
 }
index 21e07b4..876f0a9 100644 (file)
@@ -9,10 +9,25 @@ class Horde_Core_Binder_Alarm implements Horde_Injector_Binder
     {
         if (empty($GLOBALS['conf']['alarms']['driver'])) {
             $driver = null;
+            $params = array();
         } else {
             $driver = $GLOBALS['conf']['alarms']['driver'];
             $params = Horde::getDriverConfig('alarms', $driver);
         }
+
+        if (strcasecmp($driver, 'Sql') === 0) {
+            $write_db = Horde_Core_Binder_Common::createDb($params, 'alarm SQL');
+
+            /* Check if we need to set up the read DB connection
+             * separately. */
+            if (empty($params['splitread'])) {
+                $params['db'] = $write_db;
+            } else {
+                $params['write_db'] = $write_db;
+                $params['db'] = Horde_Core_Binder_Common::createDb(array_merge($params, $params['read']), 'alarm SQL');
+            }
+        }
+
         $params['logger'] = $injector->getInstance('Horde_Log_Logger');
 
         $alarm = Horde_Alarm::factory($driver, $params);
@@ -31,7 +46,8 @@ class Horde_Core_Binder_Alarm implements Horde_Injector_Binder
         $handler_params = array(
             'identity' => $injector->getInstance('Horde_Prefs_Identity'),
             'mail' => $injector->getInstance('Horde_Mail'),
-            'charset' => Horde_Nls::getCharset());
+            'charset' => Horde_Nls::getCharset()
+        );
         $alarm->addHandler('mail', new Horde_Alarm_Handler_Mail($handler_params));
 
         return $alarm;
index c6d28f8..bfcd001 100644 (file)
@@ -12,18 +12,29 @@ class Horde_Core_Binder_Cache implements Horde_Injector_Binder
 
     protected function _getCacheInstance($driver, $injector)
     {
+        if (empty($driver) || (strcasecmp($driver, 'None') === 0)) {
+            $driver = 'Null';
+        }
+
         $params = Horde::getDriverConfig('cache', $driver);
 
-        switch (strtolower($driver)) {
-        case 'memcache':
+        if (strcasecmp($driver, 'Memcache') === 0) {
             $params['memcache'] = $injector->getInstance('Horde_Memcache');
-            break;
+        } elseif (strcasecmp($driver, 'Sql') === 0) {
+            $write_db = Horde_Core_Binder_Common::createDb($params, 'cache SQL');
+
+            /* Check if we need to set up the read DB connection
+             *              * separately. */
+            if (empty($params['splitread'])) {
+                $params['db'] = $write_db;
+            } else {
+                $params['write_db'] = $write_db;
+                $params['db'] = Horde_Core_Binder_Common::createDb(array_merge($params, $params['read']), 'cache SQL');
+            }
 
-        case 'sql':
             if (!empty($params['use_memorycache'])) {
                 $params['use_memorycache'] = $this->_getCacheInstance($params['use_memorycache'], $injector);
             }
-            break;
         }
 
         if (isset($GLOBALS['conf']['cache']['default_lifetime'])) {
@@ -32,10 +43,6 @@ class Horde_Core_Binder_Cache implements Horde_Injector_Binder
 
         $params['logger'] = $injector->getInstance('Horde_Log_Logger');
 
-        if (empty($driver) || $driver == 'none') {
-            $driver = 'Null';
-        }
-
         $class = 'Horde_Cache_' . ucfirst(basename($driver));
         if (class_exists($class)) {
             return new $class($params);
diff --git a/framework/Core/lib/Horde/Core/Binder/Common.php b/framework/Core/lib/Horde/Core/Binder/Common.php
new file mode 100644 (file)
index 0000000..6304bc8
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+/**
+ * @category Horde
+ * @package  Core
+ */
+class Horde_Core_Binder_Common
+{
+    /* Utility function to use until code is transferred to new DB code. */
+    public function createDb($params, $ident)
+    {
+        Horde_Util::assertDriverConfig($params, array('charset', 'phptype'), $ident);
+
+        $params = array_merge(array(
+            'database' => '',
+            'hostspec' => '',
+            'password' => '',
+            'username' => ''
+        ), $params);
+
+        /* Connect to the SQL server using the supplied parameters. */
+        $db = DB::connect($params, array(
+            'persistent' => !empty($params['persistent']),
+            'ssl' => !empty($params['ssl'])
+        ));
+
+        if ($db instanceof PEAR_Error) {
+            throw new Horde_Exception($db);
+        }
+
+        // Set DB portability options.
+        switch ($db->phptype) {
+        case 'mssql':
+            $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+            break;
+
+        default:
+            $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+            break;
+        }
+
+        return $db;
+    }
+
+}
index bb1e3b9..a0bfe82 100644 (file)
@@ -11,7 +11,7 @@ class Horde_Core_Binder_Lock implements Horde_Injector_Binder
             $driver = 'Null';
         } else {
             $driver = $GLOBALS['conf']['lock']['driver'];
-            if (Horde_String::lower($driver) == 'none') {
+            if (strcasecmp($driver, 'None') === 0) {
                 $driver = 'Null';
             }
         }
@@ -19,8 +19,17 @@ class Horde_Core_Binder_Lock implements Horde_Injector_Binder
         $params = Horde::getDriverConfig('lock', $driver);
         $params['logger'] = $injector->getInstance('Horde_Log_Logger');
 
-        if (Horde_String::lower($driver) == 'sql') {
-            Horde_Util::assertDriverConfig($params, array('phptype'), 'Lock SQL');
+        if (strcasecmp($driver, 'Sql') === 0) {
+            $write_db = Horde_Core_Binder_Common::createDb($params, 'lock SQL');
+
+            /* Check if we need to set up the read DB connection
+             * separately. */
+            if (empty($params['splitread'])) {
+                $params['db'] = $write_db;
+            } else {
+                $params['write_db'] = $write_db;
+                $params['db'] = Horde_Core_Binder_Common::createDb(array_merge($params, $params['read']), 'lock SQL');
+            }
         }
 
         return Horde_Lock::factory($driver, $params);
@@ -30,4 +39,5 @@ class Horde_Core_Binder_Lock implements Horde_Injector_Binder
     {
         return false;
     }
+
 }
index e56156b..5c943aa 100644 (file)
@@ -7,34 +7,44 @@ class Horde_Core_Binder_Perms implements Horde_Injector_Binder
 {
     public function create(Horde_Injector $injector)
     {
-        $perm_params = array(
-            'cache' => $injector->getInstance('Horde_Cache'),
-            'logger' => $injector->getInstance('Horde_Log_Logger')
-        );
+        $params = isset($GLOBALS['conf']['perms'])
+            ? Horde::getDriverConfig('perms', $GLOBALS['conf']['perms']['driver'])
+            : array();
 
-        $perm_driver = empty($GLOBALS['conf']['perms']['driver'])
-            ? (empty($GLOBALS['conf']['datatree']['driver']) ? null : 'datatree')
+        $driver = empty($GLOBALS['conf']['perms']['driver'])
+            ? (empty($GLOBALS['conf']['datatree']['driver']) ? null : 'Datatree')
             : $GLOBALS['conf']['perms']['driver'];
 
-        switch (strtolower($perm_driver)) {
-        case 'datatree':
-            $driver = $GLOBALS['conf']['datatree']['driver'];
-            $perm_params['datatree'] = DataTree::singleton(
-                $driver,
-                array_merge(Horde::getDriverConfig('datatree', $driver), array('group' => 'horde.perms'))
+        if (strcasecmp($driver, 'Datatree') === 0) {
+            $dt_driver = $GLOBALS['conf']['datatree']['driver'];
+            $params['datatree'] = DataTree::singleton(
+                $dt_driver,
+                array_merge(Horde::getDriverConfig('datatree', $dt_driver), array('group' => 'horde.perms'))
             );
-            break;
+        } elseif (strcasecmp($driver, 'Sql') === 0) {
+            $write_db = Horde_Core_Binder_Common::createDb($params, 'perms SQL');
 
-        case 'sql':
-            // TODO
-            break;
+            /* Check if we need to set up the read DB connection
+             * separately. */
+            if (empty($params['splitread'])) {
+                $params['db'] = $write_db;
+            } else {
+                $params['write_db'] = $write_db;
+                $params['db'] = Horde_Core_Binder_Common::createDb(array_merge($params, $params['read']), 'perms SQL');
+            }
         }
 
-        return Horde_Perms::factory($perm_driver, $perm_params);
+        $params = array_merge($params, array(
+            'cache' => $injector->getInstance('Horde_Cache'),
+            'logger' => $injector->getInstance('Horde_Log_Logger')
+        ));
+
+        return Horde_Perms::factory($driver, $params);
     }
 
     public function equals(Horde_Injector_Binder $binder)
     {
         return false;
     }
+
 }
diff --git a/framework/Core/lib/Horde/Core/Binder/SessionHandler.php b/framework/Core/lib/Horde/Core/Binder/SessionHandler.php
new file mode 100644 (file)
index 0000000..5280780
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * @category Horde
+ * @package  Core
+ */
+class Horde_Core_Binder_SessionHandler implements Horde_Injector_Binder
+{
+    public function create(Horde_Injector $injector)
+    {
+        global $conf;
+
+        $driver = empty($conf['sessionhandler']['type'])
+            ? 'None'
+            : $conf['sessionhandler']['type'];
+
+        $params = Horde::getDriverConfig('sessionhandler', $driver);
+
+        if (strcasecmp($driver, 'Sql') === 0) {
+            $write_db = Horde_Core_Binder_Common::createDb($params, 'sessionhandler SQL');
+
+            /* Check if we need to set up the read DB connection
+             *              * separately. */
+            if (empty($params['splitread'])) {
+                $params['db'] = $write_db;
+            } else {
+                $params['write_db'] = $write_db;
+                $params['db'] = Horde_Core_Binder_Common::createDb(array_merge($params, $params['read']), 'sessionhandler SQL');
+            }
+        }
+
+        if (!empty($conf['sessionhandler']['memcache'])) {
+            $params['memcache'] = $injector->getInstance('Horde_Memcache');
+        }
+
+        return Horde_SessionHandler::factory($driver, $params);
+    }
+
+    public function equals(Horde_Injector_Binder $binder)
+    {
+        return false;
+    }
+}
index 32e59d7..49b5f4e 100644 (file)
@@ -15,18 +15,7 @@ class Horde_Core_Binder_Token implements Horde_Injector_Binder
             : array();
 
         if (strcasecmp($driver, 'Sql') === 0) {
-            Horde_Util::assertDriverConfig($params, array('phptype'), 'token SQL');
-
-            $params = array_merge(array(
-                'database' => '',
-                'hostspec' => '',
-                'password' => '',
-                'table' => 'horde_tokens',
-                'username' => ''
-            ), $params);
-
-            /* Connect to the SQL server using the supplied parameters. */
-            $write_db = $this->_createDb($params);
+            $write_db = Horde_Core_Binder_Common::createDb($params, 'token SQL');
 
             /* Check if we need to set up the read DB connection
              * separately. */
@@ -34,7 +23,7 @@ class Horde_Core_Binder_Token implements Horde_Injector_Binder
                 $params['db'] = $write_db;
             } else {
                 $params['write_db'] = $write_db;
-                $params['db'] = $this->_createDb(array_merge($params, $params['read']));
+                $params['db'] = Horde_Core_Binder_Common::createDb(array_merge($params, $params['read']), 'token SQL');
             }
         } elseif (strcasecmp($driver, 'None') === 0) {
             $driver = 'Null';
@@ -50,30 +39,4 @@ class Horde_Core_Binder_Token implements Horde_Injector_Binder
         return false;
     }
 
-    protected function _createDb($params)
-    {
-        /* Connect to the SQL server using the supplied parameters. */
-        $db = DB::connect($params, array(
-            'persistent' => !empty($params['persistent']),
-            'ssl' => !empty($params['ssl'])
-        ));
-
-        if ($db instanceof PEAR_Error) {
-            throw new Horde_Exception($db);
-        }
-
-        // Set DB portability options.
-        switch ($db->phptype) {
-        case 'mssql':
-            $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
-            break;
-
-        default:
-            $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-            break;
-        }
-
-        return $db;
-    }
-
 }
index 0c3be2d..3e6ce1e 100644 (file)
@@ -248,6 +248,7 @@ class Horde_Registry
             'Horde_Prefs_Identity' => new Horde_Core_Binder_Identity(),
             // 'Horde_Registry' - initialized below
             'Horde_Secret' => new Horde_Core_Binder_Secret(),
+            'Horde_SessionHandler' => new Horde_Core_Binder_SessionHandler(),
             'Horde_Template' => new Horde_Core_Binder_Template(),
             'Horde_Token' => new Horde_Core_Binder_Token(),
             'Horde_Vfs' => new Horde_Core_Binder_Vfs(),
@@ -1550,18 +1551,16 @@ class Horde_Registry
 
         if ($type == 'external') {
             $calls = $conf['sessionhandler']['params'];
-            session_set_save_handler($calls['open'],
-                                     $calls['close'],
-                                     $calls['read'],
-                                     $calls['write'],
-                                     $calls['destroy'],
-                                     $calls['gc']);
+            session_set_save_handler(
+                $calls['open'],
+                $calls['close'],
+                $calls['read'],
+                $calls['write'],
+                $calls['destroy'],
+                $calls['gc']
+            );
         } elseif ($type != 'none') {
-            $sh_config = Horde::getDriverConfig('sessionhandler', $conf['sessionhandler']['type']);
-            if (!empty($conf['sessionhandler']['memcache'])) {
-                $sh_config['memcache'] = $GLOBALS['injector']->getInstance('Horde_Memcache');
-            }
-            $this->sessionHandler = Horde_SessionHandler::factory($conf['sessionhandler']['type'], $sh_config);
+            $this->sessionHandler = $GLOBALS['injector']->getInstance('Horde_SessionHandler');
         }
     }
 
index 7e0ce8f..6d8192b 100644 (file)
@@ -67,6 +67,7 @@ Application Framework.
       <dir name="Binder">
        <file name="Alarm.php" role="php" />
        <file name="Cache.php" role="php" />
+       <file name="Common.php" role="php" />
        <file name="Db.php" role="php" />
        <file name="Dns.php" role="php" />
        <file name="Editor.php" role="php" />
@@ -79,6 +80,7 @@ Application Framework.
        <file name="Notification.php" role="php" />
        <file name="Perms.php" role="php" />
        <file name="Secret.php" role="php" />
+       <file name="SessionHandler.php" role="php" />
        <file name="Template.php" role="php" />
        <file name="Token.php" role="php" />
        <file name="Vfs.php" role="php" />
@@ -217,6 +219,7 @@ Application Framework.
    <install name="lib/Horde/Core/Autoloader/Callback/Mime.php" as="Horde/Core/Autoloader/Callback/Mime.php" />
    <install name="lib/Horde/Core/Binder/Alarm.php" as="Horde/Core/Binder/Alarm.php" />
    <install name="lib/Horde/Core/Binder/Cache.php" as="Horde/Core/Binder/Cache.php" />
+   <install name="lib/Horde/Core/Binder/Common.php" as="Horde/Core/Binder/Common.php" />
    <install name="lib/Horde/Core/Binder/Db.php" as="Horde/Core/Binder/Db.php" />
    <install name="lib/Horde/Core/Binder/Dns.php" as="Horde/Core/Binder/Dns.php" />
    <install name="lib/Horde/Core/Binder/Editor.php" as="Horde/Core/Binder/Editor.php" />
@@ -229,6 +232,7 @@ Application Framework.
    <install name="lib/Horde/Core/Binder/Notification.php" as="Horde/Core/Binder/Notification.php" />
    <install name="lib/Horde/Core/Binder/Perms.php" as="Horde/Core/Binder/Perms.php" />
    <install name="lib/Horde/Core/Binder/Secret.php" as="Horde/Core/Binder/Secret.php" />
+   <install name="lib/Horde/Core/Binder/SessionHandler.php" as="Horde/Core/Binder/SessionHandler.php" />
    <install name="lib/Horde/Core/Binder/Template.php" as="Horde/Core/Binder/Template.php" />
    <install name="lib/Horde/Core/Binder/Token.php" as="Horde/Core/Binder/Token.php" />
    <install name="lib/Horde/Core/Binder/Vfs.php" as="Horde/Core/Binder/Vfs.php" />
index 51c6264..c7b2add 100644 (file)
@@ -3,29 +3,6 @@
  * 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>
- *
- * Required by some database implementations:<pre>
- *   'database'     The name of the database.
- *   'hostspec'     The hostname of the database server.
- *   'username'     The username with which to connect to the database.
- *   'password'     The password associated with 'username'.
- *   'options'      Additional options to pass to the database.
- *   'tty'          The TTY on which to connect to the database.
- *   'port'         The port on which to connect to the database.</pre>
- *
- * Optional parameters:<pre>
- *   'table'               The name of the lock table in 'database'.
- *                         Defaults to 'horde_locks'.
- *
- * Optional values when using separate reading and writing servers, for example
- * in replication settings:<pre>
- *   'splitread'   Boolean, whether to implement the separation or not.
- *   'read'        Array containing the parameters which are different for
- *                 the read database connection, currently supported
- *                 only 'hostspec' and 'port' parameters.</pre>
- *
  * The table structure for the locks is as follows:
  * <pre>
  * CREATE TABLE horde_locks (
@@ -42,7 +19,6 @@
  * );
  * </pre>
  *
- *
  * Copyright 2008-2010 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you did
@@ -70,34 +46,42 @@ class Horde_Lock_Sql extends Horde_Lock_Driver
     private $_write_db;
 
     /**
-     * Boolean indicating whether or not we're connected to the SQL server.
+     * Constructor.
      *
-     * @var boolean
-     */
-    private $_connected = false;
-
-    /**
-     * Constructs a new Horde_Lock_sql object.
+     * @param array $params  Parameters:
+     * <pre>
+     * 'db' - (DB) [REQUIRED] The DB instance.
+     * 'table' - (string) The name of the lock table in 'database'.
+     *           DEFAULT: 'horde_locks'
+     * 'write_db' - (DB) The write DB instance.
+     * </pre>
      *
-     * @param array $params  A hash containing configuration parameters.
+     * @throws Horde_Lock_Exception
      */
     public function __construct($params = array())
     {
-        $this->_params = array_merge(array(
-            'database' => '',
-            'hostspec' => '',
-            'password' => '',
-            'table' => 'horde_locks',
-            'username' => ''
+        if (!isset($params['db'])) {
+            throw new Horde_Lock_Exception('Missing db parameter.');
+        }
+        $this->_db = $params['db'];
+
+        if (isset($params['write_db'])) {
+            $this->_write_db = $params['write_db'];
+        }
+
+        unset($params['db'], $params['write_db']);
+
+        $params = array_merge(array(
+            'table' => 'horde_locks'
         ), $params);
 
+        parent::__construct($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'));
         }
-
-        parent::__construct($this->_params);
     }
 
     /**
@@ -107,8 +91,6 @@ class Horde_Lock_Sql extends Horde_Lock_Driver
      */
     public function getLockInfo($lockid)
     {
-        $this->_connect();
-
         $now = time();
         $sql = 'SELECT lock_id, lock_owner, lock_scope, lock_principal, ' .
                'lock_origin_timestamp, lock_update_timestamp, ' .
@@ -143,8 +125,6 @@ class Horde_Lock_Sql extends Horde_Lock_Driver
      */
     public function getLocks($scope = null, $principal = null, $type = null)
     {
-        $this->_connect();
-
         $now = time();
         $sql = 'SELECT lock_id, lock_owner, lock_scope, lock_principal, ' .
                'lock_origin_timestamp, lock_update_timestamp, ' .
@@ -194,8 +174,6 @@ class Horde_Lock_Sql extends Horde_Lock_Driver
      */
     public function resetLock($lockid, $extend)
     {
-        $this->_connect();
-
         $now = time();
 
         if (!$this->getLockInfo($lockid)) {
@@ -233,8 +211,6 @@ class Horde_Lock_Sql extends Horde_Lock_Driver
     public function setLock($requestor, $scope, $principal,
                             $lifetime = 1, $type = Horde_Lock::TYPE_SHARED)
     {
-        $this->_connect();
-
         $oldlocks = $this->getLocks($scope, $principal, Horde_Lock::TYPE_EXCLUSIVE);
 
         if (count($oldlocks) != 0) {
@@ -276,8 +252,6 @@ class Horde_Lock_Sql extends Horde_Lock_Driver
      */
     public function clearLock($lockid)
     {
-        $this->_connect();
-
         if (empty($lockid)) {
             throw new Horde_Lock_Exception('Must supply a valid lock ID.');
         }
@@ -305,74 +279,10 @@ class Horde_Lock_Sql extends Horde_Lock_Driver
     }
 
     /**
-     * Opens a connection to the SQL server.
-     */
-    private function _connect()
-    {
-        if ($this->_connected) {
-            return;
-        }
-
-        $this->_write_db = DB::connect(
-            $this->_params,
-            array('persistent' => !empty($this->_params['persistent']),
-                  'ssl' => !empty($this->_params['ssl']))
-        );
-        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.
-        $portability = DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS;
-        if ($this->_write_db->phptype) {
-            $portability |= DB_PORTABILITY_RTRIM;
-        }
-        $this->_write_db->setOption('portability', $portability);
-
-        /* Check if we need to set up the read DB connection
-         * seperately. */
-        if (!empty($this->_params['splitread'])) {
-            $params = array_merge($this->_params, $this->_params['read']);
-            $this->_db = DB::connect(
-                $params,
-                array('persistent' => !empty($params['persistent']),
-                      'ssl' => !empty($params['ssl']))
-            );
-            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.
-            $portability = DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS;
-            if ($this->_db->phptype) {
-                $portability |= DB_PORTABILITY_RTRIM;
-            }
-            $this->_db->setOption('portability', $portability);
-        } else {
-            /* Default to the same DB handle for read. */
-            $this->_db = $this->_write_db;
-        }
-
-        $this->_connected = true;
-    }
-
-    /**
      * Do garbage collection needed for the driver.
      */
     private function _doGC()
     {
-        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';
index 4b6a0da..d589976 100644 (file)
@@ -73,20 +73,15 @@ class Horde_Perms
      */
     static public function factory($driver = null, $params = null)
     {
-        if (is_null($params)) {
-            $params = Horde::getDriverConfig('perms', $driver);
-        }
-
-        if (is_null($driver)) {
-            return new self($params);
-        }
+        $class = is_null($driver)
+            ? __CLASS__
+            : __CLASS__ . '_' . ucfirst(basename($driver));
 
-        $class = __CLASS__ . '_' . ucfirst(basename($driver));
-        if (!class_exists($class)) {
-            throw new Horde_Perms_Exception('Bad permissions class name: ' . $class);
+        if (class_exists($class)) {
+            return new $class($params);
         }
 
-        return new $class($params);
+        throw new Horde_Perms_Exception('Unknown driver: ' . $driver);
     }
 
     /**
index 8b10f65..66f0b85 100644 (file)
 class Horde_Perms_Sql extends Horde_Perms
 {
     /**
-     * Boolean indicating whether or not we're connected to the SQL server.
+     * Configuration parameters.
      *
-     * @var boolean
+     * @var array
      */
-    protected $_connected = false;
+    protected $_params = array();
 
     /**
      * Handle for the current database connection.
@@ -56,13 +56,31 @@ class Horde_Perms_Sql extends Horde_Perms
      * @param array $params  Configuration parameters (in addition to base
      *                       Horde_Perms parameters):
      * <pre>
-     * NONE (TODO - pass in SQL object)
+     * 'db' - (DB) [REQUIRED] The DB instance.
+     * 'table' - (string) The name of the perms table in 'database'.
+     *           DEFAULT: 'horde_perms'
+     * 'write_db' - (DB) The write DB instance.
      * </pre>
      *
      * @throws Horde_Perms_Exception
      */
     public function __construct($params = array())
     {
+        if (!isset($params['db'])) {
+            throw new Horde_Perms_Exception('Missing db parameter.');
+        }
+        $this->_db = $params['db'];
+
+        if (isset($params['write_db'])) {
+            $this->_write_db = $params['write_db'];
+        }
+
+        unset($params['db'], $params['write_db']);
+
+        $this->_params = array_merge(array(
+            'table' => 'horde_perms'
+        ), $this->_params, $params);
+
         parent::__construct($params);
     }
 
@@ -109,11 +127,10 @@ class Horde_Perms_Sql extends Horde_Perms
             return $this->_permsCache[$name];
         }
 
-        $this->_connect();
-
         $perm = $this->_cache->get('perm_sql' . $this->_cacheVersion . $name, $GLOBALS['conf']['cache']['default_lifetime']);
         if (empty($perm)) {
-            $query = 'SELECT perm_id, perm_data FROM horde_perms WHERE perm_name = ?';
+            $query = 'SELECT perm_id, perm_data FROM ' .
+                $this->_params['table'] . ' WHERE perm_name = ?';
             $result = $this->_db->getRow($query, array($name), DB_FETCHMODE_ASSOC);
 
             if ($result instanceof PEAR_Error) {
@@ -149,12 +166,11 @@ class Horde_Perms_Sql extends Horde_Perms
      */
     public function getPermissionById($id)
     {
-        $this->_connect();
-
         if ($id == Horde_Perms::ROOT || empty($id)) {
             $object = $this->newPermission(Horde_Perms::ROOT);
         } else {
-            $query = 'SELECT perm_name, perm_data FROM horde_perms WHERE perm_id = ?';
+            $query = 'SELECT perm_name, perm_data FROM ' .
+                $this->_params['table'] . ' WHERE perm_id = ?';
             $result = $this->_db->getRow($query, array($id), DB_FETCHMODE_ASSOC);
 
             if ($result instanceof PEAR_Error) {
@@ -192,8 +208,7 @@ class Horde_Perms_Sql extends Horde_Perms
         $this->_cache->expire('perm_sql' . $this->_cacheVersion . $name);
         $this->_cache->expire('perm_sql_exists_' . $this->_cacheVersion . $name);
 
-        $this->_connect();
-        $id = $this->_write_db->nextId('horde_perms');
+        $id = $this->_write_db->nextId($this->_params['table']);
 
         // remove root from the name
         $root = Horde_Perms::ROOT . ':';
@@ -205,14 +220,16 @@ class Horde_Perms_Sql extends Horde_Perms
         $parents = '';
         if (($pos = strrpos($name, ':')) !== false) {
             $parent_name = substr($name, 0, $pos);
-            $query = 'SELECT perm_id, perm_parents FROM horde_perms WHERE perm_name = ?';
+            $query = 'SELECT perm_id, perm_parents FROM ' .
+                $this->_params['table'] . ' WHERE perm_name = ?';
             $result = $this->_db->getRow($query, array($parent_name), DB_FETCHMODE_ASSOC);
             if (!empty($result)) {
                 $parents = $result['perm_parents'] . ':' . $result['perm_id'];
             }
         }
 
-        $query = 'INSERT INTO horde_perms (perm_id, perm_name, perm_parents) VALUES (?, ?, ?)';
+        $query = 'INSERT INTO ' . $this->_params['table'] .
+            ' (perm_id, perm_name, perm_parents) VALUES (?, ?, ?)';
         $perm->setId($id);
 
         $result = $this->_write_db->query($query, array($id, $name, $parents));
@@ -243,8 +260,8 @@ class Horde_Perms_Sql extends Horde_Perms
         $this->_cache->expire('perm_sql' . $this->_cacheVersion . $name);
         $this->_cache->expire('perm_sql_exists_' . $this->_cacheVersion . $name);
 
-        $this->_connect();
-        $query = 'DELETE FROM horde_perms WHERE perm_name = ?';
+        $query = 'DELETE FROM ' . $this->_params['table'] .
+            ' WHERE perm_name = ?';
         $result = $this->_write_db->query($query, array($name));
         if ($result instanceof PEAR_Error) {
             throw new Horde_Perms_Exception($result);
@@ -252,7 +269,8 @@ class Horde_Perms_Sql extends Horde_Perms
             return $result;
         }
 
-        $query = 'DELETE FROM horde_perms WHERE perm_name LIKE ?';
+        $query = 'DELETE FROM ' . $this->_params['table'] .
+            ' WHERE perm_name LIKE ?';
         return $this->_write_db->query($query, array($name . ':%'));
     }
 
@@ -270,8 +288,8 @@ class Horde_Perms_Sql extends Horde_Perms
             return Horde_Perms::ROOT;
         }
 
-        $this->_connect();
-        $query = 'SELECT perm_id FROM horde_perms WHERE perm_name = ?';
+        $query = 'SELECT perm_id FROM ' . $this->_params['table'] .
+            ' WHERE perm_name = ?';
         return $this->_db->getOne($query, array($permission->getName()));
     }
 
@@ -288,8 +306,8 @@ class Horde_Perms_Sql extends Horde_Perms
         $key = 'perm_sql_exists_' . $this->_cacheVersion . $permission;
         $exists = $this->_cache->get($key, $GLOBALS['conf']['cache']['default_lifetime']);
         if ($exists === false) {
-            $this->_connect();
-            $query = 'SELECT COUNT(*) FROM horde_perms WHERE perm_name = ?';
+            $query = 'SELECT COUNT(*) FROM ' . $this->_params['table'] .
+                ' WHERE perm_name = ?';
             $exists = $this->_db->getOne($query, array($permission));
             if ($exists instanceof PEAR_Error) {
                 throw new Horde_Perms_Exception($exists);
@@ -312,8 +330,8 @@ class Horde_Perms_Sql extends Horde_Perms
      */
     public function getParent($child)
     {
-        $this->_connect();
-        $query = 'SELECT perm_parents FROM horde_perms WHERE perm_name = ?';
+        $query = 'SELECT perm_parents FROM ' . $this->_params['table'] .
+            ' WHERE perm_name = ?';
         $parents = $this->_db->getOne($query, array($child));
 
         if ($parents instanceof PEAR_Error) {
@@ -338,8 +356,8 @@ class Horde_Perms_Sql extends Horde_Perms
      */
     public function getParents($child)
     {
-        $this->_connect();
-        $query = 'SELECT perm_parents FROM horde_perms WHERE perm_name = ?';
+        $query = 'SELECT perm_parents FROM ' .  $this->_params['table'] .
+            ' WHERE perm_name = ?';
         $result = $this->_db->getOne($query, array($child));
         if ($result instanceof PEAR_Error) {
             throw new Horde_Perms_Exception($result);
@@ -373,8 +391,8 @@ class Horde_Perms_Sql extends Horde_Perms
      */
     public function getTree()
     {
-        $this->_connect();
-        $query = 'SELECT perm_id, perm_name FROM horde_perms ORDER BY perm_name ASC';
+        $query = 'SELECT perm_id, perm_name FROM ' . $this->_params['table'] .
+            ' ORDER BY perm_name ASC';
         $tree = $this->_db->getAssoc($query);
         if ($tree instanceof PEAR_Error) {
             throw new Horde_Perms_Exception($tree);
@@ -384,73 +402,4 @@ class Horde_Perms_Sql extends Horde_Perms
         return $tree;
     }
 
-    /**
-     * Attempts to open a connection to the sql server.
-     *
-     * @throws Horde_Perms_Exception
-     */
-    protected function _connect()
-    {
-        if ($this->_connected) {
-            return;
-        }
-
-        $_params = $GLOBALS['conf']['sql'];
-        if (!isset($_params['database'])) {
-            $_params['database'] = '';
-        }
-        if (!isset($_params['username'])) {
-            $_params['username'] = '';
-        }
-        if (!isset($_params['hostspec'])) {
-            $_params['hostspec'] = '';
-        }
-
-        /* Connect to the sql server using the supplied parameters. */
-        $this->_write_db = DB::connect($_params,
-                                       array('persistent' => !empty($_params['persistent']),
-                                             'ssl' => !empty($this->_params['ssl'])));
-        if ($this->_write_db instanceof PEAR_Error) {
-            throw new Horde_Perms_Exception($this->_write_db);
-        }
-
-        /* Set DB portability options. */
-        switch ($this->_write_db->phptype) {
-        case 'mssql':
-            $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
-            break;
-
-        default:
-            $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-            break;
-        }
-
-        /* Check if we need to set up the read DB connection seperately. */
-        if (!empty($_params['splitread'])) {
-            $params = array_merge($_params, $_params['read']);
-            $this->_db = DB::connect($params,
-                                     array('persistent' => !empty($params['persistent']),
-                                           'ssl' => !empty($params['ssl'])));
-            if ($this->_db instanceof PEAR_Error) {
-                throw new Horde_Perms_Exception($this->_db);
-            }
-
-            /* Set DB portability options. */
-            switch ($this->_db->phptype) {
-            case 'mssql':
-                $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
-                break;
-
-            default:
-                $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-                break;
-            }
-        } else {
-            /* Default to the same DB handle for the writer too. */
-            $this->_db = $this->_write_db;
-        }
-
-        $this->_connected = true;
-    }
-
 }
index b2aea32..3eac8df 100644 (file)
@@ -3,31 +3,6 @@
  * Horde_SessionHandler implementation for PHP's PEAR database abstraction
  * layer.
  *
- * Required parameters:<pre>
- *   'phptype'  - (string) The database type (e.g. 'pgsql', 'mysql', etc.).
- *   'hostspec' - (string) The hostname of the database server.
- *   'protocol' - (string) The communication protocol ('tcp', 'unix', etc.).
- *   'username' - (string) The username with which to connect to the database.
- *   'password' - (string) The password associated with 'username'.
- *   'database' - (string) The name of the database.
- *   'options'  - (array) Additional options to pass to the database.
- *   'tty'      - (string) The TTY on which to connect to the database.
- *   'port'     - (integer) The port on which to connect to the database.
- * </pre>
- *
- * Optional parameters:<pre>
- *   'table'      - (string) The name of the sessiondata table in 'database'.
- *   'persistent' - (boolean) Use persistent DB connections?
- * </pre>
- *
- * Optional values when using separate reading and writing servers, for example
- * in replication settings:<pre>
- *   'splitread' - (boolean) Whether to implement the separation or not.
- *   'read'      - (array) Array containing the parameters which are
- *                 different for the writer database connection, currently
- *                 supports only 'hostspec' and 'port' parameters.
- * </pre>
- *
  * The table structure can be found in:
  *   horde/scripts/sql/horde_sessionhandler.sql.
  *
@@ -57,57 +32,39 @@ class Horde_SessionHandler_Sql extends Horde_SessionHandler
     protected $_write_db;
 
     /**
-     * Attempts to open a connection to the SQL server.
+     * Constructor.
      *
-     * @param string $save_path     The path to the session object.
-     * @param string $session_name  The name of the session.
+     * @param array $params  Parameters:
+     * <pre>
+     * 'db' - (DB) [REQUIRED] The DB instance.
+     * 'persistent' - (boolean) Use persistent DB connections?
+     *                DEFAULT: false
+     * 'table' - (string) The name of the tokens table in 'database'.
+     *           DEFAULT: 'horde_tokens'
+     * 'write_db' - (DB) The write DB instance.
+     * </pre>
      *
      * @throws Horde_Exception
      */
-    protected function _open($save_path = null, $session_name = null)
+    public function __construct($params = array())
     {
-        Horde::assertDriverConfig($this->_params, 'sessionhandler',
-                                  array('phptype'),
-                                  'session handler SQL');
-
-        if (!isset($this->_params['database'])) {
-            $this->_params['database'] = '';
-        }
-        if (!isset($this->_params['username'])) {
-            $this->_params['username'] = '';
-        }
-        if (!isset($this->_params['hostspec'])) {
-            $this->_params['hostspec'] = '';
-        }
-        if (empty($this->_params['table'])) {
-            $this->_params['table'] = 'horde_sessionhandler';
+        if (!isset($params['db'])) {
+            throw new Horde_Exception('Missing db parameter.');
         }
+        $this->_db = $params['db'];
 
-        /* Connect to the SQL server using the supplied parameters. */
-        $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')) {
-            throw new Horde_Exception_Prior($this->_write_db);
+        if (isset($params['write_db'])) {
+            $this->_write_db = $params['write_db'];
         }
 
-        $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-
-        /* Check if we need to set up the read DB connection
-         * seperately. */
-        if (!empty($this->_params['splitread'])) {
-            $params = array_merge($this->_params, $this->_params['read']);
-            $this->_db = DB::connect($params,
-                                     array('persistent' => !empty($params['persistent']),
-                                           'ssl' => !empty($params['ssl'])));
-            if (is_a($this->_db, 'PEAR_Error')) {
-                throw new Horde_Exception_Prior($this->_db);
-            }
-            $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-        } else {
-            /* Default to the same DB handle for reads. */
-            $this->_db =& $this->_write_db;
-        }
+        unset($params['db'], $params['write_db']);
+
+        $params = array_merge(array(
+            'persistent' => false,
+            'table' => 'horde_sessionhandler'
+        ), $params);
+
+        parent::__construct($params);
     }
 
     /**
@@ -120,11 +77,13 @@ class Horde_SessionHandler_Sql extends Horde_SessionHandler
         /* Close any open transactions. */
         $this->_db->commit();
         $this->_db->autoCommit(true);
-        $this->_write_db->commit();
-        $this->_write_db->autoCommit(true);
-
-        @$this->_write_db->disconnect();
         @$this->_db->disconnect();
+
+        if ($this->_write_db) {
+            $this->_write_db->commit();
+            $this->_write_db->autoCommit(true);
+            @$this->_write_db->disconnect();
+        }
     }
 
     /**