Passed
Push — master ( b97c32...e7e450 )
by Carlos C
10:36 queued 12s
created

DataTableGateway::insert()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 14
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 19
ccs 13
cts 13
cp 1
crap 3
rs 9.7998
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpCfdi\SatCatalogosPopulate\Database;
6
7
use LogicException;
8
use PDOException;
9
10
class DataTableGateway
11
{
12 13
    public function __construct(private DataTable $dataTable, private Repository $repository)
13
    {
14
    }
15
16 9
    public function dataTable(): DataTable
17
    {
18 9
        return $this->dataTable;
19
    }
20
21 10
    public function recreate(): void
22
    {
23 10
        $this->drop();
24 10
        $this->create();
25
    }
26
27 13
    private function sqlDiscoverField(DataFieldInterface $field): string
28
    {
29 13
        $sqlName = $this->repository->escapeName($field->name());
30 13
        if ($field instanceof TextDataField || $field instanceof DateDataField) {
31 13
            return $sqlName . ' text not null';
32
        }
33 4
        if ($field instanceof IntegerDataField || $field instanceof BoolDataField) {
34 4
            return $sqlName . ' int not null';
35
        }
36
        if ($field instanceof FloatDataField) {
37
            return $sqlName . ' real not null';
38
        }
39
40
        throw new LogicException("Don't know what to do with " . $field::class);
41
    }
42
43 10
    public function drop(): void
44
    {
45 10
        $sql = 'DROP TABLE IF EXISTS ' . $this->repository->escapeName($this->dataTable->name()) . ';';
46 10
        $this->repository->execute($sql);
47
    }
48
49 13
    public function create(): void
50
    {
51 13
        $fields = [];
52 13
        foreach ($this->dataTable->fields() as $field) {
53 13
            $fields[] = $this->sqlDiscoverField($field);
54
        }
55
56 13
        $pkDefinition = '';
57 13
        if (count($this->dataTable->primaryKey()) > 0) {
58 12
            $pkDefinition = 'PRIMARY KEY ('
59 12
                . implode(', ', array_map(
60 12
                    fn (string $input): string => $this->repository->escapeName($input),
61 12
                    $this->dataTable->primaryKey()
62
                ))
63
                . ')';
64
        }
65
66 13
        $sql = 'CREATE TABLE ' . $this->repository->escapeName($this->dataTable->name())
67 13
            . ' ( ' . implode(', ', array_filter([...$fields, ...[$pkDefinition]])) . ' )'
68
            . ';';
69 13
        $this->repository->execute($sql);
70
    }
71
72
    /** @param mixed[] $input */
73 12
    public function insert(array $input): void
74
    {
75 12
        $fieldNames = [];
76 12
        $preparedNames = [];
77 12
        foreach ($this->dataTable->fields() as $dataField) {
78 12
            $fieldNames[] = $this->repository->escapeName($dataField->name());
79 12
            $preparedNames[] = ':' . $dataField->name();
80
        }
81
82 12
        $sql = 'INSERT INTO ' . $this->repository->escapeName($this->dataTable->name())
83 12
            . ' (' . implode(', ', $fieldNames) . ')'
84 12
            . ' VALUES (' . implode(', ', $preparedNames) . ')'
85
            . ';';
86
87
        try {
88 12
            $this->repository->execute($sql, $input);
89 1
        } catch (PDOException $exception) {
90 1
            $message = sprintf('Unable to run %s using %s', $sql, json_encode($input, JSON_THROW_ON_ERROR));
91 1
            throw new PDOException($message, 0, $exception);
92
        }
93
    }
94
}
95