feat: implement repository architecture with smart caching
- Add base repository interfaces and abstract classes - Implement separated read/write repositories for Domain and Username models - Add intelligent query caching with automatic invalidation - Include cache management service and CLI commands - Add comprehensive configuration for cache TTL and monitoring - Enhance performance through optimized data access patterns
This commit is contained in:
187
app/Repositories/WriteRepository.php
Normal file
187
app/Repositories/WriteRepository.php
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Repositories\Contracts\WriteRepositoryInterface;
|
||||
use Illuminate\Cache\CacheManager;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
abstract class WriteRepository implements WriteRepositoryInterface
|
||||
{
|
||||
protected Model $model;
|
||||
|
||||
protected CacheManager $cache;
|
||||
|
||||
protected string $cacheTag;
|
||||
|
||||
protected string $readRepositoryClass;
|
||||
|
||||
public function __construct(Model $model, CacheManager $cache)
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->cache = $cache;
|
||||
$this->cacheTag = $this->getCacheTag();
|
||||
$this->readRepositoryClass = $this->getReadRepositoryClass();
|
||||
}
|
||||
|
||||
abstract protected function getCacheTag(): string;
|
||||
|
||||
abstract protected function getReadRepositoryClass(): string;
|
||||
|
||||
protected function getReadRepository(): mixed
|
||||
{
|
||||
return app($this->readRepositoryClass);
|
||||
}
|
||||
|
||||
protected function clearRelatedCache(Model $model): void
|
||||
{
|
||||
$this->getReadRepository()->clearCacheForModel($model);
|
||||
}
|
||||
|
||||
protected function clearCollectionCache(Collection $models): void
|
||||
{
|
||||
foreach ($models as $model) {
|
||||
$this->clearRelatedCache($model);
|
||||
}
|
||||
}
|
||||
|
||||
public function create(array $data): Model
|
||||
{
|
||||
$model = $this->model->create($data);
|
||||
$this->clearRelatedCache($model);
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
public function createMany(array $data): Collection
|
||||
{
|
||||
$models = $this->model->insert($data) ? $this->model->whereIn('id',
|
||||
$this->model->latest()->take(count($data))->pluck('id')
|
||||
)->get() : collect();
|
||||
|
||||
$this->getReadRepository()->clearCache();
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
public function update(Model $model, array $data): bool
|
||||
{
|
||||
$result = $model->update($data);
|
||||
$this->clearRelatedCache($model);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function updateById(int $id, array $data): bool
|
||||
{
|
||||
$model = $this->model->findOrFail($id);
|
||||
|
||||
return $this->update($model, $data);
|
||||
}
|
||||
|
||||
public function upsert(array $data, array|string $uniqueBy, ?array $update = null): Collection
|
||||
{
|
||||
$this->model->upsert($data, $uniqueBy, $update);
|
||||
|
||||
// Clear all cache since upsert can affect multiple records
|
||||
$this->getReadRepository()->clearCache();
|
||||
|
||||
// Return the upserted records
|
||||
$uniqueValues = collect($data)->pluck($uniqueBy);
|
||||
|
||||
return $this->model->whereIn($uniqueBy, $uniqueValues)->get();
|
||||
}
|
||||
|
||||
public function delete(Model $model): bool
|
||||
{
|
||||
$result = $model->delete();
|
||||
$this->clearRelatedCache($model);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function deleteById(int $id): bool
|
||||
{
|
||||
$model = $this->model->findOrFail($id);
|
||||
|
||||
return $this->delete($model);
|
||||
}
|
||||
|
||||
public function deleteMultiple(array $ids): int
|
||||
{
|
||||
$deleted = $this->model->whereIn('id', $ids)->delete();
|
||||
|
||||
// Clear all cache since multiple records are deleted
|
||||
$this->getReadRepository()->clearCache();
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
public function restore(Model $model): bool
|
||||
{
|
||||
$result = $model->restore();
|
||||
$this->clearRelatedCache($model);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function restoreById(int $id): bool
|
||||
{
|
||||
$model = $this->model->withTrashed()->findOrFail($id);
|
||||
|
||||
return $this->restore($model);
|
||||
}
|
||||
|
||||
public function forceDelete(Model $model): bool
|
||||
{
|
||||
$result = $model->forceDelete();
|
||||
$this->clearRelatedCache($model);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function forceDeleteById(int $id): bool
|
||||
{
|
||||
$model = $this->model->withTrashed()->findOrFail($id);
|
||||
|
||||
return $this->forceDelete($model);
|
||||
}
|
||||
|
||||
public function sync(Model $model, string $relation, array $ids, bool $detaching = true): array
|
||||
{
|
||||
$result = $model->{$relation}()->sync($ids, $detaching);
|
||||
$this->clearRelatedCache($model);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function attach(Model $model, string $relation, array $ids, array $attributes = [], bool $touch = true): void
|
||||
{
|
||||
$model->{$relation}()->attach($ids, $attributes, $touch);
|
||||
$this->clearRelatedCache($model);
|
||||
}
|
||||
|
||||
public function detach(Model $model, string $relation, ?array $ids = null, bool $touch = true): int
|
||||
{
|
||||
$result = $model->{$relation}()->detach($ids, $touch);
|
||||
$this->clearRelatedCache($model);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function clearCache(): void
|
||||
{
|
||||
$this->getReadRepository()->clearCache();
|
||||
}
|
||||
|
||||
public function clearCacheForModel(Model $model): void
|
||||
{
|
||||
$this->clearRelatedCache($model);
|
||||
}
|
||||
|
||||
public function clearCacheForCollection(Collection $models): void
|
||||
{
|
||||
$this->clearCollectionCache($models);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user