Aleksander Machniak
2012-06-19 398bff59254590cbaebec7d62b1f000f271648aa
Replace rcube_mdb2/PEAR::MDB2 with rcube_db
8 files modified
139 ■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
bin/update.sh 2 ●●● patch | view | raw | blame | history
installer/check.php 25 ●●●● patch | view | raw | blame | history
installer/config.php 9 ●●●● patch | view | raw | blame | history
installer/rcube_install.php 94 ●●●● patch | view | raw | blame | history
installer/test.php 4 ●●●● patch | view | raw | blame | history
installer/utils.php 2 ●●●●● patch | view | raw | blame | history
program/include/rcube_shared.inc 2 ●●● patch | view | raw | blame | history
CHANGELOG
@@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Add new DB abstraction layer based on PHP PDO, supporting SQLite3 (#1488332)
- Fix handling of unitless CSS size values in HTML message (#1488535)
- Fix removing contact photo using LDAP addressbook (#1488420)
- Fix storing X-ANNIVERSARY date in vCard format (#1488527)
bin/update.sh
@@ -137,7 +137,7 @@
  // check database schema
  if ($RCI->config['db_dsnw']) {
    $DB = new rcube_mdb2($RCI->config['db_dsnw'], '', false);
    $DB = new rcube_db::factory($RCI->config['db_dsnw'], '', false);
    $DB->db_connect('w');
    if ($db_error_msg = $DB->is_error()) {
      echo "Error connecting to database: $db_error_msg\n";
installer/check.php
@@ -6,7 +6,8 @@
    'DOM'       => 'dom',
    'Session'   => 'session',
    'XML'       => 'xml',
    'JSON'      => 'json'
    'JSON'      => 'json',
    'PDO'       => 'PDO',
);
$optional_php_exts = array(
@@ -21,17 +22,9 @@
$required_libs = array(
    'PEAR'      => 'PEAR.php',
    'MDB2'      => 'MDB2.php',
    'Net_SMTP'  => 'Net/SMTP.php',
    'Net_IDNA2' => 'Net/IDNA2.php',
    'Mail_mime' => 'Mail/mime.php',
);
$supported_dbs = array(
    'MySQL'         => 'mysql',
    'MySQLi'        => 'mysqli',
    'PostgreSQL'    => 'pgsql',
    'SQLite (v2)'   => 'sqlite',
);
$ini_checks = array(
@@ -61,8 +54,14 @@
    'DOM'       => 'http://www.php.net/manual/en/book.dom.php',
    'Intl'      => 'http://www.php.net/manual/en/book.intl.php',
    'Exif'      => 'http://www.php.net/manual/en/book.exif.php',
    'PDO'       => 'http://www.php.net/manual/en/book.pdo.php',
    'pdo_mysql'   => 'http://www.php.net/manual/en/book.pdo-mysql.php',
    'pdo_pgsql'   => 'http://www.php.net/manual/en/book.pdo-pgsql.php',
    'pdo_sqlite'  => 'http://www.php.net/manual/en/book.pdo-sqlite.php',
    'pdo_sqlite2' => 'http://www.php.net/manual/en/book.pdo-sqlite.php',
    'pdo_sqlsrv'  => 'http://www.php.net/manual/en/book.pdo-sqlsrv.php',
    'pdo_dblib'   => 'http://www.php.net/manual/en/book.pdo-dblib.php',
    'PEAR'      => 'http://pear.php.net',
    'MDB2'      => 'http://pear.php.net/package/MDB2',
    'Net_SMTP'  => 'http://pear.php.net/package/Net_SMTP',
    'Mail_mime' => 'http://pear.php.net/package/Mail_mime',
    'Net_IDNA2' => 'http://pear.php.net/package/Net_IDNA2',
@@ -127,14 +126,14 @@
<?php
$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
foreach ($supported_dbs as $database => $ext) {
foreach ($RCI->supported_dbs as $database => $ext) {
    if (extension_loaded($ext)) {
        $RCI->pass($database);
    }
    else {
        $_ext = $ext_dir . '/' . $prefix . $ext . '.' . PHP_SHLIB_SUFFIX;
        $msg = @is_readable($_ext) ? 'Could be loaded. Please add in php.ini' : 'Not installed';
        $RCI->na($database, $msg, $source_urls[$database]);
        $msg = @is_readable($_ext) ? 'Could be loaded. Please add in php.ini' : '';
        $RCI->na($database, $msg, $source_urls[$ext]);
    }
    echo '<br />';
}
installer/config.php
@@ -267,13 +267,8 @@
<p>Database settings for read/write operations:</p>
<?php
require_once 'MDB2.php';
$supported_dbs = array('MySQL' => 'mysql', 'MySQLi' => 'mysqli',
    'PgSQL' => 'pgsql', 'SQLite' => 'sqlite');
$select_dbtype = new html_select(array('name' => '_dbtype', 'id' => "cfgdbtype"));
foreach ($supported_dbs AS $database => $ext) {
foreach ($RCI->supported_dbs as $database => $ext) {
    if (extension_loaded($ext)) {
        $select_dbtype->add($database, $ext);
    }
@@ -284,7 +279,7 @@
$input_dbuser = new html_inputfield(array('name' => '_dbuser', 'size' => 20, 'id' => "cfgdbuser"));
$input_dbpass = new html_passwordfield(array('name' => '_dbpass', 'size' => 20, 'id' => "cfgdbpass"));
$dsnw = MDB2::parseDSN($RCI->getprop('db_dsnw'));
$dsnw = rcube_db::parse_dsn($RCI->getprop('db_dsnw'));
echo $select_dbtype->show($RCI->is_post ? $_POST['_dbtype'] : $dsnw['phptype']);
echo '<label for="cfgdbtype">Database type</label><br />';
installer/rcube_install.php
@@ -50,6 +50,17 @@
    'des_key', 'session_lifetime', 'support_url',
  );
  // list of supported database drivers
  var $supported_dbs = array(
    'MySQL'               => 'pdo_mysql',
    'PostgreSQL'          => 'pdo_pgsql',
    'SQLite'              => 'pdo_sqlite',
    'SQLite (v2)'         => 'pdo_sqlite2',
    'SQL Server (SQLSRV)' => 'pdo_sqlsrv',
    'SQL Server (DBLIB)'  => 'pdo_dblib',
  );
  /**
   * Constructor
   */
@@ -371,7 +382,7 @@
          $errors[] = "Missing columns in table '$table': " . join(',', $diff);
      }
    }
    return !empty($errors) ? $errors : false;
  }
@@ -394,87 +405,8 @@
        }
      }
    }
    return $schema;
  }
  /**
   * Compare the local database schema with the reference schema
   * required for this version of Roundcube
   *
   * @param boolean True if the schema schould be updated
   * @return boolean True if the schema is up-to-date, false if not or an error occured
   */
  function mdb2_schema_check($update = false)
  {
    if (!$this->configured)
      return false;
    $options = array(
      'use_transactions' => false,
      'log_line_break' => "\n",
      'idxname_format' => '%s',
      'debug' => false,
      'quote_identifier' => true,
      'force_defaults' => false,
      'portability' => true
    );
    $dsnw = $this->config['db_dsnw'];
    $schema = MDB2_Schema::factory($dsnw, $options);
    $schema->db->supported['transactions'] = false;
    if (PEAR::isError($schema)) {
      $this->raise_error(array('code' => $schema->getCode(), 'message' => $schema->getMessage() . ' ' . $schema->getUserInfo()));
      return false;
    }
    else {
      $definition = $schema->getDefinitionFromDatabase();
      $definition['charset'] = 'utf8';
      if (PEAR::isError($definition)) {
        $this->raise_error(array('code' => $definition->getCode(), 'message' => $definition->getMessage() . ' ' . $definition->getUserInfo()));
        return false;
      }
      // load reference schema
      $dsn_arr = MDB2::parseDSN($this->config['db_dsnw']);
      $ref_schema = INSTALL_PATH . 'SQL/' . $dsn_arr['phptype'] . '.schema.xml';
      if (is_readable($ref_schema)) {
        $reference = $schema->parseDatabaseDefinition($ref_schema, false, array(), $schema->options['fail_on_invalid_names']);
        if (PEAR::isError($reference)) {
          $this->raise_error(array('code' => $reference->getCode(), 'message' => $reference->getMessage() . ' ' . $reference->getUserInfo()));
        }
        else {
          $diff = $schema->compareDefinitions($reference, $definition);
          if (empty($diff)) {
            return true;
          }
          else if ($update) {
            // update database schema with the diff from the above check
            $success = $schema->alterDatabase($reference, $definition, $diff);
            if (PEAR::isError($success)) {
              $this->raise_error(array('code' => $success->getCode(), 'message' => $success->getMessage() . ' ' . $success->getUserInfo()));
            }
            else
              return true;
          }
          echo '<pre>'; var_dump($diff); echo '</pre>';
          return false;
        }
      }
      else
        $this->raise_error(array('message' => "Could not find reference schema file ($ref_schema)"));
        return false;
    }
    return false;
  }
installer/test.php
@@ -125,9 +125,9 @@
$db_working = false;
if ($RCI->configured) {
    if (!empty($RCI->config['db_dsnw'])) {
        $DB = new rcube_mdb2($RCI->config['db_dsnw'], '', false);
        $DB = new rcube_db::factory($RCI->config['db_dsnw'], '', false);
        $DB->db_connect('w');
        if (!($db_error_msg = $DB->is_error())) {
            $RCI->pass('DSN (write)');
            echo '<br />';
installer/utils.php
@@ -23,7 +23,6 @@
{
    $filename = preg_replace(
        array(
            '/MDB2_(.+)/',
            '/Mail_(.+)/',
            '/Net_(.+)/',
            '/Auth_(.+)/',
@@ -31,7 +30,6 @@
            '/^utf8$/'
        ),
        array(
            'MDB2/\\1',
            'Mail/\\1',
            'Net/\\1',
            'Auth/\\1',
program/include/rcube_shared.inc
@@ -407,7 +407,7 @@
            '/^utf8$/',
        ),
        array(
            'MDB2/\\1',
            'Mail/\\1',
            'Mail/\\1',
            'Net/\\1',
            'Auth/\\1',