- 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
318 lines
10 KiB
PHP
318 lines
10 KiB
PHP
<?php
|
|
|
|
namespace App\Repositories\Username\Read;
|
|
|
|
use App\enum\ProviderType;
|
|
use App\enum\UsernameType;
|
|
use App\Models\Username;
|
|
use App\Repositories\BaseRepository;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
|
|
class UsernameReadRepository extends BaseRepository
|
|
{
|
|
protected function getCacheTag(): string
|
|
{
|
|
return 'usernames';
|
|
}
|
|
|
|
public function getModel(): string
|
|
{
|
|
return Username::class;
|
|
}
|
|
|
|
public function findActive(): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('active');
|
|
|
|
return $this->executeQuery(function () {
|
|
$result = $this->query
|
|
->where('is_active', true)
|
|
->where(function ($query) {
|
|
$query->whereNull('starts_at')
|
|
->orWhere('starts_at', '<=', now());
|
|
})
|
|
->where(function ($query) {
|
|
$query->whereNull('ends_at')
|
|
->orWhere('ends_at', '>=', now());
|
|
})
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800); // 30 minutes
|
|
}
|
|
|
|
public function findActiveByType(?UsernameType $usernameType = null, ?ProviderType $providerType = null): array
|
|
{
|
|
$params = [
|
|
'username_type' => $usernameType?->value,
|
|
'provider_type' => $providerType?->value,
|
|
];
|
|
$cacheKey = $this->getCacheKey('active_by_type', $params);
|
|
|
|
return $this->executeQuery(function () use ($usernameType, $providerType) {
|
|
$query = $this->query
|
|
->where('is_active', true)
|
|
->where(function ($query) {
|
|
$query->whereNull('starts_at')
|
|
->orWhere('starts_at', '<=', now());
|
|
})
|
|
->where(function ($query) {
|
|
$query->whereNull('ends_at')
|
|
->orWhere('ends_at', '>=', now());
|
|
});
|
|
|
|
if ($usernameType) {
|
|
$query->where('username_type', $usernameType->value);
|
|
}
|
|
|
|
if ($providerType) {
|
|
$query->where('provider_type', $providerType->value);
|
|
}
|
|
|
|
$result = $query->pluck('username')->toArray();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800); // 30 minutes
|
|
}
|
|
|
|
public function findActiveByProvider(ProviderType $providerType): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('active_by_provider', ['provider' => $providerType->value]);
|
|
|
|
return $this->executeQuery(function () use ($providerType) {
|
|
$result = $this->query
|
|
->where('is_active', true)
|
|
->where('provider_type', $providerType->value)
|
|
->where(function ($query) {
|
|
$query->whereNull('starts_at')
|
|
->orWhere('starts_at', '<=', now());
|
|
})
|
|
->where(function ($query) {
|
|
$query->whereNull('ends_at')
|
|
->orWhere('ends_at', '>=', now());
|
|
})
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800);
|
|
}
|
|
|
|
public function findPublicActive(): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('public_active');
|
|
|
|
return $this->executeQuery(function () {
|
|
$result = $this->query
|
|
->where('is_active', true)
|
|
->where('username_type', UsernameType::PUBLIC->value)
|
|
->where(function ($query) {
|
|
$query->whereNull('starts_at')
|
|
->orWhere('starts_at', '<=', now());
|
|
})
|
|
->where(function ($query) {
|
|
$query->whereNull('ends_at')
|
|
->orWhere('ends_at', '>=', now());
|
|
})
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800);
|
|
}
|
|
|
|
public function findPremiumActive(): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('premium_active');
|
|
|
|
return $this->executeQuery(function () {
|
|
$result = $this->query
|
|
->where('is_active', true)
|
|
->where('username_type', UsernameType::PREMIUM->value)
|
|
->where(function ($query) {
|
|
$query->whereNull('starts_at')
|
|
->orWhere('starts_at', '<=', now());
|
|
})
|
|
->where(function ($query) {
|
|
$query->whereNull('ends_at')
|
|
->orWhere('ends_at', '>=', now());
|
|
})
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800);
|
|
}
|
|
|
|
public function findExpiringSoon(int $days = 7): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('expiring_soon', ['days' => $days]);
|
|
|
|
return $this->executeQuery(function () use ($days) {
|
|
$result = $this->query
|
|
->where('is_active', true)
|
|
->whereNotNull('ends_at')
|
|
->where('ends_at', '<=', now()->addDays($days))
|
|
->where('ends_at', '>', now())
|
|
->orderBy('ends_at', 'asc')
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 900); // 15 minutes
|
|
}
|
|
|
|
public function findInactive(): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('inactive');
|
|
|
|
return $this->executeQuery(function () {
|
|
$result = $this->query
|
|
->where('is_active', false)
|
|
->orWhere(function ($query) {
|
|
$query->whereNotNull('starts_at')
|
|
->where('starts_at', '>', now());
|
|
})
|
|
->orWhere(function ($query) {
|
|
$query->whereNotNull('ends_at')
|
|
->where('ends_at', '<', now());
|
|
})
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800);
|
|
}
|
|
|
|
public function findRecentlyUsed(int $hours = 24): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('recently_used', ['hours' => $hours]);
|
|
|
|
return $this->executeQuery(function () use ($hours) {
|
|
$result = $this->query
|
|
->whereNotNull('last_used_at')
|
|
->where('last_used_at', '>=', now()->subHours($hours))
|
|
->orderBy('last_used_at', 'desc')
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 900); // 15 minutes
|
|
}
|
|
|
|
public function findByUsername(string $username): ?Username
|
|
{
|
|
$cacheKey = $this->getCacheKey('find_by_username', ['username' => $username]);
|
|
|
|
return $this->executeQuery(function () use ($username) {
|
|
$result = $this->query->where('username', $username)->first();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 3600); // 1 hour
|
|
}
|
|
|
|
public function countActive(): int
|
|
{
|
|
$cacheKey = $this->getCacheKey('count_active');
|
|
|
|
return $this->executeQuery(function () {
|
|
$result = $this->query
|
|
->where('is_active', true)
|
|
->where(function ($query) {
|
|
$query->whereNull('starts_at')
|
|
->orWhere('starts_at', '<=', now());
|
|
})
|
|
->where(function ($query) {
|
|
$query->whereNull('ends_at')
|
|
->orWhere('ends_at', '>=', now());
|
|
})
|
|
->count();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 600); // 10 minutes
|
|
}
|
|
|
|
public function countByProvider(): array
|
|
{
|
|
$cacheKey = $this->getCacheKey('count_by_provider');
|
|
|
|
return $this->executeQuery(function () {
|
|
$result = $this->query
|
|
->selectRaw('provider_type, COUNT(*) as count')
|
|
->groupBy('provider_type')
|
|
->pluck('count', 'provider_type')
|
|
->toArray();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800);
|
|
}
|
|
|
|
public function countByType(): array
|
|
{
|
|
$cacheKey = $this->getCacheKey('count_by_type');
|
|
|
|
return $this->executeQuery(function () {
|
|
$result = $this->query
|
|
->selectRaw('username_type, COUNT(*) as count')
|
|
->groupBy('username_type')
|
|
->pluck('count', 'username_type')
|
|
->toArray();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800);
|
|
}
|
|
|
|
public function findAvailableForUse(UsernameType $type, int $limit = 10): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('available_for_use', [
|
|
'type' => $type->value,
|
|
'limit' => $limit,
|
|
]);
|
|
|
|
return $this->executeQuery(function () use ($type, $limit) {
|
|
$result = $this->query
|
|
->where('is_active', true)
|
|
->where('username_type', $type->value)
|
|
->where(function ($query) {
|
|
$query->whereNull('starts_at')
|
|
->orWhere('starts_at', '<=', now());
|
|
})
|
|
->where(function ($query) {
|
|
$query->whereNull('ends_at')
|
|
->orWhere('ends_at', '>=', now());
|
|
})
|
|
->orderBy('last_used_at', 'asc')
|
|
->limit($limit)
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 300); // 5 minutes
|
|
}
|
|
|
|
public function findUnused(int $days = 30): Collection
|
|
{
|
|
$cacheKey = $this->getCacheKey('unused', ['days' => $days]);
|
|
|
|
return $this->executeQuery(function () {
|
|
$result = $this->query
|
|
->where('is_active', true)
|
|
->where(function ($query) {
|
|
$query->whereNull('last_used_at')
|
|
->orWhere('last_used_at', '<', now()->subDays($days));
|
|
})
|
|
->orderBy('last_used_at', 'asc')
|
|
->get();
|
|
$this->resetQuery();
|
|
|
|
return $result;
|
|
}, $cacheKey, 1800);
|
|
}
|
|
}
|