Skip to content

Commit f5e1541

Browse files
committed
InsertBatch and UpdateBatch now included in Model and will validate each row prior to saving. Fixes #967
1 parent 67aadd9 commit f5e1541

4 files changed

Lines changed: 153 additions & 12 deletions

File tree

system/Database/BaseBuilder.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,13 +1508,13 @@ public function getWhere($where = null, $limit = null, $offset = null)
15081508
* @param array $set An associative array of insert values
15091509
* @param bool $escape Whether to escape values and identifiers
15101510
*
1511-
* @param int $batch_size
1511+
* @param int $batchSize
15121512
* @param bool $testing
15131513
*
15141514
* @return int Number of rows inserted or FALSE on failure
15151515
* @throws DatabaseException
15161516
*/
1517-
public function insertBatch($set = null, $escape = null, $batch_size = 100, $testing = false)
1517+
public function insertBatch($set = null, $escape = null, $batchSize = 100, $testing = false)
15181518
{
15191519
if ($set === null)
15201520
{
@@ -1547,9 +1547,9 @@ public function insertBatch($set = null, $escape = null, $batch_size = 100, $tes
15471547

15481548
// Batch this baby
15491549
$affected_rows = 0;
1550-
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batch_size)
1550+
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batchSize)
15511551
{
1552-
$sql = $this->_insertBatch($this->db->protectIdentifiers($table, true, $escape, false), $this->QBKeys, array_slice($this->QBSet, $i, $batch_size));
1552+
$sql = $this->_insertBatch($this->db->protectIdentifiers($table, true, $escape, false), $this->QBKeys, array_slice($this->QBSet, $i, $batchSize));
15531553

15541554
if ($testing)
15551555
{
@@ -1975,15 +1975,15 @@ protected function validateUpdate()
19751975
*
19761976
* Compiles an update string and runs the query
19771977
*
1978-
* @param array $set An associative array of update values
1979-
* @param string $index The where key
1980-
* @param int $batch_size The size of the batch to run
1981-
* @param bool $returnSQL True means SQL is returned, false will execute the query
1978+
* @param array $set An associative array of update values
1979+
* @param string $index The where key
1980+
* @param int $batchSize The size of the batch to run
1981+
* @param bool $returnSQL True means SQL is returned, false will execute the query
19821982
*
19831983
* @return mixed Number of rows affected or FALSE on failure
19841984
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
19851985
*/
1986-
public function updateBatch($set = null, $index = null, $batch_size = 100, $returnSQL = false)
1986+
public function updateBatch($set = null, $index = null, $batchSize = 100, $returnSQL = false)
19871987
{
19881988
if ($index === null)
19891989
{
@@ -2025,9 +2025,9 @@ public function updateBatch($set = null, $index = null, $batch_size = 100, $retu
20252025
// Batch this baby
20262026
$affected_rows = 0;
20272027
$savedSQL = [];
2028-
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batch_size)
2028+
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batchSize)
20292029
{
2030-
$sql = $this->_updateBatch($table, array_slice($this->QBSet, $i, $batch_size), $this->db->protectIdentifiers($index)
2030+
$sql = $this->_updateBatch($table, array_slice($this->QBSet, $i, $batchSize), $this->db->protectIdentifiers($index)
20312031
);
20322032

20332033
if ($returnSQL)

system/HTTP/Exceptions/HTTPException.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,11 @@ public static function forAlreadyMoved()
193193
/**
194194
* For Uploaded file move
195195
*
196+
* @param string|null $path
197+
*
196198
* @return \CodeIgniter\HTTP\Exceptions\HTTPException
197199
*/
198-
public static function forInvalidFile()
200+
public static function forInvalidFile(string $path=null)
199201
{
200202
return new static(lang('HTTP.invalidFile'));
201203
}

system/Model.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,35 @@ public function insert($data = null, bool $returnID = true)
622622

623623
//--------------------------------------------------------------------
624624

625+
/**
626+
* Compiles batch insert strings and runs the queries, validating each row prior.
627+
*
628+
* @param array $set An associative array of insert values
629+
* @param bool $escape Whether to escape values and identifiers
630+
*
631+
* @param int $batchSize
632+
* @param bool $testing
633+
*
634+
* @return int Number of rows inserted or FALSE on failure
635+
*/
636+
public function insertBatch($set = null, $escape = null, $batchSize = 100, $testing = false)
637+
{
638+
if (is_array($set) && $this->skipValidation === false)
639+
{
640+
foreach ($set as $row)
641+
{
642+
if ($this->validate($row) === false)
643+
{
644+
return false;
645+
}
646+
}
647+
}
648+
649+
return $this->builder()->insertBatch($set, $escape, $batchSize, $testing);
650+
}
651+
652+
//--------------------------------------------------------------------
653+
625654
/**
626655
* Updates a single record in $this->table. If an object is provided,
627656
* it will attempt to convert it into an array.
@@ -712,6 +741,37 @@ public function update($id = null, $data = null)
712741

713742
//--------------------------------------------------------------------
714743

744+
/**
745+
* Update_Batch
746+
*
747+
* Compiles an update string and runs the query
748+
*
749+
* @param array $set An associative array of update values
750+
* @param string $index The where key
751+
* @param int $batchSize The size of the batch to run
752+
* @param bool $returnSQL True means SQL is returned, false will execute the query
753+
*
754+
* @return mixed Number of rows affected or FALSE on failure
755+
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
756+
*/
757+
public function updateBatch($set = null, $index = null, $batchSize = 100, $returnSQL = false)
758+
{
759+
if (is_array($set) && $this->skipValidation === false)
760+
{
761+
foreach ($set as $row)
762+
{
763+
if ($this->validate($row) === false)
764+
{
765+
return false;
766+
}
767+
}
768+
}
769+
770+
return $this->builder()->updateBatch($set, $index, $batchSize, $returnSQL);
771+
}
772+
773+
//--------------------------------------------------------------------
774+
715775
/**
716776
* Deletes a single record from $this->table where $id matches
717777
* the table's primaryKey

tests/system/Database/Live/ModelTest.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,4 +633,83 @@ public function testUpdateArray()
633633
$this->seeInDatabase('user', ['id' => 1, 'name' => 'Foo Bar']);
634634
$this->seeInDatabase('user', ['id' => 2, 'name' => 'Foo Bar']);
635635
}
636+
637+
public function testInsertBatchSuccess()
638+
{
639+
$job_data = [
640+
['name' => 'Comedian', 'description' => 'Theres something in your teeth'],
641+
['name' => 'Cab Driver', 'description' => 'Iam yellow'],
642+
];
643+
644+
$model = new JobModel($this->db);
645+
$model->insertBatch($job_data);
646+
647+
$this->seeInDatabase('job', ['name' => 'Comedian']);
648+
$this->seeInDatabase('job', ['name' => 'Cab Driver']);
649+
}
650+
651+
public function testInsertBatchValidationFail()
652+
{
653+
$job_data = [
654+
['name' => 'Comedian', 'description' => null],
655+
];
656+
657+
$model = new JobModel($this->db);
658+
659+
$this->setPrivateProperty($model, 'validationRules', ['description' => 'required']);
660+
661+
$this->assertFalse($model->insertBatch($job_data));
662+
663+
$error = $model->errors();
664+
$this->assertTrue(isset($error['description']));
665+
}
666+
667+
public function testUpdateBatchSuccess()
668+
{
669+
$data = [
670+
[
671+
'name' => 'Derek Jones',
672+
'country' => 'Greece'
673+
],
674+
[
675+
'name' => 'Ahmadinejad',
676+
'country' => 'Greece'
677+
],
678+
];
679+
680+
$model = new EventModel($this->db);
681+
682+
$model->updateBatch($data, 'name');
683+
684+
$this->seeInDatabase('user', [
685+
'name' => 'Derek Jones',
686+
'country' => 'Greece'
687+
]);
688+
$this->seeInDatabase('user', [
689+
'name' => 'Ahmadinejad',
690+
'country' => 'Greece'
691+
]);
692+
}
693+
694+
//--------------------------------------------------------------------
695+
696+
public function testUpdateBatchValidationFail()
697+
{
698+
$data = [
699+
[
700+
'name' => 'Derek Jones',
701+
'country' => null
702+
],
703+
];
704+
705+
$model = new EventModel($this->db);
706+
$this->setPrivateProperty($model, 'validationRules', ['country' => 'required']);
707+
708+
$this->assertFalse($model->updateBatch($data, 'name'));
709+
710+
$error = $model->errors();
711+
$this->assertTrue(isset($error['country']));
712+
}
713+
714+
//--------------------------------------------------------------------
636715
}

0 commit comments

Comments
 (0)