packages/sql-fixture/src/Fixture/TableOverrides.php
1<?php
2
3declare(strict_types=1);
4
5namespace SqlFixture\Fixture;
6
7/**
8 * Column values to use instead of generated ones, for one table.
9 *
10 * Generated table classes build these through named arguments, so the column
11 * names and their types are checked where they are written rather than when
12 * the fixture runs. A null argument means "leave this column to the
13 * generator"; withNull() is how a column is deliberately set to NULL.
14 * @template TValue = mixed
15 */
16final class TableOverrides
17{
18 /**
19 * @param array<string, TValue> $values
20 * @param array<array-key, string> $nulls Columns to set to NULL rather than generate
21 */
22 public function __construct(
23 private readonly array $values,
24 private readonly array $nulls,
25 ) {
26 }
27
28 /**
29 * Keep only the arguments that were actually given.
30 *
31 * @template TColumn
32 * @param array<string, TColumn> $values
33 * @return self<TColumn>
34 */
35 public static function of(array $values = []): self
36 {
37 $provided = [];
38 foreach ($values as $column => $value) {
39 if ($value !== null) {
40 $provided[$column] = $value;
41 }
42 }
43
44 return new self($provided, []);
45 }
46
47 /**
48 * Set a column to NULL rather than leaving it to the generator.
49 *
50 * @return self<TValue>
51 */
52 public function withNull(string ...$columns): self
53 {
54 return new self($this->values, [...$this->nulls, ...$columns]);
55 }
56
57 /**
58 * @return array<string, TValue|null>
59 */
60 public function toArray(): array
61 {
62 $values = $this->values;
63
64 foreach ($this->nulls as $column) {
65 $values[$column] = null;
66 }
67
68 return $values;
69 }
70}
71