diff --git a/src/Core/Cache/Type/DatabaseCache.php b/src/Core/Cache/Type/DatabaseCache.php index af79b111ec..8f5b554606 100644 --- a/src/Core/Cache/Type/DatabaseCache.php +++ b/src/Core/Cache/Type/DatabaseCache.php @@ -11,6 +11,7 @@ use Friendica\Core\Cache\Capability\ICanCache; use Friendica\Core\Cache\Enum; use Friendica\Core\Cache\Exception\CachePersistenceException; use Friendica\Database\Database; +use Friendica\DI; use Friendica\Repository\CacheRepository; use Friendica\Util\DateTimeFormat; @@ -34,7 +35,8 @@ class DatabaseCache extends AbstractCache implements ICanCache $this->dba = $dba; - $this->cacheRepo = new CacheRepository($dba); + // #TODO: Replace this with constuctor injection + $this->cacheRepo = DI::databaseService()->getCacheRepository(); } /** diff --git a/src/Database/DatabaseService.php b/src/Database/DatabaseService.php index 8905c7e00c..eafa7cbf4a 100644 --- a/src/Database/DatabaseService.php +++ b/src/Database/DatabaseService.php @@ -10,8 +10,10 @@ declare(strict_types=1); namespace Friendica\Database; use Friendica\Database\Database; -use Friendica\Database\Repository\DeletedUserRepository; -use Friendica\Repository\UserdRepository; +use Friendica\Database\Repository\CacheTableRepository; +use Friendica\Database\Repository\UserdTableRepository; +use Friendica\Repository\CacheRepository; +use Friendica\Repository\DeletedUserRepository; final class DatabaseService { @@ -24,6 +26,11 @@ final class DatabaseService public function getDeletedUserRepository(): DeletedUserRepository { - return new UserdRepository($this->database); + return new UserdTableRepository($this->database); + } + + public function getCacheRepository(): CacheRepository + { + return new CacheTableRepository($this->database); } } diff --git a/src/Model/CacheModel.php b/src/Database/Model/CacheModel.php similarity index 96% rename from src/Model/CacheModel.php rename to src/Database/Model/CacheModel.php index 83c287642c..9987645616 100644 --- a/src/Model/CacheModel.php +++ b/src/Database/Model/CacheModel.php @@ -7,11 +7,11 @@ declare(strict_types=1); -namespace Friendica\Model; +namespace Friendica\Database\Model; use Exception; use Friendica\Database\DBA; -use Friendica\Database\Entity\CacheEntity; +use Friendica\Entity\CacheEntity; /** * Model for a row in the cache table diff --git a/src/Database/Repository/CacheRepository.php b/src/Database/Repository/CacheRepository.php deleted file mode 100644 index bdd46a870d..0000000000 --- a/src/Database/Repository/CacheRepository.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - public function getAllKeysValidUntil(string $expires): array; - - /** - * @throws DatabaseException - * - * @return array - */ - public function getAllKeysValidUntilWithPrefix(string $expires, string $prefix): array; - - /** - * @throws DatabaseException - * - * @return CacheEntity|null - */ - public function findOneByKeyValidUntil(string $key, string $expires); -} diff --git a/src/Database/Repository/CacheTableRepository.php b/src/Database/Repository/CacheTableRepository.php new file mode 100644 index 0000000000..1f0b278ec3 --- /dev/null +++ b/src/Database/Repository/CacheTableRepository.php @@ -0,0 +1,135 @@ +database = $database; + } + + /** + * @throws DatabaseException + * + * @return array + */ + public function getAllKeysValidUntil(string $expires): array + { + $throw = $this->database->throwExceptionsOnErrors(true); + + try { + return $this->getAllKeys($expires, null); + } catch (Throwable $th) { + if (! $th instanceof DatabaseException) { + $th = new DatabaseException('Cannot fetch all keys without prefix', 0, '', $th); + } + + throw $th; + } finally { + $this->database->throwExceptionsOnErrors($throw); + } + } + + /** + * @throws DatabaseException + * + * @return array + */ + public function getAllKeysValidUntilWithPrefix(string $expires, string $prefix): array + { + $throw = $this->database->throwExceptionsOnErrors(true); + + try { + return $this->getAllKeys($expires, $prefix); + } catch (Throwable $th) { + if (! $th instanceof DatabaseException) { + $th = new DatabaseException(sprintf('Cannot fetch all keys with prefix `%s`', $prefix), 0, '', $th); + } + + throw $th; + } finally { + $this->database->throwExceptionsOnErrors($throw); + } + } + + /** + * @throws DatabaseException + * + * @return CacheEntity|null + */ + public function findOneByKeyValidUntil(string $key, string $expires) + { + $throw = $this->database->throwExceptionsOnErrors(true); + + try { + $cacheArray = $this->database->selectFirst( + 'cache', + ['v'], + ['`k` = ? AND (`expires` >= ? OR `expires` = -1)', $key, $expires] + ); + + if (!$this->database->isResult($cacheArray)) { + return null; + } + } catch (Throwable $th) { + if (! $th instanceof DatabaseException) { + $th = new DatabaseException(sprintf('Cannot get cache entry with key `%s`', $key), 0, '', $th); + } + + throw $th; + } finally { + $this->database->throwExceptionsOnErrors($throw); + } + + try { + $entity = CacheModel::createFromArray($cacheArray); + } catch (Throwable $th) { + return null; + } + + return $entity; + } + + private function getAllKeys(string $expires, ?string $prefix = null): array + { + if ($prefix === null) { + $where = ['`expires` >= ?', $expires]; + } else { + $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', $expires, $prefix]; + } + + $stmt = $this->database->select('cache', ['k'], $where); + + $keys = []; + + try { + while ($key = $this->database->fetch($stmt)) { + array_push($keys, $key['k']); + } + } finally { + $this->database->close($stmt); + } + + return $keys; + } +} diff --git a/src/Repository/UserdRepository.php b/src/Database/Repository/UserdTableRepository.php similarity index 84% rename from src/Repository/UserdRepository.php rename to src/Database/Repository/UserdTableRepository.php index b6f01772c8..9095bbfaaa 100644 --- a/src/Repository/UserdRepository.php +++ b/src/Database/Repository/UserdTableRepository.php @@ -7,17 +7,17 @@ declare(strict_types=1); -namespace Friendica\Repository; +namespace Friendica\Database\Repository; use Exception; use Friendica\Database\Database; use Friendica\Database\DatabaseException; -use Friendica\Database\Repository\DeletedUserRepository; +use Friendica\Repository\DeletedUserRepository; /** - * Repository for deleted users + * Repository for userd table */ -final class UserdRepository implements DeletedUserRepository +final class UserdTableRepository implements DeletedUserRepository { private Database $database; diff --git a/src/Database/Entity/CacheEntity.php b/src/Entity/CacheEntity.php similarity index 78% rename from src/Database/Entity/CacheEntity.php rename to src/Entity/CacheEntity.php index 53d4e9048f..d32baee105 100644 --- a/src/Database/Entity/CacheEntity.php +++ b/src/Entity/CacheEntity.php @@ -7,10 +7,10 @@ declare(strict_types=1); -namespace Friendica\Database\Entity; +namespace Friendica\Entity; /** - * Entity for a row in the cache table + * Entity for a cache entry */ interface CacheEntity { diff --git a/src/Module/Profile/Profile.php b/src/Module/Profile/Profile.php index 12f593a870..d437f0579d 100644 --- a/src/Module/Profile/Profile.php +++ b/src/Module/Profile/Profile.php @@ -23,7 +23,6 @@ use Friendica\Core\Renderer; use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Database\Database; use Friendica\Database\DBA; -use Friendica\Database\Repository\DeletedUserRepository; use Friendica\Event\HtmlFilterEvent; use Friendica\Model\Contact; use Friendica\Model\Profile as ProfileModel; @@ -36,6 +35,7 @@ use Friendica\Network\HTTPException; use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Profile\ProfileField\Repository\ProfileField; use Friendica\Protocol\ActivityPub; +use Friendica\Repository\DeletedUserRepository; use Friendica\Util\DateTimeFormat; use Friendica\Util\Network; use Friendica\Util\Profiler; diff --git a/src/Module/User/Import.php b/src/Module/User/Import.php index 1855755a06..a3ff223084 100644 --- a/src/Module/User/Import.php +++ b/src/Module/User/Import.php @@ -20,7 +20,6 @@ use Friendica\Core\Worker; use Friendica\Database\Database; use Friendica\Database\DBA; use Friendica\Database\DBStructure; -use Friendica\Database\Repository\DeletedUserRepository; use Friendica\Model\Photo; use Friendica\Model\Profile; use Friendica\Module\Response; @@ -28,6 +27,7 @@ use Friendica\Navigation\SystemMessages; use Friendica\Network\HTTPException; use Friendica\Object\Image; use Friendica\Protocol\Delivery; +use Friendica\Repository\DeletedUserRepository; use Friendica\Security\PermissionSet\Repository\PermissionSet; use Friendica\Util\Profiler; use Friendica\Util\Strings; diff --git a/src/Repository/CacheRepository.php b/src/Repository/CacheRepository.php index 6cdba5eafc..6da86e7540 100644 --- a/src/Repository/CacheRepository.php +++ b/src/Repository/CacheRepository.php @@ -9,127 +9,32 @@ declare(strict_types=1); namespace Friendica\Repository; -use Friendica\Database\Database; use Friendica\Database\DatabaseException; -use Friendica\Database\Entity\CacheEntity; -use Friendica\Database\Repository\CacheRepository as CacheRepositoryInterface; -use Friendica\Model\CacheModel; -use Throwable; +use Friendica\Entity\CacheEntity; /** - * Repository for cache table + * Interface for a cache repository */ -final class CacheRepository implements CacheRepositoryInterface +interface CacheRepository { - private Database $database; - - public function __construct(Database $database) - { - $this->database = $database; - } + /** + * @throws DatabaseException + * + * @return array + */ + public function getAllKeysValidUntil(string $expires): array; /** * @throws DatabaseException * * @return array */ - public function getAllKeysValidUntil(string $expires): array - { - $throw = $this->database->throwExceptionsOnErrors(true); - - try { - return $this->getAllKeys($expires, null); - } catch (Throwable $th) { - if (! $th instanceof DatabaseException) { - $th = new DatabaseException('Cannot fetch all keys without prefix', 0, '', $th); - } - - throw $th; - } finally { - $this->database->throwExceptionsOnErrors($throw); - } - } - - /** - * @throws DatabaseException - * - * @return array - */ - public function getAllKeysValidUntilWithPrefix(string $expires, string $prefix): array - { - $throw = $this->database->throwExceptionsOnErrors(true); - - try { - return $this->getAllKeys($expires, $prefix); - } catch (Throwable $th) { - if (! $th instanceof DatabaseException) { - $th = new DatabaseException(sprintf('Cannot fetch all keys with prefix `%s`', $prefix), 0, '', $th); - } - - throw $th; - } finally { - $this->database->throwExceptionsOnErrors($throw); - } - } + public function getAllKeysValidUntilWithPrefix(string $expires, string $prefix): array; /** * @throws DatabaseException * * @return CacheEntity|null */ - public function findOneByKeyValidUntil(string $key, string $expires) - { - $throw = $this->database->throwExceptionsOnErrors(true); - - try { - $cacheArray = $this->database->selectFirst( - 'cache', - ['v'], - ['`k` = ? AND (`expires` >= ? OR `expires` = -1)', $key, $expires] - ); - - if (!$this->database->isResult($cacheArray)) { - return null; - } - } catch (Throwable $th) { - if (! $th instanceof DatabaseException) { - $th = new DatabaseException(sprintf('Cannot get cache entry with key `%s`', $key), 0, '', $th); - } - - throw $th; - } finally { - $this->database->throwExceptionsOnErrors($throw); - } - - try { - $entity = CacheModel::createFromArray($cacheArray); - } catch (Throwable $th) { - return null; - } - - return $entity; - } - - private function getAllKeys(string $expires, ?string $prefix = null): array - { - if ($prefix === null) { - $where = ['`expires` >= ?', $expires]; - } else { - $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', $expires, $prefix]; - } - - $stmt = $this->database->select('cache', ['k'], $where); - - $keys = []; - - try { - while ($key = $this->database->fetch($stmt)) { - array_push($keys, $key['k']); - } - } finally { - $this->database->close($stmt); - } - - return $keys; - } + public function findOneByKeyValidUntil(string $key, string $expires); } diff --git a/src/Database/Repository/DeletedUserRepository.php b/src/Repository/DeletedUserRepository.php similarity index 94% rename from src/Database/Repository/DeletedUserRepository.php rename to src/Repository/DeletedUserRepository.php index 7eeea4456f..54b8a36fbc 100644 --- a/src/Database/Repository/DeletedUserRepository.php +++ b/src/Repository/DeletedUserRepository.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Friendica\Database\Repository; +namespace Friendica\Repository; use Exception; use Friendica\Database\DatabaseException; diff --git a/tests/Unit/Repository/CacheRepositoryTest.php b/tests/Unit/Database/Repository/CacheTableRepositoryTest.php similarity index 86% rename from tests/Unit/Repository/CacheRepositoryTest.php rename to tests/Unit/Database/Repository/CacheTableRepositoryTest.php index 01a1f01348..cb710b2a59 100644 --- a/tests/Unit/Repository/CacheRepositoryTest.php +++ b/tests/Unit/Database/Repository/CacheTableRepositoryTest.php @@ -7,15 +7,15 @@ declare(strict_types=1); -namespace Friendica\Test\Unit\Repository; +namespace Friendica\Test\Unit\Database\Repository; use Friendica\Database\Database; use Friendica\Database\DatabaseException; -use Friendica\Repository\CacheRepository; +use Friendica\Database\Repository\CacheTableRepository; use PHPUnit\Framework\TestCase; use Throwable; -class CacheRepositoryTest extends TestCase +class CacheTableRepositoryTest extends TestCase { public function testGetAllKeysValidUntilReturnsArray(): void { @@ -32,7 +32,7 @@ class CacheRepositoryTest extends TestCase false ); - $repo = new CacheRepository($database); + $repo = new CacheTableRepository($database); $this->assertSame( [ @@ -49,7 +49,7 @@ class CacheRepositoryTest extends TestCase $database = $this->createStub(Database::class); $database->method('select')->willThrowException($this->createStub(Throwable::class)); - $repo = new CacheRepository($database); + $repo = new CacheTableRepository($database); $this->expectException(DatabaseException::class); @@ -71,7 +71,7 @@ class CacheRepositoryTest extends TestCase false ); - $repo = new CacheRepository($database); + $repo = new CacheTableRepository($database); $this->assertSame( [ @@ -88,7 +88,7 @@ class CacheRepositoryTest extends TestCase $database = $this->createStub(Database::class); $database->method('select')->willThrowException($this->createStub(Throwable::class)); - $repo = new CacheRepository($database); + $repo = new CacheTableRepository($database); $this->expectException(DatabaseException::class); diff --git a/tests/Unit/Repository/UserdRepositoryTest.php b/tests/Unit/Database/Repository/UserdTableRepositoryTest.php similarity index 78% rename from tests/Unit/Repository/UserdRepositoryTest.php rename to tests/Unit/Database/Repository/UserdTableRepositoryTest.php index ebfeb5f3b2..ff08ab5b5e 100644 --- a/tests/Unit/Repository/UserdRepositoryTest.php +++ b/tests/Unit/Database/Repository/UserdTableRepositoryTest.php @@ -7,19 +7,19 @@ declare(strict_types=1); -namespace Friendica\Test\Unit\Repository; +namespace Friendica\Test\Unit\Database\Repository; use Friendica\Database\Database; use Friendica\Database\DatabaseException; -use Friendica\Database\Repository\DeletedUserRepository; -use Friendica\Repository\UserdRepository; +use Friendica\Database\Repository\UserdTableRepository; +use Friendica\Repository\DeletedUserRepository; use PHPUnit\Framework\TestCase; -class UserdRepositoryTest extends TestCase +class UserdTableRepositoryTest extends TestCase { public function testImplementationOfInterfaces(): void { - $repo = new UserdRepository($this->createMock(Database::class)); + $repo = new UserdTableRepository($this->createMock(Database::class)); $this->assertInstanceOf(DeletedUserRepository::class, $repo); } @@ -31,7 +31,7 @@ class UserdRepositoryTest extends TestCase ['userd', ['username' => 'test'], 0, true], ]); - $repo = new UserdRepository($database); + $repo = new UserdTableRepository($database); $repo->insertByUsername('test'); } @@ -44,7 +44,7 @@ class UserdRepositoryTest extends TestCase new DatabaseException('An error occured.', 0, 'SQL query') ); - $repo = new UserdRepository($database); + $repo = new UserdTableRepository($database); $this->expectException(DatabaseException::class); @@ -58,7 +58,7 @@ class UserdRepositoryTest extends TestCase ['userd', ['username' => 'test'], true], ]); - $repo = new UserdRepository($database); + $repo = new UserdTableRepository($database); $this->assertTrue($repo->existsByUsername('test')); } @@ -70,7 +70,7 @@ class UserdRepositoryTest extends TestCase ['userd', ['username' => 'test'], false], ]); - $repo = new UserdRepository($database); + $repo = new UserdTableRepository($database); $this->assertFalse($repo->existsByUsername('test')); }