summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Fischer <bantu@owncloud.com>2014-03-31 20:00:44 +0200
committerAndreas Fischer <bantu@owncloud.com>2014-03-31 20:09:07 +0200
commitf9853b253c6ecb9a77a9d1c9006c5f548cdfd04e (patch)
treeacd148a858ace6d0ebc71b5534bb0ee34b57d207 /lib
parenta585cec5303a7b3d361559f73bba154fcbe0c978 (diff)
downloadnextcloud-server-f9853b253c6ecb9a77a9d1c9006c5f548cdfd04e.tar.gz
nextcloud-server-f9853b253c6ecb9a77a9d1c9006c5f548cdfd04e.zip
Deduplicate connection handling code into \OC\DB\ConnectionFactory
Diffstat (limited to 'lib')
-rw-r--r--lib/private/db.php139
-rw-r--r--lib/private/db/connectionfactory.php117
2 files changed, 158 insertions, 98 deletions
diff --git a/lib/private/db.php b/lib/private/db.php
index cfdac766bff..11532d9fa54 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 00000000000..14ffe1a4a56
--- /dev/null
+++ b/lib/private/db/connectionfactory.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Copyright (c) 2014 Andreas Fischer <bantu@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]);
+ }
+}