From b570f495cc65688e2cdd5ba32570c2796468dd44 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 4 Oct 2020 14:00:17 +0200 Subject: [PATCH] common: Support MySQL through socket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unlike PostgreSQL, MySQL’s DSN needs a separate option for UNIX sockets. It also cannot handle ports with socket. This will be useful for running tests with internal MySQL instance. --- NEWS.md | 1 + docs/content/docs/administration/options.md | 6 ++++++ src/common.php | 17 +++++++++++++++-- src/helpers/Configuration.php | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 17e9b1b80f..8393da3f66 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,6 +13,7 @@ - Data directory can be configured ([#1043](https://github.com/fossar/selfoss/pull/1043)) - New spout for searching Twitter (e.g. following hashtags) was added. ([#1213](https://github.com/fossar/selfoss/pull/1213)) - Added option `reading_speed_wpm` for showing estimated reading time. ([#1232](https://github.com/fossar/selfoss/pull/1232)) +- Added option `db_socket` for connecting to MySQL database through UNIX domain. ([#1284](https://github.com/fossar/selfoss/pull/1284)) - Search query is now part of URL. ([#1216](https://github.com/fossar/selfoss/pull/1216)) - Search will be carried out using regular expressions when the search query is wrapped in forward slashes, e.g. `/regex/`. The expression syntax is database specific. ([#1205](https://github.com/fossar/selfoss/pull/1205)) - YouTube spout now supports following playlists. ([#1260](https://github.com/fossar/selfoss/pull/1260)) diff --git a/docs/content/docs/administration/options.md b/docs/content/docs/administration/options.md index f1fa4ed117..10ba9b6169 100644 --- a/docs/content/docs/administration/options.md +++ b/docs/content/docs/administration/options.md @@ -53,6 +53,12 @@ Table prefix for MySQL/SQLite databases. This is useful to avoid conflicts when Port for database connections. By default `3306` will be used for MySQL and `5432` for PostgreSQL. +### `db_socket` +
+ +A UNIX domain socket used for connecting to the MySQL database server. Usually, you want to use `db_host=localhost`, which should use the default socket path (typically `/run/mysqld/mysqld.sock` for MySQL or `/run/postgresql` for PostgreSQL) but if you need to specify a different location, you can. This is orthogonal to `db_host` option. +
+ ### `logger_destination`
diff --git a/src/common.php b/src/common.php index f22393a429..ab35c8c586 100644 --- a/src/common.php +++ b/src/common.php @@ -84,6 +84,11 @@ $dice->addRule(daos\SourcesInterface::class, $shared); $dice->addRule(daos\TagsInterface::class, $shared); +if ($configuration->isChanged('dbSocket') && $configuration->isChanged('dbHost')) { + echo 'You cannot set both `db_socket` and `db_host` options.' . PHP_EOL; + exit; +} + // Database connection if ($configuration->dbType === 'sqlite') { $db_file = $configuration->dbFile; @@ -93,16 +98,21 @@ touch($db_file); } + // https://www.php.net/manual/en/ref.pdo-sqlite.connection.php $dsn = 'sqlite:' . $db_file; $dbParams = [ $dsn, ]; } elseif ($configuration->dbType === 'mysql') { + $socket = $configuration->dbSocket; $host = $configuration->dbHost; $port = $configuration->dbPort; $database = $configuration->dbDatabase; - if ($port !== null) { + // https://www.php.net/manual/en/ref.pdo-mysql.connection.php + if ($socket !== null) { + $dsn = "mysql:unix_socket=$socket; dbname=$database"; + } elseif ($port !== null) { $dsn = "mysql:host=$host; port=$port; dbname=$database"; } else { $dsn = "mysql:host=$host; dbname=$database"; @@ -115,10 +125,13 @@ [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4;'], ]; } elseif ($configuration->dbType === 'pgsql') { - $host = $configuration->dbHost; + $socket = $configuration->dbSocket; + // PostgreSQL uses host key for socket. + $host = $configuration->dbSocket !== null ? $configuration->dbSocket : $configuration->dbHost; $port = $configuration->dbPort; $database = $configuration->dbDatabase; + // https://www.php.net/manual/en/ref.pdo-pgsql.connection.php if ($port !== null) { $dsn = "pgsql:host=$host; port=$port; dbname=$database"; } else { diff --git a/src/helpers/Configuration.php b/src/helpers/Configuration.php index 7e331fa349..31ab8cfb24 100644 --- a/src/helpers/Configuration.php +++ b/src/helpers/Configuration.php @@ -19,6 +19,9 @@ class Configuration { 'ftrssCustomDataDir', ]; + /** @var array Keeps track of options that have been changed. */ + private $modifiedOptions = []; + // Internal but overridable values. /** @var int debugging level @internal */ @@ -56,6 +59,9 @@ class Configuration { /** @var ?int */ public $dbPort = null; + /** @var ?string */ + public $dbSocket = null; + /** @var string */ public $dbPrefix = ''; @@ -217,6 +223,7 @@ public function __construct($configPath = null, $environment = []) { } $this->{$propertyName} = $value; + $this->modifiedOptions[$propertyName] = true; } // Interpolate variables in the config values. @@ -226,4 +233,15 @@ public function __construct($configPath = null, $environment = []) { $this->{$property} = str_replace('%datadir%', $datadir, $value); } } + + /** + * Checks whether given configuration option has been changed. + * + * @param string $key + * + * @return bool + */ + public function isChanged($key) { + return isset($this->modifiedOptions[$key]); + } }