[Pkg-owncloud-commits] [owncloud] 30/153: Deduplicate connection handling code into \OC\DB\ConnectionFactory

David Prévot taffit at moszumanska.debian.org
Tue May 27 03:05:31 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository owncloud.

commit f9853b253c6ecb9a77a9d1c9006c5f548cdfd04e
Author: Andreas Fischer <bantu at owncloud.com>
Date:   Mon Mar 31 20:00:44 2014 +0200

    Deduplicate connection handling code into \OC\DB\ConnectionFactory
---
 core/command/db/converttype.php      |  45 ++++--------
 core/register_command.php            |   2 +-
 lib/private/db.php                   | 139 +++++++++++------------------------
 lib/private/db/connectionfactory.php | 117 +++++++++++++++++++++++++++++
 4 files changed, 173 insertions(+), 130 deletions(-)

diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php
index 387f873..2a4e674 100644
--- a/core/command/db/converttype.php
+++ b/core/command/db/converttype.php
@@ -22,10 +22,17 @@ class ConvertType extends Command {
 	protected $config;
 
 	/**
+	 * @var \OC\DB\ConnectionFactory
+	 */
+	protected $connectionFactory;
+
+	/**
 	 * @param \OC\Config $config
+	 * @param \OC\DB\ConnectionFactory $connectionFactory
 	 */
-	public function __construct($config) {
+	public function __construct($config, $connectionFactory) {
 		$this->config = $config;
+		$this->connectionFactory = $connectionFactory;
 		parent::__construct();
 	}
 
@@ -87,12 +94,6 @@ class ConvertType extends Command {
 		;
 	}
 
-	private static $type2driver = array(
-		'mysql' => 'pdo_mysql',
-		'pgsql' => 'pdo_pgsql',
-		'oci' => 'oci8',
-		'mssql' => 'pdo_sqlsrv',
-	);
 	protected function execute(InputInterface $input, OutputInterface $output) {
 		$fromDB = \OC_DB::getConnection();
 		$toDB = $this->getToDBConnection($input, $output);
@@ -140,35 +141,17 @@ class ConvertType extends Command {
 
 	private function getToDBConnection($input, $output) {
 		$type = $input->getArgument('type');
-		$username = $input->getArgument('username');
-		$hostname = $input->getArgument('hostname');
-		$dbname = $input->getArgument('database');
-		$password = $input->getOption('password');
-
-		if (!isset(self::$type2driver[$type])) {
-			throw new \InvalidArgumentException('Unknown type: '.$type);
-		}
 		$connectionParams = array(
-				'driver' => self::$type2driver[$type],
-				'user' => $username,
-				'password' => $password,
-				'host' => $hostname,
-				'dbname' => $dbname,
+			'host' => $input->getArgument('hostname'),
+			'user' => $input->getArgument('username'),
+			'password' => $input->getOption('password'),
+			'dbname' => $input->getArgument('database'),
+			'tablePrefix' => $this->config->getValue('dbtableprefix', 'oc_'),
 		);
 		if ($input->getOption('port')) {
 			$connectionParams['port'] = $input->getOption('port');
 		}
-		switch ($type) {
-			case 'mysql':
-			case 'mssql':
-				$connectionParams['charset'] = 'UTF8';
-				break;
-			case 'oci':
-				$connectionParams['charset'] = 'AL32UTF8';
-				break;
-		}
-
-		return \Doctrine\DBAL\DriverManager::getConnection($connectionParams);
+		return $this->connectionFactory->getConnection($type, $connectionParams);
 	}
 
 	private function getTables($db) {
diff --git a/core/register_command.php b/core/register_command.php
index a383321..f1361c8 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -9,7 +9,7 @@
 /** @var $application Symfony\Component\Console\Application */
 $application->add(new OC\Core\Command\Status);
 $application->add(new OC\Core\Command\Db\GenerateChangeScript());
-$application->add(new OC\Core\Command\Db\ConvertType(OC_Config::getObject()));
+$application->add(new OC\Core\Command\Db\ConvertType(OC_Config::getObject(), new \OC\DB\ConnectionFactory()));
 $application->add(new OC\Core\Command\Upgrade());
 $application->add(new OC\Core\Command\Maintenance\SingleUser());
 $application->add(new OC\Core\Command\App\Disable());
diff --git a/lib/private/db.php b/lib/private/db.php
index cfdac76..11532d9 100644
--- a/lib/private/db.php
+++ b/lib/private/db.php
@@ -72,102 +72,45 @@ class OC_DB {
 			$port=false;
 		}
 
-		// do nothing if the connection already has been established
-		if (!self::$connection) {
-			$config = new \Doctrine\DBAL\Configuration();
-			$eventManager = new \Doctrine\Common\EventManager();
-			switch($type) {
-				case 'sqlite':
-				case 'sqlite3':
-					$datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
-					$connectionParams = array(
-							'user' => $user,
-							'password' => $pass,
-							'path' => $datadir.'/'.$name.'.db',
-							'driver' => 'pdo_sqlite',
-					);
-					$connectionParams['adapter'] = '\OC\DB\AdapterSqlite';
-					$connectionParams['wrapperClass'] = 'OC\DB\Connection';
-					break;
-				case 'mysql':
-					$connectionParams = array(
-							'user' => $user,
-							'password' => $pass,
-							'host' => $host,
-							'port' => $port,
-							'dbname' => $name,
-							'charset' => 'UTF8',
-							'driver' => 'pdo_mysql',
-					);
-					$connectionParams['adapter'] = '\OC\DB\Adapter';
-					$connectionParams['wrapperClass'] = 'OC\DB\Connection';
-					// Send "SET NAMES utf8". Only required on PHP 5.3 below 5.3.6.
-					// See http://stackoverflow.com/questions/4361459/php-pdo-charset-set-names#4361485
-					$eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\MysqlSessionInit);
-					break;
-				case 'pgsql':
-					$connectionParams = array(
-							'user' => $user,
-							'password' => $pass,
-							'host' => $host,
-							'port' => $port,
-							'dbname' => $name,
-							'driver' => 'pdo_pgsql',
-					);
-					$connectionParams['adapter'] = '\OC\DB\AdapterPgSql';
-					$connectionParams['wrapperClass'] = 'OC\DB\Connection';
-					break;
-				case 'oci':
-					$connectionParams = array(
-							'user' => $user,
-							'password' => $pass,
-							'host' => $host,
-							'dbname' => $name,
-							'charset' => 'AL32UTF8',
-							'driver' => 'oci8',
-					);
-					if (!empty($port)) {
-						$connectionParams['port'] = $port;
-					}
-					$connectionParams['adapter'] = '\OC\DB\AdapterOCI8';
-					$connectionParams['wrapperClass'] = 'OC\DB\OracleConnection';
-					$eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit);
-					break;
-				case 'mssql':
-					$connectionParams = array(
-							'user' => $user,
-							'password' => $pass,
-							'host' => $host,
-							'port' => $port,
-							'dbname' => $name,
-							'charset' => 'UTF8',
-							'driver' => 'pdo_sqlsrv',
-					);
-					$connectionParams['adapter'] = '\OC\DB\AdapterSQLSrv';
-					$connectionParams['wrapperClass'] = 'OC\DB\Connection';
-					break;
-				default:
-					return false;
-			}
-			$connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_' );
-			try {
-				self::$connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config, $eventManager);
-				if ($type === 'sqlite' || $type === 'sqlite3') {
-					// Sqlite doesn't handle query caching and schema changes
-					// TODO: find a better way to handle this
-					self::$connection->disableQueryStatementCaching();
-				}
-			} 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();
+		$factory = new \OC\DB\ConnectionFactory();
+		if (!$factory->isValidType($type)) {
+			return false;
+		}
+
+		if ($factory->normalizeType($type) === 'sqlite3') {
+			$datadir = OC_Config::getValue("datadirectory", OC::$SERVERROOT.'/data');
+			$connectionParams = array(
+				'user' => $user,
+				'password' => $pass,
+				'path' => $datadir.'/'.$name.'.db',
+			);
+		} else {
+			$connectionParams = array(
+				'user' => $user,
+				'password' => $pass,
+				'host' => $host,
+				'dbname' => $name,
+			);
+			if (!empty($port)) {
+				$connectionParams['port'] = $port;
 			}
 		}
+
+		$connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_');
+
+		try {
+			self::$connection = $factory->getConnection($type, $connectionParams);
+		} 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();
+		}
+
 		return true;
 	}
 
@@ -202,12 +145,12 @@ class OC_DB {
 	 */
 	static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) {
 		self::connect();
-		
+
 		if ($isManipulation === null) {
 			//try to guess, so we return the number of rows on manipulations
 			$isManipulation = self::isManipulation($query);
 		}
-		
+
 		// return the result
 		try {
 			$result = self::$connection->prepare($query, $limit, $offset);
@@ -222,7 +165,7 @@ class OC_DB {
 	/**
 	 * tries to guess the type of statement based on the first 10 characters
 	 * the current check allows some whitespace but does not work with IF EXISTS or other more complex statements
-	 * 
+	 *
 	 * @param string $sql
 	 * @return bool
 	 */
@@ -245,7 +188,7 @@ class OC_DB {
 		}
 		return false;
 	}
-	
+
 	/**
 	 * @brief execute a prepared statement, on error write log and throw exception
 	 * @param mixed $stmt OC_DB_StatementWrapper,
diff --git a/lib/private/db/connectionfactory.php b/lib/private/db/connectionfactory.php
new file mode 100644
index 0000000..14ffe1a
--- /dev/null
+++ b/lib/private/db/connectionfactory.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Copyright (c) 2014 Andreas Fischer <bantu at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\DB;
+
+/**
+* Takes care of creating and configurating Doctrine connections.
+*/
+class ConnectionFactory {
+	/**
+	* @var array
+	*
+	* Array mapping DBMS type to default connection parameters passed to
+	* \Doctrine\DBAL\DriverManager::getConnection().
+	*/
+	protected $defaultConnectionParams = array(
+		'mssql' => array(
+			'adapter' => '\OC\DB\AdapterSQLSrv',
+			'charset' => 'UTF8',
+			'driver' => 'pdo_sqlsrv',
+			'wrapperClass' => 'OC\DB\Connection',
+		),
+		'mysql' => array(
+			'adapter' => '\OC\DB\Adapter',
+			'charset' => 'UTF8',
+			'driver' => 'pdo_mysql',
+			'wrapperClass' => 'OC\DB\Connection',
+		),
+		'oci' => array(
+			'adapter' => '\OC\DB\AdapterOCI8',
+			'charset' => 'AL32UTF8',
+			'driver' => 'oci8',
+			'wrapperClass' => 'OC\DB\OracleConnection',
+		),
+		'pgsql' => array(
+			'adapter' => '\OC\DB\AdapterPgSql',
+			'driver' => 'pdo_pgsql',
+			'wrapperClass' => 'OC\DB\Connection',
+		),
+		'sqlite3' => array(
+			'adapter' => '\OC\DB\AdapterSqlite',
+			'driver' => 'pdo_sqlite',
+			'wrapperClass' => 'OC\DB\Connection',
+		),
+	);
+
+	/**
+	* @brief Get default connection parameters for a given DBMS.
+	* @param string $type DBMS type
+	* @throws \InvalidArgumentException If $type is invalid
+	* @return array Default connection parameters.
+	*/
+	public function getDefaultConnectionParams($type) {
+		$normalizedType = $this->normalizeType($type);
+		if (!isset($this->defaultConnectionParams[$normalizedType])) {
+			throw new \InvalidArgumentException("Unsupported type: $type");
+		}
+		return $this->defaultConnectionParams[$normalizedType];
+	}
+
+	/**
+	* @brief Get default connection parameters for a given DBMS.
+	* @param string $type DBMS type
+	* @param array $additionalConnectionParams Additional connection parameters
+	* @return \OC\DB\Connection
+	*/
+	public function getConnection($type, $additionalConnectionParams) {
+		$normalizedType = $this->normalizeType($type);
+		$eventManager = new \Doctrine\Common\EventManager();
+		switch ($normalizedType) {
+			case 'mysql':
+				// Send "SET NAMES utf8". Only required on PHP 5.3 below 5.3.6.
+				// See http://stackoverflow.com/questions/4361459/php-pdo-charset-set-names#4361485
+				$eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\MysqlSessionInit);
+				break;
+			case 'oci':
+				$eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit);
+				break;
+		}
+		$connection = \Doctrine\DBAL\DriverManager::getConnection(
+			array_merge($this->getDefaultConnectionParams($type), $additionalConnectionParams),
+			new \Doctrine\DBAL\Configuration(),
+			$eventManager
+		);
+		switch ($normalizedType) {
+			case 'sqlite3':
+				// Sqlite doesn't handle query caching and schema changes
+				// TODO: find a better way to handle this
+				$connection->disableQueryStatementCaching();
+				break;
+		}
+		return $connection;
+	}
+
+	/**
+	* @brief Normalize DBMS type
+	* @param string $type DBMS type
+	* @return string Normalized DBMS type
+	*/
+	public function normalizeType($type) {
+		return $type === 'sqlite' ? 'sqlite3' : $type;
+	}
+
+	/**
+	* @brief Checks whether the specififed DBMS type is valid.
+	* @return bool
+	*/
+	public function isValidType($type) {
+		$normalizedType = $this->normalizeType($type);
+		return isset($this->defaultConnectionParams[$normalizedType]);
+	}
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list