Index: trunk/lib/DB.inc.php
===================================================================
--- trunk/lib/DB.inc.php	(revision 718)
+++ trunk/lib/DB.inc.php	(revision 719)
@@ -172,5 +172,5 @@
         // Connect to database. Always create a new link to the server.
         // Connection errors are suppressed so we can do our own error management below.
-        if ($this->dbh = @mysql_connect($this->getParam('db_server'), $this->getParam('db_user'), $this->getParam('db_pass'), true)) {
+        if ($this->dbh = mysql_connect($this->getParam('db_server'), $this->getParam('db_user'), $this->getParam('db_pass'), true)) {
             // Select database
             mysql_select_db($this->getParam('db_name'), $this->dbh);
Index: trunk/lib/PDO.inc.php
===================================================================
--- trunk/lib/PDO.inc.php	(revision 718)
+++ trunk/lib/PDO.inc.php	(revision 719)
@@ -242,9 +242,10 @@
 
         if (!$this->_connected) {
-            $app->logMsg(sprintf('No DB connection to run %s', __METHOD__), LOG_NOTICE, __FILE__, __LINE__);
-            return false;
-        }
+            throw new \Exception(sprintf('No DB connection to run %s', __METHOD__));
+        }
+
         $this->_connected = false;
         $this->dbh = null;
+
         return true;
     }
@@ -280,6 +281,5 @@
 
         if (!$this->_connected) {
-            $app->logMsg(sprintf('No DB connection to run %s', __METHOD__), LOG_NOTICE, __FILE__, __LINE__);
-            return false;
+            throw new \Exception(sprintf('No DB connection to run %s', __METHOD__));
         }
 
@@ -374,6 +374,5 @@
 
         if (!$this->_connected) {
-            $app->logMsg(sprintf('No DB connection to run %s', __METHOD__), LOG_NOTICE, __FILE__, __LINE__);
-            return false;
+            throw new \Exception(sprintf('No DB connection to run %s', __METHOD__));
         }
 
@@ -431,6 +430,5 @@
 
         if (!$this->_connected) {
-            $app->logMsg(sprintf('No DB connection to run %s', __METHOD__), LOG_NOTICE, __FILE__, __LINE__);
-            return false;
+            throw new \Exception(sprintf('No DB connection to run %s', __METHOD__));
         }
 
@@ -527,6 +525,5 @@
 
         if (!$this->_connected) {
-            $app->logMsg(sprintf('No DB connection to run %s', __METHOD__), LOG_NOTICE, __FILE__, __LINE__);
-            return false;
+            throw new \Exception(sprintf('No DB connection to run %s', __METHOD__));
         }
 
@@ -558,6 +555,5 @@
 
         if (!$this->_connected) {
-            $app->logMsg(sprintf('No DB connection to run %s', __METHOD__), LOG_NOTICE, __FILE__, __LINE__);
-            return false;
+            throw new \Exception(sprintf('No DB connection to run %s', __METHOD__));
         }
 
Index: trunk/lib/Prefs.inc.php
===================================================================
--- trunk/lib/Prefs.inc.php	(revision 718)
+++ trunk/lib/Prefs.inc.php	(revision 719)
@@ -121,8 +121,12 @@
         $this->setParam($params);
 
-        // Run Prefs->save() upon script completion if we're using the database storagetype.
-        // This only works if 'storagetype' is provided as a parameter to the constructor rather than via setParam() later.
-        if ('database' == $this->getParam('storagetype')) {
-            register_shutdown_function(array($this, 'save'));
+        if (isset($params['save_on_shutdown']) && $params['save_on_shutdown']) {
+            // Run Prefs->save() upon script completion if we're using the database storagetype.
+            // This only works if:
+            // - 'storagetype' is provided as a parameter to the constructor rather than via setParam() later.
+            // - $app->stop() is not called at the end of the script (which would close the PDO connection before the shutdown function runs).
+            if ('database' == $this->getParam('storagetype')) {
+                register_shutdown_function(array($this, 'save'));
+            }
         }
     }
@@ -138,5 +142,5 @@
     {
         $app =& App::getInstance();
-        $db =& DB::getInstance();
+        $pdo =& \Strangecode\Codebase\PDO::getInstance();
 
         static $_db_tested = false;
@@ -144,16 +148,18 @@
         if ($recreate_db || !$_db_tested && $this->getParam('create_table')) {
             if ($recreate_db) {
-                $db->query("DROP TABLE IF EXISTS " . $this->getParam('db_table'));
+                $pdo->query(sprintf("DROP TABLE IF EXISTS `%s`", $pdo->sanitizeIdentifier($this->getParam('db_table'))));
                 $app->logMsg(sprintf('Dropping and recreating table %s.', $this->getParam('db_table')), LOG_INFO, __FILE__, __LINE__);
             }
-            $db->query("CREATE TABLE IF NOT EXISTS " . $db->escapeString($this->getParam('db_table')) . " (
-                user_id VARCHAR(32) NOT NULL DEFAULT '',
-                pref_namespace VARCHAR(32) NOT NULL DEFAULT '',
-                pref_key VARCHAR(64) NOT NULL DEFAULT '',
-                pref_value TEXT,
-                PRIMARY KEY (user_id, pref_namespace, pref_key)
-            )");
-
-            if (!$db->columnExists($this->getParam('db_table'), array(
+            $stmt = $pdo->query(sprintf("
+                CREATE TABLE IF NOT EXISTS `%s` (
+                    `user_id` VARCHAR(32) NOT NULL DEFAULT '',
+                    `pref_namespace` VARCHAR(32) NOT NULL DEFAULT '',
+                    `pref_key` VARCHAR(64) NOT NULL DEFAULT '',
+                    `pref_value` TEXT,
+                    PRIMARY KEY (`user_id`, `pref_namespace`, `pref_key`)
+                )
+            ", $pdo->sanitizeIdentifier($this->getParam('db_table'))));
+
+            if (!$pdo->columnExists($this->getParam('db_table'), array(
                 'user_id',
                 'pref_namespace',
@@ -328,7 +334,7 @@
             || (isset($_SESSION['_prefs'][$this->_ns]['saved']) && array_key_exists($key, $_SESSION['_prefs'][$this->_ns]['saved']))) {
                 $_SESSION['_prefs'][$this->_ns]['saved'][$key] = $val;
-                $app->logMsg(sprintf('Setting session preference %s => %s', $key, getDump($val, true)), LOG_DEBUG, __FILE__, __LINE__);
+                $app->logMsg(sprintf('Setting session/database preference %s => %s', $key, getDump($val, true)), LOG_DEBUG, __FILE__, __LINE__);
             } else {
-                $app->logMsg(sprintf('Not setting session preference %s => %s', $key, getDump($val, true)), LOG_DEBUG, __FILE__, __LINE__);
+                $app->logMsg(sprintf('Not setting session/database preference %s => %s', $key, getDump($val, true)), LOG_DEBUG, __FILE__, __LINE__);
             }
             break;
@@ -499,5 +505,5 @@
     {
         $app =& App::getInstance();
-        $db =& DB::getInstance();
+        $pdo =& \Strangecode\Codebase\PDO::getInstance();
 
         // Skip this method if not using the db.
@@ -526,16 +532,11 @@
 
         // Retrieve all prefs for this user and namespace.
-        $qid = $db->query("
-            SELECT pref_key, pref_value
-            FROM " . $db->escapeString($this->getParam('db_table')) . "
-            WHERE user_id = '" . $db->escapeString($this->getParam('user_id')) . "'
-            AND pref_namespace = '" . $db->escapeString($this->getParam('namespace')) . "'
-            LIMIT 10000
-        ");
-        while (list($key, $val) = mysql_fetch_row($qid)) {
+        $stmt = $pdo->prepare(sprintf("SELECT `pref_key`, `pref_value` FROM `%s` WHERE `user_id` = ? AND `pref_namespace` = ? LIMIT 100000", $pdo->sanitizeIdentifier($this->getParam('db_table'))));
+        $stmt->execute([$this->getParam('user_id'), $this->getParam('namespace')]);
+        while (list($key, $val) = $stmt->fetch(\PDO::FETCH_NUM)) {
             $_SESSION['_prefs'][$this->_ns]['saved'][$key] = unserialize($val);
         }
 
-        $app->logMsg(sprintf('Loaded %s prefs from database.', mysql_num_rows($qid)), LOG_DEBUG, __FILE__, __LINE__);
+        $app->logMsg(sprintf('Loaded %s prefs from database.', sizeof($_SESSION['_prefs'][$this->_ns]['saved'])), LOG_DEBUG, __FILE__, __LINE__);
 
         // Data loaded only once per session.
@@ -587,5 +588,5 @@
     {
         $app =& App::getInstance();
-        $db =& DB::getInstance();
+        $pdo =& \Strangecode\Codebase\PDO::getInstance();
 
         // Skip this method if not using the db.
@@ -607,27 +608,24 @@
         if (isset($_SESSION['_prefs'][$this->_ns]['saved']) && is_array($_SESSION['_prefs'][$this->_ns]['saved']) && ($allow_empty || !empty($_SESSION['_prefs'][$this->_ns]['saved']))) {
             // Delete old prefs from database.
-            $db->query("
-                DELETE FROM " . $db->escapeString($this->getParam('db_table')) . "
-                WHERE user_id = '" . $db->escapeString($this->getParam('user_id')) . "'
-                AND pref_namespace = '" . $db->escapeString($this->getParam('namespace')) . "'
-            ");
+            $stmt = $pdo->prepare(sprintf("DELETE FROM `%s` WHERE `user_id` = ? AND `pref_namespace` = ?", $pdo->sanitizeIdentifier($this->getParam('db_table'))));
+            $stmt->execute([$this->getParam('user_id'), $this->getParam('namespace')]);
 
             // Insert new prefs.
             $insert_values = array();
             foreach ($_SESSION['_prefs'][$this->_ns]['saved'] as $key => $val) {
-                $insert_values[] = sprintf("('%s', '%s', '%s', '%s')",
-                    $db->escapeString($this->getParam('user_id')),
-                    $db->escapeString($this->getParam('namespace')),
-                    $db->escapeString($key),
-                    $db->escapeString(serialize($val))
+                $insert_values[] = sprintf("(%s, %s, %s, %s)",
+                    $pdo->quote($this->getParam('user_id')),
+                    $pdo->quote($this->getParam('namespace')),
+                    $pdo->quote($key),
+                    $pdo->quote(serialize($val))
                 );
             }
             if (!empty($insert_values)) {
-                // TODO: after MySQL 5.0.23 is released this query could benefit from INSERT DELAYED.
-                $db->query("
-                    INSERT INTO " . $db->escapeString($this->getParam('db_table')) . "
-                    (user_id, pref_namespace, pref_key, pref_value)
-                    VALUES " . join(', ', $insert_values) . "
-                ");
+                $stmt = $pdo->query(sprintf("
+                    INSERT INTO `%s`
+                    (`user_id`, `pref_namespace`, `pref_key`, `pref_value`)
+                    VALUES
+                    %s
+                ", $pdo->sanitizeIdentifier($this->getParam('db_table')), join(', ', $insert_values)));
                 $app->logMsg(sprintf('Saved %s prefs to database for user_id %s.', sizeof($insert_values), $this->getParam('user_id')), LOG_DEBUG, __FILE__, __LINE__);
             }
