Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
145
backups/docs-backup-20250731125004/database/change-tracking.md
Normal file
145
backups/docs-backup-20250731125004/database/change-tracking.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# EntityManager Change Tracking
|
||||
|
||||
Das EntityManager Change Tracking System bietet detaillierte Informationen über Änderungen an Entities und optimiert gleichzeitig die Performance durch Vermeidung unnötiger UPDATE-Queries.
|
||||
|
||||
## Features
|
||||
|
||||
### ✅ Automatische Änderungserkennung
|
||||
- Vergleicht automatisch alte vs. neue Werte für alle Entity-Properties
|
||||
- Ignoriert Relations und ID-Properties bei der Änderungserkennung
|
||||
- Behandelt `null`-Werte und Typ-sensitive Vergleiche korrekt
|
||||
|
||||
### ✅ Performance-Optimierung
|
||||
- **Keine unnötigen DB-Queries**: UPDATE wird nur ausgeführt wenn Änderungen erkannt werden
|
||||
- **Selective Updates**: Nur geänderte Felder werden in der SET-Clause verwendet
|
||||
- **IdentityMap Integration**: Nutzt bereits geladene Entities für Vergleiche
|
||||
|
||||
### ✅ Event-System Integration
|
||||
- Liefert detaillierte Informationen für `EntityUpdatedEvent`
|
||||
- Ermöglicht Audit-Logging und Change-History
|
||||
- Unterstützt Domain Events und Event-Sourcing
|
||||
|
||||
## Usage Example
|
||||
|
||||
```php
|
||||
// Original Entity in IdentityMap laden
|
||||
$user = $entityManager->find(User::class, 1);
|
||||
|
||||
// Entity modifizieren
|
||||
$user->name = 'New Name';
|
||||
$user->age = 25;
|
||||
|
||||
// Update mit automatischem Change Tracking
|
||||
$entityManager->update($user);
|
||||
|
||||
// Das EntityUpdatedEvent enthält:
|
||||
// - changes: ['name', 'age']
|
||||
// - oldValues: ['name' => 'Old Name', 'age' => 24]
|
||||
// - newValues: ['name' => 'New Name', 'age' => 25]
|
||||
```
|
||||
|
||||
## Event Data Structure
|
||||
|
||||
```php
|
||||
class EntityUpdatedEvent
|
||||
{
|
||||
public readonly array $changes; // Geänderte Property-Namen
|
||||
public readonly array $oldValues; // Alte Werte [property => value]
|
||||
public readonly array $newValues; // Neue Werte [property => value]
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Benefits
|
||||
|
||||
### UPDATE Query Optimierung
|
||||
```sql
|
||||
-- Vorher: Alle Felder werden immer aktualisiert
|
||||
UPDATE users SET name = ?, email = ?, age = ?, status = ? WHERE id = ?
|
||||
|
||||
-- Nachher: Nur geänderte Felder werden aktualisiert
|
||||
UPDATE users SET name = ?, age = ? WHERE id = ?
|
||||
```
|
||||
|
||||
### Query-Vermeidung
|
||||
```php
|
||||
// Keine Änderungen erkannt → Kein UPDATE ausgeführt
|
||||
$user = $entityManager->find(User::class, 1);
|
||||
$identicalUser = new User(id: 1, name: $user->name, email: $user->email);
|
||||
$result = $entityManager->update($identicalUser); // Kein DB-Query!
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Change Detection Algorithm
|
||||
1. **IdentityMap Lookup**: Original Entity aus IdentityMap laden (falls vorhanden)
|
||||
2. **Property Comparison**: Reflection-basierter Vergleich aller Non-Relation Properties
|
||||
3. **Change Collection**: Sammlung von geänderten Feldern, alten und neuen Werten
|
||||
4. **Query Building**: SET-Clause nur für geänderte Properties
|
||||
5. **Event Dispatch**: EntityUpdatedEvent mit vollständigen Change-Informationen
|
||||
|
||||
### Edge Cases Handling
|
||||
- **Neue Entity ohne Original**: Alle Properties werden als "geändert" behandelt
|
||||
- **Keine Änderungen**: UPDATE wird komplett übersprungen
|
||||
- **Type-sensitive Vergleiche**: `0 !== '0'` wird korrekt erkannt
|
||||
- **Null-Werte**: `null` vs. Wert-Änderungen werden korrekt verarbeitet
|
||||
|
||||
## Testing
|
||||
|
||||
Das Change Tracking System ist durch umfassende Tests abgedeckt:
|
||||
|
||||
```bash
|
||||
# Change Tracking Logic Tests
|
||||
docker exec php ./vendor/bin/pest tests/Framework/Database/ChangeTrackingLogicTest.php
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Audit Logging
|
||||
```php
|
||||
// Event Listener für Audit Trail
|
||||
class AuditLogger
|
||||
{
|
||||
public function handle(EntityUpdatedEvent $event): void
|
||||
{
|
||||
foreach ($event->changes as $property) {
|
||||
$this->logChange([
|
||||
'entity' => $event->entityClass,
|
||||
'id' => $event->entityId,
|
||||
'property' => $property,
|
||||
'old_value' => $event->oldValues[$property],
|
||||
'new_value' => $event->newValues[$property],
|
||||
'timestamp' => $event->timestamp
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Change History
|
||||
```php
|
||||
// Automatische Versionierung
|
||||
class EntityVersioning
|
||||
{
|
||||
public function handle(EntityUpdatedEvent $event): void
|
||||
{
|
||||
if (!empty($event->changes)) {
|
||||
$this->createVersion([
|
||||
'entity_type' => $event->entityClass,
|
||||
'entity_id' => $event->entityId,
|
||||
'changes' => $event->changes,
|
||||
'data' => $event->newValues,
|
||||
'previous_data' => $event->oldValues
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Performance**: Bis zu 50% weniger DB-Queries durch intelligente Änderungserkennung
|
||||
2. **Audit-fähig**: Vollständige Change-History für Compliance und Debugging
|
||||
3. **Event-driven**: Ermöglicht reactive Programmierung und Domain Events
|
||||
4. **Type-safe**: Korrekte Behandlung aller PHP-Datentypen und Edge Cases
|
||||
5. **Zero-Config**: Funktioniert automatisch ohne zusätzliche Konfiguration
|
||||
Reference in New Issue
Block a user