86 lines
3.5 KiB
PHP
86 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace Modules\EcommerceFinance\Services;
|
|
|
|
use InvalidArgumentException;
|
|
use Modules\EcommerceFinance\Contracts\BusinessMirrorDataset;
|
|
|
|
class BusinessMirrorDatasetRegistry
|
|
{
|
|
/** @return array<string,BusinessMirrorDataset> */
|
|
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; }
|
|
};
|
|
}
|
|
}
|