feat(import): сервис MonthlyPartitionManager + рефактор partitions:create-months
Выносит DDL-логику создания месячных RANGE-партиций из команды PartitionsCreateMonths в переиспользуемый сервис MonthlyPartitionManager. Сервис используется командой (DRY) и будет использован HistoricalImportService для партиций под исторические даты CSV. - MonthlyPartitionManager::ensureRange(table, from, to) — гарантирует партиции под диапазон дат, идемпотентно; отвергает незарегистрированные таблицы - MonthlyPartitionManager::ensureMonth(table, monthStart) — одна партиция - PartitionsCreateMonths рефакторена: убраны PARTITIONED_TABLES, partitionExists(), use DB; inject MonthlyPartitionManager через handle() - Test: MonthlyPartitionManagerTest (3 теста, DatabaseTransactions — DDL откат) - Regression: PartitionsCreateMonthsTest (4 теста) — зелёный, поведение не изменилось Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Services\MonthlyPartitionManager;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
uses(DatabaseTransactions::class);
|
||||
|
||||
function partitionExists(string $name): bool
|
||||
{
|
||||
return DB::selectOne(
|
||||
"SELECT 1 AS ok FROM pg_class WHERE relname = ? AND relkind = 'r'",
|
||||
[$name],
|
||||
) !== null;
|
||||
}
|
||||
|
||||
test('ensureRange создаёт месячные партиции deals под диапазон', function (): void {
|
||||
$manager = app(MonthlyPartitionManager::class);
|
||||
|
||||
$created = $manager->ensureRange(
|
||||
'deals',
|
||||
Carbon::parse('2024-02-15'),
|
||||
Carbon::parse('2024-04-03'),
|
||||
);
|
||||
|
||||
expect($created)->toBeGreaterThanOrEqual(3)
|
||||
->and(partitionExists('deals_2024_02'))->toBeTrue()
|
||||
->and(partitionExists('deals_2024_03'))->toBeTrue()
|
||||
->and(partitionExists('deals_2024_04'))->toBeTrue();
|
||||
});
|
||||
|
||||
test('ensureRange идемпотентна — повторный вызов не падает', function (): void {
|
||||
$manager = app(MonthlyPartitionManager::class);
|
||||
|
||||
$manager->ensureRange('deals', Carbon::parse('2024-02-15'), Carbon::parse('2024-02-20'));
|
||||
$secondRun = $manager->ensureRange('deals', Carbon::parse('2024-02-15'), Carbon::parse('2024-02-20'));
|
||||
|
||||
expect($secondRun)->toBe(0); // всё уже существует
|
||||
});
|
||||
|
||||
test('ensureRange отвергает неизвестную таблицу', function (): void {
|
||||
app(MonthlyPartitionManager::class)->ensureRange('orders', now(), now());
|
||||
})->throws(InvalidArgumentException::class);
|
||||
Reference in New Issue
Block a user