diff options
author | Bart Visscher <bartv@thisnet.nl> | 2013-06-28 11:48:38 +0200 |
---|---|---|
committer | Bart Visscher <bartv@thisnet.nl> | 2013-06-28 11:48:38 +0200 |
commit | b04e09a90118bfba8faa1fc6a5381c26148a4796 (patch) | |
tree | e4d235e31794601be3018e192297786f9001807f /lib | |
parent | 6145e617185e24919eaf6e94dddeb3b3be735b8c (diff) | |
download | nextcloud-server-b04e09a90118bfba8faa1fc6a5381c26148a4796.tar.gz nextcloud-server-b04e09a90118bfba8faa1fc6a5381c26148a4796.zip |
Move DoctrineStatementWrapper to its own file
Diffstat (limited to 'lib')
-rw-r--r-- | lib/db.php | 187 | ||||
-rw-r--r-- | lib/db/statementwrapper.php | 186 |
2 files changed, 190 insertions, 183 deletions
diff --git a/lib/db.php b/lib/db.php index 0fa487dedb3..e38d464e755 100644 --- a/lib/db.php +++ b/lib/db.php @@ -232,7 +232,7 @@ class OC_DB { } catch(\Doctrine\DBAL\DBALException $e) { throw new \DatabaseException($e->getMessage(), $query); } - $result=new DoctrineStatementWrapper($result); + $result=new OC_DB_StatementWrapper($result); } if ((is_null($limit) || $limit == -1) and self::$cachingEnabled ) { $type = OC_Config::getValue( "dbtype", "sqlite" ); @@ -245,7 +245,7 @@ class OC_DB { /** * @brief execute a prepared statement, on error write log and throw exception - * @param mixed $stmt DoctrineStatementWrapperm, + * @param mixed $stmt OC_DB_StatementWrapper, * an array with 'sql' and optionally 'limit' and 'offset' keys * .. or a simple sql query string * @param array $parameters @@ -278,7 +278,7 @@ class OC_DB { $stmt = self::prepare($stmt['sql'], $stmt['limit'], $stmt['offset']); } self::raiseExceptionOnError($stmt, 'Could not prepare statement'); - if ($stmt instanceof DoctrineStatementWrapper) { + if ($stmt instanceof OC_DB_StatementWrapper) { $result = $stmt->execute($parameters); self::raiseExceptionOnError($result, 'Could not execute statement'); } else { @@ -399,7 +399,7 @@ class OC_DB { * @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 - * @return bool return value from DoctrineStatementWrapper->execute() + * @return bool return value from OC_DB_StatementWrapper->execute() */ public static function insertIfNotExist($table, $input) { self::connect(); @@ -680,182 +680,3 @@ class OC_DB { self::$cachingEnabled = $enabled; } } - -/** - * small wrapper around \Doctrine\DBAL\Driver\Statement to make it behave, more like an MDB2 Statement - */ -class DoctrineStatementWrapper { - /** - * @var \Doctrine\DBAL\Driver\Statement - */ - private $statement=null; - private $lastArguments=array(); - - public function __construct($statement) { - $this->statement=$statement; - } - - /** - * pass all other function directly to the \Doctrine\DBAL\Driver\Statement - */ - public function __call($name,$arguments) { - return call_user_func_array(array($this->statement,$name), $arguments); - } - - /** - * provide numRows - */ - public function numRows() { - $type = OC_Config::getValue( "dbtype", "sqlite" ); - if ($type == 'oci') { - // OCI doesn't have a queryString, just do a rowCount for now - return $this->statement->rowCount(); - } - $regex = '/^SELECT\s+(?:ALL\s+|DISTINCT\s+)?(?:.*?)\s+FROM\s+(.*)$/i'; - $queryString = $this->statement->getWrappedStatement()->queryString; - if (preg_match($regex, $queryString, $output) > 0) { - $query = OC_DB::prepare("SELECT COUNT(*) FROM {$output[1]}"); - return $query->execute($this->lastArguments)->fetchColumn(); - }else{ - return $this->statement->rowCount(); - } - } - - /** - * make execute return the result instead of a bool - */ - public function execute($input=array()) { - if(OC_Config::getValue( "log_query", false)) { - $params_str = str_replace("\n"," ",var_export($input,true)); - OC_Log::write('core', 'DB execute with arguments : '.$params_str, OC_Log::DEBUG); - } - $this->lastArguments = $input; - if (count($input) > 0) { - - if (!isset($type)) { - $type = OC_Config::getValue( "dbtype", "sqlite" ); - } - - if ($type == 'mssql') { - $input = $this->tryFixSubstringLastArgumentDataForMSSQL($input); - } - - $result=$this->statement->execute($input); - } else { - $result=$this->statement->execute(); - } - - if ($result) { - return $this; - } else { - return false; - } - } - - private function tryFixSubstringLastArgumentDataForMSSQL($input) { - $query = $this->statement->getWrappedStatement()->queryString; - $pos = stripos ($query, 'SUBSTRING'); - - if ( $pos === false) { - return $input; - } - - 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 - */ - public function fetchRow() { - return $this->statement->fetch(); - } - - /** - * Provide a simple fetchOne. - * fetch single column from the next row - * @param int $colnum the column number to fetch - * @return string - */ - public function fetchOne($colnum = 0) { - return $this->statement->fetchColumn($colnum); - } -} diff --git a/lib/db/statementwrapper.php b/lib/db/statementwrapper.php new file mode 100644 index 00000000000..0d650186412 --- /dev/null +++ b/lib/db/statementwrapper.php @@ -0,0 +1,186 @@ +<?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. + */ + +/** + * small wrapper around \Doctrine\DBAL\Driver\Statement to make it behave, more like an MDB2 Statement + */ +class OC_DB_StatementWrapper { + /** + * @var \Doctrine\DBAL\Driver\Statement + */ + private $statement=null; + private $lastArguments=array(); + + public function __construct($statement) { + $this->statement=$statement; + } + + /** + * pass all other function directly to the \Doctrine\DBAL\Driver\Statement + */ + public function __call($name,$arguments) { + return call_user_func_array(array($this->statement,$name), $arguments); + } + + /** + * provide numRows + */ + public function numRows() { + $type = OC_Config::getValue( "dbtype", "sqlite" ); + if ($type == 'oci') { + // OCI doesn't have a queryString, just do a rowCount for now + return $this->statement->rowCount(); + } + $regex = '/^SELECT\s+(?:ALL\s+|DISTINCT\s+)?(?:.*?)\s+FROM\s+(.*)$/i'; + $queryString = $this->statement->getWrappedStatement()->queryString; + if (preg_match($regex, $queryString, $output) > 0) { + $query = OC_DB::prepare("SELECT COUNT(*) FROM {$output[1]}"); + return $query->execute($this->lastArguments)->fetchColumn(); + }else{ + return $this->statement->rowCount(); + } + } + + /** + * make execute return the result instead of a bool + */ + public function execute($input=array()) { + if(OC_Config::getValue( "log_query", false)) { + $params_str = str_replace("\n"," ",var_export($input,true)); + OC_Log::write('core', 'DB execute with arguments : '.$params_str, OC_Log::DEBUG); + } + $this->lastArguments = $input; + if (count($input) > 0) { + + if (!isset($type)) { + $type = OC_Config::getValue( "dbtype", "sqlite" ); + } + + if ($type == 'mssql') { + $input = $this->tryFixSubstringLastArgumentDataForMSSQL($input); + } + + $result=$this->statement->execute($input); + } else { + $result=$this->statement->execute(); + } + + if ($result) { + return $this; + } else { + return false; + } + } + + private function tryFixSubstringLastArgumentDataForMSSQL($input) { + $query = $this->statement->getWrappedStatement()->queryString; + $pos = stripos ($query, 'SUBSTRING'); + + if ( $pos === false) { + return $input; + } + + 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 + */ + public function fetchRow() { + return $this->statement->fetch(); + } + + /** + * Provide a simple fetchOne. + * fetch single column from the next row + * @param int $colnum the column number to fetch + * @return string + */ + public function fetchOne($colnum = 0) { + return $this->statement->fetchColumn($colnum); + } +} |