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
3declare(strict_types=1);
4
5namespace 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 */
15trait 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}