Skip to content

Commit 8e6dd8f

Browse files
committed
Allow options to be provided to Doctrine
1 parent 2078109 commit 8e6dd8f

File tree

3 files changed

+120
-5
lines changed

3 files changed

+120
-5
lines changed

config/config.sample.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,6 +1824,34 @@
18241824
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET wait_timeout = 28800'
18251825
],
18261826

1827+
/**
1828+
* Allows defining custom DB types and options as well as the ability to override
1829+
* the default connection parameters as defined by
1830+
* OC\DB\ConnectionFactory::defaultConnectionParams.
1831+
*/
1832+
'dbconnectionparams' => [
1833+
'dbtype' => [
1834+
'adapter' => AdapterMySQL::class,
1835+
'charset' => 'UTF8',
1836+
'driver' => 'pdo_dbtype',
1837+
'wrapperClass' => Doctrine\DBAL\Connection::class,
1838+
],
1839+
],
1840+
1841+
/**
1842+
* Allows additional configuration options to be provided for the database
1843+
* connection as defined by Doctrine\DBAL\Configuration::class. This is useful
1844+
* for specifying a custom logger, middlewares, etc.
1845+
*/
1846+
'dbconfigurationparams' => [
1847+
"sqllogger" => 'Doctrine\DBAL\Logging\SQLLogger',
1848+
"resultcache" => 'Psr\Cache\CacheItemPoolInterface',
1849+
"schemaassetsfilter" => 'callable',
1850+
"autocommit" => true,
1851+
"middlewares" => array(
1852+
'Doctrine\DBAL\Driver\Middleware',
1853+
),
1854+
],
18271855
/**
18281856
* sqlite3 journal mode can be specified using this configuration parameter -
18291857
* can be 'WAL' or 'DELETE' see for more details https://www.sqlite.org/wal.html

lib/private/AppFramework/App.php

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,15 @@
3434
use OC\AppFramework\DependencyInjection\DIContainer;
3535
use OC\AppFramework\Http\Dispatcher;
3636
use OC\AppFramework\Http\Request;
37-
use OCP\App\IAppManager;
38-
use OCP\Profiler\IProfiler;
3937
use OC\Profiler\RoutingDataCollector;
40-
use OCP\AppFramework\QueryException;
4138
use OCP\AppFramework\Http;
4239
use OCP\AppFramework\Http\ICallbackResponse;
4340
use OCP\AppFramework\Http\IOutput;
41+
use OCP\AppFramework\QueryException;
4442
use OCP\Diagnostics\IEventLogger;
4543
use OCP\HintException;
4644
use OCP\IRequest;
45+
use OCP\Profiler\IProfiler;
4746

4847
/**
4948
* Entry point for every request in your app. You can consider this as your
@@ -69,7 +68,7 @@ public static function buildAppNamespace(string $appId, string $topNamespace = '
6968
return $topNamespace . self::$nameSpaceCache[$appId];
7069
}
7170

72-
$appInfo = \OCP\Server::get(IAppManager::class)->getAppInfo($appId);
71+
$appInfo = self::getAppInfo($appId);
7372
if (isset($appInfo['namespace'])) {
7473
self::$nameSpaceCache[$appId] = trim($appInfo['namespace']);
7574
} else {
@@ -91,11 +90,42 @@ public static function buildAppNamespace(string $appId, string $topNamespace = '
9190
return $topNamespace . self::$nameSpaceCache[$appId];
9291
}
9392

93+
public static function getAppInfo(string $appId, bool $path = false, $lang = null) {
94+
if ($path) {
95+
$file = $appId;
96+
} else {
97+
try {
98+
if ($appPath = \OC_App::findAppInDirectories($appId, true)) {
99+
$appPath = $appPath['path'] . '/' . $appId;
100+
}
101+
} catch (\OCP\App\AppPathNotFoundException $e) {
102+
return null;
103+
}
104+
$file = $appPath . '/appinfo/info.xml';
105+
}
106+
107+
$parser = new \OC\App\InfoParser();
108+
$data = $parser->parse($file);
109+
110+
if (is_array($data)) {
111+
$data = \OC_App::parseAppInfo($data, $lang);
112+
}
113+
114+
return $data;
115+
}
116+
94117
public static function getAppIdForClass(string $className, string $topNamespace = 'OCA\\'): ?string {
95118
if (!str_starts_with($className, $topNamespace)) {
96119
return null;
97120
}
98121

122+
if (str_starts_with($className, $topNamespace)) {
123+
$classNoTopNamespace = substr($className, strlen($topNamespace));
124+
$appNameParts = explode('\\', $classNoTopNamespace, 2);
125+
$appName = reset($appNameParts);
126+
return strtolower($appName);
127+
}
128+
99129
foreach (self::$nameSpaceCache as $appId => $namespace) {
100130
if (str_starts_with($className, $topNamespace . $namespace . '\\')) {
101131
return $appId;
@@ -105,6 +135,16 @@ public static function getAppIdForClass(string $className, string $topNamespace
105135
return null;
106136
}
107137

138+
public static function registerAppClass(string $className): void {
139+
$classParts = explode('\\', $className, 2);
140+
$topNamespace = reset($classParts) . '\\';
141+
$appId = self::getAppIdForClass($className, $topNamespace);
142+
143+
if ($appPath = \OC_App::findAppInDirectories($appId, true)) {
144+
$appPath = $appPath['path'] . '/' . $appId;
145+
\OC_App::registerAutoloading($appId, $appPath);
146+
}
147+
}
108148

109149
/**
110150
* Shortcut for calling a controller method and printing the result

lib/private/DB/ConnectionFactory.php

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Doctrine\DBAL\DriverManager;
3434
use Doctrine\DBAL\Event\Listeners\OracleSessionInit;
3535
use Doctrine\DBAL\Event\Listeners\SQLSessionInit;
36+
use OC\AppFramework\App;
3637
use OC\SystemConfig;
3738

3839
/**
@@ -93,6 +94,21 @@ public function __construct(SystemConfig $systemConfig) {
9394
if ($collationOverride) {
9495
$this->defaultConnectionParams['mysql']['collation'] = $collationOverride;
9596
}
97+
98+
$connectionParams = $this->config->getValue('dbconnectionparams', array());
99+
100+
foreach ($connectionParams as $type) {
101+
foreach ($type as $key => $param) {
102+
switch ($key) {
103+
case 'adapter':
104+
case 'wrapperClass':
105+
\OC::$server->get(App::class)::registerAppClass($param);
106+
break;
107+
}
108+
}
109+
}
110+
111+
$this->defaultConnectionParams = array_replace_recursive($this->defaultConnectionParams, $connectionParams);
96112
}
97113

98114
/**
@@ -158,9 +174,40 @@ public function getConnection($type, $additionalConnectionParams) {
158174
break;
159175
}
160176
/** @var Connection $connection */
177+
$configuration = new Configuration();
178+
179+
foreach ($this->config->getValue('dbconfigurationparams', array()) as $param => $value) {
180+
switch ($param) {
181+
case "sqllogger":
182+
\OC::$server->get(App::class)::registerAppClass($value);
183+
$configuration->setSQLLogger(new $value());
184+
break;
185+
case "resultcache":
186+
\OC::$server->get(App::class)::registerAppClass($value);
187+
$configuration->setResultCache(new $value());
188+
break;
189+
case "schemaassetsfilter":
190+
$configuration->setSchemaAssetsFilter($value);
191+
break;
192+
case "autocommit":
193+
$configuration->setAutoCommit($value);
194+
break;
195+
case "middlewares":
196+
$middlewares = array();
197+
198+
foreach ($value as $middleware) {
199+
\OC::$server->get(App::class)::registerAppClass($middleware);
200+
array_push($middlewares, new $middleware());
201+
}
202+
203+
$configuration->setMiddlewares($value);
204+
break;
205+
}
206+
}
207+
161208
$connection = DriverManager::getConnection(
162209
array_merge($this->getDefaultConnectionParams($type), $additionalConnectionParams),
163-
new Configuration(),
210+
$configuration,
164211
$eventManager
165212
);
166213
return $connection;

0 commit comments

Comments
 (0)