]> source.dussan.org Git - nextcloud-server.git/commitdiff
Merge branch 'master' into doctrine
authorBart Visscher <bartv@thisnet.nl>
Sat, 23 Feb 2013 11:12:51 +0000 (12:12 +0100)
committerBart Visscher <bartv@thisnet.nl>
Mon, 25 Feb 2013 07:24:59 +0000 (08:24 +0100)
Conflicts:
lib/base.php
lib/db.php

1  2 
lib/base.php
lib/db.php

diff --cc lib/base.php
index 7acad72f02a39a6a1699a1a311346989b338976f,b5439c00abfcd9afc2eae23415e985d88f3c8577..8a665603bb5b5c1e862fc8c977347081a11cd730
@@@ -77,43 -78,41 +78,45 @@@ class OC 
         * SPL autoload
         */
        public static function autoload($className) {
-               if(array_key_exists($className, OC::$CLASSPATH)) {
+               if (array_key_exists($className, OC::$CLASSPATH)) {
                        $path = OC::$CLASSPATH[$className];
                        /** @TODO: Remove this when necessary
-                        Remove "apps/" from inclusion path for smooth migration to mutli app dir
-                       */
-                       if (strpos($path, 'apps/')===0) {
-                               OC_Log::write('core', 'include path for class "'.$className.'" starts with "apps/"', OC_Log::DEBUG);
+                       Remove "apps/" from inclusion path for smooth migration to mutli app dir
+                        */
+                       if (strpos($path, 'apps/') === 0) {
+                               OC_Log::write('core', 'include path for class "' . $className . '" starts with "apps/"', OC_Log::DEBUG);
                                $path = str_replace('apps/', '', $path);
                        }
-               }
-               elseif(strpos($className, 'OC_')===0) {
+               } elseif (strpos($className, 'OC_') === 0) {
                        $path = strtolower(str_replace('_', '/', substr($className, 3)) . '.php');
-               }
-               elseif(strpos($className, 'OCP\\')===0) {
-                       $path = 'public/'.strtolower(str_replace('\\', '/', substr($className, 3)) . '.php');
-               }
-               elseif(strpos($className, 'OCA\\')===0) {
-                       $path = 'apps/'.strtolower(str_replace('\\', '/', substr($className, 3)) . '.php');
-               }
-               elseif(strpos($className, 'Sabre_')===0) {
-                       $path =  str_replace('_', '/', $className) . '.php';
-               }
-               elseif(strpos($className, 'Doctrine\\Common')===0) {
+               } elseif (strpos($className, 'OC\\') === 0) {
+                       $path = strtolower(str_replace('\\', '/', substr($className, 3)) . '.php');
+               } elseif (strpos($className, 'OCP\\') === 0) {
+                       $path = 'public/' . strtolower(str_replace('\\', '/', substr($className, 3)) . '.php');
+               } elseif (strpos($className, 'OCA\\') === 0) {
+                       foreach (self::$APPSROOTS as $appDir) {
+                               $path = $appDir['path'] . '/' . strtolower(str_replace('\\', '/', substr($className, 3)) . '.php');
+                               $fullPath = stream_resolve_include_path($path);
+                               if (file_exists($fullPath)) {
+                                       require_once $fullPath;
+                                       return false;
+                               }
+                       }
+               } elseif (strpos($className, 'Sabre_') === 0) {
+                       $path = str_replace('_', '/', $className) . '.php';
++              } elseif(strpos($className, 'Doctrine\\Common')===0) {
 +                      $path = 'doctrine/common/lib/'.str_replace('\\', '/', $className) . '.php';
-               }
-               elseif(strpos($className, 'Doctrine\\DBAL')===0) {
++              } elseif(strpos($className, 'Doctrine\\DBAL')===0) {
 +                      $path = 'doctrine/dbal/lib/'.str_replace('\\', '/', $className) . '.php';
-               }
-               elseif(strpos($className, 'Symfony\\Component\\Routing\\')===0) {
-                       $path = 'symfony/routing/'.str_replace('\\', '/', $className) . '.php';
-               }
-               elseif(strpos($className, 'Sabre\\VObject')===0) {
+               } elseif (strpos($className, 'Symfony\\Component\\Routing\\') === 0) {
+                       $path = 'symfony/routing/' . str_replace('\\', '/', $className) . '.php';
+               } elseif (strpos($className, 'Sabre\\VObject') === 0) {
                        $path = str_replace('\\', '/', $className) . '.php';
-               }
-               elseif(strpos($className, 'Test_')===0) {
-                       $path =  'tests/lib/'.strtolower(str_replace('_', '/', substr($className, 5)) . '.php');
-               }else{
+               } elseif (strpos($className, 'Test_') === 0) {
+                       $path = 'tests/lib/' . strtolower(str_replace('_', '/', substr($className, 5)) . '.php');
+               } elseif (strpos($className, 'Test\\') === 0) {
+                       $path = 'tests/lib/' . strtolower(str_replace('\\', '/', substr($className, 5)) . '.php');
+               } else {
                        return false;
                }
  
diff --cc lib/db.php
index 2e21a11d5452e22e81892182aa212c543d454619,edbc2fe13edbca62aea008fdb12abd232b4052b7..e10a54846622c80b36d4076b6b46444533cb8c31
   *
   */
  
 +define('MDB2_SCHEMA_DUMP_STRUCTURE', '1');
++
+ class DatabaseException extends Exception{
+       private $query;
+       public function __construct($message, $query){
+               parent::__construct($message);
+               $this->query = $query;
+       }
+       public function getQuery(){
+               return $this->query;
+       }
+ }
  /**
   * This class manages the access to the database. It basically is a wrapper for
 - * MDB2 with some adaptions.
 + * Doctrine with some adaptions.
   */
  class OC_DB {
 -      const BACKEND_PDO=0;
 -      const BACKEND_MDB2=1;
 +      const BACKEND_DOCTRINE=2;
  
+       static private $preparedQueries = array();
        /**
 -       * @var MDB2_Driver_Common
 +       * @var \Doctrine\DBAL\Connection
         */
 -      static private $connection; //the prefered connection to use, either PDO or MDB2
 +      static private $connection; //the prefered connection to use, only Doctrine
        static private $backend=null;
        /**
 -       * @var MDB2_Driver_Common
 -       */
 -      static private $MDB2=null;
 -      /**
 -       * @var PDO
 -       */
 -      static private $PDO=null;
 -      /**
 -       * @var MDB2_Schema
 +       * @var Doctrine
         */
 -      static private $schema=null;
 +      static private $DOCTRINE=null;
 +
        static private $inTransaction=false;
        static private $prefix=null;
        static private $type=null;
                                default:
                                        return false;
                        }
-                       self::$DOCTRINE = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
 -
 -                      // Try to establish connection
 -                      self::$MDB2 = MDB2::factory( $dsn, $options );
 -
 -                      // Die if we could not connect
 -                      if( PEAR::isError( self::$MDB2 )) {
 -                              OC_Log::write('core', self::$MDB2->getUserInfo(), OC_Log::FATAL);
 -                              OC_Log::write('core', self::$MDB2->getMessage(), OC_Log::FATAL);
++                      try {
++                              self::$DOCTRINE = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
++                      } catch(\Doctrine\DBAL\DBALException $e) {
++                              OC_Log::write('core', $e->getMessage(), OC_Log::FATAL);
+                               OC_User::setUserId(null);
+                               // send http status 503
+                               header('HTTP/1.1 503 Service Temporarily Unavailable');
+                               header('Status: 503 Service Temporarily Unavailable');
+                               OC_Template::printErrorPage('Failed to connect to database');
+                               die();
+                       }
 -
 -                      // We always, really always want associative arrays
 -                      self::$MDB2->setFetchMode(MDB2_FETCHMODE_ASSOC);
                }
 -
 -              // we are done. great!
                return true;
        }
  
        static public function prepare( $query , $limit=null, $offset=null ) {
  
                if (!is_null($limit) && $limit != -1) {
 -                      if (self::$backend == self::BACKEND_MDB2) {
 -                              //MDB2 uses or emulates limits & offset internally
 -                              self::$MDB2->setLimit($limit, $offset);
 +                      //PDO does not handle limit and offset.
 +                      //FIXME: check limit notation for other dbs
 +                      //the following sql thus might needs to take into account db ways of representing it
 +                      //(oracle has no LIMIT / OFFSET)
 +                      $limit = (int)$limit;
 +                      $limitsql = ' LIMIT ' . $limit;
 +                      if (!is_null($offset)) {
 +                              $offset = (int)$offset;
 +                              $limitsql .= ' OFFSET ' . $offset;
 +                      }
 +                      //insert limitsql
 +                      if (substr($query, -1) == ';') { //if query ends with ;
 +                              $query = substr($query, 0, -1) . $limitsql . ';';
                        } else {
 -                              //PDO does not handle limit and offset.
 -                              //FIXME: check limit notation for other dbs
 -                              //the following sql thus might needs to take into account db ways of representing it
 -                              //(oracle has no LIMIT / OFFSET)
 -                              $limit = (int)$limit;
 -                              $limitsql = ' LIMIT ' . $limit;
 -                              if (!is_null($offset)) {
 -                                      $offset = (int)$offset;
 -                                      $limitsql .= ' OFFSET ' . $offset;
 -                              }
 -                              //insert limitsql
 -                              if (substr($query, -1) == ';') { //if query ends with ;
 -                                      $query = substr($query, 0, -1) . $limitsql . ';';
 -                              } else {
 -                                      $query.=$limitsql;
 -                              }
 +                              $query.=$limitsql;
                        }
+               } else {
+                       if (isset(self::$preparedQueries[$query])) {
+                               return self::$preparedQueries[$query];
+                       }
                }
+               $rawQuery = $query;
  
                // Optimize the query
                $query = self::processQuery( $query );
                        try{
                                $result=self::$connection->prepare($query);
                        }catch(PDOException $e) {
-                               $entry = 'DB Error: "'.$e->getMessage().'"<br />';
-                               $entry .= 'Offending command was: '.htmlentities($query).'<br />';
-                               OC_Log::write('core', $entry, OC_Log::FATAL);
-                               error_log('DB error: '.$entry);
-                               OC_Template::printErrorPage( $entry );
+                               throw new DatabaseException($e->getMessage(), $query);
                        }
 -                      $result=new PDOStatementWrapper($result);
 +                      $result=new DoctrineStatementWrapper($result);
                }
+               if (is_null($limit) || $limit == -1) {
+                       self::$preparedQueries[$rawQuery] = $result;
+               }
                return $result;
        }
  
                 * http://www.sqlite.org/lang_createtable.html
                 * http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions037.htm
                 */
-                if( $CONFIG_DBTYPE == 'pgsql' ) { //mysql support it too but sqlite doesn't
-                                $content = str_replace( '<default>0000-00-00 00:00:00</default>', '<default>CURRENT_TIMESTAMP</default>', $content );
-                }
+               if( $CONFIG_DBTYPE == 'pgsql' ) { //mysql support it too but sqlite doesn't
+                       $content = str_replace( '<default>0000-00-00 00:00:00</default>',
+                               '<default>CURRENT_TIMESTAMP</default>', $content );
+               }
 -
 -              file_put_contents( $file2, $content );
 -
 -              // Try to create tables
 -              $definition = self::$schema->parseDatabaseDefinitionFile( $file2 );
 -
 -              //clean up memory
 -              unlink( $file2 );
 -
 -              // Die in case something went wrong
 -              if( $definition instanceof MDB2_Schema_Error ) {
 -                      OC_Template::printErrorPage( $definition->getMessage().': '.$definition->getUserInfo() );
 -              }
 -              if(OC_Config::getValue('dbtype', 'sqlite')==='oci') {
 -                      unset($definition['charset']); //or MDB2 tries SHUTDOWN IMMEDIATE
 -                      $oldname = $definition['name'];
 -                      $definition['name']=OC_Config::getValue( "dbuser", $oldname );
 -              }
 -
 -              // we should never drop a database
 -              $definition['overwrite'] = false;
 -
 -              $ret=self::$schema->createDatabase( $definition );
 -
 -              // Die in case something went wrong
 -              if( $ret instanceof MDB2_Error ) {
 -                      OC_Template::printErrorPage( self::$MDB2->getDebugOutput().' '.$ret->getMessage() . ': '
 -                              . $ret->getUserInfo() );
 -              }
 -
 -              return true;
        }
  
        /**
         * @return bool
         */
        public static function updateDbFromStructure($file) {
 -              $CONFIG_DBTABLEPREFIX = OC_Config::getValue( "dbtableprefix", "oc_" );
 -              $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" );
 -
 -              self::connectScheme();
 -
 -              // read file
 -              $content = file_get_contents( $file );
 -
 -              $previousSchema = self::$schema->getDefinitionFromDatabase();
 -              if (PEAR::isError($previousSchema)) {
 -                      $error = $previousSchema->getMessage();
 -                      $detail = $previousSchema->getDebugInfo();
 -                      $message = 'Failed to get existing database structure for updating ('.$error.', '.$detail.')';
 -                      OC_Log::write('core', $message, OC_Log::FATAL);
 -                      throw new Exception($message);
 +              self::connectDoctrine();
 +              try {
 +                      $result = OC_DB_Schema::updateDbFromStructure(self::$connection, $file);
 +              } catch (Exception $e) {
 +                      OC_Log::write('core', 'Failed to update database structure ('.$e.')', OC_Log::FATAL);
-                       return false;
++                      throw $e;
                }
 -
 -              // Make changes and save them to an in-memory file
 -              $file2 = 'static://db_scheme';
 -              $content = str_replace( '*dbname*', $previousSchema['name'], $content );
 -              $content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
 +              return $result;
                /* FIXME: use CURRENT_TIMESTAMP for all databases. mysql supports it as a default for DATETIME since 5.6.5 [1]
                 * as a fallback we could use <default>0000-01-01 00:00:00</default> everywhere
                 * [1] http://bugs.mysql.com/bug.php?id=27645
                 * http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions037.htm
                 */
                if( $CONFIG_DBTYPE == 'pgsql' ) { //mysql support it too but sqlite doesn't
-                       $content = str_replace( '<default>0000-00-00 00:00:00</default>', '<default>CURRENT_TIMESTAMP</default>', $content );
+                       $content = str_replace( '<default>0000-00-00 00:00:00</default>',
+                               '<default>CURRENT_TIMESTAMP</default>', $content );
                }
 -              file_put_contents( $file2, $content );
 -              $op = self::$schema->updateDatabase($file2, $previousSchema, array(), false);
 -
 -              //clean up memory
 -              unlink( $file2 );
 -
 -              if (PEAR::isError($op)) {
 -                      $error = $op->getMessage();
 -                      $detail = $op->getDebugInfo();
 -                      $message = 'Failed to update database structure ('.$error.', '.$detail.')';
 -                      OC_Log::write('core', $message, OC_Log::FATAL);
 -                      throw new Exception($message);
 -              }
 -              return true;
 -      }
 -
 -      /**
 -       * @brief connects to a MDB2 database scheme
 -       * @returns bool
 -       *
 -       * Connects to a MDB2 database scheme
 -       */
 -      private static function connectScheme() {
 -              // We need a mdb2 database connection
 -              self::connectMDB2();
 -              self::$MDB2->loadModule('Manager');
 -              self::$MDB2->loadModule('Reverse');
 -
 -              // Connect if this did not happen before
 -              if(!self::$schema) {
 -                      require_once 'MDB2/Schema.php';
 -                      self::$schema=MDB2_Schema::factory(self::$MDB2);
 -              }
 -
 -              return true;
        }
  
        /**