Skip to content

Commit

Permalink
Merge pull request #20 from byjg/4.9
Browse files Browse the repository at this point in the history
Add the object InsertMultipleQuery
  • Loading branch information
byjg authored Sep 4, 2024
2 parents b054a92 + 962da52 commit 2bf9043
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 0 deletions.
97 changes: 97 additions & 0 deletions src/InsertMultipleQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace ByJG\MicroOrm;

use ByJG\AnyDataset\Db\DbFunctionsInterface;
use ByJG\MicroOrm\Exception\OrmInvalidFieldsException;

class InsertMultipleQuery extends Updatable
{
protected $fields = [];
protected $row = [];

public static function getInstance(string $table = null, array $fields = []): self
{
$query = new InsertMultipleQuery();
if (!is_null($table)) {
$query->table($table);
}

$query->fields($fields);

return $query;
}

public function fields(array $fields)
{
$this->fields = $fields;
$this->row = [];
return $this;
}

public function addRow($row)
{
if (count($this->fields) !== count($row)) {
throw new \InvalidArgumentException('The row must have the same number of fields');
}

$rowToAdd = [];
foreach ($this->fields as $field) {
if (!array_key_exists($field, $row)) {
throw new \InvalidArgumentException("The field '$field' must be in the row");
}
$rowToAdd[$field] = $row[$field];
}

$this->row[] = $rowToAdd;
}

/**
* @param $params
* @param DbFunctionsInterface|null $dbHelper
* @return null|string|string[]
* @throws \ByJG\MicroOrm\Exception\OrmInvalidFieldsException
*/
public function build(&$params, DbFunctionsInterface $dbHelper = null)
{
if (empty($this->fields)) {
throw new OrmInvalidFieldsException('You must specify the fields for insert');
}

$fieldsStr = $this->fields;
if (!is_null($dbHelper)) {
$fieldsStr = $dbHelper->delimiterField($fieldsStr);
}

$tableStr = $this->table;
if (!is_null($dbHelper)) {
$tableStr = $dbHelper->delimiterTable($tableStr);
}



$sql = 'INSERT INTO '
. $tableStr
. ' ( ' . implode(', ', $fieldsStr) . ' ) '
. ' values ';

$params = [];
$rowNum = 1;
foreach ($this->row as $row) {
$paramRow = [];
foreach ($row as $key => $value) {
$paramRow[$key . $rowNum] = $value;
}
$sql .= ' ( :' . implode(', :', array_keys($paramRow)) . ' ),';
$params = array_merge($params, $paramRow);
$rowNum++;
}

return ORMHelper::processLiteral(trim($sql, ","), $params);
}

public function convert(?DbFunctionsInterface $dbDriver = null): QueryBuilderInterface
{
throw new \InvalidArgumentException('It is not possible to convert an InsertMultipleQuery to a Query');
}
}
88 changes: 88 additions & 0 deletions tests/InsertMultipleQueryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

namespace Tests;

use ByJG\MicroOrm\InsertMultipleQuery;
use PHPUnit\Framework\TestCase;

class InsertMultipleQueryTest extends TestCase
{
/**
* @var InsertMultipleQuery
*/
protected $object;

protected function setUp(): void
{
$this->object = new InsertMultipleQuery();
}

protected function tearDown(): void
{
$this->object = null;
}

public function testInsert()
{
$this->object->table('test');
$this->object->fields(['fld1', 'fld2', 'fld3']);

$this->object->addRow(['fld1' => 'A', 'fld2' => 'B', 'fld3' => 'C']);
$this->object->addRow(['fld1' => 'D', 'fld2' => 'E', 'fld3' => 'F']);

$params = [];
$sql = $this->object->build($params);

$this->assertEquals('INSERT INTO test ( fld1, fld2, fld3 ) values ( :fld11, :fld21, :fld31 ), ( :fld12, :fld22, :fld32 )', $sql);
$this->assertEquals([
'fld11' => 'A',
'fld21' => 'B',
'fld31' => 'C',
'fld12' => 'D',
'fld22' => 'E',
'fld32' => 'F',
], $params);
}

public function testInsertStatic()
{
$query = InsertMultipleQuery::getInstance('test', ['fld1', 'fld2', 'fld3']);

$query->addRow(['fld1' => 'A', 'fld2' => 'B', 'fld3' => 'C']);
$query->addRow(['fld1' => 'D', 'fld2' => 'E', 'fld3' => 'F']);

$params = [];
$sql = $query->build($params);

$this->assertEquals('INSERT INTO test ( fld1, fld2, fld3 ) values ( :fld11, :fld21, :fld31 ), ( :fld12, :fld22, :fld32 )', $sql);
$this->assertEquals([
'fld11' => 'A',
'fld21' => 'B',
'fld31' => 'C',
'fld12' => 'D',
'fld22' => 'E',
'fld32' => 'F',
], $params);
}

public function testInsertError()
{
$query = InsertMultipleQuery::getInstance('test', ['fld1', 'fld2', 'fld3']);

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('The row must have the same number of fields');

$query->addRow(['fld1' => 'A', 'fld2' => 'B']);
}

public function testInsertError2()
{
$query = InsertMultipleQuery::getInstance('test', ['fld1', 'fld2', 'fld3']);

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("The field 'fld3' must be in the row");

$query->addRow(['fld1' => 'A', 'fld2' => 'B', 'nonexistent' => 'C']);
}

}

0 comments on commit 2bf9043

Please sign in to comment.