Skip to content

Commit

Permalink
Support for more complex conditions for update(),delete()
Browse files Browse the repository at this point in the history
Replacement for codeigniter4#1441  and codeigniter4#1325  + improvements (outer function for parsing id, and better condition checking).

Allows to pass more complex data for update and delete methods.
Before delete and update supports only numeric $id. and produces: WHERE primaryKey IN(1); or WHERE primaryKey IN(2,3,4) - for arrays.

I've added support for:
- non empty string -> WHERE table.primaryKey = 'value'    `$id = 'value'`  (it was wired it doesn't support it and we are thinking about production version of ci4)
- associative arrays -> WHERE table.field = 'value'  `$id =['field' => 'value']`
- more complex associative arrays -> WHERE table.field = 'value' AND table.fieldin IN(2,3,4) `$id =['field' => 'value', 'fieldin' => [2,3,4]]`
  • Loading branch information
nowackipawel authored Jan 2, 2019
1 parent 0fba13c commit 4dddb4a
Showing 1 changed file with 56 additions and 20 deletions.
76 changes: 56 additions & 20 deletions system/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -680,15 +680,64 @@ public function insertBatch($set = null, $escape = null, $batchSize = 100, $test
}

//--------------------------------------------------------------------

/**
* @param $id integer|string|array|null:
* int|string: WHERE $this->table.$this->primaryKey = $id
* indexed array: WHERE $this->table.$this->primaryKey IN ([2,3]) <i.e.: $id = [2,3]>
* associative array: WHERE $this->table.key1 = 1 AND $this->table.key2 IN([2,3]) <i.e.: $id = [key1 => 1, key2 => [2,3]]>
* @return BaseBuilder
*/
private function parseId($id = null)
{

$builder = $this->builder();

// is numeric or is non empty string
if(!empty($id))
{
if(is_numeric($id) || !is_string($id))
{
$builder = $builder->where($this->table.'.'.$this->primaryKey, $id);
}
elseif(is_array($id))
{
//$id contains an indexed array
if(array_keys($id) === range(0, count($id) -1))
{
$builder = $builder->whereIn($this->table.'.'.$this->primaryKey, $id);
}
//$id contains associative array
else
{
foreach ($id as $key => $value)
{
if(!empty($value) && is_array($value))
{
$builder = $builder->whereIn($this->table.'.'.$key, $value);
}
else
{
$builder = $builder->where($this->table.'.'.$key, $value);
}
}
}
}
}

return $builder;
}
//--------------------------------------------------------------------

/**
* Updates a single record in $this->table. If an object is provided,
* Updates a single or multiple records in $this->table. If an object is provided,
* it will attempt to convert it into an array.
*
* @param integer|array|string $id
* @param array|object $data
* @param integer|string|array|null $id The rows primary key(s) or complex conditions as specified in parseId()
* @param array|object $data
*
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
public function update($id = null, $data = null)
{
Expand Down Expand Up @@ -752,12 +801,7 @@ public function update($id = null, $data = null)
throw DataException::forEmptyDataset('update');
}

$builder = $this->builder();

if ($id)
{
$builder = $builder->whereIn($this->table . '.' . $this->primaryKey, $id);
}
$builder = $this->parseId($id);

// Must use the set() method to ensure objects get converted to arrays
$result = $builder
Expand Down Expand Up @@ -806,25 +850,17 @@ public function updateBatch($set = null, $index = null, $batchSize = 100, $retur
* Deletes a single record from $this->table where $id matches
* the table's primaryKey
*
* @param integer|array|null $id The rows primary key(s)
* @param integer|string|array|null $id The rows primary key(s) or complex conditions as specified in parseId()
* @param boolean $purge Allows overriding the soft deletes setting.
*
* @return mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
public function delete($id = null, $purge = false)
{
if (! empty($id) && is_numeric($id))
{
$id = [$id];
}

$builder = $this->builder();
if (! empty($id))
{
$builder = $builder->whereIn($this->primaryKey, $id);
}

$builder = $this->parseId($id);

$this->trigger('beforeDelete', ['id' => $id, 'purge' => $purge]);

if ($this->useSoftDeletes && ! $purge)
Expand Down

0 comments on commit 4dddb4a

Please sign in to comment.