add CsvDatabaseMapper

This commit is contained in:
Dennis Eichhorn 2023-09-26 23:07:51 +00:00
parent 2cbab79465
commit a0de10c939
3 changed files with 189 additions and 11 deletions

View File

@ -1027,7 +1027,7 @@ class Builder extends BuilderAbstract
/** /**
* Update columns. * Update columns.
* *
* @param mixed ...$tables Column names to update * @param mixed ...$columns Column names to update
* *
* @return Builder * @return Builder
* *
@ -1036,7 +1036,7 @@ class Builder extends BuilderAbstract
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function update(mixed ...$tables) : self public function update(mixed ...$columns) : self
{ {
if ($this->isReadOnly) { if ($this->isReadOnly) {
throw new \Exception(); throw new \Exception();
@ -1044,11 +1044,11 @@ class Builder extends BuilderAbstract
$this->type = QueryType::UPDATE; $this->type = QueryType::UPDATE;
/** @var mixed[] $tables */ /** @var mixed[] $columns */
/** @var mixed $table */ /** @var mixed $table */
foreach ($tables as $table) { foreach ($columns as $column) {
if (\is_string($table) || $table instanceof self) { if (\is_string($column) || $column instanceof self) {
$this->updates[] = $table; $this->updates[] = $column;
} else { } else {
throw new \InvalidArgumentException(); throw new \InvalidArgumentException();
} }

View File

@ -0,0 +1,176 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package phpOMS\Utils\IO\Csv
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\Utils\IO\Csv;
use phpOMS\DataStorage\Database\Connection\ConnectionAbstract;
use phpOMS\DataStorage\Database\Query\Builder;
use phpOMS\Utils\IO\IODatabaseMapper;
use phpOMS\Utils\StringUtils;
/**
* Csv database mapper.
*
* @package phpOMS\Utils\IO\Csv
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class CsvDatabaseMapper implements IODatabaseMapper
{
/**
* Database connection
*
* @var ConnectionAbstract
* @since 1.0.0
*/
private ConnectionAbstract $con;
/**
* Path to source or destination
*
* @var string
* @since 1.0.0
*/
private string $path = '';
/**
* Constructor.
*
* @param ConnectionAbstract $con Database connection
* @param string $path File path
*
* @since 1.0.0
*/
public function __construct(ConnectionAbstract $con, string $path)
{
$this->con = $con;
$this->path = $path;
}
/**
* {@inheritdoc}
*/
public function insert() : void
{
$fp = \fopen($this->path, 'r');
if ($fp === false) {
return;
}
$table = \basename($this->path, '.csv');
$titles = [];
// get column titles
$titles[] = \fgetcsv($fp, 4096);
$columns = \count($titles);
if ($columns === 0) {
return;
}
// insert data
$query = new Builder($this->con);
$query->insert(...$titles)->into($table);
while (($cells = \fgetcsv($fp)) !== false) {
$query->values(...$cells);
}
$query->execute();
\fclose($fp);
}
/**
* {@inheritdoc}
*/
public function select(array $queries) : void
{
$fp = \fopen($this->path, 'r+');
if ($fp === false) {
return;
}
foreach ($queries as $key => $query) {
$results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC);
if (!\is_array($results)) {
continue;
}
if ($key > 0) {
return;
}
$rows = \count($results);
if ($rows < 1) {
break;
}
$colCount = \count($results[0]);
$columns = \array_keys($results[0]);
// set column titles
for ($i = 1; $i <= $colCount; ++$i) {
\fputcsv($fp, $columns);
}
// set data
foreach ($results as $result) {
\fputcsv($fp, $result);
}
}
\fclose($fp);
}
/**
* {@inheritdoc}
*/
public function update() : void
{
$fp = \fopen($this->path, 'r+');
if ($fp === false) {
return;
}
$table = \basename($this->path, '.csv');
$titles = [];
// get column titles
$titles[] = \fgetcsv($fp, 4096);
$columns = \count($titles);
if ($columns === 0) {
return;
}
$idCol = (string) \array_shift($titles);
// update data
while (($cells = \fgetcsv($fp)) !== false) {
$query = new Builder($this->con);
$query->update($titles)->into($table);
for ($j = 2; $j <= $columns; ++$j) {
$query->sets((string) $titles[$j - 2], $cells[$j - 1]);
}
$query->where($idCol, '=', $cells[0]);
$query->execute();
}
\fclose($fp);
}
}

View File

@ -133,7 +133,7 @@ class SpreadsheetDatabaseMapper implements IODatabaseMapper
foreach ($queries as $key => $query) { foreach ($queries as $key => $query) {
$results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC); $results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC);
if ($results === null) { if (!\is_array($results)) {
continue; continue;
} }
@ -142,7 +142,7 @@ class SpreadsheetDatabaseMapper implements IODatabaseMapper
} }
$workSheet = $sheet->setActiveSheetIndex($key); $workSheet = $sheet->setActiveSheetIndex($key);
$rows = $results === null ? 0 : \count($results); $rows = \count($results);
if ($rows < 1) { if ($rows < 1) {
break; break;
@ -215,17 +215,19 @@ class SpreadsheetDatabaseMapper implements IODatabaseMapper
continue; continue;
} }
$idCol = (string) \array_shift($titles);
// update data // update data
$line = 2; $line = 2;
while (!empty($workSheet->getCell('A' . $line)->getCalculatedValue())) { while (!empty($workSheet->getCell('A' . $line)->getCalculatedValue())) {
$query = new Builder($this->con); $query = new Builder($this->con);
$query->update($table)->into($table); $query->update($titles)->into($table);
for ($j = 2; $j <= $columns; ++$j) { for ($j = 2; $j <= $columns; ++$j) {
$query->sets($titles[$j - 1], $workSheet->getCell(StringUtils::intToAlphabet($j) . $line)->getCalculatedValue()); $query->sets((string) $titles[$j - 2], $workSheet->getCell(StringUtils::intToAlphabet($j) . $line)->getCalculatedValue());
} }
$query->where((string) $titles[0], '=', $workSheet->getCell('A' . $line)->getCalculatedValue()); $query->where($idCol, '=', $workSheet->getCell('A' . $line)->getCalculatedValue());
$query->execute(); $query->execute();
++$line; ++$line;