Lines
100.00%
14 / 14
Functions and Methods
100.00%
2 / 2
Classes and Traits
100.00%
1 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| NormalizesInsertRows | 100.00% | 14 / 14 | 100.00% | 2 / 2 | 8 | 100.00% | 1 / 1 | |||
| normalizeInsertRows | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 4 | |||||
| assertUniformInsertRows | 100.00% | 11 / 11 | 100.00% | 1 / 1 | 4 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace BlueprintAU\Radiant\Database\Concerns; | |
| 6 | ||
| 7 | /** | |
| 8 | * Normalizes an insert payload into a list of rows. | |
| 9 | * | |
| 10 | * Shared by `SqlConnection`, `CsvConnection`, and `Grammar` — the three | |
| 11 | * classes that accept either a single insert row or a list of rows. A trait | |
| 12 | * (not a base class) because it must reach across two unrelated hierarchies: | |
| 13 | * the `Connections\` tree and the `Grammars\` tree. | |
| 14 | */ | |
| 15 | trait NormalizesInsertRows | |
| 16 | { | |
| 17 | /** | |
| 18 | * Normalize a single row or a list of rows into a list of rows. | |
| 19 | * | |
| 20 | * @param array<string,mixed>|list<array<string,mixed>> $values | |
| 21 | * @return list<array<string,mixed>> | |
| 22 | */ | |
| 23 | protected function normalizeInsertRows(array $values): array | |
| 24 | { | |
| 25 | // A list of rows: [[...], [...]] — each element is an associative row. | |
| 26 | if (array_is_list($values) && isset($values[0]) && is_array($values[0])) { | |
| 27 | /** @var list<array<string, mixed>> $values */ | |
| 28 | return $values; | |
| 29 | } | |
| 30 | ||
| 31 | /** @var array<string, mixed> $values */ | |
| 32 | return [$values]; | |
| 33 | } | |
| 34 | ||
| 35 | /** | |
| 36 | * Assert every row in a bulk insert carries the SAME column set. | |
| 37 | * | |
| 38 | * A multi-row INSERT compiles ONE column list and ONE placeholder | |
| 39 | * group per row — rows of differing arity produce a malformed | |
| 40 | * statement or a placeholder/binding mismatch. Padding a missing | |
| 41 | * column with NULL would silently write NULL into a nullable column | |
| 42 | * the caller never named, so ragged rows fail fast instead. | |
| 43 | * | |
| 44 | * @param list<array<string,mixed>> $rows | |
| 45 | * @return void | |
| 46 | * | |
| 47 | * @throws \InvalidArgumentException | |
| 48 | */ | |
| 49 | protected function assertUniformInsertRows(array $rows): void | |
| 50 | { | |
| 51 | if (count($rows) < 2) { | |
| 52 | return; | |
| 53 | } | |
| 54 | ||
| 55 | $expected = array_keys($rows[0]); | |
| 56 | ||
| 57 | foreach (array_slice($rows, 1) as $i => $row) { | |
| 58 | if (array_keys($row) !== $expected) { | |
| 59 | throw new \InvalidArgumentException( | |
| 60 | 'A bulk insert requires every row to carry the same columns; row ' | |
| 61 | . ($i + 1) . ' differs from row 0. Split the call or give every ' | |
| 62 | . 'row the same column set (an absent column would otherwise ' | |
| 63 | . 'silently write NULL).' | |
| 64 | ); | |
| 65 | } | |
| 66 | } | |
| 67 | } | |
| 68 | } |