diff --git a/Tests/dblayerooComplet.php b/Tests/dblayerooComplet.php index c908212..d6345e4 100644 --- a/Tests/dblayerooComplet.php +++ b/Tests/dblayerooComplet.php @@ -829,4 +829,29 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase $res); } + public function test_update5 () + { + // Manage to update the non unique fields + // the "where" column is not unique, so it allow to have twice the same + // value + $db1 = $this->db1 (); + $res = $db1->update() + ->setValues(array ("where"=>"where2")) + ->execute (); + $db1->disconnect (); + $this->assertSame (2, $res); + } + + public function test_update6 () + { + // Manage to update the primary / unique fields + // There is 2 lines in the DB, so the unique key "group" can not be updated + // with the same value twice (the result can not be unique) + $db1 = $this->db1 (); + $this->setExpectedException ("Exception"); + $res = $db1->update() + ->setValues(array ("group"=>"group3")) + ->execute (); + $db1->disconnect (); + } } diff --git a/dblayeroo.php b/dblayeroo.php index 452c222..c0b13ef 100644 --- a/dblayeroo.php +++ b/dblayeroo.php @@ -2539,36 +2539,48 @@ class dblayeroo if (! in_array ($this->primary, $uniques)) $uniques = array_merge (array ($this->primary), $uniques); $setValues = $values; - if (! array_key_exists ($this->primary, $setValues)) - $setValues[$this->primary] = null; + $foundImpactedColumns = 0; foreach ($uniques as $k=>$columns) { - if ($update !== false && ! isset ($resUpdate)) + if ($update) { // Can not update multiple UNIQUE rows with the same value - $this->debugLog ("CLONE because of update"); - $objTmp = clone $this; - $objTmp->debugDepth++; - $objTmp->clearRequest (); - $objTmp->Select (); - $objTmp->displayAdd ($this->primary); - $objTmp->displayAdd ($columns); - $objTmp->whereValues = $this->whereValues; - $objTmp->whereExpression = $this->whereExpression; - $objTmp->limitLines (3); - $resUpdate = $objTmp->execute (); - unset ($objTmp); -/* if (count ($resUpdate) > 1) - $this->DBException (sprintf (dgettext ("domframework", - "Can't update multiple rows with unique value"), $columns)); -*/ - if (count ($resUpdate) === 0) + $cols = explode (",", $columns); + foreach ($cols as $col) + { + if (!key_exists ($col, $setValues)) + continue; + // One column to set is a unique column : check if the where clause + // is filtering more than one entry. If there is more than one + // entry, generate an exception + $this->debugLog ("CLONE because of update"); + $objTmp = clone $this; + $objTmp->debugDepth++; + $objTmp->clearRequest (); + $objTmp->Select (); + $objTmp->displayAdd ($this->primary); + $objTmp->displayAdd ($columns); + $objTmp->whereValues = $this->whereValues; + $objTmp->whereExpression = $this->whereExpression; + $objTmp->limitLines (3); + $resUpdate = $objTmp->execute (); + unset ($objTmp); + if (count ($resUpdate) > 1) + $this->DBException (sprintf (dgettext ("domframework", + "Can't update multiple rows with unique value on col '%s'"), + $col)); + elseif (count ($resUpdate) === 1) + $foundImpactedColumns++; + } + if ($foundImpactedColumns === 0) { // There is no row available with the WHERE clause provided // Skip all the UNIQUE tests as there will not have any modification break; } } + if (! array_key_exists ($this->primary, $setValues)) + $setValues[$this->primary] = null; $this->debugLog ("CLONE to check primary and unique constraint"); $objTmp = clone $this;