Passed
Push — master ( 0e87cd...c4ac3e )
by Carlos C
12:45 queued 01:03
created

AbstractCsvInjector::injectValuesToDataTable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpCfdi\SatCatalogosPopulate;
6
7
use Generator;
8
use Iterator;
9
use PhpCfdi\SatCatalogosPopulate\Database\DataTable;
10
use PhpCfdi\SatCatalogosPopulate\Database\DataTableGateway;
11
use PhpCfdi\SatCatalogosPopulate\Database\Repository;
12
use PhpCfdi\SatCatalogosPopulate\Utils\ArrayProcessors\RightTrim;
13
use PhpCfdi\SatCatalogosPopulate\Utils\CsvFile;
14
use Psr\Log\LoggerInterface;
15
use RuntimeException;
16
17
abstract class AbstractCsvInjector implements InjectorInterface
18
{
19
    abstract public function checkHeaders(CsvFile $csv): void;
20
21
    abstract public function dataTable(): DataTable;
22
23 607
    public function __construct(private readonly string $sourceFile)
24
    {
25
    }
26
27 103
    public function sourceFile(): string
28
    {
29 103
        return $this->sourceFile;
30
    }
31
32 11
    public function validate(): void
33
    {
34 11
        if (! file_exists($this->sourceFile) || is_dir($this->sourceFile) || ! is_readable($this->sourceFile)) {
35 3
            throw new RuntimeException("El archivo $this->sourceFile no existe o es un directorio o no se puede leer");
36
        }
37
    }
38
39 10
    public function inject(Repository $repository, LoggerInterface $logger): int
40
    {
41 10
        $tableName = $this->dataTable()->name();
42 10
        $filename = basename($this->sourceFile);
43
44 10
        $gateway = new DataTableGateway($this->dataTable(), $repository);
45 10
        if ($this->shouldRecreateTable()) {
46 10
            $logger->info("Creando tabla {$tableName}...");
47 10
            $gateway->recreate();
48
        }
49
50 10
        $logger->info("Verificando encabezado de {$filename}...");
51 10
        $csv = $this->createCsvFileReader();
52 10
        $this->checkHeaders($csv);
53
54 10
        $logger->info("Inyectando contenidos de {$filename} a {$tableName}...");
55 10
        $injected = $this->injectCsvToDataTable($csv, $gateway);
56 10
        $logger->info("Se inyectaron {$injected} registros en {$tableName}");
57
58 10
        return $injected;
59
    }
60
61 7
    protected function createCsvFileReader(): CsvFile
62
    {
63 7
        return new CsvFile($this->sourceFile(), new RightTrim());
64
    }
65
66 10
    protected function injectCsvToDataTable(CsvFile $csv, DataTableGateway $gateway): int
67
    {
68 10
        $inserted = 0;
69 10
        foreach ($this->readLinesFromCsv($csv) as $line) {
70 10
            $values = $gateway->dataTable()->fields()->transform($line);
71 10
            $this->injectValuesToDataTable($values, $gateway);
72 10
            $inserted = $inserted + 1;
73
        }
74 10
        return $inserted;
75
    }
76
77
    /** @param array<string, scalar> $values */
78 10
    protected function injectValuesToDataTable(array $values, DataTableGateway $gateway): void
79
    {
80 10
        if ($this->shouldRecreateTable()) {
81 10
            $gateway->insert($values);
82
        } else {
83 1
            $gateway->replace($values);
84
        }
85
    }
86
87
    /**
88
     * @return Generator<int, array<int, scalar>>
89
     */
90 5
    protected function readLinesFromCsv(CsvFile $csv): Iterator
91
    {
92 5
        yield from $csv->readLines();
93
    }
94
95 10
    protected function shouldRecreateTable(): bool
96
    {
97 10
        return true;
98
    }
99
}
100