*/ public function all(): array { $datasets = []; foreach ((array) config('upstream_mirrors.datasets', []) as $key => $definition) { $datasets[(string) $key] = $this->make((string) $key, (array) $definition); } return $datasets; } public function get(string $key): BusinessMirrorDataset { $definitions = (array) config('upstream_mirrors.datasets', []); $definition = (array) ($definitions[$key] ?? []); if ($definition === []) { throw new InvalidArgumentException('未知的业务镜像数据集:' . $key); } return $this->make($key, $definition); } private function make(string $key, array $definition): BusinessMirrorDataset { $source = trim((string) ($definition['source_key'] ?? '')); $schema = trim((string) ($definition['schema'] ?? '')); $object = trim((string) ($definition['object'] ?? '')); $target = trim((string) ($definition['target'] ?? '')); $keys = array_values(array_filter(array_map('strval', (array) ($definition['keys'] ?? [])))); $watermark = trim((string) ($definition['watermark'] ?? '')); $indexes = array_values(array_map( static fn (mixed $columns): array => array_values(array_filter(array_map('strval', (array) $columns))), (array) ($definition['indexes'] ?? []), )); $indexColumns = array_merge(...($indexes ?: [[]])); foreach ([$source, $schema, $object, $target, ...$keys, ...$indexColumns] as $identifier) { if (preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $identifier) !== 1) { throw new InvalidArgumentException('业务镜像数据集包含不安全的标识符:' . $key); } } if ($keys === [] || in_array([], $indexes, true) || strlen($target) > 64) { throw new InvalidArgumentException('业务镜像数据集缺少稳定键或目标表名过长:' . $key); } if ($watermark !== '' && preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $watermark) !== 1) { throw new InvalidArgumentException('业务镜像数据集的增量字段不安全:' . $key); } return new readonly class($key, $source, $schema, $object, $target, $keys, $watermark ?: null, $indexes) implements BusinessMirrorDataset { public function __construct( private string $key, private string $source, private string $schema, private string $object, private string $target, private array $keys, private ?string $watermark, private array $indexes, ) { } public function key(): string { return $this->key; } public function sourceKey(): string { return $this->source; } public function sourceSchema(): string { return $this->schema; } public function sourceObject(): string { return $this->object; } public function targetTable(): string { return $this->target; } public function keyColumns(): array { return $this->keys; } public function watermarkColumn(): ?string { return $this->watermark; } public function indexDefinitions(): array { return $this->indexes; } }; } }