Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
CsvDatabaseMapper
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 4
420
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 insert
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
30
 select
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
72
 update
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Utils\IO\Csv
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Utils\IO\Csv;
16
17use phpOMS\DataStorage\Database\Connection\ConnectionAbstract;
18use phpOMS\DataStorage\Database\Query\Builder;
19use phpOMS\Utils\IO\IODatabaseMapper;
20
21/**
22 * Csv database mapper.
23 *
24 * @package phpOMS\Utils\IO\Csv
25 * @license OMS License 2.0
26 * @link    https://jingga.app
27 * @since   1.0.0
28 */
29class CsvDatabaseMapper implements IODatabaseMapper
30{
31    /**
32     * Database connection
33     *
34     * @var ConnectionAbstract
35     * @since 1.0.0
36     */
37    private ConnectionAbstract $con;
38
39    /**
40     * Path to source or destination
41     *
42     * @var string
43     * @since 1.0.0
44     */
45    private string $path = '';
46
47    /**
48     * Constructor.
49     *
50     * @param ConnectionAbstract $con  Database connection
51     * @param string             $path File path
52     *
53     * @since 1.0.0
54     */
55    public function __construct(ConnectionAbstract $con, string $path)
56    {
57        $this->con  = $con;
58        $this->path = $path;
59    }
60
61    /**
62     * {@inheritdoc}
63     */
64    public function insert() : void
65    {
66        $fp = \fopen($this->path, 'r');
67        if ($fp === false) {
68            return;
69        }
70
71        $table  = \basename($this->path, '.csv');
72        $titles = [];
73
74        // get column titles
75        $titles = \fgetcsv($fp, 4096);
76        if ($titles === false) {
77            return;
78        }
79
80        $columns = \count($titles);
81        if ($columns === 0) {
82            return;
83        }
84
85        // insert data
86        $query = new Builder($this->con);
87        $query->insert(...$titles)->into($table);
88
89        while (($cells = \fgetcsv($fp)) !== false) {
90            $query->values(...$cells);
91        }
92
93        $query->execute();
94
95        \fclose($fp);
96    }
97
98    /**
99     * {@inheritdoc}
100     */
101    public function select(array $queries) : void
102    {
103        $fp = \fopen($this->path, 'r+');
104        if ($fp === false) {
105            return;
106        }
107
108        foreach ($queries as $key => $query) {
109            $results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC);
110            if (!\is_array($results)) {
111                continue;
112            }
113
114            if ($key > 0) {
115                return;
116            }
117
118            $rows = \count($results);
119            if ($rows < 1) {
120                break;
121            }
122
123            $colCount = \count($results[0]);
124            $columns  = \array_keys($results[0]);
125
126            // set column titles
127            for ($i = 1; $i <= $colCount; ++$i) {
128                \fputcsv($fp, $columns);
129            }
130
131            // set data
132            foreach ($results as $result) {
133                \fputcsv($fp, $result);
134            }
135        }
136
137        \fclose($fp);
138    }
139
140    /**
141     * {@inheritdoc}
142     */
143    public function update() : void
144    {
145        $fp = \fopen($this->path, 'r+');
146        if ($fp === false) {
147            return;
148        }
149
150        $table  = \basename($this->path, '.csv');
151        $titles = [];
152
153        // get column titles
154        $titles = \fgetcsv($fp, 4096);
155        if ($titles === false) {
156            return;
157        }
158
159        $columns = \count($titles);
160        if ($columns === 0) {
161            return;
162        }
163
164        $idCol = (string) \array_shift($titles);
165
166        // update data
167        while (($cells = \fgetcsv($fp)) !== false) {
168            $query = new Builder($this->con);
169            $query->update($table);
170
171            for ($j = 2; $j <= $columns; ++$j) {
172                $query->sets((string) $titles[$j - 2], $cells[$j - 1]);
173            }
174
175            $query->where($idCol, '=', $cells[0]);
176            $query->execute();
177        }
178
179        \fclose($fp);
180    }
181}