]> source.dussan.org Git - nextcloud-server.git/commitdiff
Merge branch 'master' into doctrine
authorBart Visscher <bartv@thisnet.nl>
Sun, 10 Mar 2013 10:30:33 +0000 (11:30 +0100)
committerBart Visscher <bartv@thisnet.nl>
Sun, 10 Mar 2013 10:30:33 +0000 (11:30 +0100)
Conflicts:
lib/db.php

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

diff --cc lib/base.php
Simple merge
diff --cc lib/db.php
index 3b2590c31052ed07c41f83a83285e884ea04bcce,347deac8519db437a91fa4c9b6aebcc7e0733f02..4a511908e5abaef54e8db0d84ee5f7e0bbd31550
@@@ -37,23 -35,32 +37,24 @@@ class DatabaseException extends Excepti
  
  /**
   * 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();
+       static private $cachingEnabled = true;
  
        /**
 -       * @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
 +       * @var Doctrine
         */
 -      static private $PDO=null;
 -      /**
 -       * @var MDB2_Schema
 -       */
 -      static private $schema=null;
 +      static private $DOCTRINE=null;
 +
        static private $inTransaction=false;
        static private $prefix=null;
        static private $type=null;
                                        );
                                        break;
                                case 'oci':
 -                                      $dsn = array(
 -                                                      'phptype'  => 'oci8',
 -                                                      'username' => $user,
 +                                      $connectionParams = array(
 +                                                      'user' => $user,
                                                        'password' => $pass,
 +                                                      'host' => $host,
 +                                                      'port' => $port,
 +                                                      'dbname' => $name,
                                                        'charset' => 'AL32UTF8',
 +                                                      'driver' => 'oci8',
                                        );
 -                                      if ($host != '') {
 -                                              $dsn['hostspec'] = $host;
 -                                              $dsn['database'] = $name;
 -                                      } else { // use dbname for hostspec
 -                                              $dsn['hostspec'] = $name;
 -                                              $dsn['database'] = $user;
 -                                      }
                                        break;
+                               case 'mssql':
+                                       $dsn = array(
+                                               'phptype' => 'sqlsrv',
+                                               'username' => $user,
+                                               'password' => $pass,
+                                               'hostspec' => $host,
+                                               'database' => $name
+                                       );                    
+                                       break;
                                default:
                                        return false;
                        }
        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);
 +                      //Doctrine 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])) {
+                       if (isset(self::$preparedQueries[$query]) and self::$cachingEnabled) {
                                return self::$preparedQueries[$query];
                        }
                }
  
                self::connect();
                // return the result
 -              if(self::$backend==self::BACKEND_MDB2) {
 -                      $result = self::$connection->prepare( $query );
 -
 -                      // Die if we have an error (error means: bad query, not 0 results!)
 -                      if( PEAR::isError($result)) {
 -                              throw new DatabaseException($result->getMessage(), $query);
 -                      }
 -              }else{
 -                      try{
 +              if (self::$backend == self::BACKEND_DOCTRINE) {
 +                      try {
                                $result=self::$connection->prepare($query);
 -                      }catch(PDOException $e) {
 +                      } catch(\Doctrine\DBAL\DBALException $e) {
                                throw new DatabaseException($e->getMessage(), $query);
                        }
 -                      $result=new PDOStatementWrapper($result);
 +                      $result=new DoctrineStatementWrapper($result);
                }
-               if (is_null($limit) || $limit == -1) {
-                       self::$preparedQueries[$rawQuery] = $result;
+               if ((is_null($limit) || $limit == -1) and self::$cachingEnabled ) {
+                       $type = OC_Config::getValue( "dbtype", "sqlite" );
+                       if( $type != 'sqlite' && $type != 'sqlite3' ) {
+                               self::$preparedQueries[$rawQuery] = $result;
+                       }
                }
                return $result;
        }
                        $query = self::prepare('SELECT lastval() AS id');
                        $row = $query->execute()->fetchRow();
                        return $row['id'];
 -              }else{
+               }
+               if( $type == 'mssql' ) {
+                       if($table !== null) {
+                               $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
+                               $table = str_replace( '*PREFIX*', $prefix, $table );
+                       }
+                       return self::$connection->lastInsertId($table);
 +              } else {
                        if($table !== null) {
                                $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
                                $suffix = OC_Config::getValue( "dbsequencesuffix", "_id_seq" );
                return true;
        }
  
--      /**
++      /** else {
         * @brief saves database scheme to xml file
         * @param string $file name of file
         * @param int $mode
                        $query = str_replace( '`', '"', $query );
                        $query = str_ireplace( 'UNIX_TIMESTAMP()', 'cast(extract(epoch from current_timestamp) as integer)',
                                $query );
 -              }elseif( $type == 'oci'  ) {
 +              } elseif( $type == 'oci'  ) {
                        $query = str_replace( '`', '"', $query );
                        $query = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $query );
-               }
+               }elseif( $type == 'mssql' ) {
+                       $query = preg_replace( "/\`(.*?)`/", "[$1]", $query );
+                       $query = str_replace( 'NOW()', 'CURRENT_TIMESTAMP', $query );
+                       $query = str_replace( 'now()', 'CURRENT_TIMESTAMP', $query );
+                       $query = str_replace( 'LENGTH(', 'LEN(', $query );
+                       $query = str_replace( 'SUBSTR(', 'SUBSTRING(', $query );
+             
+             $query = self::fixLimitClauseForMSSQL($query);
+         }
  
                // replace table name prefix
                $query = str_replace( '*PREFIX*', $prefix, $query );
@@@ -587,6 -972,109 +689,96 @@@ class DoctrineStatementWrapper 
                }
        }
  
 -      /**
 -       * provide numRows
 -       */
 -      public function numRows() {
 -              $regex = '/^SELECT\s+(?:ALL\s+|DISTINCT\s+)?(?:.*?)\s+FROM\s+(.*)$/i';
 -              if (preg_match($regex, $this->statement->queryString, $output) > 0) {
 -                      $query = OC_DB::prepare("SELECT COUNT(*) FROM {$output[1]}", PDO::FETCH_NUM);
 -                      return $query->execute($this->lastArguments)->fetchColumn();
 -              }else{
 -                      return $this->statement->rowCount();
 -              }
 -      }
 -
+       private function tryFixSubstringLastArgumentDataForMSSQL($input) {
+               $query = $this->statement->queryString;
+               $pos = stripos ($query, 'SUBSTRING');
+               if ( $pos === false) {
+                       return;
+               }
+               try {
+                       $newQuery = '';
+                       $cArg = 0;
+                       $inSubstring = false;
+                       // Create new query
+                       for ($i = 0; $i < strlen ($query); $i++) {
+                               if ($inSubstring == false) {
+                                       // Defines when we should start inserting values
+                                       if (substr ($query, $i, 9) == 'SUBSTRING') {
+                                               $inSubstring = true;
+                                       }
+                               } else {
+                                       // Defines when we should stop inserting values
+                                       if (substr ($query, $i, 1) == ')') {
+                                               $inSubstring = false;
+                                       }
+                               }
+                               if (substr ($query, $i, 1) == '?') {
+                                       // We found a question mark
+                                       if ($inSubstring) {
+                                               $newQuery .= $input[$cArg];
+                                               //
+                                               // Remove from input array
+                                               //
+                                               array_splice ($input, $cArg, 1);
+                                       } else {
+                                               $newQuery .= substr ($query, $i, 1);
+                                               $cArg++;
+                                       }
+                               } else {
+                                       $newQuery .= substr ($query, $i, 1);
+                               }
+                       }
+                       // The global data we need
+                       $name = OC_Config::getValue( "dbname", "owncloud" );
+                       $host = OC_Config::getValue( "dbhost", "" );
+                       $user = OC_Config::getValue( "dbuser", "" );
+                       $pass = OC_Config::getValue( "dbpassword", "" );
+                       if (strpos($host,':')) {
+                               list($host, $port) = explode(':', $host, 2);
+                       } else {
+                               $port = false;
+                       }
+                       $opts = array();
+                       if ($port) {
+                               $dsn = 'sqlsrv:Server='.$host.','.$port.';Database='.$name;
+                       } else {
+                               $dsn = 'sqlsrv:Server='.$host.';Database='.$name;
+                       }
+                       $PDO = new PDO($dsn, $user, $pass, $opts);
+                       $PDO->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
+                       $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+                       $this->statement = $PDO->prepare($newQuery);
+                       $this->lastArguments = $input;
+                       return $input;
+               } catch (PDOException $e){
+                       $entry = 'PDO DB Error: "'.$e->getMessage().'"<br />';
+                       $entry .= 'Offending command was: '.$this->statement->queryString .'<br />';
+                       $entry .= 'Input parameters: ' .print_r($input, true).'<br />';
+                       $entry .= 'Stack trace: ' .$e->getTraceAsString().'<br />';
+                       OC_Log::write('core', $entry, 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 ($entry);
+               }
+       }
+     
        /**
         * provide an alias for fetch
         */