Skip to content

Commit c05a9f5

Browse files
authored
Add support for specifying deletion data to be inserted when a record is deleted. (#20)
1 parent df79ab3 commit c05a9f5

4 files changed

Lines changed: 57 additions & 7 deletions

File tree

src/Definition.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ class Definition
3939
*/
4040
private $deletionTimestamp;
4141

42+
/**
43+
* @var array
44+
*/
45+
private $deletionData = [];
46+
4247
/**
4348
* @var array
4449
*/
@@ -162,6 +167,18 @@ public function withDeletionTimestamp(string $column)
162167
return $this;
163168
}
164169

170+
/**
171+
* Sets an array of table data to be included when a record is removed.
172+
*
173+
* @param array $data
174+
* @return Definition
175+
*/
176+
public function withDeletionData(array $data): self
177+
{
178+
$this->deletionData = $data;
179+
return $this;
180+
}
181+
165182
/**
166183
* Sets an array of table data to be included when a record is inserted.
167184
*
@@ -257,6 +274,16 @@ public function getDeletionTimestamp()
257274
return $this->deletionTimestamp;
258275
}
259276

277+
/**
278+
* Returns an array of table data to be included when a record is removed.
279+
*
280+
* @return array
281+
*/
282+
public function getDeletionData()
283+
{
284+
return $this->deletionData;
285+
}
286+
260287
/**
261288
* Returns an array of table data to be included when a record is inserted.
262289
*

src/Mapping.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,9 @@ private function replace(array $data, array $original, array $deleteIds = [])
407407
private function delete($ids = [])
408408
{
409409
foreach ($ids as $table => $deleteColumns) {
410-
foreach ($deleteColumns as $deletion => $primaries) {
410+
foreach ($deleteColumns as $deletion => $deletionContext) {
411411
// Arrange values into groups based on all but the last key
412-
$grouped = Collection::group($primaries, function($keys) {
412+
$grouped = Collection::group($deletionContext['keys'], function(array $keys) {
413413
array_pop($keys);
414414
return implode(':', $keys);
415415
});
@@ -453,7 +453,17 @@ private function delete($ids = [])
453453

454454
$query->closeOr();
455455

456-
$result = $deletion ? $query->isNull($deletion)->update([$deletion => gmdate('Y-m-d H:i:s')]) : $query->remove();
456+
if ($deletion) {
457+
$result = $query
458+
->isNull($deletion)
459+
->update(array_merge(
460+
[$deletion => gmdate('Y-m-d H:i:s')],
461+
$deletionContext['data']
462+
));
463+
} else {
464+
$result = $query->remove();
465+
}
466+
457467
if (!$result) {
458468
throw new \Exception('Failed to delete records.');
459469
}
@@ -468,21 +478,26 @@ private function delete($ids = [])
468478
*
469479
* @param array $data
470480
* @param array $list
471-
* @return array
481+
* @return array<string, array<string, array{
482+
* keys: list<array<string, mixed>>,
483+
* data: array<string, mixed>
484+
* }>>
472485
*/
473486
private function collectPrimary(array $data = [], $list = [])
474487
{
475488
$table = $this->definition->getTable();
476489
$primaryKey = $this->definition->getPrimaryKey();
477490
$deletion = $this->definition->getDeletionTimestamp();
491+
$deletionData = $this->definition->getDeletionData();
478492

479493
$item = [];
480494

481495
foreach ($primaryKey as $column) {
482496
$item[$column] = $data[$column];
483497
}
484498

485-
$list[$table][$deletion][] = $item;
499+
$list[$table][$deletion]['keys'][] = $item;
500+
$list[$table][$deletion]['data'] = $deletionData;
486501

487502
foreach ($this->definition->getProperties() as $property) {
488503
$values = $data[$property->getName()] ?? [];

tests/Fixtures.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
-- Prepare schema
22
DROP TABLE IF EXISTS customers;
3-
CREATE TABLE customers (id INTEGER PRIMARY KEY, name TEXT, date_deleted TEXT);
3+
CREATE TABLE customers (id INTEGER PRIMARY KEY, name TEXT, date_deleted TEXT, deleted_by TEXT);
44

55
DROP TABLE IF EXISTS orders;
66
CREATE TABLE orders (id INTEGER PRIMARY KEY, customer_id INTEGER, date_created TEXT, date_deleted TEXT);

tests/MappingTest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ public function testRemove()
185185

186186
$removed = $this->getMapping()->eq('id', 1)->findOne();
187187
$this->assertNull($removed);
188+
189+
$this->assertSame(
190+
'Admin',
191+
$this->db->table('customers')->eq('id', 1)->findOneColumn('deleted_by')
192+
);
188193
}
189194

190195
public function testReadOnlyInsert()
@@ -417,7 +422,10 @@ public function getMapping()
417422
$customer = (new Definition('customers'))
418423
->withColumns('id', 'name')
419424
->withMany($order, 'orders', 'customer_id')
420-
->withDeletionTimestamp('date_deleted');
425+
->withDeletionTimestamp('date_deleted')
426+
->withDeletionData([
427+
'deleted_by' => 'Admin'
428+
]);
421429

422430
return new Mapping($this->db, $customer, [], [
423431
'inserted' => [$this->hook],

0 commit comments

Comments
 (0)