]> source.dussan.org Git - nextcloud-server.git/commitdiff
merge master into doctrine-object
authorRobin Appelman <icewind@owncloud.com>
Fri, 2 Aug 2013 17:53:04 +0000 (19:53 +0200)
committerRobin Appelman <icewind@owncloud.com>
Fri, 2 Aug 2013 17:53:04 +0000 (19:53 +0200)
1  2 
lib/db.php
lib/db/adapter.php
lib/db/connection.php

diff --cc lib/db.php
index 102782ac6ba28f9bceb085cbc7e0140a68a254fe,dd48c3294907cd3ddcbaa2f1ae11381778b4438e..fec4eaaf93fd0cc038170e227fd94eceadffc9fc
@@@ -41,18 -41,36 +41,15 @@@ class DatabaseException extends Excepti
   * Doctrine with some adaptions.
   */
  class OC_DB {
 -      const BACKEND_DOCTRINE=2;
 -
 -      static private $preparedQueries = array();
 -      static private $cachingEnabled = true;
 -
 -      /**
 -       * @var \Doctrine\DBAL\Connection
 -       */
 -      static private $connection; //the preferred connection to use, only Doctrine
 -      static private $backend=null;
        /**
-        * @var \Doctrine\DBAL\Connection
-        */
-       /**
--       * @var \Doctrine\DBAL\Connection
++       * @var \OC\DB\Connection $connection
         */
 -      static private $DOCTRINE=null;
 +      static private $connection; //the prefered connection to use, only Doctrine
  
 -      static private $inTransaction=false;
 -      static private $prefix=null;
        static private $type=null;
  
 -      /**
 -       * check which backend we should use
 -       * @return int BACKEND_DOCTRINE
 -       */
 -      private static function getDBBackend() {
 -              return self::BACKEND_DOCTRINE;
 -      }
 -
        /**
         * @brief connects to the database
 -       * @param int $backend
         * @return bool true if connection can be established or false on error
         *
         * Connects to the database as specified in config.php
                return true;
        }
  
++      /**
++       * @return \OC\DB\Connection
++       */
 +      static public function getConnection() {
 +              self::connect();
 +              return self::$connection;
 +      }
 +
        /**
         * @brief Prepare a SQL query
         * @param string $query Query string
index 2e4f230f366e1c145e72027b9863d4001582a12f,0000000000000000000000000000000000000000..6b31f37dd988333a4375d56e31e5a679b0fdf6b3
mode 100644,000000..100644
--- /dev/null
@@@ -1,70 -1,0 +1,72 @@@
-        * @param $statement that needs to be changed so the db can handle it
 +<?php
 +/**
 + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
 + * This file is licensed under the Affero General Public License version 3 or
 + * later.
 + * See the COPYING-README file.
 + */
 +
 +namespace OC\DB;
 +
 +/**
 + * This handles the way we use to write queries, into something that can be
 + * handled by the database abstraction layer.
 + */
 +class Adapter {
++
++      /**
++       * @var \OC\DB\Connection $conn
++       */
 +      protected $conn;
 +
 +      public function __construct($conn) {
 +              $this->conn = $conn;
 +      }
 +
 +      /**
 +       * @param string $table name
 +       * @return int id of last insert statement
 +       */
 +      public function lastInsertId($table) {
 +              return $this->conn->realLastInsertId($table);
 +      }
 +
 +      /**
-        * @param array key->value pairs 
-        * @return count of inserted rows
++       * @param string $statement that needs to be changed so the db can handle it
 +       * @return string changed statement
 +       */
 +      public function fixupStatement($statement) {
 +              return $statement;
 +      }
 +
 +      /**
 +       * @brief insert the @input values when they do not exist yet
 +       * @param string $table name
-                       $result = $this->conn->executeUpdate($query, $inserts);
++       * @param array $input key->value pairs
++       * @return int count of inserted rows
 +       */
 +      public function insertIfNotExist($table, $input) {
 +              $query = 'INSERT INTO `' .$table . '` (`'
 +                      . implode('`,`', array_keys($input)) . '`) SELECT '
 +                      . str_repeat('?,', count($input)-1).'? ' // Is there a prettier alternative?
 +                      . 'FROM `' . $table . '` WHERE ';
 +
 +              foreach($input as $key => $value) {
 +                      $query .= '`' . $key . '` = ? AND ';
 +              }
 +              $query = substr($query, 0, strlen($query) - 5);
 +              $query .= ' HAVING COUNT(*) = 0';
 +              $inserts = array_values($input);
 +              $inserts = array_merge($inserts, $inserts);
 +
 +              try {
-               return $result;
++                      return $this->conn->executeUpdate($query, $inserts);
 +              } catch(\Doctrine\DBAL\DBALException $e) {
 +                      $entry = 'DB Error: "'.$e->getMessage() . '"<br />';
 +                      $entry .= 'Offending command was: ' . $query.'<br />';
 +                      \OC_Log::write('core', $entry, \OC_Log::FATAL);
 +                      error_log('DB error: ' . $entry);
 +                      \OC_Template::printErrorPage( $entry );
 +              }
 +      }
 +}
index 1f01fae4f71236d8a249aabb940d0e71d7823521,0000000000000000000000000000000000000000..920fe144a8aaa9d1106f3dcd9a1dc9b62d0ec46d
mode 100644,000000..100644
--- /dev/null
@@@ -1,181 -1,0 +1,197 @@@
-        * @param Driver $driver
-        * @param Configuration $config
-        * @param EventManager $eventManager
 +<?php
 +/**
 + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
 + * This file is licensed under the Affero General Public License version 3 or
 + * later.
 + * See the COPYING-README file.
 + */
 +
 +namespace OC\DB;
 +use Doctrine\DBAL\Driver;
 +use Doctrine\DBAL\Configuration;
 +use Doctrine\DBAL\Cache\QueryCacheProfile;
 +use Doctrine\Common\EventManager;
 +
 +class Connection extends \Doctrine\DBAL\Connection {
++      /**
++       * @var string $table_prefix
++       */
 +      protected $table_prefix;
 +
++      /**
++       * @var \OC\DB\Adapter $adapter
++       */
 +      protected $adapter;
 +
++      /**
++       * @var \Doctrine\DBAL\Driver\Statement[] $preparedQueries
++       */
 +      protected $preparedQueries = array();
++
 +      protected $cachingQueryStatementEnabled = true;
 +
 +      /**
 +       * Initializes a new instance of the Connection class.
 +       *
 +       * @param array $params  The connection parameters.
-                       throw new Exception('adapter not set');
++       * @param \Doctrine\DBAL\Driver $driver
++       * @param \Doctrine\DBAL\Configuration $config
++       * @param \Doctrine\Common\EventManager $eventManager
++       * @throws \Exception
 +       */
 +      public function __construct(array $params, Driver $driver, Configuration $config = null,
 +              EventManager $eventManager = null)
 +      {
 +              if (!isset($params['adapter'])) {
-                       throw new Exception('table_prefix not set');
++                      throw new \Exception('adapter not set');
 +              }
 +              if (!isset($params['table_prefix'])) {
-        * @returns bool The return value from execute()
++                      throw new \Exception('table_prefix not set');
 +              }
 +              parent::__construct($params, $driver, $config, $eventManager);
 +              $this->adapter = new $params['adapter']($this);
 +              $this->table_prefix = $params['table_prefix'];
 +      }
 +
 +      /**
 +       * Prepares an SQL statement.
 +       *
 +       * @param string $statement The SQL statement to prepare.
++       * @param int $limit
++       * @param int $offset
 +       * @return \Doctrine\DBAL\Driver\Statement The prepared statement.
 +       */
 +      public function prepare( $statement, $limit=null, $offset=null ) {
 +              $statement = $this->replaceTablePrefix($statement);
 +              $statement = $this->adapter->fixupStatement($statement);
 +
 +              if ($limit === -1) {
 +                      $limit = null;
 +              }
 +              if (!is_null($limit)) {
 +                      $platform = $this->getDatabasePlatform();
 +                      $statement = $platform->modifyLimitQuery($statement, $limit, $offset);
 +              } else {
 +                      if (isset($this->preparedQueries[$statement]) && $this->cachingQueryStatementEnabled) {
 +                              return $this->preparedQueries[$statement];
 +                      }
 +              }
 +              $rawQuery = $statement;
 +              if(\OC_Config::getValue( "log_query", false)) {
 +                      \OC_Log::write('core', 'DB prepare : '.$statement, \OC_Log::DEBUG);
 +              }
 +              $result = parent::prepare($statement);
 +              if (is_null($limit) && $this->cachingQueryStatementEnabled) {
 +                      $this->preparedQueries[$rawQuery] = $result;
 +              }
 +              return $result;
 +      }
 +
 +      /**
 +       * Executes an, optionally parameterized, SQL query.
 +       *
 +       * If the query is parameterized, a prepared statement is used.
 +       * If an SQLLogger is configured, the execution is logged.
 +       *
 +       * @param string $query The SQL query to execute.
 +       * @param array $params The parameters to bind to the query, if any.
 +       * @param array $types The types the previous parameters are in.
 +       * @param QueryCacheProfile $qcp
 +       * @return \Doctrine\DBAL\Driver\Statement The executed statement.
 +       * @internal PERF: Directly prepares a driver statement, not a wrapper.
 +       */
 +      public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
 +      {
 +              $query = $this->replaceTablePrefix($query);
 +              $query = $this->adapter->fixupStatement($query);
 +              return parent::executeQuery($query, $params, $types, $qcp);
 +      }
 +
 +      /**
 +       * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
 +       * and returns the number of affected rows.
 +       *
 +       * This method supports PDO binding types as well as DBAL mapping types.
 +       *
 +       * @param string $query The SQL query.
 +       * @param array $params The query parameters.
 +       * @param array $types The parameter types.
 +       * @return integer The number of affected rows.
 +       * @internal PERF: Directly prepares a driver statement, not a wrapper.
 +       */
 +      public function executeUpdate($query, array $params = array(), array $types = array())
 +      {
 +              $query = $this->replaceTablePrefix($query);
 +              $query = $this->adapter->fixupStatement($query);
 +              return parent::executeUpdate($query, $params, $types);
 +      }
 +
 +      /**
 +       * Returns the ID of the last inserted row, or the last value from a sequence object,
 +       * depending on the underlying driver.
 +       *
 +       * Note: This method may not return a meaningful or consistent result across different drivers,
 +       * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
 +       * columns or sequences.
 +       *
 +       * @param string $seqName Name of the sequence object from which the ID should be returned.
 +       * @return string A string representation of the last inserted ID.
 +       */
 +      public function lastInsertId($seqName = null)
 +      {
 +              if ($seqName) {
 +                      $seqName = $this->replaceTablePrefix($seqName);
 +              }
 +              return $this->adapter->lastInsertId($seqName);
 +      }
 +
 +      // internal use
 +      public function realLastInsertId($seqName = null)
 +      {
 +              return parent::lastInsertId($seqName);
 +      }
 +
 +      /**
 +       * @brief Insert a row if a matching row doesn't exists.
 +       * @param string $table. The table to insert into in the form '*PREFIX*tableName'
 +       * @param array $input. An array of fieldname/value pairs
-        * @param mixed $error
++       * @return bool The return value from execute()
 +       */
 +      public function insertIfNotExist($table, $input) {
 +              return $this->adapter->insertIfNotExist($table, $input);
 +      }
 +
 +      /**
 +       * returns the error code and message as a string for logging
 +       * works with DoctrineException
 +       * @return string
 +       */
 +      public function getError() {
 +              $msg = $this->errorCode() . ': ';
 +              $errorInfo = $this->errorInfo();
 +              if (is_array($errorInfo)) {
 +                      $msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
 +                      $msg .= 'Driver Code = '.$errorInfo[1] . ', ';
 +                      $msg .= 'Driver Message = '.$errorInfo[2];
 +              }
 +              return $msg;
 +      }
 +
 +      // internal use
++      /**
++       * @param string $statement
++       * @return string
++       */
 +      protected function replaceTablePrefix($statement) {
 +              return str_replace( '*PREFIX*', $this->table_prefix, $statement );
 +      }
 +
 +      public function enableQueryStatementCaching() {
 +              $this->cachingQueryStatementEnabled = true;
 +      }
 +
 +      public function disableQueryStatementCaching() {
 +              $this->cachingQueryStatementEnabled = false;
 +              $this->preparedQueries = array();
 +      }
 +}