1: <?php declare(strict_types=1);
2:
3: namespace Salient\Sync\Db;
4:
5: use Salient\Contract\Core\Pipeline\ArrayMapperInterface;
6: use Salient\Contract\Core\Pipeline\PipelineInterface;
7: use Salient\Contract\Core\Buildable;
8: use Salient\Contract\Sync\EntitySource;
9: use Salient\Contract\Sync\FilterPolicy;
10: use Salient\Contract\Sync\SyncContextInterface;
11: use Salient\Contract\Sync\SyncEntityInterface;
12: use Salient\Contract\Sync\SyncOperation as OP;
13: use Salient\Core\Concern\BuildableTrait;
14: use Salient\Sync\Support\SyncPipelineArgument;
15: use Salient\Sync\AbstractSyncDefinition;
16: use Closure;
17: use LogicException;
18:
19: /**
20: * Generates closures that use a DbSyncProvider to perform sync operations on an
21: * entity
22: *
23: * @phpstan-type OverrideClosure (Closure(static, OP::*, SyncContextInterface, int|string|null, mixed...): TEntity)|(Closure(static, OP::*, SyncContextInterface, mixed...): iterable<array-key,TEntity>)|(Closure(static, OP::*, SyncContextInterface, TEntity, mixed...): TEntity)|(Closure(static, OP::*, SyncContextInterface, iterable<TEntity>, mixed...): iterable<array-key,TEntity>)
24: *
25: * @property-read string|null $Table
26: *
27: * @template TEntity of SyncEntityInterface
28: * @template TProvider of DbSyncProvider
29: *
30: * @extends AbstractSyncDefinition<TEntity,TProvider>
31: * @implements Buildable<DbSyncDefinitionBuilder<TEntity,TProvider>>
32: */
33: final class DbSyncDefinition extends AbstractSyncDefinition implements Buildable
34: {
35: /** @use BuildableTrait<DbSyncDefinitionBuilder<TEntity,TProvider>> */
36: use BuildableTrait;
37:
38: /** @var string|null */
39: protected $Table;
40:
41: /**
42: * @internal
43: *
44: * @param class-string<TEntity> $entity
45: * @param TProvider $provider
46: * @param array<OP::*> $operations
47: * @param DbSyncDefinition::* $conformity
48: * @param FilterPolicy::*|null $filterPolicy
49: * @param array<int-mask-of<OP::*>,Closure(DbSyncDefinition<TEntity,TProvider>, OP::*, SyncContextInterface, mixed...): (iterable<array-key,TEntity>|TEntity)> $overrides
50: * @phpstan-param array<int-mask-of<OP::*>,OverrideClosure> $overrides
51: * @param array<array-key,array-key|array-key[]>|null $keyMap
52: * @param int-mask-of<ArrayMapperInterface::REMOVE_NULL|ArrayMapperInterface::ADD_UNMAPPED|ArrayMapperInterface::ADD_MISSING|ArrayMapperInterface::REQUIRE_MAPPED> $keyMapFlags
53: * @param PipelineInterface<mixed[],TEntity,SyncPipelineArgument>|null $pipelineFromBackend
54: * @param PipelineInterface<TEntity,mixed[],SyncPipelineArgument>|null $pipelineToBackend
55: * @param EntitySource::*|null $returnEntitiesFrom
56: */
57: public function __construct(
58: string $entity,
59: DbSyncProvider $provider,
60: array $operations = [],
61: ?string $table = null,
62: int $conformity = DbSyncDefinition::CONFORMITY_PARTIAL,
63: ?int $filterPolicy = null,
64: array $overrides = [],
65: ?array $keyMap = null,
66: int $keyMapFlags = ArrayMapperInterface::ADD_UNMAPPED,
67: ?PipelineInterface $pipelineFromBackend = null,
68: ?PipelineInterface $pipelineToBackend = null,
69: bool $readFromList = false,
70: ?int $returnEntitiesFrom = null
71: ) {
72: parent::__construct(
73: $entity,
74: $provider,
75: $operations,
76: $conformity,
77: $filterPolicy,
78: $overrides,
79: $keyMap,
80: $keyMapFlags,
81: $pipelineFromBackend,
82: $pipelineToBackend,
83: $readFromList,
84: $returnEntitiesFrom
85: );
86:
87: $this->Table = $table;
88: }
89:
90: /**
91: * @inheritDoc
92: */
93: protected function getClosure(int $operation): ?Closure
94: {
95: // Return null if no table name has been provided
96: if ($this->Table === null) {
97: return null;
98: }
99:
100: switch ($operation) {
101: case OP::CREATE:
102: case OP::READ:
103: case OP::UPDATE:
104: case OP::DELETE:
105: case OP::CREATE_LIST:
106: case OP::READ_LIST:
107: case OP::UPDATE_LIST:
108: case OP::DELETE_LIST:
109: $closure = null;
110: break;
111:
112: default:
113: throw new LogicException("Invalid SyncOperation: $operation");
114: }
115:
116: return $closure;
117: }
118:
119: public static function getReadableProperties(): array
120: {
121: return [
122: ...parent::getReadableProperties(),
123: 'Table',
124: ];
125: }
126: }
127: