Switched database reference from storage to database.

This commit is contained in:
Abdulmhsen B. A. A
2022-07-06 20:04:20 +03:00
parent 64615be31d
commit 4ff605d5bf
32 changed files with 234 additions and 240 deletions

2
FAQ.md
View File

@@ -282,7 +282,7 @@ where `[LIBRARY_ID]` refers to backend library id
### Q: What does mapper mean?
A Mapper is class that have list of all external ids that point to record in storage. think of it as dictionary that
A Mapper is class that have list of all external ids that point to record in database. think of it as dictionary that
reference to specific item.
#### Memory Mapper (Default)

View File

@@ -26,7 +26,7 @@ return (function () {
'after' => env('WS_LOGS_PRUNE_AFTER', '-3 DAYS'),
],
],
'storage' => [
'database' => [
'version' => 'v01',
],
'export' => [
@@ -47,8 +47,8 @@ return (function () {
$config['tmpDir'] = fixPath(env('WS_TMP_DIR', ag($config, 'path')));
$config['storage'] += [
'dsn' => 'sqlite:' . ag($config, 'path') . '/db/watchstate_' . ag($config, 'storage.version') . '.db',
$config['database'] += [
'dsn' => 'sqlite:' . ag($config, 'path') . '/db/watchstate_' . ag($config, 'database.version') . '.db',
'username' => null,
'password' => null,
'options' => [

View File

@@ -4,15 +4,15 @@ declare(strict_types=1);
use App\Libs\Config;
use App\Libs\Container;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Database\PDO\PDOAdapter;
use App\Libs\Entity\StateEntity;
use App\Libs\Entity\StateInterface;
use App\Libs\Extends\ConsoleOutput;
use App\Libs\Extends\LogMessageProcessor;
use App\Libs\Mappers\Import\MemoryMapper;
use App\Libs\Mappers\ImportInterface;
use App\Libs\Mappers\ImportInterface as iImport;
use App\Libs\QueueRequests;
use App\Libs\Storage\PDO\PDOAdapter;
use App\Libs\Storage\StorageInterface;
use Monolog\Logger;
use Nyholm\Psr7\Uri;
use Psr\Http\Message\UriInterface;
@@ -22,9 +22,9 @@ use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\NullAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Psr16Cache;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpClient\CurlHttpClient;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\Console\Output\OutputInterface;
return (function (): array {
return [
@@ -113,9 +113,9 @@ return (function (): array {
PDO::class => [
'class' => function (): PDO {
$pdo = new PDO(dsn: Config::get('storage.dsn'), options: Config::get('storage.options', []));
$pdo = new PDO(dsn: Config::get('database.dsn'), options: Config::get('database.options', []));
foreach (Config::get('storage.exec', []) as $cmd) {
foreach (Config::get('database.exec', []) as $cmd) {
$pdo->exec($cmd);
}
@@ -123,14 +123,14 @@ return (function (): array {
},
],
StorageInterface::class => [
'class' => function (LoggerInterface $logger, PDO $pdo): StorageInterface {
iDB::class => [
'class' => function (LoggerInterface $logger, PDO $pdo): iDB {
$adapter = new PDOAdapter($logger, $pdo);
if (true !== $adapter->isMigrated()) {
$adapter->migrations(StorageInterface::MIGRATE_UP);
$adapter->migrations(iDB::MIGRATE_UP);
$adapter->migrateData(
Config::get('storage.version'),
Config::get('database.version'),
Container::get(LoggerInterface::class)
);
}
@@ -144,18 +144,18 @@ return (function (): array {
],
MemoryMapper::class => [
'class' => function (LoggerInterface $logger, StorageInterface $storage): ImportInterface {
return (new MemoryMapper(logger: $logger, storage: $storage))
'class' => function (LoggerInterface $logger, iDB $db): iImport {
return (new MemoryMapper(logger: $logger, db: $db))
->setOptions(options: Config::get('mapper.import.opts', []));
},
'args' => [
LoggerInterface::class,
StorageInterface::class,
iDB::class,
],
],
ImportInterface::class => [
'class' => function (ImportInterface $mapper): ImportInterface {
iImport::class => [
'class' => function (iImport $mapper): iImport {
return $mapper;
},
'args' => [

View File

@@ -160,12 +160,12 @@ class Export extends Import
if ($rItem->updated >= $entity->updated && false === ag($context->options, Options::IGNORE_DATE, false)) {
$this->logger->debug(
'Ignoring [%(backend)] [%(item.title)]. Backend date is equal or newer than storage date.',
'Ignoring [%(backend)] [%(item.title)]. Backend date is equal or newer than database date.',
[
'backend' => $context->backendName,
...$logContext,
'comparison' => [
'storage' => makeDate($entity->updated),
'database' => makeDate($entity->updated),
'backend' => makeDate($rItem->updated),
],
]

View File

@@ -229,12 +229,12 @@ class Push
if ($date->getTimestamp() >= ($timeExtra + $entity->updated)) {
$this->logger->notice(
'Ignoring [%(backend)] %(item.type) [%(item.title)]. Storage date is older than backend date.',
'Ignoring [%(backend)] %(item.type) [%(item.title)]. Database date is older than backend date.',
[
'backend' => $context->backendName,
...$logContext,
'comparison' => [
'storage' => makeDate($entity->updated),
'database' => makeDate($entity->updated),
'backend' => $date,
'difference' => $date->getTimestamp() - $entity->updated,
'extra_margin' => [

View File

@@ -169,12 +169,12 @@ final class Export extends Import
if ($rItem->updated >= $entity->updated && false === ag($context->options, Options::IGNORE_DATE, false)) {
$this->logger->debug(
'Ignoring [%(backend)] [%(item.title)]. Backend date is equal or newer than storage date.',
'Ignoring [%(backend)] [%(item.title)]. Backend date is equal or newer than database date.',
[
'backend' => $context->backendName,
...$logContext,
'comparison' => [
'storage' => makeDate($entity->updated),
'database' => makeDate($entity->updated),
'backend' => makeDate($rItem->updated),
],
]

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace App\Backends\Plex\Action;
use App\Backends\Common\CommonTrait;
use App\Backends\Common\Response;
use App\Backends\Common\Context;
use App\Backends\Common\Response;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Options;
use App\Libs\QueueRequests;
@@ -234,12 +234,12 @@ final class Push
if ($date->getTimestamp() >= ($entity->updated + $timeExtra)) {
$this->logger->notice(
'Ignoring [%(backend)] %(item.type) [%(item.title)]. Storage date is older than backend date.',
'Ignoring [%(backend)] %(item.type) [%(item.title)]. Database date is older than backend date.',
[
'backend' => $context->backendName,
...$logContext,
'comparison' => [
'storage' => makeDate($entity->updated),
'database' => makeDate($entity->updated),
'backend' => $date,
'difference' => $date->getTimestamp() - $entity->updated,
'extra_margin' => [

View File

@@ -7,10 +7,10 @@ namespace App\Commands\Backend\Ignore;
use App\Command;
use App\Libs\Config;
use App\Libs\Container;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Guid;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use PDO;
use Psr\Http\Message\UriInterface;
use Symfony\Component\Console\Completion\CompletionInput;
@@ -28,9 +28,9 @@ final class ListCommand extends Command
private PDO $db;
public function __construct(StorageInterface $storage)
public function __construct(iDB $db)
{
$this->db = $storage->getPdo();
$this->db = $db->getPdo();
parent::__construct();
}

View File

@@ -7,10 +7,10 @@ namespace App\Commands\Database;
use App\Command;
use App\Libs\Config;
use App\Libs\Container;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iFace;
use App\Libs\Guid;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use Exception;
use PDO;
use RuntimeException;
@@ -52,9 +52,9 @@ final class ListCommand extends Command
private PDO $pdo;
public function __construct(private StorageInterface $storage)
public function __construct(private iDB $db)
{
$this->pdo = $this->storage->getPdo();
$this->pdo = $this->db->getPdo();
parent::__construct();
}
@@ -134,7 +134,7 @@ final class ListCommand extends Command
{
$limit = (int)$input->getOption('limit');
$es = fn(string $val) => $this->storage->identifier($val);
$es = fn(string $val) => $this->db->identifier($val);
$params = [
'limit' => $limit <= 0 ? 20 : $limit,
@@ -262,7 +262,7 @@ final class ListCommand extends Command
$arr = [
'query' => $sql,
'parameters' => $params,
'raw' => $this->storage->getRawSQLString($sql, $params),
'raw' => $this->db->getRawSQLString($sql, $params),
];
if ('table' === $input->getOption('output')) {

View File

@@ -6,9 +6,9 @@ namespace App\Commands\Database;
use App\Command;
use App\Libs\Container;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;
use Symfony\Component\Console\Helper\Table;
@@ -22,10 +22,8 @@ class QueueCommand extends Command
{
public const ROUTE = 'db:queue';
public function __construct(
private CacheInterface $cache,
private StorageInterface $storage,
) {
public function __construct(private CacheInterface $cache, private iDB $db)
{
set_time_limit(0);
ini_set('memory_limit', '-1');
@@ -51,7 +49,7 @@ class QueueCommand extends Command
if (null !== ($id = $input->getOption('add'))) {
$item = Container::get(StateInterface::class)::fromArray(['id' => $id]);
if (null === ($item = $this->storage->get($item))) {
if (null === ($item = $this->db->get($item))) {
$output->writeln(sprintf('<error>Record id \'%d\' does not exists.</error>', $id));
return self::FAILURE;
}
@@ -85,7 +83,7 @@ class QueueCommand extends Command
}
if (!empty($items)) {
foreach ($this->storage->find(...$items) as $item) {
foreach ($this->db->find(...$items) as $item) {
$entities[$item->id] = $item;
}
}

View File

@@ -6,14 +6,14 @@ namespace App\Commands\State;
use App\Command;
use App\Libs\Config;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Mappers\Import\DirectMapper;
use App\Libs\Message;
use App\Libs\Options;
use App\Libs\QueueRequests;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerInterface as iLogger;
use RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -29,10 +29,10 @@ class ExportCommand extends Command
public const TASK_NAME = 'export';
public function __construct(
private StorageInterface $storage,
private iDB $db,
private DirectMapper $mapper,
private QueueRequests $queue,
private LoggerInterface $logger
private iLogger $logger
) {
set_time_limit(0);
ini_set('memory_limit', '-1');
@@ -194,14 +194,14 @@ class ExportCommand extends Command
$lastSync = makeDate($minDate);
$this->logger->notice('STORAGE: Loading changed items since [%(date)].', [
$this->logger->notice('DATABASE: Loading changed items since [%(date)].', [
'date' => $lastSync->format('Y-m-d H:i:s T')
]);
$entities = $this->storage->getAll($lastSync);
$entities = $this->db->getAll($lastSync);
if (count($entities) < 1 && count($export) < 1) {
$this->logger->notice('STORAGE: No play state change detected since [%(date)].', [
$this->logger->notice('DATABASE: No play state change detected since [%(date)].', [
'date' => $lastSync->format('Y-m-d H:i:s T')
]);
return self::SUCCESS;
@@ -459,7 +459,7 @@ class ExportCommand extends Command
],
]);
$this->storage->singleTransaction();
$this->db->singleTransaction();
$requests = [];

View File

@@ -6,14 +6,14 @@ namespace App\Commands\State;
use App\Command;
use App\Libs\Config;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Mappers\Import\DirectMapper;
use App\Libs\Mappers\ImportInterface;
use App\Libs\Mappers\ImportInterface as iImport;
use App\Libs\Message;
use App\Libs\Options;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerInterface as iLogger;
use RuntimeException;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableSeparator;
@@ -31,11 +31,8 @@ class ImportCommand extends Command
public const TASK_NAME = 'import';
public function __construct(
private StorageInterface $storage,
private ImportInterface $mapper,
private LoggerInterface $logger
) {
public function __construct(private iDB $db, private iImport $mapper, private iLogger $logger)
{
set_time_limit(0);
ini_set('memory_limit', '-1');
@@ -67,7 +64,7 @@ class ImportCommand extends Command
'metadata-only',
null,
InputOption::VALUE_NONE,
'import metadata changes only. Works when there are records in storage.'
'import metadata changes only. Works when there are records in database.'
)
->addOption('show-messages', null, InputOption::VALUE_NONE, 'Show internal messages.')
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.')
@@ -109,7 +106,7 @@ class ImportCommand extends Command
if ($input->getOption('trace')) {
$mapperOpts[Options::DEBUG_TRACE] = true;
$this->storage->setOptions(options: [Options::DEBUG_TRACE => true]);
$this->db->setOptions(options: [Options::DEBUG_TRACE => true]);
}
if ($input->getOption('always-update-metadata')) {
@@ -117,7 +114,7 @@ class ImportCommand extends Command
}
if ($input->getOption('direct-mapper')) {
$this->mapper = new DirectMapper(logger: $this->logger, storage: $this->storage);
$this->mapper = new DirectMapper(logger: $this->logger, db: $this->db);
}
if (!empty($mapperOpts)) {
@@ -206,7 +203,7 @@ class ImportCommand extends Command
],
]);
$this->storage->singleTransaction();
$this->db->singleTransaction();
foreach ($list as $name => &$server) {
$metadata = false;

View File

@@ -7,13 +7,13 @@ namespace App\Commands\State;
use App\Command;
use App\Libs\Config;
use App\Libs\Container;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Options;
use App\Libs\QueueRequests;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use Psr\Log\LoggerInterface;
use Psr\SimpleCache\CacheInterface;
use Psr\Log\LoggerInterface as iLogger;
use Psr\SimpleCache\CacheInterface as iCache;
use Psr\SimpleCache\InvalidArgumentException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -28,10 +28,10 @@ class PushCommand extends Command
public const TASK_NAME = 'push';
public function __construct(
private LoggerInterface $logger,
private CacheInterface $cache,
private StorageInterface $storage,
private QueueRequests $queue,
private iLogger $logger,
private iCache $cache,
private iDB $db,
private QueueRequests $queue
) {
set_time_limit(0);
ini_set('memory_limit', '-1');
@@ -49,7 +49,7 @@ class PushCommand extends Command
'ignore-date',
null,
InputOption::VALUE_NONE,
'Ignore date comparison. Push storage state to the backends regardless of date.'
'Force sync database item state to the backends regardless of date comparison.'
)
->setAliases(['push']);
}
@@ -82,7 +82,7 @@ class PushCommand extends Command
}
if (!empty($items)) {
foreach ($this->storage->find(...$items) as $item) {
foreach ($this->db->find(...$items) as $item) {
$entities[$item->id] = $item;
}
}

View File

@@ -6,10 +6,10 @@ namespace App\Commands\System;
use App\Command;
use App\Libs\Config;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Guid;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use PDO;
use Psr\Log\LoggerInterface as iLogger;
use Symfony\Component\Console\Input\InputInterface;
@@ -39,9 +39,9 @@ final class IndexCommand extends Command
private PDO $db;
public function __construct(StorageInterface $storage, private iLogger $logger)
public function __construct(iDB $db, private iLogger $logger)
{
$this->db = $storage->getPdo();
$this->db = $db->getPdo();
parent::__construct();
}

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace App\Commands\System;
use App\Command;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -15,7 +15,7 @@ final class MaintenanceCommand extends Command
{
public const ROUTE = 'system:db:maintenance';
public function __construct(private StorageInterface $storage)
public function __construct(private iDB $db)
{
parent::__construct();
}
@@ -28,7 +28,7 @@ final class MaintenanceCommand extends Command
protected function runCommand(InputInterface $input, OutputInterface $output): int
{
$this->storage->maintenance();
$this->db->maintenance();
return self::SUCCESS;
}

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace App\Commands\System;
use App\Command;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -16,7 +16,7 @@ final class MakeCommand extends Command
{
public const ROUTE = 'system:db:make';
public function __construct(private StorageInterface $storage)
public function __construct(private iDB $db)
{
parent::__construct();
}
@@ -30,7 +30,7 @@ final class MakeCommand extends Command
protected function runCommand(InputInterface $input, OutputInterface $output): int
{
$file = $this->storage->makeMigration($input->getArgument('filename'));
$file = $this->db->makeMigration($input->getArgument('filename'));
$output->writeln(sprintf('<info>Created new migration at \'%s\'.</info>', $file));

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace App\Commands\System;
use App\Command;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Routable;
use App\Libs\Storage\StorageInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -16,7 +16,7 @@ final class MigrationsCommand extends Command
{
public const ROUTE = 'system:db:migrations';
public function __construct(private StorageInterface $storage)
public function __construct(private iDB $db)
{
parent::__construct();
}
@@ -36,6 +36,6 @@ final class MigrationsCommand extends Command
$opts['fresh'] = true;
}
return $this->storage->migrations(StorageInterface::MIGRATE_UP, $opts);
return $this->db->migrations(iDB::MIGRATE_UP, $opts);
}
}

View File

@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace App\Libs\Database;
use RuntimeException;
class DatabaseException extends RuntimeException
{
}

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Libs\Storage;
namespace App\Libs\Database;
use App\Libs\Entity\StateInterface;
use Closure;
@@ -12,19 +12,19 @@ use PDOException;
use Psr\Log\LoggerInterface;
use RuntimeException;
interface StorageInterface
interface DatabaseInterface
{
public const MIGRATE_UP = 'up';
public const MIGRATE_DOWN = 'down';
/**
* Set storage driver options.
* Set db driver options.
*
* @param array $options
* @return StorageInterface
* @return self
*/
public function setOptions(array $options): StorageInterface;
public function setOptions(array $options): self;
/**
* Insert Entity immediately.
@@ -101,7 +101,7 @@ interface StorageInterface
public function commit(array $entities, array $opts = []): array;
/**
* Migrate Backend Storage Schema.
* Run database migrations.
*
* @param string $dir direction {@see MIGRATE_UP}, {@see MIGRATE_DOWN}
* @param array $opts
@@ -111,7 +111,7 @@ interface StorageInterface
public function migrations(string $dir, array $opts = []): mixed;
/**
* Migrate Backend storage data from old version.
* Migrate data from old database version.
*
* @param string $version represent the new version.
* @param LoggerInterface|null $logger
@@ -121,14 +121,14 @@ interface StorageInterface
public function migrateData(string $version, LoggerInterface|null $logger = null): mixed;
/**
* Does the backend storage need to run migrations?
* Is the database up to date with migrations?
*
* @return bool
*/
public function isMigrated(): bool;
/**
* Run Maintenance on backend storage.
* Run Maintenance tasks on database.
*
* @param array $opts
* @return mixed
@@ -172,7 +172,7 @@ interface StorageInterface
/**
* Wrap Queries into single transaction.
*
* @param Closure(StorageInterface): mixed $callback
* @param Closure(DatabaseInterface): mixed $callback
*
* @return mixed
* @throws PDOException

View File

@@ -2,13 +2,13 @@
declare(strict_types=1);
namespace App\Libs\Storage\PDO;
namespace App\Libs\Database\PDO;
use App\Libs\Container;
use App\Libs\Database\DatabaseException as DBException;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Options;
use App\Libs\Storage\StorageException;
use App\Libs\Storage\StorageInterface;
use Closure;
use DateTimeInterface;
use PDO;
@@ -16,7 +16,7 @@ use PDOException;
use PDOStatement;
use Psr\Log\LoggerInterface;
final class PDOAdapter implements StorageInterface
final class PDOAdapter implements iDB
{
private const LOCK_RETRY = 4;
@@ -57,7 +57,7 @@ final class PDOAdapter implements StorageInterface
{
try {
if (null !== ($entity->id ?? null)) {
throw new StorageException(
throw new DBException(
sprintf('Unable to insert item that has primary key. \'%s\'.', $entity->id), 21
);
}
@@ -117,7 +117,7 @@ final class PDOAdapter implements StorageInterface
$inTraceMode = true === (bool)($this->options[Options::DEBUG_TRACE] ?? false);
if ($inTraceMode) {
$this->logger->debug(sprintf('STORAGE: Looking for \'%s\'.', $entity->getName()));
$this->logger->debug(sprintf('DATABASE: Looking for \'%s\'.', $entity->getName()));
}
if (null !== $entity->id) {
@@ -133,7 +133,7 @@ final class PDOAdapter implements StorageInterface
$item = $entity::fromArray($item);
if ($inTraceMode) {
$this->logger->debug(sprintf('STORAGE: Found \'%s\' using direct id match.', $item->getName()), [
$this->logger->debug(sprintf('DATABASE: Found \'%s\' using direct id match.', $item->getName()), [
iState::COLUMN_ID => $entity->id
]);
}
@@ -143,7 +143,7 @@ final class PDOAdapter implements StorageInterface
if (null !== ($item = $this->findByExternalId($entity))) {
if ($inTraceMode) {
$this->logger->debug(sprintf('STORAGE: Found \'%s\' using external id match.', $item->getName()), [
$this->logger->debug(sprintf('DATABASE: Found \'%s\' using external id match.', $item->getName()), [
iState::COLUMN_GUIDS => $entity->getGuids(),
]);
}
@@ -164,7 +164,7 @@ final class PDOAdapter implements StorageInterface
}
if (true === (bool)($this->options[Options::DEBUG_TRACE] ?? false)) {
$this->logger->info('STORAGE: Selecting fields', $opts['fields'] ?? ['all']);
$this->logger->info('DATABASE: Selecting fields', $opts['fields'] ?? ['all']);
}
$sql = "SELECT {$fields} FROM state";
@@ -216,7 +216,7 @@ final class PDOAdapter implements StorageInterface
{
try {
if (null === ($entity->id ?? null)) {
throw new StorageException('Unable to update item without primary key.', 51);
throw new DBException('Unable to update item with out primary key.', 51);
}
$data = $entity->getAll();
@@ -334,15 +334,15 @@ final class PDOAdapter implements StorageInterface
return $actions;
});
}
public function migrations(string $dir, array $opts = []): mixed
{
$class = new PDOMigrations($this->pdo, $this->logger);
return match (strtolower($dir)) {
StorageInterface::MIGRATE_UP => $class->up(),
StorageInterface::MIGRATE_DOWN => $class->down(),
default => throw new StorageException(sprintf('Unknown direction \'%s\' was given.', $dir), 91),
iDB::MIGRATE_UP => $class->up(),
iDB::MIGRATE_DOWN => $class->down(),
default => throw new DBException(sprintf('Unknown direction \'%s\' was given.', $dir), 91),
};
}
@@ -366,7 +366,7 @@ final class PDOAdapter implements StorageInterface
return (new PDOMigrations($this->pdo, $this->logger))->runMaintenance();
}
public function setLogger(LoggerInterface $logger): StorageInterface
public function setLogger(LoggerInterface $logger): iDB
{
$this->logger = $logger;
@@ -535,7 +535,7 @@ final class PDOAdapter implements StorageInterface
$stmt = $this->pdo->prepare($sql);
if (false === $this->execute($stmt, $cond)) {
throw new StorageException('Failed to execute sql query.', 61);
throw new DBException('Failed to execute sql query.', 61);
}
if (false === ($row = $stmt->fetch(PDO::FETCH_ASSOC))) {

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Libs\Storage\PDO;
namespace App\Libs\Database\PDO;
use App\Libs\Config;
use App\Libs\Entity\StateInterface as iFace;
@@ -19,8 +19,8 @@ final class PDODataMigration
public function __construct(private PDO $pdo, private LoggerInterface $logger)
{
$this->version = Config::get('storage.version');
$this->dbPath = dirname(after(Config::get('storage.dsn'), 'sqlite:'));
$this->version = Config::get('database.version');
$this->dbPath = dirname(after(Config::get('database.dsn'), 'sqlite:'));
}
public function setLogger(LoggerInterface $logger): self

View File

@@ -2,9 +2,9 @@
declare(strict_types=1);
namespace App\Libs\Storage\PDO;
namespace App\Libs\Database\PDO;
use App\Libs\Storage\StorageInterface;
use App\Libs\Database\DatabaseInterface as iDB;
use PDO;
use Psr\Log\LoggerInterface;
use RuntimeException;
@@ -56,7 +56,7 @@ final class PDOMigrations
continue;
}
if (null === ag($migrate, StorageInterface::MIGRATE_UP, null)) {
if (null === ag($migrate, iDB::MIGRATE_UP, null)) {
$this->logger->debug(
sprintf(
'Migration #%d - %s has no up path, Skipping.',
@@ -71,7 +71,7 @@ final class PDOMigrations
$this->logger->info(sprintf('Applying Migration #%d - %s', ag($migrate, 'id'), ag($migrate, 'name')));
$this->pdo->exec((string)ag($migrate, StorageInterface::MIGRATE_UP));
$this->pdo->exec((string)ag($migrate, iDB::MIGRATE_UP));
$this->setVersion(ag($migrate, 'id'));
}
@@ -186,8 +186,8 @@ final class PDOMigrations
'type' => $type,
'id' => $id,
'name' => $name,
StorageInterface::MIGRATE_UP => $up,
StorageInterface::MIGRATE_DOWN => $down,
iDB::MIGRATE_UP => $up,
iDB::MIGRATE_DOWN => $down,
];
}

View File

@@ -289,8 +289,8 @@ interface StateInterface
* so to mark items as unplayed the following conditions **MUST** be met<br><br>
*
* 1- Backend item **MUST** be marked as unplayed.<br>
* 2- Storage item **MUST** be marked as played.<br>
* 3- Storage metadata **MUST** contain {@see iFace::COLUMN_META_DATA_PLAYED_AT} and {@see iFace::COLUMN_META_DATA_ADDED_AT} columns.<br>
* 2- db item **MUST** be marked as played.<br>
* 3- db metadata **MUST** contain {@see iFace::COLUMN_META_DATA_PLAYED_AT} and {@see iFace::COLUMN_META_DATA_ADDED_AT} columns.<br>
* 4- backend {@see iFace::COLUMN_UPDATED} **MUST** be equal to database metadata {@see iFace::COLUMN_META_DATA_ADDED_AT}<br><br>
*
* @param StateInterface $backend Backend object.

View File

@@ -5,10 +5,10 @@ declare(strict_types=1);
namespace App\Libs;
use App\Cli;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iFace;
use App\Libs\Extends\ConsoleHandler;
use App\Libs\Extends\ConsoleOutput;
use App\Libs\Storage\StorageInterface;
use Closure;
use ErrorException;
use Laminas\HttpHandlerRunner\Emitter\EmitterInterface;
@@ -330,9 +330,9 @@ final class Initializer
return new Response(304);
}
$storage = Container::get(StorageInterface::class);
$db = Container::get(iDB::class);
if (null === ($local = $storage->get($entity))) {
if (null === ($local = $db->get($entity))) {
if (true === $metadataOnly) {
$this->write(
$request, Logger::INFO,
@@ -349,7 +349,7 @@ final class Initializer
return new Response(204);
}
$entity = $storage->insert($entity);
$entity = $db->insert($entity);
if (true === $entity->isWatched()) {
queuePush($entity);
@@ -382,7 +382,7 @@ final class Initializer
$keys = array_merge($keys, [iFace::COLUMN_GUIDS, iFace::COLUMN_EXTRA]);
}
$local = $storage->update(
$local = $db->update(
$local->apply(
entity: $entity,
fields: array_merge($keys, [iFace::COLUMN_EXTRA])
@@ -428,7 +428,7 @@ final class Initializer
// -- Handle mark as unplayed logic.
if (false === $entity->isWatched() && true === $local->shouldMarkAsUnplayed($entity)) {
$local = $storage->update(
$local = $db->update(
$local->apply(entity: $entity, fields: [iFace::COLUMN_META_DATA])->markAsUnplayed($entity)
);
@@ -450,7 +450,7 @@ final class Initializer
}
if ((clone $cloned)->apply(entity: $entity, fields: $keys)->isChanged(fields: $keys)) {
$local = $storage->update(
$local = $db->update(
$local->apply(
entity: $entity,
fields: array_merge($keys, [iFace::COLUMN_EXTRA])
@@ -490,7 +490,7 @@ final class Initializer
}
if ((clone $cloned)->apply($entity)->isChanged()) {
$local = $storage->update($local->apply($entity));
$local = $db->update($local->apply($entity));
$stateChanged = $cloned->isWatched() !== $local->isWatched();
$this->write(

View File

@@ -5,12 +5,12 @@ declare(strict_types=1);
namespace App\Libs\Mappers\Import;
use App\Libs\Container;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Guid;
use App\Libs\Mappers\ImportInterface as iImport;
use App\Libs\Message;
use App\Libs\Options;
use App\Libs\Storage\StorageInterface as iStorage;
use DateTimeInterface as iDate;
use Exception;
use PDOException;
@@ -45,7 +45,7 @@ final class DirectMapper implements iImport
protected bool $fullyLoaded = false;
public function __construct(protected iLogger $logger, protected iStorage $storage)
public function __construct(protected iLogger $logger, protected iDB $db)
{
}
@@ -70,7 +70,7 @@ final class DirectMapper implements iImport
],
];
foreach ($this->storage->getAll($date, opts: $opts) as $entity) {
foreach ($this->db->getAll($date, opts: $opts) as $entity) {
$pointer = $entity->id;
if (null !== ($this->objects[$pointer] ?? null)) {
@@ -112,7 +112,7 @@ final class DirectMapper implements iImport
$this->actions[$entity->type]['failed']++;
Message::increment("{$entity->via}.{$entity->type}.failed");
$this->logger->notice('MAPPER: Ignoring [%(backend)] [%(title)]. Does not exist in storage.', [
$this->logger->notice('MAPPER: Ignoring [%(backend)] [%(title)]. Does not exist in database.', [
'metaOnly' => true,
'backend' => $entity->via,
'title' => $entity->getName(),
@@ -147,7 +147,7 @@ final class DirectMapper implements iImport
if (true === $inDryRunMode) {
$entity->id = random_int((int)(PHP_INT_MAX / 2), PHP_INT_MAX);
} else {
$entity = $this->storage->insert($entity);
$entity = $this->db->insert($entity);
}
$this->logger->notice('MAPPER: [%(backend)] added [%(title)] as new item.', [
@@ -211,7 +211,7 @@ final class DirectMapper implements iImport
]);
if (false === $inDryRunMode) {
$this->storage->update($local);
$this->db->update($local);
}
if (null === ($this->changed[$local->id] ?? null)) {
@@ -228,7 +228,7 @@ final class DirectMapper implements iImport
'backend' => $entity->via,
'title' => $cloned->getName(),
'state' => [
'storage' => $cloned->getAll(),
'database' => $cloned->getAll(),
'backend' => $entity->getAll()
],
]);
@@ -260,7 +260,7 @@ final class DirectMapper implements iImport
)->markAsUnplayed($entity);
if (false === $inDryRunMode) {
$this->storage->update($local);
$this->db->update($local);
}
$this->logger->notice('MAPPER: [%(backend)] marked [%(title)] as unplayed.', [
@@ -284,7 +284,7 @@ final class DirectMapper implements iImport
'backend' => $entity->via,
'title' => $cloned->getName(),
'state' => [
'storage' => $cloned->getAll(),
'database' => $cloned->getAll(),
'backend' => $entity->getAll()
],
]);
@@ -326,7 +326,7 @@ final class DirectMapper implements iImport
}
if (false === $inDryRunMode) {
$this->storage->update($local);
$this->db->update($local);
}
if (null === ($this->changed[$local->id] ?? null)) {
@@ -342,7 +342,7 @@ final class DirectMapper implements iImport
'id' => $cloned->id,
'title' => $cloned->getName(),
'state' => [
'storage' => $cloned->getAll(),
'database' => $cloned->getAll(),
'backend' => $entity->getAll()
],
]);
@@ -386,7 +386,7 @@ final class DirectMapper implements iImport
}
if (false === $inDryRunMode) {
$this->storage->update($local);
$this->db->update($local);
}
if (null === ($this->changed[$local->id] ?? null)) {
@@ -403,7 +403,7 @@ final class DirectMapper implements iImport
'backend' => $entity->via,
'title' => $cloned->getName(),
'state' => [
'storage' => $cloned->getAll(),
'database' => $cloned->getAll(),
'backend' => $entity->getAll()
],
]);
@@ -418,7 +418,7 @@ final class DirectMapper implements iImport
'backend' => $entity->via,
'title' => $cloned->getName(),
'state' => [
'storage' => $cloned->getAll(),
'database' => $cloned->getAll(),
'backend' => $entity->getAll(),
],
]);
@@ -441,7 +441,7 @@ final class DirectMapper implements iImport
$entity->id = $pointer;
return $this->storage->get($entity);
return $this->db->get($entity);
}
public function remove(iState $entity): bool
@@ -456,7 +456,7 @@ final class DirectMapper implements iImport
unset($this->changed[$entity->id]);
}
return $this->storage->remove($entity);
return $this->db->remove($entity);
}
public function commit(): mixed
@@ -500,7 +500,7 @@ final class DirectMapper implements iImport
return [];
}
return $this->storage->find(...$list);
return $this->db->find(...$list);
}
public function getObjectsCount(): int
@@ -516,13 +516,13 @@ final class DirectMapper implements iImport
public function setLogger(iLogger $logger): self
{
$this->logger = $logger;
$this->storage->setLogger($logger);
$this->db->setLogger($logger);
return $this;
}
public function setStorage(iStorage $storage): self
public function setDatabase(iDB $db): self
{
$this->storage = $storage;
$this->db = $db;
return $this;
}
@@ -585,7 +585,7 @@ final class DirectMapper implements iImport
}
}
if (false === $this->fullyLoaded && null !== ($lazyEntity = $this->storage->get($entity))) {
if (false === $this->fullyLoaded && null !== ($lazyEntity = $this->db->get($entity))) {
$this->objects[$lazyEntity->id] = $lazyEntity->id;
$this->addPointers($lazyEntity, $lazyEntity->id);

View File

@@ -4,12 +4,12 @@ declare(strict_types=1);
namespace App\Libs\Mappers\Import;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Guid;
use App\Libs\Mappers\ImportInterface as iImport;
use App\Libs\Message;
use App\Libs\Options;
use App\Libs\Storage\StorageInterface as iStorage;
use DateTimeInterface as iDate;
use PDOException;
use Psr\Log\LoggerInterface as iLogger;
@@ -37,7 +37,7 @@ final class MemoryMapper implements iImport
protected bool $fullyLoaded = false;
public function __construct(protected iLogger $logger, protected iStorage $storage)
public function __construct(protected iLogger $logger, protected iDB $db)
{
}
@@ -52,7 +52,7 @@ final class MemoryMapper implements iImport
{
$this->fullyLoaded = null === $date;
foreach ($this->storage->getAll($date, opts: ['class' => $this->options['class'] ?? null]) as $entity) {
foreach ($this->db->getAll($date, opts: ['class' => $this->options['class'] ?? null]) as $entity) {
$pointer = self::GUID . $entity->id;
if (null !== ($this->objects[$pointer] ?? null)) {
@@ -91,7 +91,7 @@ final class MemoryMapper implements iImport
if (false === ($pointer = $this->getPointer($entity))) {
if (true === $metadataOnly) {
Message::increment("{$entity->via}.{$entity->type}.failed");
$this->logger->notice('MAPPER: Ignoring [%(backend)] [%(title)]. Does not exist in storage.', [
$this->logger->notice('MAPPER: Ignoring [%(backend)] [%(title)]. Does not exist in database.', [
'metaOnly' => true,
'backend' => $entity->via,
'title' => $entity->getName(),
@@ -300,7 +300,7 @@ final class MemoryMapper implements iImport
'backend' => $entity->via,
'title' => $cloned->getName(),
'state' => [
'storage' => $cloned->getAll(),
'database' => $cloned->getAll(),
'backend' => $entity->getAll(),
],
]);
@@ -324,7 +324,7 @@ final class MemoryMapper implements iImport
$this->removePointers($this->objects[$pointer]);
$this->storage->remove($this->objects[$pointer]);
$this->db->remove($this->objects[$pointer]);
if (null !== ($this->objects[$pointer] ?? null)) {
unset($this->objects[$pointer]);
@@ -339,7 +339,7 @@ final class MemoryMapper implements iImport
public function commit(): mixed
{
$state = $this->storage->transactional(function (iStorage $storage) {
$state = $this->db->transactional(function (iDB $db) {
$list = [
iState::TYPE_MOVIE => ['added' => 0, 'updated' => 0, 'failed' => 0],
iState::TYPE_EPISODE => ['added' => 0, 'updated' => 0, 'failed' => 0],
@@ -365,12 +365,12 @@ final class MemoryMapper implements iImport
if (null === $entity->id) {
if (false === $inDryRunMode) {
$storage->insert($entity);
$db->insert($entity);
}
$list[$entity->type]['added']++;
} else {
if (false === $inDryRunMode) {
$storage->update($entity);
$db->update($entity);
}
$list[$entity->type]['updated']++;
}
@@ -419,13 +419,13 @@ final class MemoryMapper implements iImport
public function setLogger(iLogger $logger): self
{
$this->logger = $logger;
$this->storage->setLogger($logger);
$this->db->setLogger($logger);
return $this;
}
public function setStorage(iStorage $storage): self
public function setDatabase(iDB $db): self
{
$this->storage = $storage;
$this->db = $db;
return $this;
}
@@ -495,7 +495,7 @@ final class MemoryMapper implements iImport
}
}
if (false === $this->fullyLoaded && null !== ($lazyEntity = $this->storage->get($entity))) {
if (false === $this->fullyLoaded && null !== ($lazyEntity = $this->db->get($entity))) {
$this->objects[self::GUID . $entity->id] = $lazyEntity;
$this->addPointers($this->objects[self::GUID . $entity->id], self::GUID . $entity->id);

View File

@@ -4,11 +4,11 @@ declare(strict_types=1);
namespace App\Libs\Mappers\Import;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateEntity;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Guid;
use App\Libs\Mappers\ImportInterface as iImport;
use App\Libs\Storage\StorageInterface as iStorage;
use DateTimeInterface as iDate;
use JsonMachine\Items;
use JsonMachine\JsonDecoder\DecodingError;
@@ -141,7 +141,7 @@ final class RestoreMapper implements iImport
return $this;
}
public function setStorage(iStorage $storage): self
public function setDatabase(iDB $db): self
{
return $this;
}

View File

@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace App\Libs\Mappers;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Entity\StateInterface;
use App\Libs\Storage\StorageInterface;
use Countable;
use DateTimeInterface;
use Psr\Log\LoggerInterface;
@@ -22,7 +22,7 @@ interface ImportInterface extends Countable
public function setOptions(array $options = []): self;
/**
* Preload data from storage as usable entity.
* Preload data from db.
*
* @param DateTimeInterface|null $date
*
@@ -60,7 +60,7 @@ interface ImportInterface extends Countable
public function remove(StateInterface $entity): bool;
/**
* Commit Entities to storage backend.
* Commit changed items to db.
*
* @return mixed
*/
@@ -108,13 +108,13 @@ interface ImportInterface extends Countable
public function setLogger(LoggerInterface $logger): self;
/**
* Inject Storage.
* Inject db handler.
*
* @param StorageInterface $storage
* @param iDB $db
*
* @return self
*/
public function SetStorage(StorageInterface $storage): self;
public function setDatabase(iDB $db): self;
/**
* Are we in dry run mode?

View File

@@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Libs\Storage;
use RuntimeException;
class StorageException extends RuntimeException
{
public const SETUP_NOT_CALLED = 1;
}

View File

@@ -2,14 +2,14 @@
declare(strict_types=1);
namespace Tests\Storage;
namespace Tests\Database;
use App\Libs\Database\DatabaseException as DBException;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Database\PDO\PDOAdapter;
use App\Libs\Entity\StateEntity;
use App\Libs\Entity\StateInterface;
use App\Libs\Guid;
use App\Libs\Storage\PDO\PDOAdapter;
use App\Libs\Storage\StorageException;
use App\Libs\Storage\StorageInterface;
use DateTimeImmutable;
use Error;
use Monolog\Handler\TestHandler;
@@ -24,7 +24,7 @@ class PDOAdapterTest extends TestCase
private array $testMovie = [];
private array $testEpisode = [];
private StorageInterface|null $storage = null;
private iDB|null $db = null;
protected TestHandler|null $handler = null;
public function setUp(): void
@@ -40,22 +40,22 @@ class PDOAdapterTest extends TestCase
$logger->pushHandler($this->handler);
Guid::setLogger($logger);
$this->storage = new PDOAdapter($logger, new PDO('sqlite::memory:'));
$this->storage->migrations('up');
$this->db = new PDOAdapter($logger, new PDO('sqlite::memory:'));
$this->db->migrations('up');
}
public function test_insert_throw_exception_if_has_id(): void
{
$this->expectException(StorageException::class);
$this->expectException(DBException::class);
$this->expectExceptionCode(21);
$item = new StateEntity($this->testEpisode);
$this->storage->insert($item);
$this->storage->insert($item);
$this->db->insert($item);
$this->db->insert($item);
}
public function test_insert_successful(): void
{
$item = $this->storage->insert(new StateEntity($this->testEpisode));
$item = $this->db->insert(new StateEntity($this->testEpisode));
$this->assertSame(1, $item->id);
}
@@ -73,45 +73,45 @@ class PDOAdapterTest extends TestCase
$item = new StateEntity($test);
// -- db should be empty at this stage. as such we expect null.
$this->assertNull($this->storage->get($item));
$this->assertNull($this->db->get($item));
// -- insert and return object and assert it's the same
$modified = $this->storage->insert(clone $item);
$modified = $this->db->insert(clone $item);
$this->assertSame($modified->getAll(), $this->storage->get($item)->getAll());
$this->assertSame($modified->getAll(), $this->db->get($item)->getAll());
// -- look up based on id
$this->assertSame($modified->getAll(), $this->storage->get($modified)->getAll());
$this->assertSame($modified->getAll(), $this->db->get($modified)->getAll());
}
public function test_getAll_call_without_initialized_container(): void
{
$this->expectException(Error::class);
$this->expectExceptionMessage('Call to a member function');
$this->storage->getAll();
$this->db->getAll();
}
public function test_getAll_conditions(): void
{
$item = new StateEntity($this->testEpisode);
$this->assertSame([], $this->storage->getAll(opts: ['class' => $item]));
$this->assertSame([], $this->db->getAll(opts: ['class' => $item]));
$this->storage->insert($item);
$this->db->insert($item);
$this->assertCount(1, $this->storage->getAll(opts: ['class' => $item]));
$this->assertCount(1, $this->db->getAll(opts: ['class' => $item]));
// -- future date should be 0.
$this->assertCount(0, $this->storage->getAll(date: new DateTimeImmutable('now'), opts: ['class' => $item]));
$this->assertCount(0, $this->db->getAll(date: new DateTimeImmutable('now'), opts: ['class' => $item]));
}
public function test_update_call_without_id_exception(): void
{
$this->expectException(StorageException::class);
$this->expectException(DBException::class);
$this->expectExceptionCode(51);
$item = new StateEntity($this->testEpisode);
$this->storage->update($item);
$this->db->update($item);
}
public function test_update_conditions(): void
@@ -125,13 +125,13 @@ class PDOAdapterTest extends TestCase
ksort($test[$key]);
}
$item = $this->storage->insert(new StateEntity($test));
$item = $this->db->insert(new StateEntity($test));
$item->guids[Guid::GUID_IMDB] = '6101';
$updatedItem = $this->storage->update($item);
$updatedItem = $this->db->update($item);
$this->assertSame($item, $updatedItem);
$this->assertSame($updatedItem->getAll(), $this->storage->get($item)->getAll());
$this->assertSame($updatedItem->getAll(), $this->db->get($item)->getAll());
}
public function test_remove_conditions(): void
@@ -140,17 +140,17 @@ class PDOAdapterTest extends TestCase
$item2 = new StateEntity($this->testMovie);
$item3 = new StateEntity([]);
$this->assertFalse($this->storage->remove($item1));
$this->assertFalse($this->db->remove($item1));
$item1 = $this->storage->insert($item1);
$this->storage->insert($item2);
$item1 = $this->db->insert($item1);
$this->db->insert($item2);
$this->assertTrue($this->storage->remove($item1));
$this->assertInstanceOf(StateInterface::class, $this->storage->get($item2));
$this->assertTrue($this->db->remove($item1));
$this->assertInstanceOf(StateInterface::class, $this->db->get($item2));
// -- remove without id pointer.
$this->assertTrue($this->storage->remove($item2));
$this->assertFalse($this->storage->remove($item3));
$this->assertTrue($this->db->remove($item2));
$this->assertFalse($this->db->remove($item3));
}
public function test_commit_conditions(): void
@@ -160,7 +160,7 @@ class PDOAdapterTest extends TestCase
$this->assertSame(
['added' => 2, 'updated' => 0, 'failed' => 0],
$this->storage->commit([$item1, $item2])
$this->db->commit([$item1, $item2])
);
$item1->guids['guid_anidb'] = StateInterface::TYPE_EPISODE . '/1';
@@ -168,14 +168,14 @@ class PDOAdapterTest extends TestCase
$this->assertSame(
['added' => 0, 'updated' => 2, 'failed' => 0],
$this->storage->commit([$item1, $item2])
$this->db->commit([$item1, $item2])
);
}
public function test_migrations_call_with_wrong_direction_exception(): void
{
$this->expectException(StorageException::class);
$this->expectException(DBException::class);
$this->expectExceptionCode(91);
$this->storage->migrations('not_dd');
$this->db->migrations('not_dd');
}
}

View File

@@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Tests\Mappers\Import;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Database\PDO\PDOAdapter;
use App\Libs\Entity\StateEntity;
use App\Libs\Entity\StateInterface as iFace;
use App\Libs\Guid;
use App\Libs\Mappers\Import\DirectMapper;
use App\Libs\Message;
use App\Libs\Storage\PDO\PDOAdapter;
use App\Libs\Storage\StorageInterface;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
use PDO;
@@ -24,7 +24,7 @@ class DirectMapperTest extends TestCase
private array $testEpisode = [];
protected DirectMapper|null $mapper = null;
protected StorageInterface|null $storage = null;
protected iDB|null $db = null;
protected TestHandler|null $handler = null;
public function setUp(): void
@@ -40,11 +40,11 @@ class DirectMapperTest extends TestCase
$logger->pushHandler($this->handler);
Guid::setLogger($logger);
$this->storage = new PDOAdapter($logger, new PDO('sqlite::memory:'));
$this->storage->migrations('up');
$this->db = new PDOAdapter($logger, new PDO('sqlite::memory:'));
$this->db->migrations('up');
$this->mapper = new DirectMapper($logger, $this->storage);
$this->mapper = new DirectMapper($logger, $this->db);
$this->mapper->setOptions(options: ['class' => new StateEntity([])]);
Message::reset();
@@ -110,7 +110,7 @@ class DirectMapperTest extends TestCase
// -- expect null as we haven't added anything to db yet.
$this->assertNull($this->mapper->get($testEpisode));
$this->storage->commit([$testEpisode, $testMovie]);
$this->db->commit([$testEpisode, $testMovie]);
clone $testMovie2 = $testMovie;
clone $testEpisode2 = $testEpisode;
@@ -171,7 +171,7 @@ class DirectMapperTest extends TestCase
{
$testEpisode = new StateEntity($this->testEpisode);
$this->assertFalse($this->mapper->has($testEpisode));
$this->storage->commit([$testEpisode]);
$this->db->commit([$testEpisode]);
$this->assertTrue($this->mapper->has($testEpisode));
}

View File

@@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Tests\Mappers\Import;
use App\Libs\Database\DatabaseInterface as iDB;
use App\Libs\Database\PDO\PDOAdapter;
use App\Libs\Entity\StateEntity;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Guid;
use App\Libs\Mappers\Import\MemoryMapper;
use App\Libs\Message;
use App\Libs\Storage\PDO\PDOAdapter;
use App\Libs\Storage\StorageInterface;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
use PDO;
@@ -24,7 +24,7 @@ class MemoryMapperTest extends TestCase
private array $testEpisode = [];
private MemoryMapper|null $mapper = null;
private StorageInterface|null $storage = null;
private iDB|null $db = null;
protected TestHandler|null $handler = null;
public function setUp(): void
@@ -40,10 +40,10 @@ class MemoryMapperTest extends TestCase
$logger->pushHandler($this->handler);
Guid::setLogger($logger);
$this->storage = new PDOAdapter($logger, new PDO('sqlite::memory:'));
$this->storage->migrations('up');
$this->db = new PDOAdapter($logger, new PDO('sqlite::memory:'));
$this->db->migrations('up');
$this->mapper = new MemoryMapper($logger, $this->storage);
$this->mapper = new MemoryMapper($logger, $this->db);
$this->mapper->setOptions(options: ['class' => new StateEntity([])]);
Message::reset();
@@ -57,7 +57,7 @@ class MemoryMapperTest extends TestCase
// -- expect 0 as we have not modified or added new item yet.
$this->assertSame(0, $this->mapper->getObjectsCount());
$this->storage->commit([$testEpisode, $testMovie]);
$this->db->commit([$testEpisode, $testMovie]);
$this->mapper->loadData();
@@ -76,7 +76,7 @@ class MemoryMapperTest extends TestCase
// -- expect 0 as we have not modified or added new item yet.
$this->assertSame(0, $this->mapper->getObjectsCount());
$this->storage->commit([$testEpisode, $testMovie]);
$this->db->commit([$testEpisode, $testMovie]);
$this->mapper->loadData(makeDate($time - 1));
@@ -143,7 +143,7 @@ class MemoryMapperTest extends TestCase
// -- expect null as we haven't added anything to db yet.
$this->assertNull($this->mapper->get($testEpisode));
$this->storage->commit([$testEpisode, $testMovie]);
$this->db->commit([$testEpisode, $testMovie]);
clone $testMovie2 = $testMovie;
clone $testEpisode2 = $testEpisode;
@@ -164,7 +164,7 @@ class MemoryMapperTest extends TestCase
$this->mapper->loadData();
$this->storage->commit([$testEpisode, $testMovie]);
$this->db->commit([$testEpisode, $testMovie]);
$this->assertNull($this->mapper->get($testMovie));
$this->assertNull($this->mapper->get($testEpisode));
@@ -223,7 +223,7 @@ class MemoryMapperTest extends TestCase
{
$testEpisode = new StateEntity($this->testEpisode);
$this->assertFalse($this->mapper->has($testEpisode));
$this->storage->commit([$testEpisode]);
$this->db->commit([$testEpisode]);
$this->assertTrue($this->mapper->has($testEpisode));
}
@@ -236,7 +236,7 @@ class MemoryMapperTest extends TestCase
$testEpisode->updated = $time;
$this->mapper->loadData();
$this->storage->commit([$testEpisode, $testMovie]);
$this->db->commit([$testEpisode, $testMovie]);
$this->assertFalse($this->mapper->has($testEpisode));
$this->mapper->loadData(makeDate($time - 1));
$this->assertTrue($this->mapper->has($testEpisode));
@@ -261,7 +261,7 @@ class MemoryMapperTest extends TestCase
$this->assertCount(0, $this->mapper->getObjects());
$this->storage->commit([$testMovie, $testEpisode]);
$this->db->commit([$testMovie, $testEpisode]);
$this->mapper->loadData();