From 2ae6a0d96d45e2270a9c06bbfc91d1733fa9fce3 Mon Sep 17 00:00:00 2001
From: Robin Appelman <icewind@owncloud.com>
Date: Wed, 10 Sep 2014 13:24:49 +0200
Subject: [PATCH] Move creating the database connection to the server container

---
 lib/private/appframework/db/db.php   | 52 +++++++++++++---------
 lib/private/db.php                   | 65 +---------------------------
 lib/private/db/connectionfactory.php | 37 ++++++++++++++++
 lib/private/server.php               | 21 ++++++++-
 4 files changed, 90 insertions(+), 85 deletions(-)

diff --git a/lib/private/appframework/db/db.php b/lib/private/appframework/db/db.php
index fc77a38f81..91572ad9e5 100644
--- a/lib/private/appframework/db/db.php
+++ b/lib/private/appframework/db/db.php
@@ -30,28 +30,40 @@ use \OCP\IDb;
  * Small Facade for being able to inject the database connection for tests
  */
 class Db implements IDb {
+	/**
+	 * @var \OCP\IDBConnection
+	 */
+	protected $connection;
 
+	/**
+	 * @param \OCP\IDBConnection $connection
+	 */
+	public function __construct($connection) {
+		$this->connection = $connection;
+	}
 
-    /**
-     * Used to abstract the owncloud database access away
-     * @param string $sql the sql query with ? placeholder for params
-     * @param int $limit the maximum number of rows
-     * @param int $offset from which row we want to start
-     * @return \OC_DB_StatementWrapper prepared SQL query
-     */
-    public function prepareQuery($sql, $limit=null, $offset=null){
-        return \OCP\DB::prepare($sql, $limit, $offset);
-    }
-
-
-    /**
-     * Used to get the id of the just inserted element
-     * @param string $tableName the name of the table where we inserted the item
-     * @return int the id of the inserted element
-     */
-    public function getInsertId($tableName){
-        return \OCP\DB::insertid($tableName);
-    }
+	/**
+	 * Used to abstract the owncloud database access away
+	 *
+	 * @param string $sql the sql query with ? placeholder for params
+	 * @param int $limit the maximum number of rows
+	 * @param int $offset from which row we want to start
+	 * @return \OC_DB_StatementWrapper prepared SQL query
+	 */
+	public function prepareQuery($sql, $limit = null, $offset = null) {
+		return $this->connection->prepare($sql, $limit, $offset);
+	}
+
+
+	/**
+	 * Used to get the id of the just inserted element
+	 *
+	 * @param string $tableName the name of the table where we inserted the item
+	 * @return int the id of the inserted element
+	 */
+	public function getInsertId($tableName) {
+		return $this->connection->lastInsertId($tableName);
+	}
 
 
 }
diff --git a/lib/private/db.php b/lib/private/db.php
index 381ed93e81..59d61ffa29 100644
--- a/lib/private/db.php
+++ b/lib/private/db.php
@@ -46,66 +46,6 @@ class OC_DB {
 	 */
 	static private $connection; //the preferred connection to use, only Doctrine
 
-	/**
-	 * connects to the database
-	 * @return boolean|null true if connection can be established or false on error
-	 *
-	 * Connects to the database as specified in config.php
-	 */
-	public static function connect() {
-		if(self::$connection) {
-			return true;
-		}
-
-		$type = OC_Config::getValue('dbtype', 'sqlite');
-		$factory = new \OC\DB\ConnectionFactory();
-		if (!$factory->isValidType($type)) {
-			return false;
-		}
-
-		$connectionParams = array(
-			'user' => OC_Config::getValue('dbuser', ''),
-			'password' => OC_Config::getValue('dbpassword', ''),
-		);
-		$name = OC_Config::getValue('dbname', 'owncloud');
-
-		if ($factory->normalizeType($type) === 'sqlite3') {
-			$datadir = OC_Config::getValue("datadirectory", OC::$SERVERROOT.'/data');
-			$connectionParams['path'] = $datadir.'/'.$name.'.db';
-		} else {
-			$host = OC_Config::getValue('dbhost', '');
-			if (strpos($host, ':')) {
-				// Host variable may carry a port or socket.
-				list($host, $portOrSocket) = explode(':', $host, 2);
-				if (ctype_digit($portOrSocket)) {
-					$connectionParams['port'] = $portOrSocket;
-				} else {
-					$connectionParams['unix_socket'] = $portOrSocket;
-				}
-			}
-			$connectionParams['host'] = $host;
-			$connectionParams['dbname'] = $name;
-		}
-
-		$connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_');
-
-		try {
-			self::$connection = $factory->getConnection($type, $connectionParams);
-			self::$connection->getConfiguration()->setSQLLogger(\OC::$server->getQueryLogger());
-		} 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;
-	}
-
 	/**
 	 * The existing database connection is closed and connected again
 	 */
@@ -116,11 +56,10 @@ class OC_DB {
 	}
 
 	/**
-	 * @return \OC\DB\Connection
+	 * @return \OCP\IDBConnection
 	 */
 	static public function getConnection() {
-		self::connect();
-		return self::$connection;
+		return \OC::$server->getDatabaseConnection();
 	}
 
 	/**
diff --git a/lib/private/db/connectionfactory.php b/lib/private/db/connectionfactory.php
index a5260c1a4c..1f676f1fca 100644
--- a/lib/private/db/connectionfactory.php
+++ b/lib/private/db/connectionfactory.php
@@ -118,4 +118,41 @@ class ConnectionFactory {
 		$normalizedType = $this->normalizeType($type);
 		return isset($this->defaultConnectionParams[$normalizedType]);
 	}
+
+	/**
+	 * Create the connection parameters for the config
+	 *
+	 * @param \OCP\IConfig $config
+	 * @return array
+	 */
+	public function createConnectionParams($config) {
+		$type = $config->getSystemValue('dbtype', 'sqlite');
+
+		$connectionParams = array(
+			'user' => $config->getSystemValue('dbuser', ''),
+			'password' => $config->getSystemValue('dbpassword', ''),
+		);
+		$name = $config->getSystemValue('dbname', 'owncloud');
+
+		if ($this->normalizeType($type) === 'sqlite3') {
+			$datadir = $config->getSystemValue("datadirectory", \OC::$SERVERROOT . '/data');
+			$connectionParams['path'] = $datadir . '/' . $name . '.db';
+		} else {
+			$host = $config->getSystemValue('dbhost', '');
+			if (strpos($host, ':')) {
+				// Host variable may carry a port or socket.
+				list($host, $portOrSocket) = explode(':', $host, 2);
+				if (ctype_digit($portOrSocket)) {
+					$connectionParams['port'] = $portOrSocket;
+				} else {
+					$connectionParams['unix_socket'] = $portOrSocket;
+				}
+			}
+			$connectionParams['host'] = $host;
+			$connectionParams['dbname'] = $name;
+		}
+
+		$connectionParams['tablePrefix'] = $config->getSystemValue('dbtableprefix', 'oc_');
+		return $connectionParams;
+	}
 }
diff --git a/lib/private/server.php b/lib/private/server.php
index 26d540ab23..b0d63af155 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -217,8 +217,25 @@ class Server extends SimpleContainer implements IServerContainer {
 		$this->registerService('Crypto', function ($c) {
 			return new Crypto(\OC::$server->getConfig(), \OC::$server->getSecureRandom());
 		});
+		$this->registerService('DatabaseConnection', function ($c) {
+			/**
+			 * @var Server $c
+			 */
+			$factory = new \OC\DB\ConnectionFactory();
+			$type = $c->getConfig()->getSystemValue('dbtype', 'sqlite');
+			if (!$factory->isValidType($type)) {
+				throw new \DatabaseException('Invalid database type');
+			}
+			$connectionParams = $factory->createConnectionParams($c->getConfig());
+			$connection = $factory->getConnection($type, $connectionParams);
+			$connection->getConfiguration()->setSQLLogger($c->getQueryLogger());
+			return $connection;
+		});
 		$this->registerService('Db', function ($c) {
-			return new Db();
+			/**
+			 * @var Server $c
+			 */
+			return new Db($c->getDatabaseConnection());
 		});
 		$this->registerService('HTTPHelper', function (SimpleContainer $c) {
 			$config = $c->query('AllConfig');
@@ -469,7 +486,7 @@ class Server extends SimpleContainer implements IServerContainer {
 	 * @return \OCP\IDBConnection
 	 */
 	function getDatabaseConnection() {
-		return \OC_DB::getConnection();
+		return $this->query('DatabaseConnection');
 	}
 
 	/**
-- 
GitLab