Importer::importRecord()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 3
dl 0
loc 14
ccs 5
cts 5
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpCfdi\RfcLinc\Updater;
6
7
use EngineWorks\ProgressStatus\NullProgress;
8
use EngineWorks\ProgressStatus\ProgressInterface;
9
use PhpCfdi\RfcLinc\DataGateway\FactoryInterface;
10
use PhpCfdi\RfcLinc\Domain\Catalog;
11
use PhpCfdi\RfcLinc\Domain\ListedRfc;
12
use PhpCfdi\RfcLinc\Domain\RfcLog;
13
use PhpCfdi\RfcLinc\Util\ReaderInterface;
14
15
class Importer
16
{
17
    /** @var FactoryInterface */
18
    private $gateways;
19
20
    /** @var Catalog */
21
    private $catalog;
22
23
    /** @var ProgressInterface */
24
    private $progress;
25
26 8
    public function __construct(Catalog $catalog, FactoryInterface $gateways, ProgressInterface $progress = null)
27
    {
28 8
        $this->catalog = $catalog;
29 8
        $this->gateways = $gateways;
30 8
        $this->progress = $progress ?: new NullProgress();
31 8
    }
32
33 3
    public function catalog(): Catalog
34
    {
35 3
        return $this->catalog;
36
    }
37
38
    public function gateways(): FactoryInterface
39
    {
40
        return $this->gateways;
41
    }
42
43
    public function progress(): ProgressInterface
44
    {
45
        return $this->progress;
46
    }
47
48 5
    public function incrementInserted()
49
    {
50 5
        $this->catalog->setInserted($this->catalog->inserted() + 1);
51 5
    }
52
53 3
    public function incrementUpdated()
54
    {
55 3
        $this->catalog->setUpdated($this->catalog->updated() + 1);
56 3
    }
57
58 3
    public function incrementDeleted()
59
    {
60 3
        $this->catalog->setDeleted($this->catalog->deleted() + 1);
61 3
    }
62
63 3
    public function importReader(ReaderInterface $reader): int
64
    {
65 3
        $processedLines = 0;
66 3
        while (true) {
67 3
            $line = $reader->readLine();
68 3
            if (false === $line) { // line: end of line
69 3
                break;
70
            }
71 3
            if ($this->importLine($line)) {
72 3
                $processedLines = $processedLines + 1;
73 3
                $this->progress->increase();
74
            }
75
        }
76 3
        return $processedLines;
77
    }
78
79 5
    public function importLine(string $line): bool
80
    {
81 5
        $input = str_getcsv($line, '|');
82 5
        if (3 === count($input)) {
83
            // do a simple check of the last item (can only be 1 or 0)
84
            // todo: benchmark to test using in_array
85 5
            if ('0' === $input[2] || '1' === $input[2]) {
86 5
                $this->importRecord($input[0], '1' === $input[1], '1' === $input[2]);
87 5
                return true;
88
            }
89
        }
90 4
        return false;
91
    }
92
93 4
    public function importRecord(string $rfc, bool $sncf, bool $sub)
94
    {
95 4
        $gwRfc = $this->gateways->listedRfc();
96
        /*
97
         * This has been tested
98
         * Is less expensive to perform exists + get + update than get + update
99
         * in mysql and pgsql, sqlite is almost the same
100
         */
101 4
        if ($gwRfc->exists($rfc)) {
102
            // update
103 2
            $this->performUpdate($gwRfc->get($rfc), $sncf, $sub);
104
        } else {
105
            // insert
106 4
            $this->performInsert(new ListedRfc($rfc, $this->catalog->date(), $sncf, $sub, false));
107
        }
108 4
    }
109
110 4
    public function performInsert(ListedRfc $listedRfc)
111
    {
112 4
        $this->gateways->listedRfc()->insert($listedRfc);
113 4
        $this->createLog($listedRfc->rfc(), RfcLog::ACTION_CREATED);
114 4
        $this->incrementInserted();
115 4
    }
116
117 2
    public function performUpdate(ListedRfc $listedRfc, bool $sncf, bool $sub)
118
    {
119 2
        $changed = false;
120 2
        if ($sncf !== $listedRfc->sncf()) {
121 2
            $listedRfc->setSncf($sncf);
122 2
            $this->createLog($listedRfc->rfc(), $sncf ? RfcLog::ACTION_CHANGE_SNCF_ON : RfcLog::ACTION_CHANGE_SNCF_OFF);
123 2
            $changed = true;
124
        }
125 2
        if ($sub !== $listedRfc->sub()) {
126 2
            $listedRfc->setSub($sub);
127 2
            $this->createLog($listedRfc->rfc(), $sub ? RfcLog::ACTION_CHANGE_SUB_ON : RfcLog::ACTION_CHANGE_SUB_OFF);
128 2
            $changed = true;
129
        }
130
131
        // change delete status and store
132 2
        $listedRfc->setDeleted(false);
133 2
        $this->gateways->listedRfc()->update($listedRfc);
134
135
        // only increment counter if a significant value changed
136 2
        if ($changed) {
137 2
            $this->incrementUpdated();
138
        }
139 2
    }
140
141 2
    public function performDelete(string $rfc)
142
    {
143 2
        $this->createLog($rfc, RfcLog::ACTION_REMOVED);
144 2
        $this->incrementDeleted();
145 2
    }
146
147 5
    public function createLog(string $rfc, int $type)
148
    {
149 5
        $this->gateways->rfclog()->insert(
150 5
            new RfcLog($this->catalog->date(), $rfc, $type)
151
        );
152 5
    }
153
}
154