cascadeDelete method

Future<CascadeDeleteResult<T>> cascadeDelete({
  1. required String id,
  2. required String userId,
  3. DataSource source = DataSource.local,
  4. bool forceRemoteSync = false,
})

Deletes an entity with cascading behavior based on relationship configurations.

This method respects the CascadeDeleteBehavior configured on each relationship:

The method performs deletes in dependency order to avoid foreign key constraint violations.

Returns a CascadeDeleteResult containing information about the operation.

Implementation

Future<CascadeDeleteResult<T>> cascadeDelete({
  required String id,
  required String userId,
  DataSource source = DataSource.local,
  bool forceRemoteSync = false,
}) async {
  _ensureInitialized();
  // Check for user switch before proceeding.
  await _syncEngineInstance.checkForUserSwitch(userId);

  final entity = await localAdapter.read(id, userId: userId);
  if (entity == null) {
    _logger.debug('Entity $id does not exist for user $userId, skipping cascade delete');
    return CascadeDeleteResult<T>(
      success: false,
      entity: null,
      deletedEntities: {},
      restrictedRelations: {},
      errors: ['Entity $id does not exist'],
    );
  }

  if (!entity.isRelational) {
    // Fall back to regular delete for non-relational entities
    final deleted = await delete(id: id, userId: userId, source: source, forceRemoteSync: forceRemoteSync);
    return CascadeDeleteResult<T>(
      success: deleted,
      entity: entity,
      deletedEntities: deleted
          ? {
              T: [entity]
            }
          : {},
      restrictedRelations: {},
      errors: deleted ? [] : ['Failed to delete entity'],
    );
  }

  final deletePlan = await _buildCascadeDeletePlan(entity, userId, CascadeAnalyticsBuilder());

  if (!deletePlan.canDelete) {
    return CascadeDeleteResult<T>(
      success: false,
      entity: entity,
      deletedEntities: {},
      restrictedRelations: deletePlan.restrictedRelations,
      errors: ['Delete restricted by relationships'],
    );
  }

  // Execute the delete plan
  final result = await _executeCascadeDeletePlan(deletePlan, userId, source, forceRemoteSync);

  // Emit the main entity delete event
  _eventController.add(
    DataChangeEvent<T>(
      userId: userId,
      data: entity,
      changeType: ChangeType.deleted,
      source: source,
    ),
  );

  return result;
}