1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-15 06:44:03 +00:00

Refactor DB cache bootstrapper, update tests accordingly

This commit is contained in:
lukinovec 2025-08-04 11:29:48 +02:00
parent bc846391ea
commit 872bf9df72
2 changed files with 135 additions and 16 deletions

View file

@ -13,40 +13,73 @@ use Stancl\Tenancy\Contracts\Tenant;
* This bootstrapper allows cache to be stored in the tenant databases by switching
* the database cache store's (and cache locks) connection.
*
* Intended to be used with the 'database' cache store, instead of CacheTenancyBootstrapper.
* Intended to be used with database driver-based cache stores, instead of CacheTenancyBootstrapper.
*
* On bootstrap(), the database cache store's connection is set to 'tenant'
* and the database cache store is purged from the CacheManager's resolved stores.
* This forces the manager to resolve a new instance of the database store created with the 'tenant' DB connection on the next cache operation.
* On bootstrap(), all database cache stores' connections are set to 'tenant'
* and the database cache stores are purged from the CacheManager's resolved stores.
* This forces the manager to resolve new instances of the database stores created with the 'tenant' DB connection on the next cache operation.
*
* On revert(), the cache store's connection is reverted to the originally used one (usually 'central'), and again,
* the database cache store is purged from the CacheManager's resolved stores so that the originally used one is resolved on the next cache operation.
* On revert(), the cache stores' connections are reverted to the originally used ones (usually 'central'), and again,
* the database cache stores are purged from the CacheManager's resolved stores so that the originally used ones are resolved on the next cache operation.
*/
class DatabaseCacheBootstrapper implements TenancyBootstrapper
{
/**
* Cache stores to process. If null, all stores with 'database' driver will be processed.
* If array, only the specified stores will be processed (with driver validation).
*/
public static array|null $stores = null;
public function __construct(
protected Repository $config,
protected CacheManager $cache,
protected string|null $originalConnection = null,
protected string|null $originalLockConnection = null
protected array $originalConnections = [],
protected array $originalLockConnections = []
) {}
public function bootstrap(Tenant $tenant): void
{
$this->originalConnection = $this->config->get('cache.stores.database.connection');
$this->originalLockConnection = $this->config->get('cache.stores.database.lock_connection');
$stores = $this->getDatabaseCacheStores();
$this->config->set('cache.stores.database.connection', 'tenant');
$this->config->set('cache.stores.database.lock_connection', 'tenant');
foreach ($stores as $storeName) {
$this->originalConnections[$storeName] = $this->config->get("cache.stores.{$storeName}.connection");
$this->originalLockConnections[$storeName] = $this->config->get("cache.stores.{$storeName}.lock_connection");
$this->cache->purge('database');
$this->config->set("cache.stores.{$storeName}.connection", 'tenant');
$this->config->set("cache.stores.{$storeName}.lock_connection", 'tenant');
$this->cache->purge($storeName);
}
}
public function revert(): void
{
$this->config->set('cache.stores.database.connection', $this->originalConnection);
$this->config->set('cache.stores.database.lock_connection', $this->originalLockConnection);
foreach ($this->originalConnections as $storeName => $originalConnection) {
$this->config->set("cache.stores.{$storeName}.connection", $originalConnection);
$this->config->set("cache.stores.{$storeName}.lock_connection", $this->originalLockConnections[$storeName]);
$this->cache->purge('database');
$this->cache->purge($storeName);
}
}
/**
* Get the names of cache stores that use the database driver.
*/
protected function getDatabaseCacheStores(): array
{
// Get all stores specified in the static $stores property.
// If they don't have the database driver, ignore them.
if (static::$stores !== null) {
return array_filter(static::$stores, function ($storeName) {
$store = $this->config->get("cache.stores.{$storeName}");
return $store && ($store['driver'] ?? null) === 'database';
});
}
// Get all stores with database driver if $stores is null
return array_keys(array_filter($this->config->get('cache.stores', []), function ($store) {
return ($store['driver'] ?? null) === 'database';
}));
}
}