isAvailable() ? null : __('search.index.fulltext.unsupported_driver'); } /** * {@inheritDoc} * * 지원 필터: `table`(테이블명, 프리픽스 생략 가능) · `index`(인덱스명) · `samples`(표본 행 수) */ public function inspect(array $filters = []): array { $sampleSize = (int) ($filters['samples'] ?? FulltextIndexInspector::DEFAULT_SAMPLE_SIZE); $results = $this->inspector->inspectAll( table: isset($filters['table']) ? (string) $filters['table'] : null, index: isset($filters['index']) ? (string) $filters['index'] : null, sampleSize: max(1, $sampleSize), ); return array_map(fn (array $result) => $this->toHealth($result), $results); } /** * {@inheritDoc} */ public function rebuild(SearchIndexHealth $health): void { $context = $health->context; $this->inspector->rebuild(new FulltextIndexDefinition( table: (string) ($context['table'] ?? ''), name: (string) ($context['name'] ?? ''), columns: (array) ($context['columns'] ?? []), parser: isset($context['parser']) ? (string) $context['parser'] : null, )); } /** * 점검기 결과를 엔진 중립 판정 DTO 로 옮깁니다. * * @param array{definition: FulltextIndexDefinition, status: SearchIndexStatus, probed: int, found: int, reason: ?string} $result 점검기 결과 * @return SearchIndexHealth */ private function toHealth(array $result): SearchIndexHealth { $definition = $result['definition']; $status = $result['status']; $measurement = $status === SearchIndexStatus::Skipped ? (string) $result['reason'] : __('search.index.fulltext.self_match', ['found' => $result['found'], 'probed' => $result['probed']]); return new SearchIndexHealth( driver: self::DRIVER, identifier: $definition->label(), status: $status, measurement: $measurement, details: [ 'table' => $definition->table, 'index' => $definition->name, 'columns' => $definition->columns, 'parser' => $definition->parser, 'probed' => $result['probed'], 'found' => $result['found'], ], context: [ 'table' => $definition->table, 'name' => $definition->name, 'columns' => $definition->columns, 'parser' => $definition->parser, ], ); } }