Completed
Pull Request — master (#17978)
by Thomas
09:39
created

lib/private/DB/ConnectionFactory.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * @author Andreas Fischer <[email protected]>
4
 * @author Jörn Friedrich Dreyer <[email protected]>
5
 * @author Morris Jobke <[email protected]>
6
 * @author Robin Appelman <[email protected]>
7
 * @author Thomas Müller <[email protected]>
8
 *
9
 * @copyright Copyright (c) 2016, ownCloud GmbH.
10
 * @license AGPL-3.0
11
 *
12
 * This code is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License, version 3,
14
 * as published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License, version 3,
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
23
 *
24
 */
25
26
namespace OC\DB;
27
use Doctrine\DBAL\Event\Listeners\OracleSessionInit;
28
use Doctrine\DBAL\Event\Listeners\SQLSessionInit;
29
use Doctrine\DBAL\Event\Listeners\MysqlSessionInit;
30
31
/**
32
* Takes care of creating and configuring Doctrine connections.
33
*/
34
class ConnectionFactory {
35
	/**
36
	* @var array
37
	*
38
	* Array mapping DBMS type to default connection parameters passed to
39
	* \Doctrine\DBAL\DriverManager::getConnection().
40
	*/
41
	protected $defaultConnectionParams = [
42
		'mysql' => [
43
			'adapter' => '\OC\DB\AdapterMySQL',
44
			'charset' => 'UTF8',
45
			'driver' => 'pdo_mysql',
46
			'wrapperClass' => 'OC\DB\Connection',
47
		],
48
		'oci' => [
49
			'adapter' => '\OC\DB\AdapterOCI8',
50
			'charset' => 'AL32UTF8',
51
			'driver' => 'oci8',
52
			'wrapperClass' => 'OC\DB\OracleConnection',
53
		],
54
		'pgsql' => [
55
			'adapter' => '\OC\DB\AdapterPgSql',
56
			'driver' => 'pdo_pgsql',
57
			'wrapperClass' => 'OC\DB\Connection',
58
		],
59
		'sqlite3' => [
60
			'adapter' => '\OC\DB\AdapterSqlite',
61
			'driver' => 'pdo_sqlite',
62
			'wrapperClass' => 'OC\DB\Connection',
63
		],
64
	];
65
66
	/**
67
	* @brief Get default connection parameters for a given DBMS.
68
	* @param string $type DBMS type
69
	* @throws \InvalidArgumentException If $type is invalid
70
	* @return array Default connection parameters.
71
	*/
72
	public function getDefaultConnectionParams($type) {
73
		$normalizedType = $this->normalizeType($type);
74
		if (!isset($this->defaultConnectionParams[$normalizedType])) {
75
			throw new \InvalidArgumentException("Unsupported type: $type");
76
		}
77
		$result = $this->defaultConnectionParams[$normalizedType];
78
		// \PDO::MYSQL_ATTR_FOUND_ROWS may not be defined, e.g. when the MySQL
79
		// driver is missing. In this case, we won't be able to connect anyway.
80
		if ($normalizedType === 'mysql' && defined('\PDO::MYSQL_ATTR_FOUND_ROWS')) {
81
			$result['driverOptions'] = [
82
				\PDO::MYSQL_ATTR_FOUND_ROWS => true,
83
			];
84
		}
85
86
		return $result;
87
	}
88
89
	/**
90
	* @brief Get default connection parameters for a given DBMS.
91
	* @param string $type DBMS type
92
	* @param array $additionalConnectionParams Additional connection parameters
93
	* @return \OC\DB\Connection
94
	*/
95
	public function getConnection($type, $additionalConnectionParams) {
96
		$normalizedType = $this->normalizeType($type);
97
		$eventManager = new \Doctrine\Common\EventManager();
98
		switch ($normalizedType) {
99
			case 'mysql':
100
				// Send "SET NAMES utf8". Only required on PHP 5.3 below 5.3.6.
101
				// See http://stackoverflow.com/questions/4361459/php-pdo-charset-set-names#4361485
102
				$eventManager->addEventSubscriber(new MysqlSessionInit);
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\DBAL\Event\Listeners\MysqlSessionInit has been deprecated with message: Use "charset" option to PDO MySQL Connection instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
103
				$eventManager->addEventSubscriber(
104
					new SQLSessionInit("SET SESSION AUTOCOMMIT=1"));
105
				break;
106
			case 'oci':
107
				$eventManager->addEventSubscriber(new OracleSessionInit);
108
				// the driverOptions are unused in dbal and need to be mapped to the parameters
109
				if (isset($additionalConnectionParams['driverOptions'])) {
110
					$additionalConnectionParams = array_merge($additionalConnectionParams, $additionalConnectionParams['driverOptions']);
111
				}
112
				break;
113
			case 'sqlite3':
114
				$journalMode = $additionalConnectionParams['sqlite.journal_mode'];
115
				$additionalConnectionParams['platform'] = new OCSqlitePlatform();
116
				$eventManager->addEventSubscriber(new SQLiteSessionInit(true, $journalMode));
117
				break;
118
		}
119
		$connection = \Doctrine\DBAL\DriverManager::getConnection(
120
			array_merge($this->getDefaultConnectionParams($type), $additionalConnectionParams),
121
			new \Doctrine\DBAL\Configuration(),
122
			$eventManager
123
		);
124
		return $connection;
125
	}
126
127
	/**
128
	* @brief Normalize DBMS type
129
	* @param string $type DBMS type
130
	* @return string Normalized DBMS type
131
	*/
132
	public function normalizeType($type) {
133
		return $type === 'sqlite' ? 'sqlite3' : $type;
134
	}
135
136
	/**
137
	* @brief Checks whether the specified DBMS type is valid.
138
	* @return bool
139
	*/
140
	public function isValidType($type) {
141
		$normalizedType = $this->normalizeType($type);
142
		return isset($this->defaultConnectionParams[$normalizedType]);
143
	}
144
145
	/**
146
	 * Create the connection parameters for the config
147
	 *
148
	 * @param \OC\SystemConfig $config
149
	 * @return array
150
	 */
151
	public function createConnectionParams($config) {
152
		$type = $config->getValue('dbtype', 'sqlite');
153
154
		$connectionParams = [
155
			'user' => $config->getValue('dbuser', ''),
156
			'password' => $config->getValue('dbpassword', ''),
157
		];
158
		$name = $config->getValue('dbname', 'owncloud');
159
160
		if ($this->normalizeType($type) === 'sqlite3') {
161
			$dataDir = $config->getValue("datadirectory", \OC::$SERVERROOT . '/data');
162
			$connectionParams['path'] = $dataDir . '/' . $name . '.db';
163
		} else {
164
			$host = $config->getValue('dbhost', '');
165
			if (strpos($host, ':')) {
166
				// Host variable may carry a port or socket.
167
				list($host, $portOrSocket) = explode(':', $host, 2);
168
				if (ctype_digit($portOrSocket)) {
169
					$connectionParams['port'] = $portOrSocket;
170
				} else {
171
					$connectionParams['unix_socket'] = $portOrSocket;
172
				}
173
			}
174
			$connectionParams['host'] = $host;
175
			$connectionParams['dbname'] = $name;
176
		}
177
178
		$connectionParams['tablePrefix'] = $config->getValue('dbtableprefix', 'oc_');
179
		$connectionParams['sqlite.journal_mode'] = $config->getValue('sqlite.journal_mode', 'WAL');
180
181
		//additional driver options, eg. for mysql ssl
182
		$driverOptions = $config->getValue('dbdriveroptions', null);
183
		if ($driverOptions) {
184
			$connectionParams['driverOptions'] = $driverOptions;
185
		}
186
187
		// set default table creation options
188
		$connectionParams['defaultTableOptions'] = [
189
			'collate' => 'utf8_bin',
190
			'tablePrefix' => $connectionParams['tablePrefix']
191
		];
192
193
		return $connectionParams;
194
	}
195
}
196