From d1396b7dfe91138dcda53df0c0378281e7edb771 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 27 Feb 2019 15:12:26 +1300 Subject: [PATCH] BUG Fix writeBaseRecord with unique indexes Fixes #6819 --- src/ORM/DataObject.php | 12 ++++--- tests/php/ORM/DataObjectSchemaTest.php | 31 +++++++++++++++++++ .../ORM/DataObjectSchemaTest/AllIndexes.php | 5 +++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index dc8c2c18971..682f7b15042 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -1413,8 +1413,10 @@ protected function prepareManipulationTable($baseTable, $now, $isNewRecord, &$ma // Inserts done one the base table are performed in another step, so the manipulation should instead // attempt an update, as though it were a normal update. $manipulation[$table]['command'] = $isNewRecord ? 'insert' : 'update'; - $manipulation[$table]['id'] = $this->record['ID']; $manipulation[$table]['class'] = $class; + if ($this->isInDB()) { + $manipulation[$table]['id'] = $this->record['ID']; + } } /** @@ -1433,10 +1435,10 @@ protected function writeBaseRecord($baseTable, $now) } // Perform an insert on the base table - $insert = new SQLInsert('"' . $baseTable . '"'); - $insert - ->assign('"Created"', $now) - ->execute(); + $manipulation = []; + $this->prepareManipulationTable($baseTable, $now, true, $manipulation, $this->baseClass()); + DB::manipulate($manipulation); + $this->changed['ID'] = self::CHANGE_VALUE; $this->record['ID'] = DB::get_generated_id($baseTable); } diff --git a/tests/php/ORM/DataObjectSchemaTest.php b/tests/php/ORM/DataObjectSchemaTest.php index da2a51d2328..e8fa1cb3d54 100644 --- a/tests/php/ORM/DataObjectSchemaTest.php +++ b/tests/php/ORM/DataObjectSchemaTest.php @@ -343,4 +343,35 @@ public function testFieldsCanBeIndexedFromFieldSpecs() 'columns' => ['IndexedMoneyCurrency', 'IndexedMoneyAmount'] ], $indexes['IndexedMoney']); } + + /** + * Ensure that records with unique indexes can be written + */ + public function testWriteUniqueIndexes() + { + // Create default object + $zeroObject = new AllIndexes(); + $zeroObject->Number = 0; + $zeroObject->write(); + + $this->assertListEquals( + [ + ['Number' => 0], + ], + AllIndexes::get() + ); + + // Test a new record can be created without clashing with default value + $validObject = new AllIndexes(); + $validObject->Number = 1; + $validObject->write(); + + $this->assertListEquals( + [ + ['Number' => 0], + ['Number' => 1], + ], + AllIndexes::get() + ); + } } diff --git a/tests/php/ORM/DataObjectSchemaTest/AllIndexes.php b/tests/php/ORM/DataObjectSchemaTest/AllIndexes.php index ae36d951a00..9c7f9b1a25d 100644 --- a/tests/php/ORM/DataObjectSchemaTest/AllIndexes.php +++ b/tests/php/ORM/DataObjectSchemaTest/AllIndexes.php @@ -5,6 +5,11 @@ use SilverStripe\ORM\DataObject; use SilverStripe\ORM\FieldType\DBIndexable; +/** + * @property int $Number + * @property string $Content + * @property string $Title + */ class AllIndexes extends DataObject implements TestOnly { private static $table_name = 'DataObjectSchemaTest_AllIndexes';