From 711cfbf8a7a42fe4e7ea185867fee94c4154b130 Mon Sep 17 00:00:00 2001 From: "Abdulmhsen B. A. A" Date: Fri, 18 Mar 2022 14:25:07 +0300 Subject: [PATCH] enabled support for mysql, pgsql as PDO backends. --- Dockerfile | 2 +- config/config.php | 19 +++------- docker/Dockerfile | 2 +- .../mysql_1644418046_create_state_table.sql | 32 +++++++++++++++++ .../pgsql_1644418046_create_state_table.sql | 35 +++++++++++++++++++ src/Libs/Storage/PDO/PDOAdapter.php | 33 +++++++++-------- src/Libs/Storage/PDO/PDOMigrations.php | 2 +- 7 files changed, 92 insertions(+), 33 deletions(-) create mode 100644 src/Libs/Storage/PDO/Migrations/mysql_1644418046_create_state_table.sql create mode 100644 src/Libs/Storage/PDO/Migrations/pgsql_1644418046_create_state_table.sql diff --git a/Dockerfile b/Dockerfile index 399330da..3016f226 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ LABEL maintainer="admin@arabcoders.org" ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/bin/ RUN mv "${PHP_INI_DIR}/php.ini-production" "${PHP_INI_DIR}/php.ini" && chmod +x /usr/bin/install-php-extensions && \ - sync && install-php-extensions pdo mbstring ctype sqlite3 json opcache xhprof && \ + sync && install-php-extensions pdo mbstring ctype sqlite3 json opcache xhprof pgsql mysql && \ apk add --no-cache caddy nano curl procps net-tools iproute2 shadow runuser && \ curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer && \ mkdir -p /app /config diff --git a/config/config.php b/config/config.php index b11375a5..a9612c69 100644 --- a/config/config.php +++ b/config/config.php @@ -13,16 +13,13 @@ use App\Libs\Servers\JellyfinServer; use App\Libs\Servers\PlexServer; use App\Libs\Storage\PDO\PDOAdapter; use Monolog\Logger; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; return (function () { $config = [ 'name' => 'WatchState', 'version' => 'v0.0.0', 'tz' => null, - 'path' => fixPath( - env('WS_DATA_PATH', fn() => env('IN_DOCKER') ? '/config' : realpath(__DIR__ . '/../var')) - ), + 'path' => fixPath(env('WS_DATA_PATH', fn() => env('IN_DOCKER') ? '/config' : realpath(__DIR__ . '/../var'))), ]; $config['tmpDir'] = fixPath(env('WS_TMP_DIR', fn() => ag($config, 'path'))); @@ -30,10 +27,7 @@ return (function () { $config['storage'] = [ 'type' => PDOAdapter::class, 'opts' => [ - 'dsn' => env( - 'WS_STORAGE_PDO_DSN', - fn() => 'sqlite:' . ag($config, 'path') . '/db/watchstate.db' - ), + 'dsn' => env('WS_STORAGE_PDO_DSN', fn() => 'sqlite:' . ag($config, 'path') . '/db/watchstate.db'), 'username' => env('WS_STORAGE_PDO_USERNAME', null), 'password' => env('WS_STORAGE_PDO_PASSWORD', null), 'exec' => [ @@ -41,6 +35,8 @@ return (function () { 'PRAGMA journal_mode=MEMORY', 'PRAGMA SYNCHRONOUS=OFF' ], + 'pgsql' => [], + 'mysql' => [], ], 'singleTransaction' => env('WS_STORAGE_PDO_ST', false), ], @@ -77,13 +73,6 @@ return (function () { ], ]; - $config['cache'] = [ - 'adapter' => FilesystemAdapter::class, - 'config' => [ - 'directory' => ag($config, 'tmpDir') . '/cache', - ], - ]; - $config['debug'] = [ 'profiler' => [ 'options' => [ diff --git a/docker/Dockerfile b/docker/Dockerfile index 162a3bc8..36a4d9ee 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -8,7 +8,7 @@ LABEL maintainer="admin@arabcoders.org" ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/bin/ RUN mv "${PHP_INI_DIR}/php.ini-production" "${PHP_INI_DIR}/php.ini" && chmod +x /usr/bin/install-php-extensions && \ - sync && install-php-extensions pdo mbstring ctype sqlite3 json opcache xhprof && \ + sync && install-php-extensions pdo mbstring ctype sqlite3 json opcache xhprof pgsql mysql && \ apk add --no-cache caddy nano curl procps net-tools iproute2 shadow runuser && \ curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer && \ mkdir -p /app /config diff --git a/src/Libs/Storage/PDO/Migrations/mysql_1644418046_create_state_table.sql b/src/Libs/Storage/PDO/Migrations/mysql_1644418046_create_state_table.sql new file mode 100644 index 00000000..1060be36 --- /dev/null +++ b/src/Libs/Storage/PDO/Migrations/mysql_1644418046_create_state_table.sql @@ -0,0 +1,32 @@ +-- # migrate_up + +CREATE TABLE `state` +( + `id` int(11) NOT NULL AUTO_INCREMENT, + `type` varchar(50) NOT NULL, + `updated` int(11) NOT NULL, + `watched` tinyint(4) NOT NULL DEFAULT 0, + `meta` text DEFAULT NULL, + `guid_plex` varchar(255) DEFAULT NULL, + `guid_imdb` varchar(255) DEFAULT NULL, + `guid_tvdb` varchar(255) DEFAULT NULL, + `guid_tmdb` varchar(255) DEFAULT NULL, + `guid_tvmaze` varchar(255) DEFAULT NULL, + `guid_tvrage` varchar(255) DEFAULT NULL, + `guid_anidb` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `type` (`type`), + KEY `watched` (`watched`), + KEY `updated` (`updated`), + KEY `guid_plex` (`guid_plex`), + KEY `guid_imdb` (`guid_imdb`), + KEY `guid_tvdb` (`guid_tvdb`), + KEY `guid_tmdb` (`guid_tmdb`), + KEY `guid_tvmaze` (`guid_tvmaze`), + KEY `guid_tvrage` (`guid_tvrage`), + KEY `guid_anidb` (`guid_anidb`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- # migrate_down + +DROP TABLE IF EXISTS `state`; diff --git a/src/Libs/Storage/PDO/Migrations/pgsql_1644418046_create_state_table.sql b/src/Libs/Storage/PDO/Migrations/pgsql_1644418046_create_state_table.sql new file mode 100644 index 00000000..dec2f4df --- /dev/null +++ b/src/Libs/Storage/PDO/Migrations/pgsql_1644418046_create_state_table.sql @@ -0,0 +1,35 @@ +-- # migrate_up + +CREATE SEQUENCE state_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1; + +CREATE TABLE "state" ( + "id" integer DEFAULT nextval('state_id_seq') NOT NULL, + "type" character varying NOT NULL, + "updated" integer NOT NULL, + "watched" smallint NOT NULL, + "meta" json, + "guid_plex" character varying, + "guid_imdb" character varying, + "guid_tvdb" character varying, + "guid_tmdb" character varying, + "guid_tvmaze" character varying, + "guid_tvrage" character varying, + "guid_anidb" character varying, + CONSTRAINT "state_pkey" PRIMARY KEY ("id") +) WITH (oids = false); + +CREATE INDEX "state_guid_anidb" ON "state" USING btree ("guid_anidb"); +CREATE INDEX "state_guid_imdb" ON "state" USING btree ("guid_imdb"); +CREATE INDEX "state_guid_plex" ON "state" USING btree ("guid_plex"); +CREATE INDEX "state_guid_tmdb" ON "state" USING btree ("guid_tmdb"); +CREATE INDEX "state_guid_tvdb" ON "state" USING btree ("guid_tvdb"); +CREATE INDEX "state_guid_tvmaze" ON "state" USING btree ("guid_tvmaze"); +CREATE INDEX "state_guid_tvrage" ON "state" USING btree ("guid_tvrage"); +CREATE INDEX "state_type" ON "state" USING btree ("type"); +CREATE INDEX "state_updated" ON "state" USING btree ("updated"); +CREATE INDEX "state_watched" ON "state" USING btree ("watched"); + +-- # migrate_down + +DROP TABLE IF EXISTS "state"; +DROP SEQUENCE IF EXISTS state_id_seq; diff --git a/src/Libs/Storage/PDO/PDOAdapter.php b/src/Libs/Storage/PDO/PDOAdapter.php index 0fb9ce89..4f766bd8 100644 --- a/src/Libs/Storage/PDO/PDOAdapter.php +++ b/src/Libs/Storage/PDO/PDOAdapter.php @@ -20,9 +20,8 @@ final class PDOAdapter implements StorageInterface { private array $supported = [ 'sqlite', - // @TODO For v1.x support mysql/pgsql - //'mysql', - //'pgsql' + 'mysql', + 'pgsql' ]; private PDO|null $pdo = null; @@ -50,18 +49,22 @@ final class PDOAdapter implements StorageInterface throw new StorageException('No storage.opts.dsn (Data Source Name) was provided.', 10); } - $this->pdo = new PDO( - $opts['dsn'], $opts['username'] ?? null, $opts['password'] ?? null, - array_replace_recursive( - [ - PDO::ATTR_EMULATE_PREPARES => false, - PDO::ATTR_STRINGIFY_FETCHES => false, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - ], - $opts['options'] ?? [] - ) - ); + try { + $this->pdo = new PDO( + $opts['dsn'], $opts['username'] ?? null, $opts['password'] ?? null, + array_replace_recursive( + [ + PDO::ATTR_EMULATE_PREPARES => false, + PDO::ATTR_STRINGIFY_FETCHES => false, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ], + $opts['options'] ?? [] + ) + ); + } catch (PDOException $e) { + throw new \RuntimeException(sprintf('Unable to connect to storage backend. \'%s\'.', $e->getMessage())); + } $driver = $this->getDriver(); diff --git a/src/Libs/Storage/PDO/PDOMigrations.php b/src/Libs/Storage/PDO/PDOMigrations.php index b0447a90..98bc5286 100644 --- a/src/Libs/Storage/PDO/PDOMigrations.php +++ b/src/Libs/Storage/PDO/PDOMigrations.php @@ -21,8 +21,8 @@ final class PDOMigrations public function __construct(private PDO $pdo, private LoggerInterface $logger) { $this->path = __DIR__ . '/Migrations'; - $this->versionFile = Config::get('path') . '/db/pdo_migrations_version'; $this->driver = $this->getDriver(); + $this->versionFile = Config::get('path') . sprintf('/db/%s.migration', $this->driver); } public function setLogger(LoggerInterface $logger): self